示例#1
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 Viewport3DX viewport, Vector2 point2d)//, out Vector3 pointNear, out Vector3 pointFar)
        {
            var camera = viewport.Camera as ProjectionCamera;

            if (camera != null)
            {
                var px = (float)point2d.X;
                var py = (float)point2d.Y;

                var     viewMatrix = camera.GetViewMatrix();
                Vector3 v          = new Vector3();

                var   matrix      = CameraExtensions.InverseViewMatrix(ref viewMatrix);
                float w           = (float)viewport.ActualWidth;
                float h           = (float)viewport.ActualHeight;
                var   aspectRatio = w / h;

                var     projMatrix = camera.GetProjectionMatrix(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 PerspectiveCamera)
                {
                    zn = camera.Position.ToVector3();
                }
                else
                {
                    v.Z = 0;
                    Vector3.TransformCoordinate(ref v, ref matrix, out zn);
                }
                Vector3 r = zf - zn;
                r.Normalize();

                return(new Ray(zn, r));
            }
            throw new HelixToolkitException("Unproject camera error.");
        }
        /// <summary>
        /// Initial implementation of hittest for billboard. Needs further improvement.
        /// </summary>
        /// <param name="rayWS"></param>
        /// <param name="hits"></param>
        /// <returns></returns>
        protected override bool OnHitTest(IRenderMatrices context, Ray rayWS, ref List <HitTestResult> hits)
        {
            var g      = this.geometryInternal as IBillboardText;
            var h      = false;
            var result = new HitTestResult();

            result.Distance = double.MaxValue;

            if (context == null || g.Width == 0 || g.Height == 0)
            {
                return(false);
            }

            if (g != null)
            {
                BoundingBox b      = new BoundingBox();
                var         left   = -g.Width / 2;
                var         right  = -left;
                var         top    = -g.Height / 2;
                var         bottom = -top;
                if (FixedSize)
                {
                    var viewportMatrix   = context.ViewportMatrix;
                    var projectionMatrix = context.ProjectionMatrix;
                    var viewMatrix       = context.ViewMatrix;
                    var visualToScreen   = viewMatrix * projectionMatrix * viewportMatrix;

                    var center      = new Vector4(g.Positions[0], 1);
                    var screenPoint = Vector4.Transform(center, visualToScreen);
                    var spw         = screenPoint.W;
                    var spx         = screenPoint.X;
                    var spy         = screenPoint.Y;
                    var spz         = screenPoint.Z / spw / projectionMatrix.M33;

                    var     matrix = CameraExtensions.InverseViewMatrix(ref viewMatrix);
                    var     width  = (float)context.ActualWidth;
                    var     height = (float)context.ActualHeight;
                    Vector3 v      = new Vector3();

                    var x = spx + left * spw;
                    var y = spy + bottom * spw;
                    v.X = (2 * x / width / spw - 1) / projectionMatrix.M11;
                    v.Y = -(2 * y / height / spw - 1) / projectionMatrix.M22;
                    v.Z = spz;

                    Vector3 bl;
                    Vector3.TransformCoordinate(ref v, ref matrix, out bl);


                    x   = spx + right * spw;
                    y   = spy + bottom * spw;
                    v.X = (2 * x / width / spw - 1) / projectionMatrix.M11;
                    v.Y = -(2 * y / height / spw - 1) / projectionMatrix.M22;
                    v.Z = spz;

                    Vector3 br;
                    Vector3.TransformCoordinate(ref v, ref matrix, out br);

                    x   = spx + right * spw;
                    y   = spy + top * spw;
                    v.X = (2 * x / width / spw - 1) / projectionMatrix.M11;
                    v.Y = -(2 * y / height / spw - 1) / projectionMatrix.M22;
                    v.Z = spz;

                    Vector3 tr;
                    Vector3.TransformCoordinate(ref v, ref matrix, out tr);

                    x   = spx + left * spw;
                    y   = spy + top * spw;
                    v.X = (2 * x / width / spw - 1) / projectionMatrix.M11;
                    v.Y = -(2 * y / height / spw - 1) / projectionMatrix.M22;
                    v.Z = spz;

                    Vector3 tl;
                    Vector3.TransformCoordinate(ref v, ref matrix, out tl);

                    b = BoundingBox.FromPoints(new Vector3[] { tl, tr, bl, br });

                    /*
                     * var visualToScreen = viewport.GetViewProjectionMatrix() * viewport.GetViewportMatrix();
                     *
                     * var screenToVisual = visualToScreen.Inverted();
                     *
                     * var center = new Vector4(g.Positions[0], 1);
                     * var screenPoint = Vector4.Transform(center, visualToScreen);
                     * var spw = screenPoint.W;
                     * var spx = screenPoint.X;
                     * var spy = screenPoint.Y;
                     * var spz = screenPoint.Z;
                     *
                     * //Debug.WriteLine(spw);
                     * // Debug.WriteLine(string.Format("Z={0}; W={1}", spz, spw));
                     * var bl = new Vector4(spx + left * spw, spy + bottom * spw, spz, spw);
                     * bl = Vector4.Transform(bl, screenToVisual);
                     * bl /= bl.W;
                     *
                     * var br = new Vector4(spx + right * spw, spy + bottom * spw, spz, spw);
                     * br = Vector4.Transform(br, screenToVisual);
                     * br /= br.W;
                     *
                     * var tr = new Vector4(spx + right * spw, spy + top * spw, spz, spw);
                     * tr = Vector4.Transform(tr, screenToVisual);
                     * tr /= tr.W;
                     *
                     * var tl = new Vector4(spx + left * spw, spy + top * spw, spz, spw);
                     * tl = Vector4.Transform(tl, screenToVisual);
                     * tl /= tl.W;
                     *
                     * b = BoundingBox.FromPoints(new Vector3[] { tl.ToVector3(), tr.ToVector3(), bl.ToVector3(), br.ToVector3() });
                     */
                }
                else
                {
                    var center     = new Vector4(g.Positions[0], 1);
                    var viewMatrix = context.ViewMatrix;

                    var vcenter = Vector4.Transform(center, viewMatrix);
                    var vcX     = vcenter.X;
                    var vcY     = vcenter.Y;

                    var bl            = new Vector4(vcX + left, vcY + bottom, vcenter.Z, vcenter.W);
                    var br            = new Vector4(vcX + right, vcY + bottom, vcenter.Z, vcenter.W);
                    var tr            = new Vector4(vcX + right, vcY + top, vcenter.Z, vcenter.W);
                    var tl            = new Vector4(vcX + left, vcY + top, vcenter.Z, vcenter.W);
                    var invViewMatrix = CameraExtensions.InverseViewMatrix(ref viewMatrix);

                    bl  = Vector4.Transform(bl, invViewMatrix);
                    bl /= bl.W;
                    br  = Vector4.Transform(br, invViewMatrix);
                    br /= br.W;
                    tr  = Vector4.Transform(tr, invViewMatrix);
                    tr /= tr.W;
                    tl  = Vector4.Transform(tl, invViewMatrix);
                    tl /= tl.W;
                    b   = BoundingBox.FromPoints(new Vector3[] { tl.ToVector3(), tr.ToVector3(), bl.ToVector3(), br.ToVector3() });
                }

                // this all happens now in world space now:
                //Debug.WriteLine(string.Format("RayPosition:{0}; Direction:{1};", rayWS.Position, rayWS.Direction));
                if (rayWS.Intersects(ref b))
                {
                    float distance;
                    if (Collision.RayIntersectsBox(ref rayWS, ref b, out distance))
                    {
                        h = true;
                        result.ModelHit = this;
                        result.IsValid  = true;
                        result.PointHit = (rayWS.Position + (rayWS.Direction * distance)).ToPoint3D();
                        result.Distance = distance;
                        Debug.WriteLine(string.Format("Hit; HitPoint:{0}; Bound={1}; Distance={2}", result.PointHit, b, distance));
                    }
                }
            }
            if (h)
            {
                hits.Add(result);
            }
            return(h);
        }
示例#3
0
        public override void Render(RenderContext context)
        {
            if (!this.renderHost.IsShadowMapEnabled)
            {
                return;
            }

            /// --- set rasterizes state here with proper shadow-bias, as depth-bias and slope-bias in the rasterizer
            this.Device.ImmediateContext.Rasterizer.SetViewport(0, 0, width, height, 0.0f, 1.0f);
            this.Device.ImmediateContext.OutputMerger.SetTargets(depthViewSM);
            this.Device.ImmediateContext.ClearDepthStencilView(depthViewSM, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);

            var root = context.Canvas.Renderable.Items;

            foreach (var item in root)
            {
                var light = item as Light3D;
                if (light != null)
                {
                    Camera lightCamera = null;
                    //if (light is PointLightBase3D)
                    //{
                    //    var plight = (PointLightBase3D)light;
                    //    lightCamera = new PerspectiveCamera()
                    //    {
                    //        Position = plight.Position,
                    //        LookDirection = plight.Direction,
                    //        UpDirection = Vector3.UnitY.ToVector3D(),
                    //    };
                    //}
                    // else
                    if (light is DirectionalLight3D)
                    {
                        var dlight = (DirectionalLight3D)light;
                        var dir    = light.Direction.Normalized();
                        var pos    = -50 * light.Direction;

                        //lightCamera = new PerspectiveCamera()
                        //{
                        //    LookDirection = dir.ToVector3D(),
                        //    Position = (System.Windows.Media.Media3D.Point3D)(pos.ToVector3D()),
                        //    UpDirection = Vector3.UnitZ.ToVector3D(),
                        //    NearPlaneDistance = 1,
                        //    FarPlaneDistance = 100,
                        //    FieldOfView = 10,
                        //};

                        lightCamera = new OrthographicCamera()
                        {
                            LookDirection     = dir.ToVector3D(),
                            Position          = (System.Windows.Media.Media3D.Point3D)(pos.ToVector3D()),
                            UpDirection       = Vector3.UnitZ.ToVector3D(),
                            Width             = 100,
                            NearPlaneDistance = 1,
                            FarPlaneDistance  = 500,
                        };
                    }

                    if (lightCamera != null)
                    {
                        var sceneCamera = context.Camera;

                        light.LightViewMatrix       = CameraExtensions.GetViewMatrix(lightCamera);
                        light.LightProjectionMatrix = CameraExtensions.GetProjectionMatrix(lightCamera, context.Canvas.ActualWidth / context.Canvas.ActualHeight);

                        this.shadowPassContext.IsShadowPass = true;
                        this.shadowPassContext.Camera       = lightCamera;
                        foreach (var e in root)
                        {
                            var smodel = e as IThrowingShadow;
                            if (smodel != null)
                            {
                                if (smodel.IsThrowingShadow)
                                {
                                    var model = smodel as IRenderable;
                                    model.Render(this.shadowPassContext);
                                }
                            }
                        }
                        context.Camera = sceneCamera;
                    }
                }
            }

            this.texShadowMapVariable.SetResource(this.texShadowMapView);
            //this.texShadowMapVariable.SetResource(this.texColorMapView);
            this.vShadowMapInfoVariable.Set(new Vector4((float)this.Intensity, (float)this.FactorPCF, (float)this.Bias, 0));
            this.vShadowMapSizeVariable.Set(new Vector2(width, height));

            //System.Console.WriteLine("ShadowMap rendered!");
            context.Canvas.SetDefaultRenderTargets();
        }