0
\$\begingroup\$

I'm making my first 3D-game with XNA (MonoGame) and have come to a point where I wish to add a crosshair for the player. To do this I need the on-screen coordinates of the location where my fighter would actually fire. However, I've run into some problems with this, mainly in finding my world matrix...

When drawing, I use the following snippet:

foreach (ModelMesh mesh in model.Meshes)
        {
            foreach (BasicEffect effect in mesh.Effects)
            {
                effect.EnableDefaultLighting();

                effect.World = transforms[mesh.ParentBone.Index]
                     * Matrix.CreateRotationX(angle.X)
                     * Matrix.CreateRotationY(angle.Y)
                     * Matrix.CreateRotationZ(angle.Z)
                     * Matrix.CreateTranslation(Position);

                effect.View = camera.ViewMatrix;

                effect.Projection = camera.Projection;
            }
            mesh.Draw();
        }

My understanding is that to be able to get my 2D screen coordinates, I need to use something like this:

//Yes, this currently returns a Vector3 and probably looks horrible on line 2 but I have not yet had any ouput to test this with
Vector3 temp = Game1.game.GraphicsDevice.Viewport.Unproject(Fighter.player.Position + Fighter.player.Forward * 50, Camera3D.camera.Projection, Camera3D.camera.ViewMatrix, Matrix.Identity);
Position = new Vector2(temp.X, temp.Y);

Which requires the world transform as the final argument. Since my effect.world changes with each BasicEffect (7 of them) I can't really get a hold on what my World Matrix is.

Any help?

EDIT

In my case I was able to use the code I used above with the only change that instead of Viewport.Unproject I used Viewport.Project.

I'm still not sure how to get the world matrix when it's set with variables that can vary (such as transforms[mesh.ParentBone.Index]) and am still intrested in this. My specific problem however was solvable by simply using Matrix.Identity as world matrix.

\$\endgroup\$
0
\$\begingroup\$

To get 2d screen coordinates from a 3d world space location, you would use Viewport.Project, not Viewport.Unproject.

The world matrix to put in the Project method would be the same one you use to set the effect.World property for rendering.

\$\endgroup\$
  • \$\begingroup\$ Yes, well the problem is that my effect.world uses transforms[mesh.ParentBone.Index] and therefore is not really extractable, hence my question. \$\endgroup\$ – Felix ZY Jul 29 '14 at 13:45
  • \$\begingroup\$ Yes it is, give the transforms class scope, then instead of setting their values them in the Draw() method, set the transforms values in the Update() method after moving or rotating the object then simply use them in the Project and later use them in the Draw() method for the effect.World. \$\endgroup\$ – Steve H Jul 29 '14 at 14:38
  • \$\begingroup\$ Ah, yes, I see your point. Cant believe I missed that. \$\endgroup\$ – Felix ZY Jul 29 '14 at 14:41
  • \$\begingroup\$ It's been a few months, here is a more accurate response: Yes it is, give the transforms class scope, then instead of setting their values them in the Draw() method, set the transforms values in the LoadContent() method after loading the model, then simply use them in the Project and later use them in the Draw() method for the effect.World. \$\endgroup\$ – Steve H Jul 29 '14 at 14:45
  • \$\begingroup\$ Do it in the LoadContent because your really ever only need to set those transforms once, not every frame like the Update would do. \$\endgroup\$ – Steve H Jul 29 '14 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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