Bounding/Triangle based collision detection for more than 1 object - possible?

Hi,



Is bounding based collision detection possible to implement for more than 1 node - e.g. can I do that for players and enemies?? I tried but for some reason if I kept both player and the enemy the player would go through more often than not?? Is it some known problem or am I implementing it incorrectly?? Just to answer any common questions - I am not setting it to "lastPosition" but making calculations instead as because the velocity does not go zero the player keeps bumping into the wall.



player collision detection(added same for enemies but then player went through most walls)




 private void findCollisions() //try and use this method for all have node as param
    {
        //Expand the collision detection to be even more precise
        //e.g. say movement in only one direction
        BoundingCollisionResults results = new BoundingCollisionResults();
        results.clear();
        walls.findCollisions(player1, results);
       
       
        if(results.getNumber()==0)
        {
            lastPosition = new Vector3f(player1.getLocalTranslation());
            System.out.println(player.getLocalTranslation());
        }
       
        else
        {
           
            //player1.getLocalTranslation().set(lastPosition);           
           
           
            Vector3f position = player1.getLocalTranslation();
            float X = position.getX();
            float Y = position.getY();
            float Z = position.getZ();
          
                      
            if(player1.getLocalTranslation().getX() > lastPosition.getX() && player1.getLocalTranslation().getZ() > lastPosition.getZ())
            {
                player1.setLocalTranslation(X-2.05f, Y, Z-2.05f);
                //player1.setLocalTranslation(lastPosition);
                System.out.println("Collision Detected at +X and +Z: " + player1.getLocalTranslation());
            }
           
            else if(player1.getLocalTranslation().getX() > lastPosition.getX() && player1.getLocalTranslation().getZ() < lastPosition.getZ())
            {
                player1.setLocalTranslation(X-2.05f, Y, Z+2.05f);
                System.out.println("Collision Detected at +X and -Z: " + player1.getLocalTranslation());
            }
           
            else if(player1.getLocalTranslation().getX() < lastPosition.getX() && player1.getLocalTranslation().getZ() > lastPosition.getZ())
            {
                player1.setLocalTranslation(X+2.05f, Y, Z-2.05f);
                System.out.println("Collision Detected at -X and +Z: " + player1.getLocalTranslation());
            }
           
            else if(player1.getLocalTranslation().getX() < lastPosition.getX() && player1.getLocalTranslation().getZ() < lastPosition.getZ())
            {
                player1.setLocalTranslation(X+2.05f, Y, Z+2.05f);
                System.out.println("Collision Detected at -X and -Z: " + player1.getLocalTranslation());
            }       
       
        }        
    }
   


basically use ray detection.



shoot a ray from ur player's current localtranslation forward, then find the intersection point and calculate the distance.



if ur player is really wide like a tank or something, u should shoot 2 rays from both sides of the bounding box of ur player.



this approach can also be used to prevent ur player from walking up a steep hill.

the lower part of the code isnt necessary.



the easist way is to set the player's translation back to the last translation. theres no point of doing the calculation.

Thanks neakor. The only problem with that is because the player is going at a certain velocity if I set it to last position which is closest to the wall the player will keep going into the wall. Because the velocity is handled by flagrush handler it is difficult to set it to 0. I tried to set the velocity to 0 on collision by making the flagrush handler and inner class and tried something along these lines:




float velocity;

if(player1.hasCollision(walls, false))
        {
            velocity = 0f;
            KeyNodeForwardAction forward = new KeyNodeForwardAction(player1, velocity);
            addAction(forward, "forward", true);
        }
       
        else
        {
            velocity = 22f;
            KeyNodeForwardAction forward = new KeyNodeForwardAction(player1, velocity);
            addAction(forward, "forward", true);
        }



Unfortunately that does not seem to work. If I could find another way to set this velocity to 0 on collision then it would be the best. Any ideas?

my approach to this kind problem is proactive.



instead of moving the ur player back to a previous location, do a collision check before u move it. if the returned distance between ur player and other objects is less than a tolerance value, just forbid the player from moving.

That sounds a better approach neakor. How do you do that kind of collision check? From what you say and from your experience it sounds like you have already worked on a game before. How did you approach it in terms of coding what you say above - could you give a small example?

Alright… I have come up with the code that throws the ray in default direction(that is enemy's +Z) and based on the results, if they contain "Walls" then it will detect their distance.  If this distance becomes less than 4f then now we need to find the next suitable point. I can detect the direction of players movement but how do I detect the next best point for movement and set enemy's translation to that point? The code about the functionality is as below:




 private void findEnemyCollisions()
     {
        Vector3f eP = enemyNode.getLocalTranslation();
       
        Ray ray = new Ray(enemyNode.getLocalTranslation(), enemyNode.getLocalRotation().getRotationColumn(2));
        PickResults results = new BoundingPickResults();
        results.setCheckDistance(true);
        enemyNode.findPick(ray,results);
        System.out.println(ray.direction);
        System.out.println(results.getPickData(2).getTargetMesh().getParentGeom().getParent().getName());
              
       
        if(results.getNumber() > 0)
        {
            Vector3f position = enemyNode.getLocalTranslation();
            float X = position.getX();
            float Y = position.getY();
            float Z = position.getZ();
           
            for(int i = 0; i < results.getNumber(); i++)
            {
                if(results.getPickData(i).getTargetMesh().getParentGeom().getName() == "Walls")
                {
                    if(results.getPickData(i).getDistance() < 4f)
                    {
                            if(enemyNode.getLocalTranslation().getX() > lastPosition.getX() && enemyNode.getLocalTranslation().getZ() > lastPosition.getZ())
                            {
                                System.out.println("Movement Detected in +X and +Z: " + enemyNode.getLocalTranslation());
                            }
           
                            else if(enemyNode.getLocalTranslation().getX() > lastPosition.getX() && enemyNode.getLocalTranslation().getZ() < lastPosition.getZ())
                            {
                                System.out.println("Movement Detected in at +X and -Z: " + guardNode.getLocalTranslation());
                            }
           
                            else if(enemyNode.getLocalTranslation().getX() < lastPosition.getX() && enemyNode.getLocalTranslation().getZ() > lastPosition.getZ())
                            {
                                System.out.println("Movement Detected in -X and +Z: " + enemyNode.getLocalTranslation());
                            }
           
                            else if(enemyNode.getLocalTranslation().getX() < lastPosition.getX() && enemyNode.getLocalTranslation().getZ() < lastPosition.getZ())
                            {
                                System.out.println("Movement Detected in -X and -Z: " + enemyNode.getLocalTranslation());
                            } 
                    }
                }
               
                System.out.println("Name of the object: " + results.getPickData(i).getTargetMesh().getParentGeom().getName() + " Distance: " + results.getPickData(i).getDistance());

            }
              
            results.clear();
           
        }

                       
     }



I appreciate all you help neakor as I dont have long before finishing the project and this function would prove invaluable. Also, this would help in bringing all small bits and pieces such as following the player, getting back to get med and ammo supplies, implementing a fourth bot that hunts down the player - all with avoiding collision which will be the best.

im not quite sure what u wanna do next.



do u want the player to go around the wall and the enemy or something?

This system is for enemy use primarily - I want enemy to avoid collisions with walls when it chases player and player goes inside a loop of walls(maze) or something - e.g. when player runs away now and goes inside such a loop, instead of enemy following the player through that path it goes through the wall and gets infront of the player - e.g. by using addLocal and subtractLocal






Vector3f pP = player1.getLocalTranslation();
enemyNode.lookAt(player1.getLocalTranslation(), Vector3f.UNIT_Y);
shootAtPlayer(enemyNode, ammoEnemy);
Vector3f currentEnemyPosition3 = enemyNode.getLocalTranslation();
Vector3f differenceVector2 = (new Vector3f(pP.x-10, pP.y, pP.z).subtractLocal(currentEnemyPosition3).normalize());
enemyNode.setLocalTranslation(currentEnemyPosition3.addLocal(differenceVector2.mult(0.07f)));



This technique could help in avoiding such collisions.

if u want ur AI to chase the player without going through walls, this simple collision check is definitely far from enough.



u need a path finding algorithm such as A* in addition to the ray detection.



if what my understanding of ur goal is correct here, u r facing a much bigger problem than i originally thought.

Yeah I know… Primarily I just want it to detect the wall and find a safe point I dont care greatly about a chase as I know pathfinding algorithm is required for one. If its moving in a specific direction and it detects a wall at equal to or less than tolerable distance just move to a suitable point. If I implement this then if there is a chase if will create a bouncing movement as it will try to chase a player using addLocal/subtractLocal and this algorithm will set its location to a specific point. I dont mind that for the timebeing. First priority is Collision Avoidance/Detection.



Sorry if I was unclear. I just want simple collision check first and foremost.