svxtc

I have this code that creates a model at the position of the mouse click but the model never shows up at that position. Maybe someone out there knows why the models seem to be offset. If I click in the top left corner of the screen, the model shows up in the center of the window. Here is the code:


#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.Collections;
#endregion

namespace Commander
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
ContentManager content;

float mouseX, mouseY;

ArrayList modelPosition = new ArrayList();
Model currentModel;
float modelRotation = 0.0f;

Vector3 cameraPosition = new Vector3(0.0f, 0.0f, 5000.0f);

float aspectRatio = 640.0f / 480.0f;
bool clickDown;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
}

private void MouseUpdate()
{
MouseState newMouse = Mouse.GetState();
mouseX = newMouse.X;
mouseY = -newMouse.Y;

if (newMouse.LeftButton == ButtonState.Pressed)
{
clickDown = true;
}
else if (clickDown)
{
modelPosition.Add(new Vector3(mouseX, mouseY, 0.0f));
clickDown = false;
}
}

protected override void Initialize()
{
base.Initialize();
}

protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
currentModel = content.Load<Model>("Models\\p1_wedge");
}

// TODO: Load any ResourceManagementMode.Manual content
}

protected override void UnloadGraphicsContent(bool unloadAllContent)
{
if (unloadAllContent == true)
{
content.Unload();
}
}

protected override void Update(GameTime gameTime)
{
// Allows the default game to exit on Xbox 360 and Windows
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

//This code is so that I can see where the mouse is and how many models are on the screen.
Window.Title = "Models: " + modelPosition.Count.ToString() + " - " +
"X=" + mouseX.ToString() + ", Y=" + mouseY.ToString();
MouseUpdate();

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

Matrix[] transforms = new Matrix[currentModel.Bones.Count];
currentModel.CopyAbsoluteBoneTransformsTo(transforms);
for (int i = 0; i < modelPosition.Count; i++)
{
foreach (ModelMesh mesh in currentModel.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();

effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
aspectRatio, 1.0f, 10000.0f);

effect.World = transforms[mesh.ParentBone.Index] *
Matrix.CreateRotationY(modelRotation) *
Matrix.CreateTranslation((Vector3)modelPositionIdea);

}
mesh.Draw();
}
}


base.Draw(gameTime);
}
}
}



Re: XNA Game Studio Express Model Position Problem

dczraptor

Here's the culprit:

modelPosition.Add(new Vector3(mouseX, mouseY, 0.0f));

Mouse coordinates are different from 3D coordinates. In mouse coordinates, 0,0 is top left corner, while in 3D, (0,0,0) is the center of the screen (assuming you're looking at the center). You're going to need to do some unprojecting to transform mouse coordinates to world coordinates.

http://msdn2.microsoft.com/en-us/library/bb203905.aspx






Re: XNA Game Studio Express Model Position Problem

svxtc

But wouldn't that last zero be the depth I don't think that it would have an effect on the position.



Re: XNA Game Studio Express Model Position Problem

Kyle_W

Dczraptor is correct. If your 3D camera is focused on (0,0,0) then you would need to draw your 3D object at (0,0,0) to have it show up in the center of the screen, but if you click in the center of the screen, the mouse X and Y coordinates will be something like 512 and 384 (if you were running at 1024 x 768 resolution).



Re: XNA Game Studio Express Model Position Problem

svxtc

Is there any way to fix that



Re: XNA Game Studio Express Model Position Problem

Kyle_W

Well you can make your 3D object move in the XY plane in a way that is relative to the mouse XY position in the game window, but the 3D object won't necessarily track directly under the mouse cursor. What you could do is subtract half of the game window height from the mouse Y value and subtract half of the game window width from the mouse X value. This will give you a value of (0,0) when the mouse is in the center of the game window. Then you will need to cast the modified mouse coordinates to float variables (since they are integers initially) and multiply them by a scaling factor such as 0.01 to determine the actual X and Y coordinates for the 3D object. The scaling factor you choose will depend on how far away the camera is along the Z axis.



Re: XNA Game Studio Express Model Position Problem

Kyle_W

Note that my previous suggestion will not look right if you intend to rotate the camera in a way such that it is not looking directly at the 3D XY plane. In this case you may need to use the unproject method previously suggested, or you could take the 3D coordinates generated from my previous suggestion and multiply them by a 3D rotational matrix relative to the camera's angle, depending on what you are trying to accomplish.



Re: XNA Game Studio Express Model Position Problem

svxtc

So i got the model to follow the mouse and when the mouse is over the center of the window so is the model. The problem that I am still having is when i get closer to the edges of the window the less the model actually stays under the mouse. You mentioned scaling but I don't know how to go about that. What might I do to make it work The camera is set to (0.0f, 0.0f, 5000.0f);



Re: XNA Game Studio Express Model Position Problem

Kyle_W

Just take the 3D X and Y coordinates that you generated for the object and try multiplying them by different numbers until you find a number that gives the best results. You could also reduce the Z position of the camera, but this will make your objects closer and therefore bigger on the screen.



Re: XNA Game Studio Express Model Position Problem

NickMcCrea

svxtc, I posted in another thread about what you're potentially doing wrong here...if you get more inaccurate as you move away from the origin, are you setting the points of your object to the intersect X,Y and not farPoint XY Remember that the end of the ray will be far behind the plane the object is moving in... I only ask because I was doing this for ages before I figured out I needed to find the point of intersection myself..I'll quote myself...


I think I know svxtc's exact problem, but it's different from mine...I think he's doing the unproject of the mouse position, and then using the farPoint of his Ray to set the X, and Y coordinates of his 3D object, not the exact point of the intersect with his plane of movement. That's why he gets more inaccurate the further from the origin...I'll try and draw an ASCI diagram :)

He's using two vectors, nearPoint and farPoint, say, to draw a Ray from nearPoint in the direction of farPoint.

x nearPoint
|<------ angle theta
| \
| \ distance Dsmall
| \
____ \x Intersect with XY plane
| \
| \ Dbig
| \
| \
________ \ x farPoint


If, as I suspect, he's doing the ray /bounding box intersection to detect a mouse ray/ 3d object collision, he's then setting the position of his object to be (FarPoint.X, farPoint.Y, 0). This gets more inaccurate the further away from the origin you are, because angle theta is getting bigger.

You need to set the position of the your 3D object to be the X,Y coords of the point of intersect, not the XY of farPoint. So you need to know distance Dsmall, which you can work out using the ratios of the two right angled triangles in the diagram above (you should have all the info you need with the coordinates of farPoint and nearPoint).

At least, I think that's his problem :).





Re: XNA Game Studio Express Model Position Problem

svxtc

I tried that and it seems that this works:

mouseX = (newMouse.X - (Window.ClientBounds.Width / 2)) * 6;

mouseY = (-newMouse.Y - (Window.ClientBounds.Height / 2)) * 6;

modelPosition.X = mouseX;

modelPosition.Y = mouseY;

Thanks for the help!





Re: XNA Game Studio Express Model Position Problem

svxtc

I think that I understand what you are saying but where would I differentiate the two points (nearpoint and farpoint) Do you mean I would need to alter the Z coordinate of the object to get the right position Don't quite understand it.



Re: XNA Game Studio Express Model Position Problem

NickMcCrea

Are you trying to use a Ray to intersect with a bounding box of your Object Then setting the object position to the mouse position

If so, bear in mind that your Ray (form nearPoint to the direction of Farpoint) will pass through your 3D object at some angle, and probably not directly 'straight'. So if you're wanting your object to track the position of the mouse, the points you're interested in are not nearPoint or farPoint, but the point of intersection of your Ray and object boundingbox.

These have to be calculated manually, but you've got enough information to do that.

Any clearer I'm assuming this is your problem because I think I was doing the same thing for ages :)




Re: XNA Game Studio Express Model Position Problem

NickMcCrea

I've jumped ahead of myself, haven't I You're not using Ray-BoundingBox intersection...

My bad :)




Re: XNA Game Studio Express Model Position Problem

svxtc

Yeah, I am just trying to get the model to follow the mouse. This is something that I am currently just testing so that I can later try to implement it into both a level editor and a RTS game.