/// <summary> /// Rotates a Visual3D object around the z-axis. /// </summary> /// <remarks> /// The successive transformation operations (translation, scaling or rotation) are cumulative (the last one is relative to its previous one). /// </remarks> /// <param name="visual">A Visual3D object to rotate.</param> /// <param name="angle">The angle of the z-axis rotation, in degrees.</param> public void RotateZ(Visual3D visual, double angle) { Matrix3D matrix = (Matrix3D)visual.GetValue(MatrixProperty); Quaternion q = new Quaternion(new Vector3D(0, 0, 1) * matrix, angle); matrix.RotateAt(q, (Point3D)visual.GetValue(PositionProperty)); visual.SetValue(MatrixPropertyKey, matrix); ApplyTransform(visual); }
/// <summary> /// Scales a Visual3D object. /// </summary> /// <remarks> /// The successive transformation operations (translation, scaling or rotation) are cumulative (the last one is relative to its previous one). /// </remarks> /// <param name="visual">A Visual3D object to scale.</param> /// <param name="v">A vector containing the x-, y- and z-axis scale factors.</param> public void Scale(Visual3D visual, Vector3D v) { Matrix3D matrix = (Matrix3D)visual.GetValue(MatrixProperty); matrix.ScaleAt( v, (Point3D)visual.GetValue(PositionProperty)); visual.SetValue(MatrixPropertyKey, matrix); ApplyTransform(visual); }
/// <summary> /// Rotates a Visual3D object around the z-, y- and then x-axis. /// </summary> /// <remarks> /// The successive transformation operations (translation, scaling or rotation) are cumulative (the last one is relative to its previous one). /// </remarks> /// <param name="visual">A Visual3D object to rotate.</param> /// <param name="angleX">The angle of the x-axis rotation, in degrees.</param> /// <param name="angleY">The angle of the y-axis rotation, in degrees.</param> /// <param name="angleZ">The angle of the z-axis rotation, in degrees.</param> public void RotateZYX(Visual3D visual, double angleX, double angleY, double angleZ) { Point3D position = (Point3D)visual.GetValue(PositionProperty); Matrix3D matrix = (Matrix3D)visual.GetValue(MatrixProperty); matrix.RotateAt(new Quaternion(new Vector3D(0, 0, 1) * matrix, angleZ), position); matrix.RotateAt(new Quaternion(new Vector3D(0, 1, 0) * matrix, angleY), position); matrix.RotateAt(new Quaternion(new Vector3D(1, 0, 0) * matrix, angleX), position); visual.SetValue(MatrixPropertyKey, matrix); ApplyTransform(visual); }
/// <summary> /// Translates a Visual3D object. /// </summary> /// <remarks> /// The successive transformation operations (translation, scaling or rotation) are cumulative (the last one is relative to its previous one). /// </remarks> /// <param name="visual">A Visual3D object to scale.</param> /// <param name="v">A vector containing the x-, y- and z-axis offsets.</param> public void Translate(Visual3D visual, Vector3D v) { Matrix3D matrix = (Matrix3D)visual.GetValue(MatrixProperty); matrix.Translate(v); visual.SetValue(MatrixPropertyKey, matrix); ApplyTransform(visual); Point3D position = (Point3D)visual.GetValue(PositionProperty) + v; visual.SetValue(PositionPropertyKey, position); }
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); }
private void ApplyTransform(Visual3D visual) { Matrix3D matrix = (Matrix3D)visual.GetValue(MatrixProperty); MatrixTransform3D previousMatrixTransform = (MatrixTransform3D)visual.GetValue(MatrixTransformProperty); visual.SetValue(PreviousMatrixTransformPropertyKey, previousMatrixTransform); // new instance because MatrixTransform3D may be frozen and can't accept a new matrix MatrixTransform3D matrixTransform = new MatrixTransform3D(matrix); visual.SetValue(MatrixTransformPropertyKey, matrixTransform); if (visual.Transform != null) { if (visual.Transform is Transform3DGroup) { Transform3DGroup transformGroup = (Transform3DGroup)visual.Transform; if (!transformGroup.Children.Contains(previousMatrixTransform)) { transformGroup.Children.Add(matrixTransform); } else { int previousIndex = transformGroup.Children.IndexOf(previousMatrixTransform); transformGroup.Children[previousIndex] = matrixTransform; } } else { Transform3DGroup transformGroup = new Transform3DGroup(); transformGroup.Children.Add(visual.Transform); transformGroup.Children.Add(matrixTransform); visual.Transform = transformGroup; } } else { visual.Transform = matrixTransform; } }
/// <summary> /// Moves a Visual3D object to a new position. It updates the Position property. /// </summary> /// <remarks> /// The successive transformation operations (translation, scaling or rotation) are cumulative (the last one is relative to its previous one). /// </remarks> /// <param name="visual">A Visual3D object to move.</param> /// <param name="p">A Point3D object designing the new position.</param> public void MoveTo(Visual3D visual, Point3D p) { Matrix3D matrix = (Matrix3D)visual.GetValue(MatrixProperty); matrix.OffsetX = p.X; matrix.OffsetY = p.Y; matrix.OffsetZ = p.Z; visual.SetValue(MatrixPropertyKey, matrix); ApplyTransform(visual); visual.SetValue(PositionPropertyKey, p); }
/// <summary> /// Gets the object space to world space transformation for the given Visual3D /// </summary> /// <param name="visual3DStart">The visual whose world space transform should be found</param> /// <param name="viewport">The containing Viewport3D for the Visual3D</param> /// <returns>The world space transformation</returns> internal static Matrix3D GetWorldTransformationMatrix(Visual3D visual3DStart, out Viewport3DVisual viewport) { DependencyObject dependencyObject = visual3DStart; Matrix3D worldTransform = Matrix3D.Identity; while (dependencyObject != null) { Visual3D visual3D = dependencyObject as Visual3D; // we reached the top if (visual3D == null) { break; } Transform3D transform = (Transform3D)visual3D.GetValue(Visual3D.TransformProperty); if (transform != null) { transform.Append(ref worldTransform); } dependencyObject = VisualTreeHelper.GetParent(dependencyObject); } if (dependencyObject != null) { viewport = (Viewport3DVisual)dependencyObject; } else { viewport = null; } return(worldTransform); }
public static SelectablePrimitive GetPrimitiveData(Visual3D target) { return((SelectablePrimitive)target.GetValue(PrimitiveDataProperty)); }