예제 #1
0
파일: CameraExt.cs 프로젝트: AyyTee/Aventyr
        /// <summary>
        /// Create a view matrix for this Camera
        /// </summary>
        public static Matrix4 GetViewMatrix(ICamera2 camera, bool isOrtho = true)
        {
            Transform2 transform = camera.GetWorldTransform();
            Matrix4 m = Matrix4.CreateRotationZ(transform.Rotation);
            Vector3 lookat = new Vector3(transform.Position) + Vector3.Transform(new Vector3(0, 0, -1), m);
            Vector3 eye;
            Matrix4 perspective;

            if (isOrtho)
            {
                float x = camera.ViewOffset.X / 2;
                float y = camera.ViewOffset.Y / 2;

                float width = transform.Scale.X * camera.Aspect;
                float height = transform.Scale.Y;
                x *= transform.Scale.X * camera.Aspect;
                y *= transform.Scale.Y;
                perspective = Matrix4.CreateOrthographicOffCenter(x - width / 2, x + width / 2, y - height / 2, y + height / 2, camera.ZNear, camera.ZFar);
                eye = new Vector3(transform.Position) + new Vector3(0, 0, 50);
                return Matrix4.LookAt(eye, lookat, new Vector3(GetUp(camera))) * perspective;
            }

            perspective = Matrix4.CreatePerspectiveFieldOfView((float)camera.Fov, camera.Aspect, 0.01f, 10000f);
            perspective = Matrix4.CreateScale(transform.Scale.X, transform.Scale.Y, Math.Abs(transform.Size)) * perspective;
            eye = new Vector3(transform.Position) + new Vector3(0, 0, (float)GetWorldZ(camera));
            return Matrix4.LookAt(eye, lookat, new Vector3(GetUp(camera))) * perspective * Matrix4.CreateTranslation(new Vector3(-camera.ViewOffset.X, -camera.ViewOffset.Y, 0));
        }
예제 #2
0
파일: CameraExt.cs 프로젝트: AyyTee/Aventyr
        //get xy world offset needed to make v appear to overlap target in screen space.
        public static Vector2 GetOverlapOffset(ICamera2 camera, Vector3 v, Vector3 target)
        {
            Vector3 cameraPos = new Vector3(camera.GetWorldTransform().Position);
            cameraPos.Z = (float)GetWorldZ(camera);
            float x = (v.X - cameraPos.X) / (v.Z - cameraPos.Z) - (target.X - cameraPos.X) / (target.Z - cameraPos.Z);
            float y = (v.Y - cameraPos.Y) / (v.Z - cameraPos.Z) - (target.Y - cameraPos.Y) / (target.Z - cameraPos.Z);
            Vector2 offset = -new Vector2(x, y) * (v.Z - cameraPos.Z);

            return offset;
        }
예제 #3
0
파일: CameraExt.cs 프로젝트: AyyTee/Aventyr
 public static Transform2 GetWorldViewpoint(ICamera2 camera)
 {
     return new Transform2(camera.ViewOffset).Transform(camera.GetWorldTransform());
 }
예제 #4
0
파일: CameraExt.cs 프로젝트: AyyTee/Aventyr
 private static double GetWorldZ(ICamera2 camera)
 {
     return Math.Abs(camera.GetWorldTransform().Size / (2 * Math.Tan(camera.Fov / 2)));
 }
예제 #5
0
파일: CameraExt.cs 프로젝트: AyyTee/Aventyr
 private static Vector2 GetUp(ICamera2 camera)
 {
     Matrix4 m = Matrix4.CreateRotationZ(camera.GetWorldTransform().Rotation);
     return Vector2Ext.Transform(new Vector2(0, 1), m);
 }
예제 #6
0
        public static PortalView CalculatePortalViews(IList<IPortal> portals, ICamera2 camera, int depth)
        {
            Debug.Assert(camera != null);
            Debug.Assert(depth >= 0);
            Debug.Assert(portals != null);
            List<IntPoint> view = ClipperConvert.ToIntPoint(CameraExt.GetWorldVerts(camera));
            List<List<IntPoint>> paths = new List<List<IntPoint>>();
            paths.Add(view);
            PortalView portalView = new PortalView(null, CameraExt.GetViewMatrix(camera), view, new LineF[0], new LineF[0]);
            Vector2 camPos = camera.GetWorldTransform().Position;

            List<Func<bool>> actionList = new List<Func<bool>>();

            foreach (IPortal p in portals)
            {
                actionList.Add(() => CalculatePortalViews(p, null, portals, CameraExt.GetViewMatrix(camera), camPos, camPos - camera.GetWorldVelocity().Position / Controller.DrawsPerSecond, portalView, Matrix4.Identity, actionList));
            }

            while (actionList.Count > 0 && depth > 0)
            {
                bool result = actionList.First().Invoke();
                if (result)
                {
                    depth--;
                }
                actionList.RemoveAt(0);
            }

            return portalView;
        }
예제 #7
0
파일: Renderer.cs 프로젝트: AyyTee/Aventyr
        /// <summary>
        /// Draw the edges for each portal potentially including motion blur.
        /// </summary>
        /// <param name="portalViewList"></param>
        /// <param name="cam"></param>
        private void RenderPortalEdges(List<PortalView> portalViewList, ICamera2 cam)
        {
            int iterations = Math.Min(portalViewList.Count, StencilMaxValue);
            /* Escape early if there aren't any visible portals.
             * The first iteration is just for the main view which doesn't have portal edges.*/
            if (iterations <= 1)
            {
                return;
            }

            GL.Clear(ClearBufferMask.DepthBufferBit);
            SetEnable(EnableCap.StencilTest, false);
            GL.Disable(EnableCap.DepthTest);
            GL.Clear(ClearBufferMask.StencilBufferBit);
            Clipper c = new Clipper();
            c.StrictlySimple = true;

            Model portalEdges = new Model();
            portalEdges.SetTexture(Textures["lineBlur.png"]);
            SetEnable(EnableCap.Blend, true);
            for (int i = 1; i < iterations; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    LineF line = portalViewList[i].FovLines[j];
                    float minWidth = Math.Abs(cam.GetWorldTransform().Size) / 300;
                    double angleDiff = GetLineBlurAngle(line, portalViewList[i].FovLinesPrevious[j]);
                    float widthEnd = (float)Math.Tan(angleDiff) * line.Length;
                    widthEnd = Math.Max(widthEnd, minWidth);

                    Vector2[] lineWidth = PolygonFactory.CreateLineWidth(line, minWidth);

                    Vector2 camPos = cam.GetWorldTransform().Position;
                    Vector2[] lineWidthOff = Vector2Ext.Transform(lineWidth, Matrix4.CreateTranslation(new Vector3(-camPos)));
                    Vector2[] lineTarget = PolygonFactory.CreateLineWidth(line.Translate(-camPos), minWidth, widthEnd);
                    Matrix4d homography = Matrix4d.CreateTranslation(new Vector3d((Vector2d)(-camPos)));
                    homography *= MathExt.GetHomography(lineWidthOff, lineTarget);
                    homography *= Matrix4d.CreateTranslation(new Vector3d((Vector2d)camPos));

                    bool obscured = true;
                    for (int k = 0; k < portalViewList[i].Parent.Paths.Count; k++)
                    {
                        List<IntPoint> path = portalViewList[i].Parent.Paths[k];
                        if (Clipper.PointInPolygon(ClipperConvert.ToIntPoint(line[0]), path) == 1)
                        {
                            obscured = false;
                            break;
                        }
                    }
                    if (obscured)
                    {
                        continue;
                    }

                    foreach (PortalView p in portalViewList[i].Parent.Children)
                    {
                        if (p == portalViewList[i])
                        {
                            continue;
                        }
                        if (p.PortalLine.IsInsideFOV(camPos, line[0]))
                        {
                            obscured = true;
                            break;
                        }
                    }
                    if (obscured)
                    {
                        continue;
                    }
                    int index = ModelFactory.AddPolygon((Mesh)portalEdges.Mesh, lineWidth);

                    IMesh mesh = portalEdges.Mesh;
                    for (int k = index; k < mesh.GetVertices().Count; k++)
                    {
                        Vertex vertex = mesh.GetVertices()[k];
                        Vector3 pos = Vector3Ext.Transform(vertex.Position, homography);
                        pos.Z = CameraExt.UnitZToWorld(cam, pos.Z);

                        Vector2 texCoord;
                        Vector2 v = new Vector2(vertex.Position.X, vertex.Position.Y);
                        double distance = MathExt.PointLineDistance(v, line.GetPerpendicularLeft(), false);
                        double texCoordX = MathExt.PointLineDistance(v, line, false) / minWidth;
                        if (line.GetSideOf(v) == Side.Left)
                        {
                            texCoordX *= -1;
                        }
                        texCoordX += 0.5;
                        texCoord = new Vector2((float)texCoordX, (float)(distance / line.Length));

                        mesh.GetVertices()[k] = new Vertex(pos, texCoord);
                    }
                }
            }
            RenderModel(portalEdges, CameraExt.GetViewMatrix(cam, false));
            SetEnable(EnableCap.Blend, false);
            GL.Enable(EnableCap.DepthTest);
        }