/// <summary> /// Traverses the specified action. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="function">The function. Return true to continue traverse, otherwise stop at current node</param> public static void Traverse(this ViewportCore viewport, Func <SceneNode, bool> function) { viewport.Renderables.PreorderDFT((node) => { return(function(node)); }); }
public CoreTestApp(Form window) { viewport = new ViewportCore(window.Handle); cameraController = new CameraController(viewport); this.window = window; window.ResizeEnd += Window_ResizeEnd; window.Load += Window_Load; window.FormClosing += Window_FormClosing; window.MouseMove += Window_MouseMove; window.MouseDown += Window_MouseDown; window.MouseUp += Window_MouseUp; window.MouseWheel += Window_MouseWheel; window.KeyDown += Window_KeyDown; window.KeyUp += Window_KeyUp; window.KeyPress += Window_KeyPress; effectsManager = new DefaultEffectsManager(); effectsManager.AddTechnique(ImGuiNode.RenderTechnique); viewport.EffectsManager = effectsManager; viewport.OnStartRendering += Viewport_OnStartRendering; viewport.OnStopRendering += Viewport_OnStopRendering; viewport.OnErrorOccurred += Viewport_OnErrorOccurred; //viewport.FXAALevel = FXAALevel.Low; viewport.RenderHost.EnableRenderFrustum = false; viewport.RenderHost.RenderConfiguration.EnableRenderOrder = true; viewport.BackgroundColor = new Color4(0.45f, 0.55f, 0.6f, 1f); InitializeScene(); }
/// <summary> /// Finds the nearest point and its normal. /// </summary> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="position"> /// The position. /// </param> /// <param name="point"> /// The point. /// </param> /// <param name="normal"> /// The normal. /// </param> /// <param name="model"> /// The model. /// </param> /// <returns> /// The find nearest. /// </returns> public static bool FindNearest(this ViewportCore viewport, Vector2 position, out Vector3 point, out Vector3 normal, out object model) { point = new Vector3(); normal = new Vector3(); model = null; if (viewport.CameraCore is ProjectionCameraCore) { var hits = FindHits(viewport, position); if (hits.Count > 0) { point = hits[0].PointHit; normal = hits[0].NormalAtHit; model = hits[0].ModelHit; return(true); } else { return(false); } } else { return(false); } }
/// <summary> /// Zooms to fit the specified sphere. /// </summary> /// <param name="camera"> /// The camera. /// </param> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="center"> /// The center of the sphere. /// </param> /// <param name="radius"> /// The radius of the sphere. /// </param> /// <param name="animationTime"> /// The animation time. /// </param> public static void ZoomExtents( this CameraCore camera, ViewportCore viewport, Vector3 center, float radius, float animationTime = 0) { // var target = Camera.Position + Camera.LookDirection; if (camera is PerspectiveCameraCore pcam) { float disth = radius / (float)Math.Tan(0.5 * pcam.FieldOfView * Math.PI / 180); float vfov = pcam.FieldOfView / viewport.ViewportRectangle.Width * viewport.ViewportRectangle.Height; float distv = radius / (float)Math.Tan(0.5 * vfov * Math.PI / 180); float dist = Math.Max(disth, distv); var dir = camera.LookDirection; dir.Normalize(); LookAt(camera, center, dir * dist, animationTime); } else if (camera is OrthographicCameraCore orth) { LookAt(camera, center, camera.LookDirection, animationTime); float newWidth = radius * 2; if (viewport.ViewportRectangle.Width > viewport.ViewportRectangle.Height) { newWidth = radius * 2 * viewport.ViewportRectangle.Width / viewport.ViewportRectangle.Height; } orth.AnimateWidth(newWidth, animationTime); } }
/// <summary> /// Projects the specified 3D point to a 2D screen point. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="point">The 3D point.</param> /// <returns>The point.</returns> public static Vector2 Project(this ViewportCore viewport, Vector3 point) { var matrix = GetScreenViewProjectionMatrix(viewport); var pointTransformed = Vector3.Transform(point, matrix); var pt = new Vector2((int)pointTransformed.X, (int)pointTransformed.Y); return(pt); }
/// <summary> /// Traverses the Visual3D/Element3D tree and invokes the specified action on each Element3D of the specified type. /// </summary> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="action"> /// The action. /// </param> public static void Traverse(this ViewportCore viewport, Action <SceneNode> action) { viewport.Renderables.PreorderDFT((node) => { action(node); return(true); }); }
/// <summary> /// Finds the bounding box of the viewport. /// </summary> /// <param name="viewport">The viewport.</param> /// <returns>The bounding box.</returns> public static BoundingBox FindBounds(this ViewportCore viewport) { if (viewport.RenderHost != null && viewport.RenderHost.IsRendering) { viewport.RenderHost.UpdateAndRender(); } return(FindBoundsInternal(viewport)); }
/// <summary> /// Zooms to fit the specified bounding rectangle. /// </summary> /// <param name="camera"> /// The actual camera. /// </param> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="bounds"> /// The bounding rectangle. /// </param> /// <param name="animationTime"> /// The animation time. /// </param> public static void ZoomExtents( this CameraCore camera, ViewportCore viewport, BoundingBox bounds, float animationTime = 0) { var diagonal = bounds.Maximum - bounds.Minimum; var center = bounds.Center + (diagonal * 0.5f); float radius = diagonal.Length() * 0.5f; ZoomExtents(camera, viewport, center, radius, animationTime); }
/// <summary> /// Un-project a point from the screen (2D) to a point on plane (3D) /// </summary> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="p"> /// The 2D point. /// </param> /// <param name="position"> /// plane position /// </param> /// <param name="normal"> /// plane normal /// </param> /// <returns> /// A 3D point. /// </returns> public static Vector3?UnProjectOnPlane(this ViewportCore viewport, Vector2 p, Vector3 position, Vector3 normal) { var ray = UnProject(viewport, p); if (ray == null) { return(null); } return(ray.PlaneIntersection(position, normal)); }
public void HitTestShouldReturnOnePointOnFrontOfCubeWithNoCuttingPlanes() { var viewport = new ViewportCore(IntPtr.Zero); var ray = new Ray(new Vector3(2f, 0f, 0f), new Vector3(-1, 0, 0)); var hits = new List <HitTestResult>(); var sceneNode = GetNode(); sceneNode.HitTest(viewport.RenderContext, ray, ref hits); Assert.AreEqual(1, hits.Count); Assert.AreEqual(new Vector3(0.5f, 0, 0), hits[0].PointHit); }
/// <summary> /// Zooms to the extents of the specified viewport. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="animationTime">The animation time.</param> public static void ZoomExtents(this ViewportCore viewport, float animationTime = 0) { var bounds = viewport.FindBounds(); var diagonal = bounds.Maximum - bounds.Minimum; if (diagonal.LengthSquared() == 0) { return; } viewport.CameraCore.ZoomExtents(viewport, bounds, animationTime); }
/// <summary> /// Zooms to fit the extents of the specified viewport. /// </summary> /// <param name="camera"> /// The actual camera. /// </param> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="animationTime"> /// The animation time. /// </param> public static void ZoomExtents( this CameraCore camera, ViewportCore viewport, float animationTime = 0) { var bounds = viewport.FindBoundsInternal(); var diagonal = bounds.Maximum - bounds.Minimum; if (diagonal.LengthSquared().Equals(0)) { return; } ZoomExtents(camera, viewport, bounds, animationTime); }
/// <summary> /// Zooms the camera to the specified rectangle. /// </summary> /// <param name="camera"> /// The camera. /// </param> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="zoomRectangle"> /// The zoom rectangle. /// </param> public static void ZoomToRectangle(this CameraCore camera, ViewportCore viewport, RectangleF zoomRectangle) { if (camera is ProjectionCameraCore pcam) { var topLeftRay = viewport.UnProjectToRay(new Vector2(zoomRectangle.Top, zoomRectangle.Left)); var topRightRay = viewport.UnProjectToRay(new Vector2(zoomRectangle.Top, zoomRectangle.Right)); var centerRay = viewport.UnProjectToRay( new Vector2( (zoomRectangle.Left + zoomRectangle.Right) * 0.5f, (zoomRectangle.Top + zoomRectangle.Bottom) * 0.5f)); if (topLeftRay == null || topRightRay == null || centerRay == null) { // could not invert camera matrix return; } var u = topLeftRay.Direction; var v = topRightRay.Direction; var w = centerRay.Direction; u.Normalize(); v.Normalize(); w.Normalize(); if (camera is PerspectiveCameraCore perspectiveCamera) { var distance = pcam.LookDirection.Length(); // option 1: change distance var newDistance = distance * zoomRectangle.Width / viewport.ViewportRectangle.Width; var newLookDirection = (float)newDistance * w; var newPosition = perspectiveCamera.Position + ((distance - (float)newDistance) * w); var newTarget = newPosition + newLookDirection; LookAt(pcam, newTarget, newLookDirection, 200); } else if (camera is OrthographicCameraCore orthographicCamera) { orthographicCamera.Width *= zoomRectangle.Width / viewport.ViewportRectangle.Width; var oldTarget = pcam.Position + pcam.LookDirection; var distance = pcam.LookDirection.Length(); var newTarget = centerRay.PlaneIntersection(oldTarget, w); if (newTarget != null) { orthographicCamera.LookDirection = w * distance; orthographicCamera.Position = newTarget.Value - orthographicCamera.LookDirection; } } } }
public CoreTestApp(Form window) { viewport = new ViewportCore(window.Handle); this.window = window; window.ResizeEnd += Window_ResizeEnd; window.Load += Window_Load; window.FormClosing += Window_FormClosing; effectsManager = new DefaultEffectsManager(); viewport.EffectsManager = effectsManager; viewport.OnStartRendering += Viewport_OnStartRendering; viewport.OnStopRendering += Viewport_OnStopRendering; viewport.OnErrorOccurred += Viewport_OnErrorOccurred; viewport.FXAALevel = FXAALevel.Low; InitializeScene(); }
internal static BoundingBox FindBoundsInternal(this ViewportCore viewport) { var maxVector = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); var firstModel = viewport.Renderables.PreorderDFT((r) => { if (r.Visible && !(r is ScreenSpacedNode)) { return(true); } return(false); }).Where(x => { if (x is IBoundable b) { return(b.HasBound && b.BoundsWithTransform.Maximum != b.BoundsWithTransform.Minimum && b.BoundsWithTransform.Maximum != Vector3.Zero && b.BoundsWithTransform.Maximum != maxVector); } else { return(false); } }).FirstOrDefault(); if (firstModel == null) { return(new BoundingBox()); } var bounds = firstModel.BoundsWithTransform; foreach (var renderable in viewport.Renderables.PreorderDFT((r) => { if (r.Visible && !(r is ScreenSpacedNode)) { return(true); } return(false); })) { if (renderable is IBoundable r) { if (r.HasBound && r.BoundsWithTransform.Maximum != maxVector) { bounds = global::SharpDX.BoundingBox.Merge(bounds, r.BoundsWithTransform); } } } return(bounds); }
public CoreTestApp(Form window) { viewport = new ViewportCore(window.Handle); this.window = window; window.ResizeEnd += Window_ResizeEnd; window.Load += Window_Load; window.FormClosing += Window_FormClosing; effectsManager = new DefaultEffectsManager(); viewport.EffectsManager = effectsManager; viewport.OnStartRendering += Viewport_OnStartRendering; viewport.OnStopRendering += Viewport_OnStopRendering; viewport.OnErrorOccurred += Viewport_OnErrorOccurred; viewport.FXAALevel = FXAALevel.Low; //viewport.RenderHost.EnableRenderFrustum = false; viewport.RenderHost.RenderConfiguration.EnableRenderOrder = true; InitializeScene(); }
public static Matrix GetViewportMatrix(this ViewportCore viewport) { return(new Matrix( viewport.ViewportRectangle.Width / 2f, 0, 0, 0, 0, -viewport.ViewportRectangle.Height / 2f, 0, 0, 0, 0, 1, 0, (viewport.ViewportRectangle.Width - 1) / 2f, (viewport.ViewportRectangle.Height - 1) / 2f, 0, 1)); }
/// <summary> /// Finds the hits for a given 2D viewport position. /// </summary> /// <param name="viewport"> /// The viewport. /// </param> /// <param name="position"> /// The position. /// </param> /// <returns> /// List of hits, sorted with the nearest hit first. /// </returns> public static IList <HitTestResult> FindHits(this ViewportCore viewport, Vector2 position) { if (viewport.CameraCore is ProjectionCameraCore) { var ray = UnProject(viewport, position); var hits = new List <HitTestResult>(); foreach (var element in viewport.Renderables) { element.HitTest(viewport.RenderContext, ray, ref hits); } hits.Sort(); return(hits); } else { return(EmptyHits); } }
/// <summary> /// Un-projects a 2D screen point. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="point2d">The input point.</param> /// <returns>The ray.</returns> public static Ray UnProject(this ViewportCore viewport, Vector2 point2d) { var camera = viewport.CameraCore as ProjectionCameraCore; if (camera != null) { var px = (float)point2d.X; var py = (float)point2d.Y; var viewMatrix = camera.CreateViewMatrix(); Vector3 v = new Vector3(); var matrix = MatrixExtensions.PsudoInvert(ref viewMatrix); float w = (float)viewport.ViewportRectangle.Width; float h = (float)viewport.ViewportRectangle.Height; var aspectRatio = w / h; var projMatrix = camera.CreateProjectionMatrix(aspectRatio); Vector3 zn, zf; v.X = (2 * px / w - 1) / projMatrix.M11; v.Y = -(2 * py / h - 1) / projMatrix.M22; v.Z = 1 / projMatrix.M33; Vector3.TransformCoordinate(ref v, ref matrix, out zf); if (camera is PerspectiveCameraCore) { zn = camera.Position; } else { v.Z = 0; Vector3.TransformCoordinate(ref v, ref matrix, out zn); } Vector3 r = zf - zn; r.Normalize(); return(new Ray(zn + r * camera.NearPlaneDistance, r)); } throw new HelixToolkitException("Unproject camera error."); }
public static Matrix GetProjectionMatrix(this ViewportCore viewport) { return(viewport.RenderContext != null ? viewport.RenderContext.ProjectionMatrix : viewport.CameraCore.CreateProjectionMatrix((float)viewport.ViewportRectangle.Width / (float)viewport.ViewportRectangle.Height)); }
/// <summary> /// /// </summary> /// <param name="viewport"></param> /// <param name="point2d"></param> /// <returns></returns> public static Ray UnProjectToRay(this ViewportCore viewport, Vector2 point2d) { var r = viewport.UnProject(point2d); return(new Ray(r.Position, r.Direction)); }
/// <summary> /// Zooms to the extents of the specified bounding sphere. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="center">The center of the sphere.</param> /// <param name="radius">The radius of the sphere.</param> /// <param name="animationTime">The animation time.</param> public static void ZoomExtents(this ViewportCore viewport, Vector3 center, float radius, float animationTime = 0) { viewport.CameraCore.ZoomExtents(viewport, center, radius, animationTime); }
/// <summary> /// Zooms to the extents of the specified bounding box. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="bounds">The bounding rectangle.</param> /// <param name="animationTime">The animation time.</param> public static void ZoomExtents(this ViewportCore viewport, BoundingBox bounds, float animationTime = 0) { viewport.CameraCore.ZoomExtents(viewport, bounds, animationTime); }
public static Matrix GetScreenViewProjectionMatrix(this ViewportCore viewport) { return(GetViewProjectionMatrix(viewport) * GetViewportMatrix(viewport)); }
/// <summary> /// Zooms the viewport to the specified rectangle. /// </summary> /// <param name="viewport">The viewport.</param> /// <param name="rectangle">The rectangle.</param> public static void ZoomToRectangle(this ViewportCore viewport, RectangleF rectangle) { viewport.CameraCore.ZoomToRectangle(viewport, rectangle); }