Picking .3ds part two ... (quick help really appreciated)

Hi guys,



As mentioned in previous threads I am developing line of sight for the enemy and so I have implemented 5 rays 1 at enemyNode.getLocalTranslation, 1 at enemyNode.getLocalTranslation.x+1, 1 at enemyNode.getLocalTranslation.x-1, 1 at enemyNode.getLocalTranslation+2 and enemyNode.getLocalTranslation-2. The .3ds object is a simple file, imported in standard way and to my knowledge consists of 3 basic objects - object1, object2, object3. When I use picking - boundingPicking, it collides with its own 3 objects for some reason so I choose getPickResults(3) where the fourth observation can be the first. However, this changes for some reason and I get "java.lang.IndexOutOfBoundsException: Index: 3, Size: 3" :




12-Mar-2008 05:50:27 class Demonstration.Ares start()
SEVERE: Exception in game loop
java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
        at java.util.ArrayList.RangeCheck(ArrayList.java:546)
        at java.util.ArrayList.get(ArrayList.java:321)
        at com.jme.intersection.PickResults.getPickData(Unknown Source)
        at Demonstration.Ares.lineOfSightEnemy(Ares.java:1673)
        at Demonstration.Ares.enemyAI(Ares.java:1735)
        at Demonstration.Ares.update(Ares.java:320)
        at com.jme.app.BaseGame.start(Unknown Source)
        at Demonstration.Ares.main(Ares.java:288)
12-Mar-2008 05:50:27 com.jme.app.BaseGame start
INFO: Application ending.
BUILD SUCCESSFUL (total time: 18 seconds)



The actual code is as follows:

Code for lineofSight



public boolean lineOfSightEnemy() 
    {
        Vector3f eP = enemyNode.getLocalTranslation();
       
        Ray ray = new Ray(enemyNode.getLocalTranslation(), enemyNode.getLocalRotation().getRotationColumn(2));
        PickResults results = new BoundingPickResults();
        results.setCheckDistance(true);
        scene.findPick(ray,results);
        System.out.println(ray.direction);
        System.out.println(results.getPickData(3).getTargetMesh().getParentGeom().getParent().getName());
       
        Ray ray1 = new Ray(new Vector3f(eP.x + 1, eP.y, eP.z), enemyNode.getLocalRotation().getRotationColumn(2));
        PickResults results1 = new BoundingPickResults();
        results1.setCheckDistance(true);
        scene.findPick(ray1,results1);
        System.out.println(ray1.direction);
        System.out.println(results1.getPickData(3).getTargetMesh().getParentGeom().getParent().getName());
       
        Ray ray2 = new Ray(new Vector3f(eP.x - 1, eP.y, eP.z), enemyNode.getLocalRotation().getRotationColumn(2));
        PickResults results2 = new BoundingPickResults();
        results1.setCheckDistance(true);
        scene.findPick(ray2,results2);
        System.out.println(ray2.direction);
        System.out.println(results2.getPickData(0).getTargetMesh().getParentGeom().getParent().getName());
       
        Ray ray3 = new Ray(new Vector3f(eP.x + 2, eP.y, eP.z), enemyNode.getLocalRotation().getRotationColumn(2));
        PickResults results3 = new BoundingPickResults();
        results3.setCheckDistance(true);
        scene.findPick(ray3,results3);
        System.out.println(ray3.direction);
        System.out.println(results3.getPickData(3).getTargetMesh().getParentGeom().getParent().getName());
       
        Ray ray4 = new Ray(new Vector3f(eP.x - 2, eP.y, eP.z), enemyNode.getLocalRotation().getRotationColumn(2));
        PickResults results4 = new BoundingPickResults();
        results4.setCheckDistance(true);
        scene.findPick(ray4, results4);
        System.out.println(ray4.direction);
        System.out.println(results4.getPickData(0).getTargetMesh().getParentGeom().getParent().getName());
       
        if(results.getNumber() > 0  && results.getPickData(3).getTargetMesh().getParentGeom().getParent().getName() != "Walls"
                && player1.getWorldBound().intersects(ray))
        {
            System.out.println("Inside the first loop");
                                                                                 //three are itself as explained
            //shootAtPlayer(enemyNode, ammoEnemy);                                                                  //in the post
            System.out.println("!!!!!!!!!!!!!!!!!Player spotted!!!!!!!!!!!!");
            results.clear();                               
              
            return true;
           
        }
       
      
        else if(results1.getNumber() > 0  && results1.getPickData(3).getTargetMesh().getParentGeom().getParent().getName() != "Walls"
                && player1.getWorldBound().intersects(ray1))
        {
            System.out.println("Inside the second loop");
                                                                                    //three are itself as explained
            //shootAtPlayer(guardNode, ammoGuard);                                                                  //in the post
            System.out.println("!!!!!!!!!!!!!!!!!Player spotted!!!!!!!!!!!!");
            results1.clear();
           
            return true;
                   
        }
       
        if(results2.getNumber() > 0  && results2.getPickData(3).getTargetMesh().getParentGeom().getParent().getName() != "Walls"
                && player1.getWorldBound().intersects(ray2))
        {
            System.out.println("Inside the third loop");
                                                                                 //three are itself as explained
            //shootAtPlayer(enemyNode, ammoEnemy);                                                                  //in the post
            System.out.println("!!!!!!!!!!!!!!!!!Player spotted!!!!!!!!!!!!");
            results2.clear();                               
              
            return true;
           
        }
       
        if(results3.getNumber() > 0  && results3.getPickData(3).getTargetMesh().getParentGeom().getParent().getName() != "Walls"
                && player1.getWorldBound().intersects(ray3))
        {
            System.out.println("Inside the fourth loop");
                                                                                 //three are itself as explained
            //shootAtPlayer(enemyNode, ammoEnemy);                                                                  //in the post
            System.out.println("!!!!!!!!!!!!!!!!!Player spotted!!!!!!!!!!!!");
            results3.clear();                               
              
            return true;
           
        }
       
        if(results4.getNumber() > 0  && results4.getPickData(3).getTargetMesh().getParentGeom().getParent().getName() != "Walls"
                && player1.getWorldBound().intersects(ray4))
        {
            System.out.println("Inside the fifth loop");
                                                                                 //three are itself as explained
            //shootAtPlayer(enemyNode, ammoEnemy);                                                                  //in the post
            System.out.println("!!!!!!!!!!!!!!!!!Player spotted!!!!!!!!!!!!");
            results4.clear();                               
              
            return true;
           
        }
                                                                
        else
        {
            return false;
        }

    }



Code used in the enemyAI



private void enemyAI()   //get health and ammo at the same place and move them bit forward //escape when ammo is finished
    {
        if(health2 <=70)
        {
            Vector3f currentEnemyPosition = enemyNode.getLocalTranslation();
            Vector3f differenceVector = (new Vector3f(-100, 14, 58)).subtractLocal(currentEnemyPosition);
            enemyNode.setLocalTranslation(currentEnemyPosition.addLocal(differenceVector.mult(0.09f)));
        }
       
        if(ammoEnemy <= 10)
        {
            Vector3f currentEnemyPosition2 = enemyNode.getLocalTranslation();
            Vector3f differenceVector1 = (new Vector3f(-35, 14, 15)).subtractLocal(currentEnemyPosition2).normalize();
            enemyNode.setLocalTranslation(currentEnemyPosition2.addLocal(differenceVector1.mult(0.09f)));
        }
       
        if(!lineOfSightEnemy())     //noplayerinsight
        {
            movementEnemy(true);
            //System.out.println("Enemy Ammo: " + ammoEnemy);
            //-55, 14, 58
        }
        else
        {
            enemyNode.lookAt(player1.getLocalTranslation(), Vector3f.UNIT_Y);
            movementEnemy(false);
            Vector3f currentEnemyPosition3 = enemyNode.getLocalTranslation();
            Vector3f differenceVector2 = (new Vector3f(player1.getLocalTranslation()).subtractLocal(currentEnemyPosition3).normalize());
            enemyNode.setLocalTranslation(currentEnemyPosition3.addLocal(differenceVector2.mult(0.08f)));
           
           
           // shootAtPlayer(enemyNode, ammoEnemy);  
           
        }
       
    }
   
    private boolean movementEnemy(boolean noEnemyInSight) //slow enemy and enemy2 down
    {
       
        if(noEnemyInSight)
        {
            enemyNode.getLocalTranslation().x += movementSpeed * 0.011;
       
            if (enemyNode.getLocalTranslation().x > 64)
            {
                enemyNode.getLocalTranslation().x = 64;
                movementSpeed *= -1;
                enemyNode.lookAt(new Vector3f(34, 15, 40), Vector3f.UNIT_Y);
            }
           
            else if (enemyNode.getLocalTranslation().x < -60)
            {
                enemyNode.getLocalTranslation().x = -60;
                enemyNode.lookAt(new Vector3f(24, 15, 50), Vector3f.UNIT_Y);
                movementSpeed *= -1;
            }
           
            return true;
        }
       
        else
        {
           
                return false;               
        }  
       
    }




Guys I would really appreciate any quick help as I need to get it done within 24 hours and this is a fundamental feature to the game. You have been great all year and I have worked my as* off so just want to not fall at the final hurdle.

Thanks,

Dev

if i understand it correctly, then, if nothing else is in sight, the ray will only collide with with the enemy node itself, and thus only contain 3 pick results, index 0 - 2.



So you would need to check, if you actually got more than 3 pick results, and only then grab the 4.

The thing is even if something is in sight if its not moving then it will definitely detect its own 3 objects and then the fourth one will be the other object first in sight. However, this changes when its moving. For just the one original ray fired from the enemy location - enemyNode.getLocal translation, when its travelling in -ve x direction it detects its own three objects and others while in +ve x direction it detects its own two objects and others. The output from this original ray and first five of its results e.g. getPickData(0)-getPickData(4) and the direction of the ray can be documented as below:



Going one way:




object3
object1
Walls
Walls
Walls
com.jme.math.Vector3f [X=0.99296516, Y=0.0, Z=0.11840707]
com.jme.math.Vector3f [X=0.99296516, Y=0.0, Z=0.11840707]
com.jme.math.Vector3f [X=0.99296516, Y=0.0, Z=0.11840707]



Coming back



object2
object3
object1
Walls
skybox
com.jme.math.Vector3f [X=-0.99999994, Y=0.0, Z=5.9604645E-8]
com.jme.math.Vector3f [X=-0.99999994, Y=0.0, Z=5.9604645E-8]
com.jme.math.Vector3f [X=-0.99999994, Y=0.0, Z=5.9604645E-8]




Is there not a possible way to make these rays visible so we can see whats going on??

Thanks