Simulate "camera.lookAt(SimpleVector)" for an Obje

Started by Mr.Marbles, April 27, 2006, 04:11:33 PM

Previous topic - Next topic

Mr.Marbles

I have a gun turret in my application which is made up of two moving parts: 1) the base 2) the gun. The base rotates on the y-axis and the gun rotates on the x-axis. I have a flying target in my scene and I'd like the turret to track the target using the same principle of the camera "lookAt()" function. What's the simplest way to get this done keeping in mind that the base of the turrent and the gun on the turret rotate on two different axis. I've tried several methods involving vector math but my linear algebra is a little rusty  :oops: . That's why I was thinking of the camera "lookAt()" function.

Melssj5

keep a reference to the gun object3d and to the base object3d.

base.rotateY (angle);
gun.rotateX (angle);

you must calculate the angle using mathematics. Not a big problem.

I may help you more later, i must to to the University.
Nada por ahora

Mr.Marbles

Melssj5,

Thanks for the reply. Maybe I wasn't clear enough in my question. I know how to rotate the objects, it's the angles I'm having a hard time with. As I mentioned my vector math is a little weak.

EgonOlsen

You may calculate the angle using some basic trigeometry but i think you'll run into problems when hitting the 90° barrier...at least that's what happened to me, but i'm not sure if its possible to get around this or not. SimpleVector has a getRotationMatrix()-method that can be used to simulate a kind of lookAt for objects. I've done simple example myself and it seems to work. First, i've created myself a turret with a gun out of primitives like so:


   Object3D turret=Primitives.getCube(1f);
   turret.setOrigin(turretPos);
   w.addObject(turret);
   turret.build();
   
   Object3D gun=Primitives.getBox(0.1f,20f);
   gun.rotateX(-(float)Math.PI/2);
   gun.rotateMesh();
   gun.setRotationMatrix(new Matrix());
   w.addObject(gun);
   gun.setOrigin(turretPos);
   gun.build();
   
   SimpleVector offset=new SimpleVector(0,0,3);
   gun.setRotationPivot(turret.getRotationPivot().calcSub(offset));
   gun.translate(offset);


You already have a model for this, i assume. So the following may look different for you depending on the orientation of it...anyway, i did this to make the turret/gun combo follow a target:


     // Get the vector from the turret to the target (o2 is the target)
     SimpleVector xd=turret.getTransformedCenter();
     xd.scalarMul(-1f);
     xd.add(o2.getTransformedCenter());
     
     // Copy it...
     SimpleVector yd=new SimpleVector(xd);
     
     // Make the turret rotate in the x-z-plane only
     xd.y=0;
     
     // Create needed rotation matrices
     Matrix rotX=xd.getRotationMatrix();
     Matrix rotY=yd.getRotationMatrix();
     
     // Apply them
     turret.setRotationMatrix(rotX);
     gun.setRotationMatrix(rotY);


The basic idea is, to make the turret lookAt() in the z-x-plane only, while the gun tracks the target without any limitation. I'm still not sure that this is 100% correct in all cases but it worked fine in my example.

Mr.Marbles

EgonOlsen,

Thank you! This works very well. I've made some changes to your original code:


     // Get the vector from the turret to the target (o2 is the target)
     SimpleVector xd=turret.getTransformedCenter();
     xd.scalarMul(-1f);
     xd.add(o2.getTransformedCenter());


I replaced with:


     // Get the vector from the turret to the target (o2 is the target)
     SimpleVector xd = o2.getTransformedCenter().
                                             calcSub(turret.getTransformedCenter());


Also, my gun is attached to the turret:


turret.addChild(gun);


So I don't need to worry about the gun movement on the y-axis since it will inherit the rotation from its parent.

Just one last question about this topic. How can I calculate the delta displacement for the y and x axis. In other words, I need to know how many degrees (or radians) the turret has turned (and how high the gun has elevated) between each rendered frame. I'm displaying these readings on my gui.

Mr.Marbles

I've found a way to extract the angle information from the matricies:


// Vector between target and turret
SimpleVector targetTurretVec = target.getTransformedCenter().calcSub(turret.getTransformedCenter());

// Copy it for gun
SimpleVector targetGunVec = new SimpleVector(targetTurretVec);

// Make the turret rotate in the y-z-plane only
targetTurretVec.x=0;
// Make the gun rotate in the x-z-plane only
targetGunVec.y=0;

// Get rotation matrices
float [] turretMat=targetTurretVec.getRotationMatrix().getDump();
float [] gunMat=targetGunVec .getRotationMatrix().getDump();

double turretAngle = Math.acos((turretMat[0]+turretMat[5]+turretMat[10]-1)/2f);
double gunAngle = Math.acos((gunMat[0]+gunMat[5]+gunMat[10]-1)/2f);


I got the formula for extracting the angles from this site

EgonOlsen

Great. That could be quite handy in some situations.