I've created a 2D visual that fires events when child elements are clicked. I'd like to translate a 3D plane mesh onto the center of the control that is clicked, however I can't seem to figure out how to map the 2D point that I get from the event back
to the 3D coordinate system.
Thanks in advance.
Did you ever get this sorted?
Mar 5, 2008 at 11:37 AM
Edited Mar 5, 2008 at 11:38 AM
Hi, I expect this code helps you (and others)
Be aware, host window should be maximized, camera looking straight towards -Z direction, upVector = 0,1,0.
I use this code to convert from Mouse coordinates to 3d World coordinates for Drag&Drop objects in scene, I believe is buggy as is first implementation, so check it and feel free to fix it. :)
PositionX, PositionY, PositionZ represents object world coordinates, (not local coordinates, or offsets in local space)
// How this routine works
// At certain Z relative from Camera Position and certaing FoV (in radians)
// the plane where element lies has certain dimensions (width and height in 3d Space)
// so calculate this width and height in 3d and scale 2D mouse displacement on viewport to this relative coordinates
Point position = e.GetPosition(Scene.Viewport3D); // e is MouseEventArgs
double width = Scene.Viewport3D.ActualWidth;
double height = Scene.Viewport3D.ActualHeight;
double xx, yy;
xx = position.X - width / 2; // centered mouse X
yy = (position.Y - height / 2 ) * -1; // positive Y is up, invert centered mouse Y
double aspectRatio = width / height; // aspectRatio on Screen
double zPlane = this.PositionZ - Scene.ActiveCamera.Position.Z; // object position in 3D Space relative from camera, Z axis fixed.
zPlane = zPlane + zPlane * 0.155; // arbitrary adjustment, why? (I don't know) :) (seems calculations are buggy.
double fov = Math3D.Deg2Rad(Scene.ActiveCamera.FieldOfView); // convert to radians
double Height_3DAtZ = Math.Abs(System.Math.Tan(fov / 2) * zPlane); // Calculate height at z Position
double Width3DAtZ = Height3DAtZ * aspectRatio; // calculate width from height and aspect ratio
// calculate position
double x = xx / (width / 2);
x = (Width_3DAtZ / 2) * x;
//double y = yy / (Height_3DAtZ / 2);
double y = yy / (height / 2);
y = (Height_3DAtZ / 2) * y;
// Set current object current position
this.PositionX = x;
this.PositionY = y;
Many thanks for this Jesus.
I actually abandoned that part of the project I was working on due to time.
I hope that this code serves as a handy guide to those who follow us here...