Friday, 28 November 2008

What do i need to do to get there?

Another lesson in using vectors to get around in the world. I've got a tank, and I want to get it to move to another position on the map and also point it in the direction of the enemy. To do this, i need a three phase controller: something that turns the tank until it's pointing in the direction of the target position, something that will make the tank move forward until it's got where it's going, then another to aim the tank at the target baddie.

first, using the right vector of the tank transform (tank.right), I can dot the difference vector of the target position and the tank's current position.

directionDot = dot( target.pos - tank.pos, tank.right )

the value of this dot product will tell we which direction to turn. If the value is positive, then turn right, else, turn left. We can repeat this until the dot product changes value, and at that point, we can pretend we turned correctly, but instead just make a new transform matrix that points exactly at the target.

making a look at matrix can be as simple as normalising the difference vector and crossing with up to create the side vector.

tank.forward = normalised( target.pos - tank.pos )
tank.right = cross( tank.up, tank.forward )

The tank now needs to move forward. We can use the forward vector to do this, just add on the product of the tank speed with the forward vector to the position.

tank.pos += tank.forward * tank.speed

do this until we're no longer decreasing the size of the difference vector (target.pos - tank.pos), once it is increasing again, just set the tank pos right.

tank.pos = target.pos

and then it's back to aiming the tank.

aimDot = dot( baddie.pos-tank.pos, tank.right )

if( aimDot ) rotateRight else rotateLeft

again, once the dot changes sign, just create a look at matrix at the tank position.

For more advanced simulators, you might want to be less stringent about when to move from one phase to the next.
e.g. Turn until the dot for turning is very small, then begin to move forward at the same time, but only if the distance is over a specified threshold. Once within a certain distance of the target, begin turning to face baddie.

None of these operations require sins or cosines because you can pre-create all your rotation matrices for the simple solution, and for the more advanced solution, you're probably playing with a physics engine to make the tank move.

No comments: