/// <summary> /// Transforms from local to world coordinates. /// </summary> /// <param name="vector"> /// The vector (local coordinates). /// </param> /// <returns> /// Transformed vector (world coordinates). /// </returns> protected Vector3D ToWorld(Vector3D vector) { var mat = Visual3DHelper.GetTransform(this); var t = new MatrixTransform3D(mat); return(t.Transform(vector)); }
/// <summary> /// Transforms from local to world coordinates. /// </summary> /// <param name="point"> /// The point (local coordinates). /// </param> /// <returns> /// Transformed point (world coordinates). /// </returns> protected Point3D ToWorld(Point3D point) { var mat = Visual3DHelper.GetTransform(this); var t = new MatrixTransform3D(mat); return(t.Transform(point)); }
/// <summary> /// The sort children. /// </summary> private void SortChildren() { var vp = Visual3DHelper.GetViewport3D(this); if (vp == null) { return; } var cam = vp.Camera as ProjectionCamera; if (cam == null) { return; } var cameraPos = cam.Position; var transform = new MatrixTransform3D(Visual3DHelper.GetTransform(this)); IList <Visual3D> transparentChildren = new List <Visual3D>(); IList <Visual3D> opaqueChildren = new List <Visual3D>(); if (this.CheckForOpaqueVisuals) { foreach (var child in this.Children) { if (this.IsVisualTransparent(child)) { transparentChildren.Add(child); } else { opaqueChildren.Add(child); } } } else { transparentChildren = this.Children; } // sort the children by distance from camera (note that OrderBy is a stable sort algorithm) var sortedTransparentChildren = transparentChildren.OrderBy(item => - this.GetCameraDistance(item, cameraPos, transform)).ToList(); this.Children.Clear(); // add the opaque children foreach (var c in opaqueChildren) { this.Children.Add(c); } // add the sorted transparent children foreach (var c in sortedTransparentChildren) { this.Children.Add(c); } }
/// <summary> /// Transforms from world to local coordinates. /// </summary> /// <param name="worldPoint"> /// The point (world coordinates). /// </param> /// <returns> /// Transformed vector (local coordinates). /// </returns> protected Point3D ToLocal(Point3D worldPoint) { var mat = Visual3DHelper.GetTransform(this); mat.Invert(); var t = new MatrixTransform3D(mat); return(t.Transform(worldPoint)); }
/// <summary> /// The sort children. /// </summary> private void SortChildren() { var vp = Visual3DHelper.GetViewport3D(this); if (vp == null) { return; } var cam = vp.Camera as ProjectionCamera; if (cam == null) { return; } var cameraPos = cam.Position; var transform = new MatrixTransform3D(Visual3DHelper.GetTransform(this)); IList <Visual3D> transparentChildren = new List <Visual3D>(); IList <Visual3D> opaqueChildren = new List <Visual3D>(); if (this.CheckForOpaqueVisuals) { foreach (var child in this.Children) { if (this.IsVisualTransparent(child)) { transparentChildren.Add(child); } else { opaqueChildren.Add(child); } } } else { transparentChildren = this.Children; } // sort the children by distance from camera (note that OrderBy is a stable sort algorithm) var sortedTransparentChildren = transparentChildren.OrderBy(item => - this.GetCameraDistance(item, cameraPos, transform)).ToList(); // Now that opaqueChildren and sortedTransparentChildren describe our desired ordering, we need sort the current children in the new order. // To optimize the efficiency of this procedure we want to change the children list as little as possible. // Unfortunatally the Visual3DCollection does not have a swap method and we always need to remove an item before we can add it again as // temporary duplicates result in exceptions in the visual tree. // Due to this set of considerations we use selection sort to sort the current Children. (if we could swap without removal, cycle sort might be a small improvement) for (int desiredIndex = 0; desiredIndex < opaqueChildren.Count; desiredIndex++) { Visual3D currentChild = opaqueChildren[desiredIndex]; int currentIndex = Children.IndexOf(currentChild); //Insert in the proper spot if not contained: if (currentIndex == -1) { Children.Insert(desiredIndex, currentChild); continue; } //Do nothing if it is in the correct spot; //The order of the opaque children does not matter as long as they are before the transparent children: if (currentIndex < opaqueChildren.Count) { continue; } //remove from old spot and insert to the new correct spot: Children.RemoveAt(currentIndex); Children.Insert(desiredIndex, currentChild); } for (int desiredIndex = opaqueChildren.Count; desiredIndex < opaqueChildren.Count + sortedTransparentChildren.Count; desiredIndex++) { Visual3D currentChild = sortedTransparentChildren[desiredIndex - opaqueChildren.Count]; int currentIndex = Children.IndexOf(currentChild); //Insert in the proper spot if not contained: if (currentIndex == -1) { Children.Insert(desiredIndex, currentChild); continue; } //Do nothing if it is in the correct spot: if (currentIndex == desiredIndex) { continue; } //remove from old spot and insert to the new correct spot: Children.RemoveAt(currentIndex); Children.Insert(desiredIndex, currentChild); } }