I did some playing around with Hit Testing using the Visual Tree Helper class. Here are a few things that I learned:
- The viewport mouse-down event does not fire unless the cursor is over a displayed triangle in the viewport. I am thinking it would be possible to place a large surface at end of the field of view opposite from the camera. There is no reason this could not be almost transparent.
- It is easy to get the vertices of the triangle that was hit.
- It is easy to get the point on the surface where the hit occurred.
- You can the endpoints of a line along the cursor using the following code:
LineRange range;
ViewportInfo.Point2DtoPoint3D(_viewport, ptMouse, out range);
In the viewport mouse-down event, I put the following code:
base.OnMouseLeftButtonDown(args);
Point ptMouse = args.GetPosition(_viewport);VisualTreeHelper.HitTest(_viewport, null, HitTestDown, new PointHitTestParameters(ptMouse));
I then created the HitTestDown call-back routine:
HitTestResultBehavior HitTestDown(HitTestResult result) {
RayMeshGeometry3DHitTestResult resultMesh = result as RayMeshGeometry3DHitTestResult;
ModVis3D vis = resultMesh.VisualHit as ModVis3D;
string nl = Environment.NewLine;
int Vertex1 = resultMesh.VertexIndex1;
int Vertex2 = resultMesh.VertexIndex2;
int Vertex3 = resultMesh.VertexIndex3;
string sResult = vis.Generator.Name + nl;
sResult += Vertex1 + " " + Vertex2 + " " + Vertex3 + nl;
sResult += resultMesh.VertexWeight1 + " " + resultMesh.VertexWeight2 + " " + resultMesh.VertexWeight3 + nl;
sResult += resultMesh.PointHit.X + " " + resultMesh.PointHit.Y + " " + resultMesh.PointHit.Z + nl;
Model3D mod = resultMesh.ModelHit;
if (mod is Model3DGroup) {
sResult += "mod is Model3DGroup" + nl;
} else {
GeometryModel3D model = mod as GeometryModel3D;
MeshGeometry3D mesh = model.Geometry as MeshGeometry3D;
sResult += "Vertex1: ";
sResult += mesh.Positions[Vertex1].X.ToString() + " ";
sResult += mesh.Positions[Vertex1].Y.ToString() + " ";
sResult += mesh.Positions[Vertex1].Z.ToString() + " ";
sResult += nl;
sResult += "Vertex2: ";
sResult += mesh.Positions[Vertex2].X.ToString() + " ";
sResult += mesh.Positions[Vertex2].Y.ToString() + " ";
sResult += mesh.Positions[Vertex2].Z.ToString() + " ";
sResult += nl;
sResult += "Vertex3: ";
sResult += mesh.Positions[Vertex3].X.ToString() + " ";
sResult += mesh.Positions[Vertex3].Y.ToString() + " ";
sResult += mesh.Positions[Vertex3].Z.ToString() + " ";
sResult += nl;
}
SWF.MessageBox.Show(sResult);
return HitTestResultBehavior.Stop;
}
No comments:
Post a Comment