Object Orientation

Jan 24, 2009 at 1:33 AM
I need some help and know that you guys can help. I'm using the "SpawnPrimitive" method to shoot arrows from where ever the camera is. Unfortunately, I can't get the arrows to go in the direction that the camera is looking. At first, I couldn't even get the arrows to shoot out from the same side that the camera is looking at. So, I changed the orientation in my SpawnPrimitive call (the second parameter) to use Matrix.Identity and it works. However, if I turn to the side or in a different direction, the arrows still come out in front of me, but they're turned in the direction they were originally. They look like I'm shooting them sideways. I need help getting my arrows turned to look like I'm shooting them straight instead of on their side. The "ArrowObject" is simply a BoxObject with a different name. I'm trying to keep all of my objects separated for special customization.

Here is the code I'm using.

PhysicObject physObj = SpawnPrimitive(cCamera.cameraPosition, Matrix.Identity);

private PhysicObject SpawnPrimitive(Vector3 pos, Matrix ori)
{
            Vector3 sideLengths = new Vector3(1.0f, 1.0f, 3.0f);
            PhysicObject physicObj = new ArrowObject(this, arrowModel, sideLengths, ori, pos);

            return physicObj;
}

Thanks in advance...
Jan 27, 2009 at 1:11 PM
The orientation of the objects should be the inverse of the view matrix (Camera orientation).

Matrix arrowOrientation = Matrix.Invert(cCamera.ViewMatrix); // Get the inverse view matrix.
arrowOrientation.Translation = Vector3.Zero; // We don't want any translation added to the arrow.

If you don't have the view-matrix available you can create an orientation matrix using:

Matrix orientation = Matrix.Identity;
orientation.Forward = <The direction you want it to point>;
orientation.Right = Vector3.Normalize(Vector3.Cross(orientation.Forward, Vector3.Up)); // Vector3.Up can be replaced with whatever the up-vector of your world is.
orientation.Up = Vector3.Normalize(Vector3.Cross(orientation.Right, orientation.Forward));

Im pretty sure that code will do the trick. If you get them upside-down or something like that just switch "Cross(orientation.Forward, Vector3.Up)" for "Cross(Vector3.Up, orientation.Forward)".
Hope this helps.
Jan 27, 2009 at 9:57 PM
I tried your suggestions, but still with no luck. The arrows still fly in sideways, backwards, etc... However, when I shoot a sphere object using the same code, the sphere always shoots out in the same direction the camera is looking. It never turns as it's coming out.
Jan 28, 2009 at 12:16 AM
I got it working finally.

ArrowObject:
        public ArrowObject(Game game, Model model, Vector3 sideLengths, Matrix orientation, Vector3 position) : base(game, model)
        {
            body = new Body();
            collision = new CollisionSkin(body);

            collision.AddPrimitive(
                new Box(-0.5f * sideLengths, orientation, sideLengths),
                (int)MaterialTable.MaterialID.UserDefined,
                new MaterialProperties(0.8f, 0.8f, 0.7f));
            body.CollisionSkin = this.collision;
            body.MoveTo(position, Matrix.Identity);
            body.EnableBody();
            this.scale = sideLengths;
        }

        public override void ApplyEffects(BasicEffect effect)
        {
            Vector3 color = new Vector3(205, 133, 63);
            color /= 255.0f;
            effect.DiffuseColor = color;
        }


Camera:
Matrix camRotMatrix = Matrix.CreateFromYawPitchRoll(Yaw, Pitch, Roll);

Game:
HandleInput( ):

PhysicObject physObj = SpawnPrimitive(cCamera.cameraPosition, cCamera.camRotMatrix);

SpawnPrimitive( ):
PhysicObject physicObj = new ArrowObject(this, arrowModel, new Vector3(1.0f, 1.0f, 3.0f), ori, pos);