0
\$\begingroup\$

I am having a hard time understanding how to go about this. I have a 2D game with some 3D models in it. I want to move a 3D model to where the mouse cursor is currently at in every frame (In other words, center a 3D model in a specific Point(x,y)).

This is my drawing code to position the model in the center of the screen:

Matrix[] transforms = new Matrix[Model.Bones.Count];
Model.CopyAbsoluteBoneTransformsTo(transforms);
ModelMesh mesh = Model.Meshes[0];
BasicEffect effect = (BasicEffect)mesh.Effects[0];
Vector3 modelPosition = new Vector3(0, 0, 0);

effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
    aspectRatio, 1.0f, 10000.0f);
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] * 
    Matrix.CreateTranslation(modelPosition);

    mesh.Draw();

I suppose I would need a formula to convert the (camera position,model position, aspect ratio, field of view) into pixels ? Does anyone know how it works ?

\$\endgroup\$
2
  • \$\begingroup\$ Why not instead of translating the world/cam/aspectratio/fov into pixels just translate the mouse coordinates into world coordinates? I have a picking function in my game engine that takes x and y position of the mouse and converts it to world coordinates in order to shoot a ray through the scene and check collision. \$\endgroup\$ Commented Feb 17, 2015 at 3:18
  • \$\begingroup\$ @AndrewWilson that might be the way to do it \$\endgroup\$
    – dimitris93
    Commented Feb 17, 2015 at 3:21

1 Answer 1

0
\$\begingroup\$

This function takes in mouse coordinates and picks the model from the 3d scene by shooting a ray through it. Btw the screen size in world coordinates is 2x2 stretching from -1 to +1 on both the x and y axis. The screen size in pixels would be mClientWidth and mClientHeight. You'll see both those in "Compute picking ray in view space"

void Pick(int sx, int sy)
{
    float dist = MathHelper::Infinity;
    float tmin = 0.0f;
    XMMATRIX P = cam->GetProj();

    // Compute picking ray in view space.
    float vx = (+2.0f*sx / mClientWidth - 1.0f) / P(0, 0);
    float vy = (-2.0f*sy / mClientHeight + 1.0f) / P(1, 1);

    // Ray definition in view space.
    XMVECTOR rayOrigin = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
    XMVECTOR rayDir = XMVectorSet(vx, vy, 1.0f, 0.0f);

    // Tranform ray to local space of Mesh.
    XMMATRIX V = cam->GetView();
    XMMATRIX invView = XMMatrixInverse(&XMMatrixDeterminant(V), V);

    // Make the ray direction unit length for the intersection tests.
    rayDir = XMVector3Normalize(rayDir);

    XMMATRIX W = XMMatrixIdentity();
    XMMATRIX invWorld = XMMatrixInverse(&XMMatrixDeterminant(W), W);
    XMMATRIX toLocal = XMMatrixMultiply(invView, invWorld);
    rayOrigin = XMVector3TransformCoord(rayOrigin, toLocal);
    rayDir = XMVector3TransformNormal(rayDir, toLocal);

    if (XNA::IntersectRayOrientedBox(rayOrigin, rayDir, scene["Main_Scene"]->instance[i].boundBox, &tmin))
        if (tmin < dist)
        {
            // The model of Main_Scene and instance i was hit.
            dist = tmin;
            tmin = MathHelper::Infinity;
        }
}
\$\endgroup\$
6
  • \$\begingroup\$ um, i am writing in C# with xna (monogame) \$\endgroup\$
    – dimitris93
    Commented Feb 17, 2015 at 3:25
  • \$\begingroup\$ You can still apply the math behind this. In XNA you have to set up a projection and view matrix which I'm sure you are familiar with. XMMATRIX is your basic 4x4 matrix. Width and height is pixel width and height of the screen. and XMVECTOR is a vector with 4 components. \$\endgroup\$ Commented Feb 17, 2015 at 3:29
  • \$\begingroup\$ ok i will have to check this tomorrow and see how it goes \$\endgroup\$
    – dimitris93
    Commented Feb 17, 2015 at 3:31
  • \$\begingroup\$ What does XMMatrixIdentity mean ? \$\endgroup\$
    – dimitris93
    Commented Feb 22, 2015 at 1:30
  • \$\begingroup\$ @Shiro That's the identity matrix. 4x4 matrix with 1's in positions [0,0], [1,1], [2,2], [3,3]. (Diagonal line of 1's) It represents no rotation, no translation, and a scale of 1. \$\endgroup\$ Commented Feb 22, 2015 at 16:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .