Hi everyone
I've got a problem with my WPF application.
I have a Viewport3D where I add some 3D objects in runtime. I have a Canvas which contains the names (TextBlock or Label) of built 3D object. So using 3DTools, I can rotate, move and zoom a camera and all names of the 3D objects (on the Canvas) are shown correctly and are situated where 3D objects are situated (on the Viewport3D). In other words everything works fine, but there is just one problem: when some 3D objects are situated on the back side of the camera (we cannot see them)
their names are shown on the Canvas anyway, so in other words - we cannot see the 3D objects but we can see their names.
(Note: this happens only if I move the camera by axis Z - back and forward. If I move the camera by axises X and Y everything works how it's expected)
Any decisions how can fix this situation? Maybe I my function for converting from 3D to 2D (and revers) is not correct ?
Hope u understood my problem, but if u need some code snippets or screenshots I can provide.
[UPDATED]
i dont know how to add some appl here so I added some images. Hope this helps:
The 3D objects are in front of the camera. Everything is fine
http://imageshack.us/photo/my-images/717/19999718.gif[
^]
Then I move the camera forward.
The some 3D objects with names: badName# are behind of the camera but their names are not and we cannot see the 3D objects but we can see their names ! Other objects are still in front of the camera (here is ok).
http://imageshack.us/photo/my-images/824/65567950.gif[
^]
The code of the 2D to 3D conversion and reverse:
public static Point3D Convert2DPoint(Point pointToConvert, Visual3D sphere, TranslateTransform3D cameraPosition)
{
bool success = true;
Viewport3DVisual viewport;
Matrix3D screenTransform = TryTransformTo2DAncestor(sphere, out viewport, out success);
Point3D pointInWorld = new Point3D();
if (screenTransform.HasInverse)
{
Matrix3D reverseTransform = screenTransform;
reverseTransform.Invert();
Point3D pointOnScreen = new Point3D(pointToConvert.X, pointToConvert.Y, 1);
pointInWorld = reverseTransform.Transform(pointOnScreen);
pointInWorld = new Point3D(((pointInWorld.X + cameraPosition.OffsetX) / 2),
((pointInWorld.Y + cameraPosition.OffsetY) / 2),
((pointInWorld.Z + cameraPosition.OffsetZ) / 2));
}
return pointInWorld;
}
public static Point Convert3DPoint(Point3D p3d, Viewport3D vp)
{
bool TransformationResultOK;
Viewport3DVisual vp3Dv = VisualTreeHelper.GetParent(vp.Children[0]) as Viewport3DVisual;
Matrix3D m = TryWorldToViewportTransform(vp3Dv, out TransformationResultOK);
if (!TransformationResultOK) return new Point(0, 0);
Point3D pb = m.Transform(p3d);
Point p2d = new Point(pb.X, pb.Y);
return p2d;
}
The class with these methods has 440 lines of code (class MathUtils from well-known 3DTools), so if u need the other methods I can paste them here.
Here how I position TextBlocks on the Canvas if the 3D objects or the Camera were moved:
public override void MoveCanvas(Viewport3D viewport)
{
try
{
Point point2D = MathUtils.Convert3DPoint((Point3D)Position, viewport);
Canvas.SetTop(nameInCanvas, point2D.Y - 20);
Canvas.SetLeft(nameInCanvas, point2D.X - 20);
Canvas.SetTop(valueInCanvas, point2D.Y);
Canvas.SetLeft(valueInCanvas, point2D.X);
}
catch { }
}