private HitTestResultBehavior HitTestCallback(HitTestResult result) { RayMeshGeometry3DHitTestResult rayHit = result as RayMeshGeometry3DHitTestResult; ProjectionCamera camera = _viewport3D.Viewport.Camera as ProjectionCamera; HitTestResultBehavior result2; if (rayHit != null && rayHit.ModelHit != null) { Model3D model = rayHit.ModelHit; Visual3D visual3D = rayHit.VisualHit; if (visual3D != null) { if (string.Compare(Convert.ToString(visual3D.GetValue(FrameworkElement.NameProperty)), "CurveVisual") != 0) { result2 = HitTestResultBehavior.Continue; return(result2); } } MeshGeometry3D mesh = rayHit.MeshHit; if (mesh != null) { Point3D p = mesh.Positions[rayHit.VertexIndex1]; Point3D p2 = mesh.Positions[rayHit.VertexIndex2]; Point3D p3 = mesh.Positions[rayHit.VertexIndex3]; double x = p.X * rayHit.VertexWeight1 + p2.X * rayHit.VertexWeight2 + p3.X * rayHit.VertexWeight3; double y = p.Y * rayHit.VertexWeight1 + p2.Y * rayHit.VertexWeight2 + p3.Y * rayHit.VertexWeight3; double z = p.Z * rayHit.VertexWeight1 + p2.Z * rayHit.VertexWeight2 + p3.Z * rayHit.VertexWeight3; // point in local coordinates Point3D localPoint = new Point3D(x, y, z); Point3D p4 = localPoint; // transform to global coordinates // first transform the Model3D hierarchy GeneralTransform3D t2 = Viewport3DHelper.GetTransform(rayHit.VisualHit, rayHit.ModelHit); if (t2 != null) { p4 = t2.Transform(p4); } // then transform the Visual3D hierarchy up to the Viewport3D ancestor GeneralTransform3D t3 = Viewport3DHelper.GetTransform(_viewport3D.Viewport, rayHit.VisualHit); if (t3 != null) { p4 = t3.Transform(p4); } double distance = (camera.Position - p4).LengthSquared; if (distance < _minimumDistance) { _minimumDistance = distance; _nearestPt = localPoint; _nearestNormal = Vector3D.CrossProduct(p2 - p, p3 - p); _rayhit = rayHit; } } } result2 = HitTestResultBehavior.Continue; return(result2); }
/// <summary> /// Intersects the specified source mesh geometry with the specified plane. /// </summary> /// <param name="source">The source.</param> /// <param name="inverseTransform">The inverse transform of the source.</param> /// <param name="plane">The plane.</param> /// <param name="complement">Cut with the complement set if set to <c>true</c>.</param> /// <returns>The intersected geometry.</returns> private MeshGeometry3D Intersect(MeshGeometry3D source, GeneralTransform3D inverseTransform, Plane3D plane, bool complement) { var p = inverseTransform.Transform(plane.Position); var p2 = inverseTransform.Transform(plane.Position + plane.Normal); var n = p2 - p; if (complement) { n *= -1; } return(MeshGeometryHelper.Cut(source, p, n)); }
/// <summary> /// Update the transformation on the controlled object as the dragged-mouse moves. (Ignore if the motion's not part of a drag). /// /// </summary> public void mouseMove(System.Windows.Input.MouseEventArgs e) { // if not in drag, ignore // if in drag, // note that current point may not lie on sphere! // compute rotation taking start-point to current point // concatenate that with initial transform if (_inDrag) { Debug.Print("In drag!"); Point3D currPoint = spherePointFromMousePosition(e.GetPosition(_viewport3D)); Point3D origin = new Point3D(0, 0, 0); GeneralTransform3D tt = _initialTransform.Inverse; Vector3D vec1 = tt.Transform(_startPoint) - tt.Transform(origin); Vector3D vec2 = tt.Transform(currPoint) - tt.Transform(origin); Debug.Print(" vec1: " + vec1.ToString()); Debug.Print(" vec2: " + vec2.ToString()); vec1.Normalize(); vec2.Normalize(); // Now build an arcball interaction to take vec1 to vec2 and past it (i.e., double the rotation): double angle = 2 * Math.Acos(Vector3D.DotProduct(vec1, vec2)); Vector3D axis = Vector3D.CrossProduct(vec1, vec2); RotateTransform3D rotateTransform = new RotateTransform3D(); rotateTransform.Rotation = new AxisAngleRotation3D(axis, 180 * angle / Math.PI); Debug.Print("axis: " + axis.ToString()); Debug.Print("angle: " + angle.ToString()); Transform3DGroup tg = new Transform3DGroup(); tg.Children.Add(rotateTransform); tg.Children.Add(_initialTransform); _controlled.Transform = tg; } }