3D Manipulators (gizmo)

Started by
3 comments, last by slayeriq 14 years, 2 months ago
Hello, For a 3d editor i am trying to include 3d manipulators move, rotate, and scale. Now i have the manipulators drawing and i can detect whether the user has clicked on one or not, and which of the axis the user has selected. The only problem i am having is actually manipulating the object itself i cant figure out how to translate the mouse movement into 3d movement. This is what i have come up with for now this is just the code for the x axis:


selectedObject.x += delta.X * speed/(float)gameTime.ElapsedGameTime.TotalMilliseconds;

//update gizmo position
Gizmo3D.Position = selectedObject.Position;



But now when i move something it looks like the object doesn't move along with the mouse. In this video
you can see that the movement is really direct to the object. What should i do to make manipulating objects more direct and precise. Thanks in advance, [Edited by - slayeriq on February 9, 2010 5:44:26 PM]
Advertisement
The action you need to take varies with the type of manipulator.

Warning: Math required!

There are more refined ways to do this, but this will either work for you or give you a start.

For example, for the manipulators that work in a single direction (e.g., the X-axis arrow that allow movement only along 1 axis):

1. Unproject the mouse position where it "picks" the arrow (on WM_LBUTTONDOWN probably). Save as WP (world position) and as MP1 (first mouse position). Calculate D = distance from eye to WP. You have to "pick" the arrow so WP, MP1 and D can be used to start the sequence.
2. When the mouse moves, unproject the new mouse pos to get the 3D direction vector. Set MP2 at the position along the mouse direction vector a distance D from the eye. This is actually a spherical movement of the point but for small movements of a few pixels it's fine.
3. MP2-MP1 is the mouse's 3D movement at a distance D from the eye. The component of MP2-MP1 along the X-axis is the distance and direction to move the object and the manipulators. This makes the object appear to move along the x-axis the same distance along the x-axis that the mouse has "moved."
4. Update WP += x-dist-direction. Recalculate D for the new WP. Set MP1 = position along the mouse direction vector the new distance D from the eye.
5. Wait for another mouse move or WM_LBUTTONUP.

Rotation manipulators are done similarly, intersecting the mouse direction vector with the plane containing the "picked" manipulator, but using the change in angle with respect to the origin of the rotation from one mouse move to the next.

Confused yet? [WINK]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Your calculation is based on the screen space delta value in mouse position, which is usually not going to directly correspond to the selected manipulater's current orientation. Since the manipulater is not aligned with the screen, then you need to translate the mouse position into the frame of reference of the manipulater.

I haven't done this myself, but my first guess would be to perform a ray picking operation when you press the mouse button to select the manipulater. This will tell you the world space position of the mouse. Then, when the mouse position changes you would recalculate the y coordinate where the new ray intersects the manipulater (assuming you selected the y-translation manipulater). Then find the world space difference between the two points and translate the object by that much. This will make the object seem to follow the screen space movement of the mouse, even though you are manipulating the world space position.

The other manipulators would be similar in nature - just use the world space ray picking intersections to guide the manipulations.
You might want to Google for 'Trackball controller' or 'Arcball controller'.
Quote:Original post by Buckeye
The action you need to take varies with the type of manipulator.

Warning: Math required!

There are more refined ways to do this, but this will either work for you or give you a start.

For example, for the manipulators that work in a single direction (e.g., the X-axis arrow that allow movement only along 1 axis):

1. Unproject the mouse position where it "picks" the arrow (on WM_LBUTTONDOWN probably). Save as WP (world position) and as MP1 (first mouse position). Calculate D = distance from eye to WP. You have to "pick" the arrow so WP, MP1 and D can be used to start the sequence.
2. When the mouse moves, unproject the new mouse pos to get the 3D direction vector. Set MP2 at the position along the mouse direction vector a distance D from the eye. This is actually a spherical movement of the point but for small movements of a few pixels it's fine.
3. MP2-MP1 is the mouse's 3D movement at a distance D from the eye. The component of MP2-MP1 along the X-axis is the distance and direction to move the object and the manipulators. This makes the object appear to move along the x-axis the same distance along the x-axis that the mouse has "moved."
4. Update WP += x-dist-direction. Recalculate D for the new WP. Set MP1 = position along the mouse direction vector the new distance D from the eye.
5. Wait for another mouse move or WM_LBUTTONUP.

Rotation manipulators are done similarly, intersecting the mouse direction vector with the plane containing the "picked" manipulator, but using the change in angle with respect to the origin of the rotation from one mouse move to the next.

Confused yet? [WINK]


Actually i get it [SMILE] Thank you.

This topic is closed to new replies.

Advertisement