Example #1
0
        /// <summary>
        /// Creates a Model using data from an obj file.  If unable to parse the file, null will be returned.
        /// </summary>
        public Model LoadObj(FileStream stream)
        {
            StreamReader reader = new StreamReader(stream);
            Dictionary<string, int> vectorMap = new Dictionary<string, int>();
            List<Vector3> points = new List<Vector3>();
            List<Vector3> normals = new List<Vector3>();
            List<Vector2> texCoords = new List<Vector2>();
            Model model = new Model();
            model.Mesh = new Mesh();
            string mtlFileName = "";
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                line = line.Trim(splitChar);
                string[] parameters = line.Split(splitChar);

                switch (parameters[0])
                {
                    case "mtllib":
                        mtlFileName = string.Join(splitChar.ToString(), parameters, 1, parameters.Length - 1);
                        break;

                    case "p": // Point
                        break;

                    case "v": // Vertex
                        Vector3 vert;
                        if (!parseVector3(parameters, out vert))
                        {
                            return null;
                        }
                        points.Add(vert);
                        break;

                    case "vt": // TexCoord
                        Vector2 tex;
                        if (!parseVector2(parameters, out tex))
                        {
                            return null;
                        }
                        texCoords.Add(tex);
                        break;

                    case "vn": // Normal
                        Vector3 norm;
                        if (!parseVector3(parameters, out norm))
                        {
                            return null;
                        }
                        normals.Add(norm);
                        break;

                    case "f": // Face
                        if (!parseFace(model, parameters, points, normals, texCoords, vectorMap))
                        {
                            return null;
                        }
                        break;
                }
            }

            string mtlFilePath = Path.Combine(Path.GetDirectoryName(stream.Name), mtlFileName);
            model.SetTexture(LoadMtl(mtlFilePath));
            return model;
        }
Example #2
0
        /// <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);
        }