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 this enemy class, and I want it to

1) Spawn at a certain place Vector3 pos

2) Rotate to face my player position

3) Move forward

As this code is now, it will appear at it's specified place: pos, and attempt to rotate to face it's target: targetShip. It fails to correctly face it's target, because of this offset.

If I remove the code that assigns a value to translation, or if I normalize pos then the model will appear at the origin and rotate to face it's target correctly.

If I try to move it at all using any of the comment out code regarding translation, It appears to start someplace else and I never can find it.

However, if I remove the code relating to rotation, and uncomment the code relating to translation, then I can get it to move forward.

The trick is doing it all together.

    class Enemy : BasicModel
    {


        Matrix rotation = Matrix.Identity;
        Matrix translation = Matrix.Identity;
        public Vector3 pos, up, right, targetShip,dir;

        public Enemy(Model m, Vector3 pos)
            : base(m)
        {
            up = Vector3.Up;
            //sets the position to the Vector3 as it's spawn point.
            translation = Matrix.CreateTranslation(pos);

        }

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

          pos = transform.Translation;

          rotation = RotateToFace(targetShip, pos, Vector3.Up);
          //Attempt at moving the model forward. Causes it to go out of view
          //translation *= Matrix.CreateTranslation(this.GetWorld().Backward);
          //translation *= Matrix.CreateTranslation(pos);
        }

        public override Matrix GetWorld()
        {
            return rotation * world * translation ;

        }

        /*Params: O = Our target
         * P = Our position
         * U = up.
         * 
         * Code from some site I googled up.
          */
        Matrix 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);
            return rot;
        }



    }
}

----


This is fixed now, and all this code is mostly obsolete.

share|improve this question
    
Is this question too much? I Allow me to clarify: I can do all of these things independently, but I can't do them all together. –  Houseman Apr 26 '12 at 13:53
    
I think your translation computation looks weird: translation *= Matrix.CreateTranslation(this.GetWorld().Backward); translation *= Matrix.CreateTranslation(pos); If you get this: this.GetWorld().Backward, it calculates with current translation. Than you take result and multiplies translation with it (again). First of all: Shouldn't you reset translation somewhere? Is all that multiplication right? –  zacharmarz Apr 26 '12 at 14:15
    
What's your exactly question? I couldn't spot any. –  Gustavo Maciel Apr 26 '12 at 18:11
    
@zacharmaz, I don't know, is my multiplication right? Do I need to reset my translation? Also, you can ignore the line containing pos. @Gustavo I want my code to work. It's not working. I don't know why. –  Houseman Apr 26 '12 at 18:15
add comment

4 Answers

up vote 0 down vote accepted

The model's position was coming up as invalid because it's position, {0,0,0} was being normalized.

Also, I changed the RotateToFace method to return a Quaternion.

share|improve this answer
add comment

Some remarks which won't fit in a comment; low quality answer here because it's bed time.

That code looks nearly right.

I don't like the manual matrix creation (especially if you got it from an OpenGL website: OpenGL uses a different 'hand' for the co-ordinate system to DirectX): instead use the built-in Matrix.CreateLookAt.

You might try fiddling with the order of multiplication of the matrices: a * b != b * a with matrices.

In addition you are not looking for Backward, instead Matrix.Invert(). However, again, it doesn't work like elementary algebra so a * b * c * Inverse(a) != b * c - so you will need to recalculate the entire chain of matrices again. Camera classes usually have this information baked in, which you should find extremely useful for your entity class. Basically:

// Fiddle with the order; it should give you the general idea though, you 
// can't simply UNDO multiplication in matrices.
var world = Matrix.LookAt(pos, up, ...) * Matrix.Translate(translation, ...) * Matrix.Scale(...);
var wvp = world * view * projection;
share|improve this answer
    
He has created another thread.. and it is resolved... :) gamedev.stackexchange.com/questions/28379/… –  Blau May 2 '12 at 22:18
add comment
Matrix PlayerAbsoluteTransform;


void UpdatePlayer( Vector3 EnemyPosition, float PlayerVelocity, float Seconds)
{
     Vector3 PlayerPosition = PlayerAbsoluteTransform.Translation;
     Vector3 Forward = EnemyPosition - PlayerPosition;
     Forward.Normalize();

     // This moves your player towars the enemy
     PlayerPosition += Forward * PlayerVelocity * Seconds; 

     // This create the transform matrix for your model, 
     // note that maybe you have to rotate the model before to face right
     PlayerAbsoluteTransform = Matrix.CreateWorld(PlayerPosition, Forward, PlayerUp);
}
share|improve this answer
    
With that code, the enemy faces away from the player position, and If I apply the code relating to moving the mesh, it disappears. –  Houseman Apr 27 '12 at 18:52
    
maybe you are not applying transform right... because I'm sure that if data is right, matrix.CreateWorld returns a right worldmatrix for the object... facing in the forward direction... –  Blau Apr 27 '12 at 20:12
    
For translating the world forward, I'm using translation*= Matrix.CreateTranslation(this.GetWorld().Backward); –  Houseman Apr 27 '12 at 20:49
    
lol... that is bad done... you have to add the translation... and you are multiplying it... you have to think that when you move an object you "add" a translation offset... you should learn some basic algebra before going to make a 3d game... –  Blau Apr 27 '12 at 21:05
    
Excuse me, but I have this same exact code in another class and it works perfectly for moving the model. In fact, if I were to comment out all the code concerning rotation, you would see it move. What doesn't work, however, is your solution. –  Houseman Apr 28 '12 at 4:09
show 7 more comments

You can try to use other way: if you know direction of enemy and position of ship, you can compute angle between current direction of enemy and new direction (ShipPosition - EnemyPosition): angle = acos(dot(dir,newdir)), dir and newdir should be normalized. Also compute "up vector" of this rotation by cross product: up = cross(dir, newdir).

Then try to make rotation matrix according to this page in section Rotation matrix from axis and angle.

share|improve this answer
    
I can rotate the enemy to face it's target just fine. –  Houseman Apr 25 '12 at 7:17
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.