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.

This seems like a simple problem with an equally simple solution that is invisible to me.

I have a model that spawns at the origin and looks at my player model wherever it goes.

I would like it to move forward where it's going. Whenever I try to translate it, it disappears. What am I doing wrong and how do I fix it?

public override void Update()
{
    //Glo is a global class, where I store the player's world.
    targetShip = Glo.world.Translation;
    targetShip.Normalize();

    //Rotates the model to face the player's position
    rotation = RotateToFace(targetShip, pos, Vector3.Up);
    pos += Vector3.Normalize(targetShip - pos) * 20f;

}

public override Matrix GetWorld()
{
    // return  rotation * translation * world ;
    return Matrix.CreateFromQuaternion(rotation) * Matrix.CreateTranslation(pos);
}

UPDATE: When I replace:

translation *= Matrix.CreateTranslation(direction);

with

translation *= Matrix.CreateTranslation(Vector3.Forward);

It now moves forward.

It does not correctly face me, however. It still thinks it's at the origin, and is rotating accordingly.


Here is the edited RotateToFace function The original just returns a Matrix.

Quaternion RotateToFace(Vector3 O, Vector3 P, Vector3 U)
{

    //The direction we're facing.
    Vector3 D = (O - P);
    //Our relative Right.
    Vector3 Right = Vector3.Cross(U, D);
    Vector3.Normalize(ref Right, out Right);
    //Our back
    Vector3 Backwards = Vector3.Cross(Right, U);
    Vector3.Normalize(ref Backwards, out Backwards);
    //Our relative up
    Vector3 Up = Vector3.Cross(Backwards, Right);
    //Make a matrix out of all of these.
    Matrix rot = new Matrix(Right.X, Right.Y, Right.Z, 0, Up.X, Up.Y, Up.Z, 0, Backwards.X, Backwards.Y, Backwards.Z, 0, 0, 0, 0, 1);
    Quaternion rot2 = Quaternion.CreateFromRotationMatrix(rot);
    return rot2;
}

Draw code:

public void Draw(Camera camera)
{
    Matrix[] transforms = new Matrix[model.Bones.Count];
    model.CopyAbsoluteBoneTransformsTo(transforms);

    foreach (ModelMesh mesh in model.Meshes)
    {
        foreach (BasicEffect be in mesh.Effects)
        {
            be.EnableDefaultLighting();
            be.Projection = camera.projection;
            be.View = camera.view;
            be.World = GetWorld() * mesh.ParentBone.Transform;

        }

        mesh.Draw();
    }
}
share|improve this question
    
Try to in GetWorld method multiply matrixes in this order: return rotation * translation *world; btw what is world matrix there? –  Vodáček May 1 '12 at 18:23
    
I tried that, and that did not seem to change anything. world is read by other classes for hit detection and seems to be the object's real position –  Houseman May 1 '12 at 18:33

1 Answer 1

up vote 2 down vote accepted

I can't figure out your code, a lot of parts in it don't make sense, such as normalizing the position. But if I understood the problem, you want to make the model to always be looking and moving in the direction of a certain target. And you already have an helper method called RotateToFace that takes care of the rotation part.

Then moving the model should really be as simple as taking the direction between itself and the target, and adding that direction to the model's position multiplied by a certain speed factor. Something like:

public class Entity
{
    public Vector3 Position { get; set; }
    public Quaternion Rotation { get; set; }
    public Vector3 Target { get; set; }
    public float Speed { get; set; }
    public float MinChaseDistance { get; set; }

    public void Update(float elapsed)
    {
        Rotation = RotateToFace(Target, Position, Vector3.Up);
        if(Vector3.Distance(Target, Position) > MinChaseDistance) 
            Position += Vector3.Normalize(Target - Position) * Speed * elapsed;
    }

    public Matrix GetWorldMatrix()
    {
        return Matrix.CreateFromQuaternion(Rotation) *
               Matrix.CreateTranslation(Position);
    }
}

Note: Missed it earlier, but the distance check is actually essential, because if you don't have that and Target happens to match Position, you'll get a call to Normalize on a zero vector, and the Position becomes corrupt (i.e. filled with NaNs).

share|improve this answer
    
The RotateToFace function returns a Matrix, so I applied your code accordingly. However, it didn't work. My model does not move –  Houseman May 1 '12 at 18:46
1  
@OWiz That's part of the problem. You're doing all of the intermediate calculations with matrices, and it's a mess. You really should be working with simple position and rotation properties, and the only part in the code that needs to convert it to matrices is the GetWorldMatrix method. It would be a lot simpler and cleaner that way. I would recommend trying it in a separate class for starters. –  David Gouveia May 1 '12 at 18:51
    
Okay, well that theory helps. Forgive me for not doing it the "right" way, I don't have much experience in dealing with quats and matrices. I'll try this now.... It doesn't work. Whenever I include the code relating to translating the object, the model appears to vanish. –  Houseman May 1 '12 at 21:55
    
@OWiz edit your question by including the code for 'RotateToFace' please –  Steve H May 2 '12 at 2:22
1  
@OWiz Regardless of the rotation code, that single Position += ... line should be enough to move the model towards the target. If it's not moving, then it's either that you're not calculating the world matrix correctly, the Position or Target values are wrong, or the Speed is too large. –  David Gouveia May 2 '12 at 6:05

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.