WPF3D How to manipulate objects in a plane paralle

2020-03-29 09:30发布

问题:

I am making a application in WPF. I am using a lot the 3DTools. I have a tetrahedron and, inside it, a cube. I want to move the cube in 3D directions.

My tetrahedron, centered in the (0,0,0) rotates using a Trackball (programmatically, I have a transparent border over my viewport to capture the events).

The users for the application think the more naturally way to move the cube inside it is to move it always in a 2D plane (parallel to the screen). So, if I want to move it deeper in the screen, I just rotate the tetrahedron and move it in Y axis, for example. I think this can be a good solution.

I have to problems, and I would like help to solve then: first, when I move my tetrahedron (inside the Trackball) the Trackball looks like moving all the system coordinates. I say this because I draw axis for debug purpose, and those axis are being rotate also. But this is not true - they are moving just because are objects inside the trackball (right?). EDIT Actually, I think the coordinate system inside the trackball are really changing. When I move the cube in Y-X axis, I behaves ok. But if I turn a little bit, and try to move in the Z axis, I see it getting bigger (closer to camera) and smaller (far from camera). =(

So my questions is how to define a plane which will not be rotate by trackball? For me the answer looks something like "ok, just define it outside the track ball" but, as I said (and 3DTools documentation say) I have a border over my viewport... So I do not know how to handle this.

My tetraedron in a set of ScreenSpaceLines3D. I will have to keep the cube inside it. My second question is how to I trace the positions of the vertex of the tetrahedron of it being rotated? I got really disappointed when the Position property gave me the original positions and nothing else. Should I keep the matrix transformations and apply then to my points when I need then?

Sorry for long text, but I really stuck in this not so much programming questions. I am knew in WPF, I still have some lacks of concepts.

Thanks in advance,

Pedro

回答1:

What I'd do is then try to make your own manipulators (create new classes that replace TrackBall Manipulator from 3DTools) to do these. For instance, in the past I have made Zoom/pan, Rotate around a target, Free rotate, Free move, Rotate object, Translate object etc... all by doing simple matrix / vector manipulations.

For your example, what you need to do is calculate the normal which is orthogonal to the plane between Camera->Target and the world up vector. this will give you a vector which is "parallel" top the camera, like a local X-Axis if you are looking into the screen. Using this vector you can constrain the motion of the cube in this direction.

To do this, compute the vector V from camera to target. This is achieved by substracting the object location from the camera location. Then, calculate a vector to translate in sideways as follows:

Given a vector of your camera to target, v = xi, yj, zk
Normalise the vector, v' = xi, yj, zk / sqrt(xi^2 + yj^2 + zk^2)
Let U = global world up vector u = 0, 0, 1

Then we can compute R = Horizontal Vector that is parallel to the camera's view direction

R = v' ^ U, where ^ is the cross product, given by   
 a ^ b = (a2b3 - a3b2)i + (a3b1 - a1b3)j + (a1b2 - a2b1)k 

This will give you a vector that looks like this.

Now you know this vector R, when you move the mouse left/right you can use this to translate the object. For instance, in pseudocode:

// Pseudocode
onMouseMove()
{
    // Using calculation for R vector above
    Vector r = calulateVector();

    // Assuming passed in the number of points to translate 
    // (or some derivative of mousemove)
    let int pts = mousePointsMovedLeftOrRight;

    // Perform a translate in direction of R
    Vector targetPosition = TargetObject.PositionVector;
    targetPosition.X += r.X * pts;
    targetPosition.Y += r.Y * pts;
    targetPosition.Z += r.Z * pts;
}

I've got code on my laptop at home which can do this (It's OpenGL but same principle - provides various manipulations of objects and camera in 3D space). Please feel free to contact me/comment if you want to know more.

Best regards,



回答2:

I have done something similar without a Trackball. I just used the MouseMove event to move and orient the camera, but it would be just as applicable to move an object. I still have the code if you want it.



标签: c# .net wpf 3d