• 12
• 12
• 9
• 10
• 13

# [SOLVED] Move 3D object with 2D mouse

This topic is 3097 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Thank you for the link Jose.

So, my new test code is:
//Plane with Z = objectZCoordfloat A = 0.0f;float B = 0.0f;float C = -1.0f;float D = objectZCoord;D3DXVECTOR3 R0 = rayStart;D3DXVECTOR3 Rd = rayEnd;//Already tested and they're okD3DXVECTOR3 Pn = D3DXVECTOR3(A, B, C);float Vd = D3DXVec3Dot(&Pn, &Rd);float V0 = - ( D3DXVec3Dot(&Pn, &R0) + D);float t = V0 / Vd;float Xi = R0.x + Rd.x * t;float Yi = R0.y + Rd.y * t;float Zi = R0.z + Rd.z * t;

rayStart and rayEnd were calculated using D3DXVec3Unproject() already posted previously. I *think* (but now I've no more certainties) that they're ok.

The Zi value is equal (except for a little approximation) to the objectZCoord.
But the Xi and Yi values aren't correct. For "correct" I mean that they are not under my mouse icon on screen...

Am I missing something??

If you want I can post some real values to play with.

##### Share on other sites
If I understand you correctly, you have a plane described by normal=(0,0,-1) and a z intercept of objectZCoord. You want to obtain the world coordinates X & Y on that plane under the mouse pointer. I think this should work.
POINT mousePt;D3DXVECTOR3 v0, v1;D3DXVECTOR3 rayPos, rayDir;v0 = D3DXVECTOR3(mousePt.x, mousePt.y, 0);v1 = D3DXVECTOR3(mousePt.x, mousePt.y, 1);D3DXVec3Unproject(&rayPos, &v0, &vp, &proj, &view, &world);D3DXVec3Unproject(&rayDir, &v1, &vp, &proj, &view, &world);rayDir -= rayPos;D3DXVec3Normalize(&rayDir,&rayDir);// rayDir is a vector in 3D world from eye point to infinity// define D3DXVECTOR3 wPos = rayPos+factor*rayDir with wPos a point in the plane// you want to solve for factor// wPos.z = rayPos.z + factor*rayDir.z// wPos.z = objectZCoord // since it's in the plane// CHECK FOR RAYDIR.Z==0 to avoid division by zero// This happens when you're looking parallel to the plane// factor = (wPos.z - rayPos.z)/rayDir.z// wPos.x = rayPos.x + rayDir.x*factor // desired x value// wPos.y = rayPos.y + rayDir.y*factor // desired y value

EDIT: check for negative "factor" values for the case where the ray direction is pointing away from the plane rather than toward it.

[Edited by - Buckeye on September 23, 2009 7:15:38 AM]

##### Share on other sites
You've understood my problem.

I post a numerical example.

1) Put an object (formed by two triangles) in the world described by:
//World Matrix:1 0 -0  00 1 0   00 0 1   00 0 410 1//410 is the objectZCoord

2) Mouse click happens in 784, 583
3) New world coordinates returned by my function: 747, -550, 410
4) Your function returns 964, -711, 410

On screen, my function renders the object exactly under the mouse icon, yours doesn't. There's always an offset (except for objectZCoord = 0)

I don't know if it helps you to understand better, I hope so.

I'm a bit confusing and I need your help...

##### Share on other sites
My code assumes the world matrix is the device matrix obtained with dev->GetTransform(D3DTS_WORLD,&world), not the model matrix.

##### Share on other sites
Quote:
 Original post by BuckeyeMy code assumes the world matrix is the device matrix obtained with dev->GetTransform(D3DTS_WORLD,&world), not the model matrix.

Uh?! This is what MSDN says and this is my religion too:
World transformation, as the name suggests, converts vertices from object space to world space. It usually consists of one or more scaling, rotation, and translation, based on the size, orientation, and position we would like to give to the object. Every object in the scene has its own world transformation matrix. This is because each object has its own size, orientation, and position.

Also I'm using DirectX 10 that hasn't got the Device->GetTransform method.

By the way, assuming that matrix (the one I've posted) is your "device" matrix, your code should work without problem.
In my case I've one object that I'd like to put in (Some_X_Value, Some_Y_Value, 410). So I need to calculate the Some_X_Value and Some_Y_Value which represent the mouse icon projected in 3D world.

I hope I've explained it more clearly. Sorry if it isn't so clear but I'm not english.

Thank you.

##### Share on other sites
Quote:
 I'm using DirectX 10 that hasn't got the Device->GetTransform method.
Okay. Use an identity matrix for the calc.
Quote:
 I need to calculate the Some_X_Value and Some_Y_Value which represent the mouse icon projected in 3D world.

Your original calc uses the object's transform to calculate a ray position and direction in the object's space, not the 3D world space. Use an identity matrix for that first unproject calc to get the vector in world space. Then use objectZCoord (the object's transform) to transform the ray vector. In your original calc, you've applied the object's transform twice.

Your original calc is calculating the X and Y position of the mouse as if it were moved to the object's position, then moving it again by the same amount. The reason your calculated positions weren't precise was because it calculated the X and Y positions as if the object was at 410 + 410, not just 410.

##### Share on other sites
Quote:
 Your original calc uses the object's transform to calculate a ray position and direction in the object's space, not the 3D world space

I disagree with you, maybe beacuse I'm really getting cunfused...

I repost my simplified code. This is the function which purpose is Get a 3D ray (that is two 3D points) from a 2D point:

D3DXVECTOR3 temp3dPoint;temp3dPoint.x = (float) point2dX;temp3dPoint.y = (float) point2dY;temp3dPoint.z = viewport.MaxDepth;D3DXVECTOR3 rayStart;D3DXVec3Unproject(&rayStart, &temp3dPoint, &viewport, &G_Direct3D->projectionMatrix, &G_Direct3D->viewMatrix, &worldMatrix);temp3dPoint.z = viewport.MinDepth;D3DXVECTOR3 rayEnd;D3DXVec3Unproject(&rayEnd, &temp3dPoint, &viewport, &G_Direct3D->projectionMatrix, &G_Direct3D->viewMatrix, &worldMatrix);

What is "worldMatrix" for you? I don't think it's always an identity matrix. Perhaps it'd be if there weren't translations, rotation, ecc.

##### Share on other sites
One more try. I'm trying to help you, but if you don't agree, that's up to you.

1. What are you using for the worldMatrix? If you're using the object's matrix, you're positioning the vector in your object's space, not the world space.

2. The ray should start at the near (minimum value) not the far (maximum) value.

3. The ray should end at the far value, not the near value.

##### Share on other sites
Hey Buckeye, I was trying to say that I disagree with you only beacuse I don't understand what you wrote. It wasn't my intention to say that you're wrong. Apologize me for this misunderstanding.

You (Ripiz and Buckeye) have already helped me in "Picking 3D mesh with mouse" (http://www.gamedev.net/community/forums/topic.asp?topic_id=547663).

In that case the "worldMatrix" was the object world matrix, right?! I hope so... Ok, call that object "A".

Now, in this case, I need to put "A" in another 3D world, for example the world of object "B". So my answers are:

1 - "B" object world matrix.
2 & 3 - Of course! They were typing errors.

Thank you again for your help, I've really appreciated it.

##### Share on other sites
Quote:
 In that case the "worldMatrix" was the object world matrix, right?!

Apparently. The matrixWorld you used in that post worked correctly because it was really world(Identity)Matrix*objectMatrix.

In any case, that isn't relevant to your question in this post, which was to locate the x/y values in the 3D world for a known z value. How you obtained that z-value doesn't make any difference to that calc, and you shouldn't be using the object's matrix at all for that calc. It's a simple matter of determining a point in 3D space.

If you had originally asked, "How do I find the x/y coordinates under the mouse for any z-value?," you'd have gotten the same answer.

Once the x/y values are calculated, then you can move your object.