Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have the following scene:

enter image description here

And I have two 3D vectors, the camera position, and the focus position. The focus vector is always behind the monster. I know how to rotate the camera around the focus with the help of my mouse, but the monster is always facing the same direction, and I'd like to change that!

I'd like it to work almost as in World of Warcraft; while I'm standing still I can move the camera around freely, but as soon as I move, the monster should change the direction according to the camera.position >>> focus vector. Also, I need to make it move in that direction, I guess I could have a 2D vector called speed, which I should change accordingly (it would look like a rotating radius of a circle I guess).

How do I do this?

For reference, I'm working in Three.js, and this is the code with which I rotate the camera:

onDocumentMouseDown = function(event) 
{
    event.preventDefault();

    game.isMouseDown = true;

    game.onMouseDownTheta = game.theta;
    game.onMouseDownPhi = game.phi;
    game.onMouseDownPosition.x = event.clientX;
    game.onMouseDownPosition.y = event.clientY;
}

onDocumentMouseMove = function(event) 
{
    event.preventDefault();

    if (game.isMouseDown)
    {
        game.theta = -((event.clientX - game.onMouseDownPosition.x) * 0.5) + game.onMouseDownTheta;
        game.phi = ((event.clientY - game.onMouseDownPosition.y) * 0.5) + game.onMouseDownPhi;
        game.phi = Math.min(160, Math.max(20, game.phi));

        game.cameraBuff.x = game.radious * Math.sin(game.theta * Math.PI / 360 ) * Math.cos( game.phi * Math.PI / 360 );
        game.cameraBuff.y = game.radious * Math.sin(game.phi * Math.PI / 360 );
        game.cameraBuff.z = game.radious * Math.cos(game.theta * Math.PI / 360 ) * Math.cos( game.phi * Math.PI / 360 );
    }
}

And at render time I do this:

self.camera.position.x += self.cameraBuff.x;
self.camera.position.y += self.cameraBuff.y;
self.camera.position.z += self.cameraBuff.z;

self.camera.lookAt(self.focus);
self.renderer.render(self.scene, self.camera);

self.camera.position.x -= self.cameraBuff.x;
self.camera.position.y -= self.cameraBuff.y;
self.camera.position.z -= self.cameraBuff.z;
share|improve this question
    
are you storing camera's and player's direction as a vector? this should help a lot. –  Gustavo Maciel May 26 '12 at 18:10
    
No, there's no direction at all! –  jco May 26 '12 at 18:19
    
(I mean, only positions are stored. The objects have a rotation vector, but that doesn't affect direction at all.) –  jco May 26 '12 at 18:58
    
the rotation vector IS the direction vector. Try making direction = normalize(position - focus) should work. –  Gustavo Maciel May 26 '12 at 23:16
add comment

2 Answers 2

up vote 0 down vote accepted

If you know how to turn the mesh to a desired rotation vector, you can just get the direction the object should walk with the following formula direction = normalize(position - focus) Where position is the mesh position and focus is your focus position. If the focus is really behind the mesh as you said, just multiply it by -1.

If as you said, you can't use the focus here, you can do the same with the camera position direction = normalize(position - camera) Multiply by -1, and as you want to move just on the XZ plane, set Y to 0. Should look like this:

direction = normalize(position - camera);
direction *= -1;
direction.Y = 0;
share|improve this answer
    
But the focus point is the mesh position! So I'd just get [0, 0, 0]... Maybe I should do it with the camera position, that makes sense. –  jco May 27 '12 at 9:38
    
Haven't you said the focus point is behind the position? You can still make it with the camera position, true, but you should set your Y component to 0. –  Gustavo Maciel May 27 '12 at 16:04
    
Focus point = mesh position, forgot to mention, which is technically a bit "behind" the actual mesh. I did it like this: var c = Math.sqrt(cameraPos.x*cameraPos.x + cameraPos.z*cameraPos.z); var rat = 1/c; mesh.direction.x = cameraPos.x*rat; mesh.monster.direction.z = cameraPos.z*rat; Assuming that the mesh's position is 0, I translate it so it is. –  jco May 27 '12 at 16:07
    
Also, I'm not sure if this works. If I were to rotate it, it would paint a square, that is, the speed would vary depending on the direction. I need it to paint a circle, so I'm using the Pythagora's theorem. –  jco May 27 '12 at 16:09
    
that's why we have the normalize function there. –  Gustavo Maciel May 27 '12 at 17:11
add comment

I assume you still want the monster to stand upright, so if you want it to face away from the camera while aligned to the ground, simply create a LookAt rotation matrix like so: LookAt(eyePos, targetPos, up) where eyePos would be monster.pos, targetPos would be [monster.pos.x - camera.pos.x, monster.pos.y - camera.pos.y, monster.pos.z] (ignoring the camera's height), and up would be [0,0,1] , assuming z is the "up" axis. If there is no LookAt matrix function provided, you find find an implementation here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.