コード例 #1
0
 /// <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));
     });
 }
コード例 #2
0
ファイル: CoreTestApp.cs プロジェクト: xzcxlyh/helix-toolkit
 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();
 }
コード例 #3
0
 /// <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);
     }
 }
コード例 #4
0
        /// <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);
            }
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
 /// <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);
     });
 }
コード例 #7
0
 /// <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));
 }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        /// <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));
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
        /// <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);
        }
コード例 #13
0
        /// <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;
                    }
                }
            }
        }
コード例 #14
0
 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();
 }
コード例 #15
0
        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);
        }
コード例 #16
0
 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();
 }
コード例 #17
0
 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));
 }
コード例 #18
0
        /// <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);
            }
        }
コード例 #19
0
        /// <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.");
        }
コード例 #20
0
 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));
 }
コード例 #21
0
        /// <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));
        }
コード例 #22
0
 /// <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);
 }
コード例 #23
0
 /// <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);
 }
コード例 #24
0
 public static Matrix GetScreenViewProjectionMatrix(this ViewportCore viewport)
 {
     return(GetViewProjectionMatrix(viewport) * GetViewportMatrix(viewport));
 }
コード例 #25
0
 /// <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);
 }