Beispiel #1
0
        private void ParseLine(string line)
        {
            string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case GraphicTypes.Vertex:
                    var v = new Vertex();
                    v.ParseFromString(parts);
                    VertexList.Add(v);
                    break;

                case GraphicTypes.VertexNormal:
                    var vn = new VertexNormal();
                    vn.ParseFromString(parts);
                    NormalList.Add(vn);
                    break;

                case GraphicTypes.Face:
                    var f = new Face();
                    f.ParseFromString(parts);
                    FaceList.Add(f);
                    break;

                case GraphicTypes.TextureVertex:
                    var vt = new TextureVertex();
                    vt.ParseFromString(parts);
                    TextureList.Add(vt);
                    break;
                }
            }
        }
Beispiel #2
0
        private void InitializeBuffers()
        {
            vertexCount = 6;
            indexCount  = 6;

            var vertices = new TextureVertex[vertexCount];

            foreach (var vertex in vertices)
            {
                //set to zero
            }

            int[] indices = new int[indexCount];
            for (int i = 0; i < indexCount; i++)
            {
                indices[i] = i;
            }

            var vertexBufferDesc = new BufferDescription()
            {
                Usage = ResourceUsage.Dynamic,
                //or size of constant buffer
                SizeInBytes         = Utilities.SizeOf <TextureVertex>() * vertexCount,
                BindFlags           = BindFlags.VertexBuffer,
                CpuAccessFlags      = CpuAccessFlags.Write,
                OptionFlags         = ResourceOptionFlags.None,
                StructureByteStride = 0
            };

            // Create the vertex buffer.
            vertexBuffer = Buffer.Create(device, vertices, vertexBufferDesc);

            // Create the index buffer.
            indexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, indices);
        }
Beispiel #3
0
        static GraphicsBufferView CreateVertexBufferView(GraphicsCopyContext copyContext, GraphicsBuffer vertexBuffer, GraphicsBuffer uploadBuffer, float aspectRatio)
        {
            var uploadBufferView = uploadBuffer.CreateBufferView <TextureVertex>(3);
            var vertexBufferSpan = uploadBufferView.Map <TextureVertex>();

            {
                vertexBufferSpan[0] = new TextureVertex {
                    Position = Vector3.Create(0.0f, 0.25f * aspectRatio, 0.0f),
                    UV       = Vector2.Create(0.5f, 0.0f)
                };

                vertexBufferSpan[1] = new TextureVertex {
                    Position = Vector3.Create(0.25f, -0.25f * aspectRatio, 0.0f),
                    UV       = Vector2.Create(1.0f, 1.0f)
                };

                vertexBufferSpan[2] = new TextureVertex {
                    Position = Vector3.Create(-0.25f, -0.25f * aspectRatio, 0.0f),
                    UV       = Vector2.Create(0.0f, 1.0f)
                };
            }
            uploadBufferView.UnmapAndWrite();

            var vertexBufferView = vertexBuffer.CreateBufferView <TextureVertex>(3);

            copyContext.Copy(vertexBufferView, uploadBufferView);
            return(vertexBufferView);
        }
Beispiel #4
0
        /// <summary>
        /// Parses and loads a line from an OBJ file.
        /// Currently only supports V, VT, F and MTLLIB prefixes
        /// </summary>
        private void processLine(string line)
        {
            string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case "mtllib":
                    Mtl = parts[1];
                    break;

                case "v":
                    Vertex v = new Vertex();
                    v.LoadFromStringArray(parts);
                    VertexList.Add(v);
                    v.Index = VertexList.Count();
                    break;

                case "f":
                    Face f = new Face();
                    f.LoadFromStringArray(parts);
                    FaceList.Add(f);
                    break;

                case "vt":
                    TextureVertex vt = new TextureVertex();
                    vt.LoadFromStringArray(parts);
                    TextureList.Add(vt);
                    vt.Index = TextureList.Count();
                    break;
                }
            }
        }
        private void ProcessLine(string line)
        {
            string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case "usemtl":
                    UseMtl = parts[1];
                    break;

                case "mtllib":
                    Mtl = parts[1];
                    break;

                case "v":
                    Vertex v = new Vertex();
                    v.LoadFromStringArray(parts);
                    VertexList.Add(v);
                    v.Index = VertexList.Count();
                    break;

                case "vn":
                    VertexNormal vn = new VertexNormal();
                    vn.LoadFromStringArray(parts);
                    NormalList.Add(vn);
                    vn.Index = NormalList.Count();
                    break;

                case "s":
                    break;

                case "f":
                    Face f = new Face();
                    f.LoadFromStringArray(parts);
                    f.UseMtl = UseMtl;
                    FaceList.Add(f);
                    TriangleCount += f.VertexIndexList.Length - 2;
                    break;

                case "vt":
                    TextureVertex vt = new TextureVertex();
                    vt.LoadFromStringArray(parts);
                    TextureList.Add(vt);
                    vt.Index = TextureList.Count();
                    break;

                default:
                    System.Diagnostics.Debug.WriteLine(line);
                    break;
                }
            }
        }
Beispiel #6
0
        public int Compare(TextureVertex x, TextureVertex y)
        {
            if (x.XAxis == y.XAxis && x.YAxis == y.YAxis)
            {
                return(1);
            }

            else
            {
                return(0);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Parses and loads a line from an OBJ file.
        /// Currently only supports V, VT, F and MTLLIB prefixes
        /// </summary>
        private void processLine(string line)
        {
            string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case "usemtl":
                    UseMtl = parts[1];
                    break;

                case "o":
                    _currentObjectName = parts[1];
                    objects.Add(_currentObjectName);
                    break;

                case "mtllib":
                    Mtl = parts[1];
                    break;

                case "v":
                    Vertex v = new Vertex();
                    v.LoadFromStringArray(parts);
                    VertexList.Add(v);
                    v.Index = VertexList.Count();
                    break;

                case "vn":
                    Normal vn = new Normal();
                    vn.LoadFromStringArray(parts);
                    NormalList.Add(vn);
                    vn.Index = NormalList.Count();
                    break;

                case "f":
                    Face f = new Face();
                    f.LoadFromStringArray(parts);
                    f.UseMtl     = UseMtl;
                    f.objectName = _currentObjectName;
                    FaceList.Add(f);
                    break;

                case "vt":
                    TextureVertex vt = new TextureVertex();
                    vt.LoadFromStringArray(parts);
                    TextureList.Add(vt);
                    vt.Index = TextureList.Count();
                    break;
                }
            }
        }
Beispiel #8
0
        private static void ProcessTextureVertex(string[] lineParts, Mesh mesh)
        {
            if (lineParts.Length < 3)
            {
                return;
            }

            if (!float.TryParse(lineParts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out float u) ||
                !float.TryParse(lineParts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out float v))
            {
                return;
            }

            TextureVertex textureVertex = new TextureVertex(u, v);

            mesh.TextureVertices.Add(textureVertex);
        }
        public static T[] TextureVertex <T>(Vector3[] positions) where T : struct
        {
            Vector2[] textureCoord = GetTextureCoord();

            TextureVertex[] vertices = new TextureVertex[positions.Length];
            //from this array, make coresponding structure
            for (int i = 0; i < positions.Length; i++)
            {
                TextureVertex a = new TextureVertex();
                a.Position  = positions[i];
                a.Texture   = textureCoord[i];
                vertices[i] = a;
            }

            var y = (T[])Convert.ChangeType(vertices, typeof(T[]));

            return(y);
        }
Beispiel #10
0
        /// <summary>
        /// Build a TextureVertexDrawable from the text
        /// </summary>
        /// <param name="text"></param>
        /// <param name="color"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        private TextureVertexDrawable BuildDrawable(string text, Color color, float scale = 1f)
        {
            float UnitScale     = WorldTextRenderer.Units * scale;
            int   verticesCount = text.Length * 4;

            TextureVertex[] vertices = new TextureVertex[verticesCount];

            float x = 0f;
            int   i = 0;

            foreach (char l in text)
            {
                if (WorldTextRenderer.CharacterMap.TryGetValue(l, out BmFontChar fontChar))
                {
                    Vector4F UVPos = this.CharPositionToUV(fontChar.GetVector4I());

                    float xOffset  = fontChar.XOffset * UnitScale;
                    float yOffset  = fontChar.YOffset * UnitScale;
                    float xAdvance = fontChar.XAdvance * UnitScale;
                    float width    = fontChar.Width * UnitScale;
                    float height   = fontChar.Height * UnitScale;

                    vertices[i].Color     = color;
                    vertices[i + 1].Color = color;
                    vertices[i + 2].Color = color;
                    vertices[i + 3].Color = color;

                    vertices[i].Position     = new Vector3F(x + xOffset, 0f, 0f);
                    vertices[i + 1].Position = new Vector3F(x + xOffset, height, 0f);
                    vertices[i + 2].Position = new Vector3F(x + xOffset + width, height, 0f);
                    vertices[i + 3].Position = new Vector3F(x + xOffset + width, 0f, 0f);

                    vertices[i].Texture     = new Vector2F(UVPos.X, UVPos.W);
                    vertices[i + 1].Texture = new Vector2F(UVPos.X, UVPos.Y);
                    vertices[i + 2].Texture = new Vector2F(UVPos.Z, UVPos.Y);
                    vertices[i + 3].Texture = new Vector2F(UVPos.Z, UVPos.W);

                    x += xAdvance;
                    i += 4;
                }
            }

            return(new TextureVertexDrawable(vertices, verticesCount));
        }
Beispiel #11
0
        public SplashScreen(string engineLogoPath, string fmodLogoPath, string gameLogoPath)
        {
            var v0 = new TextureVertex(-1, -1, 0, 0, 0);
            var v1 = new TextureVertex(1, -1, 0, 1, 0);
            var v2 = new TextureVertex(-1, 1, 0, 0, 1);
            var v3 = new TextureVertex(1, 1, 0, 1, 1);

            _shader = new UnlitShader("EngineAssets/Shaders/textured_mesh.vert", "EngineAssets/Shaders/textured_mesh.frag");
            _shader.SetInt("texture0", 0);
            _engineLogo = new StaticTexturedMesh(engineLogoPath, _shader, "position", "textureCoords", true);
            _engineLogo.AddSquare(v0, v1, v2, v3);
            _engineLogo.BakeMesh();
            _fmodLogo = new StaticTexturedMesh(fmodLogoPath, _shader, "position", "textureCoords", true);
            _fmodLogo.AddSquare(v0, v1, v2, v3);
            _fmodLogo.BakeMesh();
            _gameLogo = new StaticTexturedMesh(gameLogoPath, _shader, "position", "textureCoords", true);
            _gameLogo.AddSquare(v0, v1, v2, v3);
            _gameLogo.BakeMesh();
        }
        public List <TextureVertex> LookForTextureVertex()
        {
            List <TextureVertex> texVerts = new List <TextureVertex>();

            string        content        = LoadFile.FileContent;
            List <string> textVertexsTab = new List <string>();

            content = content.Remove(0, content.IndexOf("vt "));

            var lines = content.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var line in lines)
            {
                if (line.StartsWith("vt "))
                {
                    textVertexsTab.Add(line.Substring(3));
                }
            }

            foreach (var vert in textVertexsTab)
            {
                TextureVertex texVert = new TextureVertex();
                var           vertTab = vert.Split(' ', StringSplitOptions.RemoveEmptyEntries);
                if (vertTab.Length == 2)
                {
                    texVert.XAxis = (float)Convert.ToDouble(vertTab[0], CultureInfo.InvariantCulture);
                    texVert.YAxis = (float)Convert.ToDouble(vertTab[1], CultureInfo.InvariantCulture);
                }
                else
                {
                    throw new NullReferenceException(message: $"Doesn't found x, y TExtureVertex. \n textVertexsTab[this] = {vert}\n");
                }

                texVerts.Add(texVert);

                //normals.Add(new Normal() { XAxis = 0, YAxis = -1, ZAxis = 0 });
                //normals.Add(new Normal() { XAxis = 0, YAxis = 1, ZAxis = 0 });
            }

            waveFront.TexVertexs = texVerts;
            return(texVerts);
        }
Beispiel #13
0
        private void ProcessLine(string line)
        {
            var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length <= 0)
            {
                return;
            }

            switch (parts[0])
            {
            case "v":
                var vertex = new GeometricVertex();
                vertex.ProcessData(parts, _maxValue);
                GeometricVertices.Add(vertex);
                break;

            case "f":
                var face = new FaceVertex();
                face.ProcessData(parts);
                FaceVertices.Add(face);
                break;

            case "vt":
                var textureVertex = new TextureVertex();
                textureVertex.ProcessData(parts);
                TextureVertices.Add(textureVertex);
                break;

            case "vn":
                var normalVertex = new NormalVertex();
                normalVertex.ProcessData(parts);
                NormalVertices.Add(normalVertex);
                break;
            }
        }
Beispiel #14
0
        private static void ProcessFace(string[] lineParts, Mesh mesh)
        {
            if (lineParts.Length < 4)
            {
                return;
            }

            List <FaceElement> faceElements = new List <FaceElement>();

            for (int i = 1; i < lineParts.Length; i++)
            {
                string linePart = lineParts[i];

                string[] referenceNumberParts = linePart.Split('/');
                if (referenceNumberParts.Length == 3)
                {
                    Vertex        v  = GetExistingVertex(referenceNumberParts[0], mesh.GeometricVertices);
                    TextureVertex vt = GetExistingVertex(referenceNumberParts[1], mesh.TextureVertices);
                    Vector        vn = GetExistingVertex(referenceNumberParts[2], mesh.VertexNormals);

                    faceElements.Add(new FaceElement(v, vt, vn));
                }
                else if (referenceNumberParts.Length == 1)
                {
                    Vertex v = GetExistingVertex(referenceNumberParts[0], mesh.GeometricVertices);

                    faceElements.Add(new FaceElement(v, null, null));
                }
                else
                {
                    return;
                }
            }

            mesh.Faces.Add(new Face(faceElements));
        }
Beispiel #15
0
        /// <summary>
        /// Parses and loads a line from an OBJ file.
        /// Currently only supports V, VT, F and MTLLIB prefixes
        /// </summary>
        private void processLine2(string line)
        {
            string[] parts        = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            gf       CurrentGroup = Objects[Objects.Count - 1].groups[Objects[Objects.Count - 1].groups.Count - 1];

            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case "usemtl":
                    UseMtl = parts[1];
                    break;

                case "mtllib":
                    Mtl = parts[1];
                    break;

                case "v":
                    Vertex v = new Vertex();
                    v.LoadFromStringArray(parts);
                    VertexList.Add(v);
                    v.Index = VertexList.Count();
                    //CurrentGroup.vertexList.Add(v);
                    //v.Index = CurrentGroup.vertexList.Count();
                    break;

                case "f":
                    Face f = new Face();
                    f.LoadFromStringArray(parts);
                    f.UseMtl = UseMtl;
                    //FaceList.Add(f);
                    GroupFaces[GroupFaces.Count - 1].faces.Add(f);
                    break;

                case "vt":
                    TextureVertex vt = new TextureVertex();
                    vt.LoadFromStringArray(parts);
                    TextureList.Add(vt);
                    vt.Index = TextureList.Count();
                    break;

                case "g":
                    if (gVerified)
                    {
                        GroupFaces.Add(new gf());
                    }
                    else
                    {
                        gVerified = true;
                    }
                    GroupFaces[GroupFaces.Count - 1].name = parts[1];

                    break;

                case "o":
                    //objects and groups are usually considered indetical, however objects in T2T are used to represent shapes, while groups are used to represent primitives
                    //when an o is encountered, we create a new o into the object list and set our global o pointer to the newly made o
                    //when we do the import, a group faces is a primitive so we can loop through all o's(shapes) and get all GroupFaces(primitives)
                    //there is always a default group 0, and if the user imports an obj with no groups or objects, we just push them all into object 0 group 0
                    if (oVerified)
                    {
                        Objects.Add(new obj());
                    }
                    else
                    {
                        oVerified = true;
                    }
                    Objects[Objects.Count - 1].name = parts[1];
                    Objects[Objects.Count - 1].groups.Add(GroupFaces[GroupFaces.Count - 1]);
                    break;
                }
            }
        }
Beispiel #16
0
        /// <summary>
        /// Writes an OBJ uses vertices and faces contained within the provided boundries.
        /// Typically used by WriteObjGridTile(...)
        /// Returns number of vertices written, or 0 if nothing was written.
        /// </summary>
        public int WriteObj(string path, Extent boundries)
        {
            if (!Directory.Exists(Path.GetDirectoryName(path)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }
            if (File.Exists(path))
            {
                File.Delete(path);
            }

            // Build the chunk
            List <Vertex>        chunkVertexList;
            List <Face>          chunkFaceList;
            List <TextureVertex> chunkTextureList;

            FaceList.ForEach(f => f.RevertVertices());
            chunkFaceList = FaceList.Where(v => v.InExtent(boundries, VertexList)).ToList();

            // Build a list of vertices indexes needed for these faces
            List <int> requiredVertices        = null;
            List <int> requiredTextureVertices = null;

            var tv  = Task.Run(() => { requiredVertices = chunkFaceList.SelectMany(f => f.VertexIndexList).Distinct().ToList(); });
            var ttv = Task.Run(() => { requiredTextureVertices = chunkFaceList.SelectMany(f => f.TextureVertexIndexList).Distinct().ToList(); });

            Task.WaitAll(new Task[] { tv, ttv });

            // Abort if we would be writing an empty file
            if (!requiredVertices.Any())
            {
                return(0);
            }

            using (var outStream = File.OpenWrite(path))
                using (var writer = new StreamWriter(outStream))
                {
                    // Write some header data
                    writer.WriteLine("# Generated by Cuber");

                    if (!string.IsNullOrEmpty(mtl))
                    {
                        writer.WriteLine("mtllib " + mtl);
                    }

                    //Write each vertex and update faces
                    Console.WriteLine("Writing vertices.");
                    int newVertexIndex = 0;

                    Parallel.ForEach(requiredVertices, new ParallelOptions {
                        MaxDegreeOfParallelism = NUMCORES
                    }, i =>
                    {
                        Vertex moving = VertexList[i - 1];
                        int newIndex  = WriteVertexWithNewIndex(moving, ref newVertexIndex, writer);

                        var facesRequiringUpdate = chunkFaceList.Where(f => f.VertexIndexList.Contains(i));
                        foreach (var face in facesRequiringUpdate)
                        {
                            face.UpdateVertexIndex(moving.Index, newIndex);
                        }
                    });


                    //Write each texture vertex and update faces
                    Console.WriteLine("Writing texture vertices.");
                    int newTextureVertexIndex = 0;

                    Parallel.ForEach(requiredTextureVertices, new ParallelOptions {
                        MaxDegreeOfParallelism = NUMCORES
                    }, i =>
                    {
                        TextureVertex moving = TextureList[i - 1];
                        int newIndex         = WriteVertexWithNewIndex(moving, ref newTextureVertexIndex, writer);

                        var facesRequiringUpdate = chunkFaceList.Where(f => f.TextureVertexIndexList.Contains(i));
                        foreach (var face in facesRequiringUpdate)
                        {
                            face.UpdateTextureVertexIndex(moving.Index, newIndex);
                        }
                    });

                    // Write the faces
                    Console.WriteLine("Writing faces.");
                    chunkFaceList.ForEach(f => writer.WriteLine(f));
                }

            return(requiredVertices.Count());
        }
Beispiel #17
0
 public FaceElement(Vertex v, TextureVertex vt, Vector vn)
 {
     V  = v;
     Vt = vt;
     Vn = vn;
 }
Beispiel #18
0
        /// <summary>
        /// Build a TextureVertexDrawable from the text where it is contained within a region
        /// </summary>
        /// <param name="text"></param>
        /// <param name="textBox"></param>
        /// <param name="alignment"></param>
        /// <param name="color"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        private TextureVertexDrawable BuildDrawable(string text, Vector2F textBox, BmFontAlign alignment, Color color, float scale)
        {
            float UnitScale     = WorldTextRenderer.Units * scale;
            int   verticesCount = text.Length * 4;

            TextureVertex[]       vertices   = new TextureVertex[verticesCount];
            List <BmFontCharInfo> charInfo   = new List <BmFontCharInfo>();
            List <float>          lineWidths = new List <float>();

            // Textbox edge locations, make its origin the center
            float textBoxLeft   = -textBox.X * 0.5f;
            float textBoxRight  = textBox.X * 0.5f;
            float textBoxTop    = textBox.Y * 0.5f;
            float textBoxBottom = -textBox.Y * 0.5f;

            // Keep track of offset positions
            int   vIdx       = 0;     // Vertex index
            float x          = textBoxLeft;
            float y          = textBoxTop;
            float lineHeight = WorldTextRenderer.FontFile.Info.Size * UnitScale;
            float lineWidth  = 0f;
            int   lineNumber = 1;
            int   wordNumber = 1;

            // First we build everything, afterward we reposition vertices according to the BmFontCharinfo and alignment
            // Should be slightly more efficient as to realign all previous characters on the line as soon as we add a new one
            foreach (char c in text)
            {
                // Supplied new line
                if (c == '\r' || c == '\n')
                {
                    x  = textBoxLeft;
                    y -= lineHeight;
                    lineWidths.Add(lineWidth);
                    lineWidth  = 0f;
                    wordNumber = 1;
                    lineNumber++;

                    continue;
                }

                BmFontChar fontChar = WorldTextRenderer.CharacterMap.GetOrDefault(c);
                if (fontChar == null)
                {
                    continue;
                }

                float xOffset  = fontChar.XOffset * UnitScale;
                float yOffset  = fontChar.YOffset * UnitScale;
                float xAdvance = fontChar.XAdvance * UnitScale;
                float width    = fontChar.Width * UnitScale;
                float height   = fontChar.Height * UnitScale;

                // Newline supplied or needed
                if (lineWidth + xAdvance >= textBox.X)
                {
                    x  = textBoxLeft;
                    y -= lineHeight;

                    // Outside of bottom boundary; just stop
                    if (y - yOffset - lineHeight < textBoxBottom)
                    {
                        break;
                    }

                    // If we exceed the textbox and are not on the first word
                    // we move the last word down a line
                    if (wordNumber != 1)
                    {
                        float previousLineWidth = lineWidth;
                        lineWidth = 0f;

                        for (int i = 0; i < charInfo.Count; i++)
                        {
                            // If the previous line ended with a space remove it's width
                            if (charInfo[i].LineNumber == lineNumber && charInfo[i].WordNumber == (wordNumber - 1) && charInfo[i].Char == ' ')
                            {
                                previousLineWidth -= charInfo[i].XAdvance;
                            }

                            if (charInfo[i].LineNumber == lineNumber && charInfo[i].WordNumber == wordNumber)
                            {
                                charInfo[i].LineNumber++;
                                charInfo[i].WordNumber = 1;

                                vertices[charInfo[i].FirstVertexIndex].Position.X     = x + charInfo[i].XOffset;
                                vertices[charInfo[i].FirstVertexIndex].Position.Y     = y - charInfo[i].Height;
                                vertices[charInfo[i].FirstVertexIndex + 1].Position.X = x + charInfo[i].XOffset;
                                vertices[charInfo[i].FirstVertexIndex + 1].Position.Y = y;
                                vertices[charInfo[i].FirstVertexIndex + 2].Position.X = x + charInfo[i].XOffset + charInfo[i].Width;
                                vertices[charInfo[i].FirstVertexIndex + 2].Position.Y = y;
                                vertices[charInfo[i].FirstVertexIndex + 3].Position.X = x + charInfo[i].XOffset + charInfo[i].Width;
                                vertices[charInfo[i].FirstVertexIndex + 3].Position.Y = y - charInfo[i].Height;

                                x         += charInfo[i].XAdvance;
                                lineWidth += charInfo[i].XAdvance;
                            }
                        }

                        lineWidths.Add(previousLineWidth - lineWidth);
                    }
                    else
                    {
                        lineWidths.Add(lineWidth);
                        lineWidth = 0f;
                    }

                    wordNumber = 1;
                    lineNumber++;
                }

                // Ignore spaces on a new line
                if (lineWidth == 0f && c == ' ')
                {
                    continue;
                }

                Vector4F UVPos = this.CharPositionToUV(fontChar.GetVector4I());

                vertices[vIdx].Color     = color;
                vertices[vIdx + 1].Color = color;
                vertices[vIdx + 2].Color = color;
                vertices[vIdx + 3].Color = color;

                vertices[vIdx].Position     = new Vector3F(x + xOffset, y - height, 0f);
                vertices[vIdx + 1].Position = new Vector3F(x + xOffset, y, 0f);
                vertices[vIdx + 2].Position = new Vector3F(x + xOffset + width, y, 0f);
                vertices[vIdx + 3].Position = new Vector3F(x + xOffset + width, y - height, 0f);

                vertices[vIdx].Texture     = new Vector2F(UVPos.X, UVPos.W);
                vertices[vIdx + 1].Texture = new Vector2F(UVPos.X, UVPos.Y);
                vertices[vIdx + 2].Texture = new Vector2F(UVPos.Z, UVPos.Y);
                vertices[vIdx + 3].Texture = new Vector2F(UVPos.Z, UVPos.W);

                if (c == ' ')
                {
                    wordNumber++;
                }

                charInfo.Add(new BmFontCharInfo(c, vIdx, xOffset, yOffset, width, height, xAdvance, lineNumber, wordNumber));

                if (c == ' ')
                {
                    wordNumber++;
                }

                x         += xAdvance;
                lineWidth += xAdvance;
                vIdx      += 4;
            }

            // Bail out early if we have top left alignment
            if (!alignment.HasFlag(BmFontAlign.Center) && !alignment.HasFlag(BmFontAlign.Right) &&
                !alignment.HasFlag(BmFontAlign.Middle) && !alignment.HasFlag(BmFontAlign.Bottom))
            {
                return(new TextureVertexDrawable(vertices, verticesCount));
            }

            // Add last line, this never creates a new line so we need to manually add it
            lineWidths.Add(lineWidth);

            // Lets justify the text!
            float offsetX    = 0;
            float offsetY    = 0;
            float textHeight = lineWidths.Count * lineHeight;

            if (alignment.HasFlag(BmFontAlign.Middle))
            {
                offsetY -= (textBox.Y - textHeight) / 2;
            }
            if (alignment.HasFlag(BmFontAlign.Bottom))
            {
                offsetY -= textBox.Y - textHeight;
            }

            for (int line = 0; line < lineWidths.Count; line++)
            {
                lineWidth = lineWidths[line];

                if (alignment.HasFlag(BmFontAlign.Center))
                {
                    offsetX = (textBox.X - lineWidth) / 2;
                }
                if (alignment.HasFlag(BmFontAlign.Right))
                {
                    offsetX = textBox.X - lineWidth;
                }

                for (int j = 0; j < charInfo.Count; j++)
                {
                    if (charInfo[j].LineNumber == (line + 1))
                    {
                        vertices[charInfo[j].FirstVertexIndex].Position.X     += offsetX;
                        vertices[charInfo[j].FirstVertexIndex].Position.Y     += offsetY;
                        vertices[charInfo[j].FirstVertexIndex + 1].Position.X += offsetX;
                        vertices[charInfo[j].FirstVertexIndex + 1].Position.Y += offsetY;
                        vertices[charInfo[j].FirstVertexIndex + 2].Position.X += offsetX;
                        vertices[charInfo[j].FirstVertexIndex + 2].Position.Y += offsetY;
                        vertices[charInfo[j].FirstVertexIndex + 3].Position.X += offsetX;
                        vertices[charInfo[j].FirstVertexIndex + 3].Position.Y += offsetY;
                    }
                }
            }

            return(new TextureVertexDrawable(vertices, verticesCount));
        }
Beispiel #19
0
        /// <summary>
        /// Writes out the OpenCTM format for the chunk
        ///
        /// According to http://openctm.sourceforge.net/media/FormatSpecification.pdf
        /// </summary>
        /// <param name="path">path of file to create</param>
        /// <param name="chunkFaceList">list of faces associated with this chunk</param>
        /// <param name="tile">texture tile information (used to associated with specific texture file)</param>
        private void WriteOpenCtmFormattedFile(string path, List <Face> chunkFaceList, Vector2 tile)
        {
            // Build a list of vertices indexes needed for these faces
            List <Tuple <int, int> > uniqueVertexUVPairs = null;

            var tv = Task.Run(() => { uniqueVertexUVPairs = chunkFaceList.AsParallel().SelectMany(f => f.VertexIndexList.Zip(f.TextureVertexIndexList, (v, uv) => new Tuple <int, int>(v, uv))).Distinct().ToList(); });

            Task.WaitAll(new Task[] { tv });


            using (var outStream = File.OpenWrite(path))
                using (var writer = new BinaryWriter(outStream))
                {
                    // Header
                    writer.Write(Encoding.UTF8.GetBytes("OCTM"));
                    writer.Write(5);                                                                        // Version
                    writer.Write(0x00574152);                                                               // Compression (RAW)
                    writer.Write(uniqueVertexUVPairs.Count);                                                // Vertex count
                    writer.Write(chunkFaceList.Count);                                                      // Triangle count
                    writer.Write(1);                                                                        // UV count
                    writer.Write(0);                                                                        // attribute map count
                    writer.Write(0);                                                                        // flags
                    WriteOpenCTMString(writer, "Created by Uniscan's Slice tool (legacy name: PyriteCli)"); // comment

                    //Body

                    Dictionary <Tuple <int, int>, int> seenVertexUVPairs = new Dictionary <Tuple <int, int>, int>();
                    List <int> vertices  = new List <int>(uniqueVertexUVPairs.Count);
                    List <int> uvs       = new List <int>(uniqueVertexUVPairs.Count);
                    int        nextIndex = 0;
                    // Indices
                    writer.Write(0x58444e49); // "INDX"
                    Parallel.ForEach(chunkFaceList, f =>
                    {
                        lock (writer)
                        {
                            for (int i = 0; i < 3; i++)
                            {
                                int vertexIndex      = f.VertexIndexList[i];
                                int uvIndex          = f.TextureVertexIndexList[i];
                                Tuple <int, int> key = new Tuple <int, int>(vertexIndex, uvIndex);
                                if (!seenVertexUVPairs.ContainsKey(key))
                                {
                                    // This is a new vertex uv pair
                                    seenVertexUVPairs[key] = nextIndex++;
                                    vertices.Add(vertexIndex);
                                    uvs.Add(uvIndex);
                                }

                                writer.Write(seenVertexUVPairs[key]);
                            }
                        }
                    });

                    //Vertices
                    writer.Write(0x54524556);
                    vertices.ForEach(vertexIndex =>
                    {
                        Vertex vertex = VertexList[vertexIndex - 1];
                        writer.Write((float)vertex.X);
                        writer.Write((float)vertex.Y);
                        writer.Write((float)vertex.Z);
                    });

                    //Normals
                    // Not supported -- Skipped

                    // UV Maps
                    writer.Write(0x43584554);
                    WriteOpenCTMString(writer, "Diffuse color");
                    WriteOpenCTMString(writer, string.Format("{0}_{1}.jpg", tile.X, tile.Y));
                    uvs.ForEach(uvIndex =>
                    {
                        TextureVertex vertex = TextureList[uvIndex - 1];
                        writer.Write((float)vertex.X);
                        writer.Write((float)vertex.Y);
                    });
                }
        }
Beispiel #20
0
        private void WriteObjFormattedFile(string path, string mtlOverride, List <Face> chunkFaceList, Vector2 tile, SlicingOptions options, string comment = "")
        {
            // Build a list of vertices indexes needed for these faces
            List <int> requiredVertices        = null;
            List <int> requiredTextureVertices = null;

            var tv  = Task.Run(() => { requiredVertices = chunkFaceList.AsParallel().SelectMany(f => f.VertexIndexList).Distinct().ToList(); });
            var ttv = Task.Run(() => { requiredTextureVertices = chunkFaceList.AsParallel().SelectMany(f => f.TextureVertexIndexList).Distinct().ToList(); });

            Task.WaitAll(new Task[] { tv, ttv });

            using (var outStream = File.OpenWrite(path))
                using (var writer = new StreamWriter(outStream))
                {
                    // Write some header data
                    writer.WriteLine("# Generated by Uniscan's Slice tool (legacy name: PyriteCli)");
                    if (!string.IsNullOrEmpty(comment))
                    {
                        writer.WriteLine("# " + comment);
                    }

                    if (!string.IsNullOrEmpty(mtlOverride))
                    {
                        writer.WriteLine("mtllib " + mtlOverride);
                    }
                    else if (!string.IsNullOrEmpty(_mtl) && !options.RequiresTextureProcessing())
                    {
                        writer.WriteLine("mtllib " + _mtl);
                    }
                    else if (options.RequiresTextureProcessing() && options.WriteMtl)
                    {
                        writer.WriteLine("mtllib texture\\{0}_{1}.mtl", tile.X, tile.Y);
                    }

                    // Write each vertex and update faces
                    _verticesRequireReset = true;
                    int newVertexIndex = 0;

                    Parallel.ForEach(requiredVertices, i =>
                    {
                        Vertex moving = VertexList[i - 1];
                        int newIndex  = WriteVertexWithNewIndex(moving, ref newVertexIndex, writer);

                        var facesRequiringUpdate = chunkFaceList.Where(f => f.VertexIndexList.Contains(i));
                        foreach (var face in facesRequiringUpdate)
                        {
                            face.UpdateVertexIndex(moving.Index, newIndex);
                        }
                    });


                    // Write each texture vertex and update faces
                    int newTextureVertexIndex = 0;

                    Parallel.ForEach(requiredTextureVertices, i =>
                    {
                        TextureVertex moving = TextureList[i - 1];
                        int newIndex         = WriteVertexWithNewIndex(moving, ref newTextureVertexIndex, writer);

                        var facesRequiringUpdate = chunkFaceList.Where(f => f.TextureVertexIndexList.Contains(i));
                        foreach (var face in facesRequiringUpdate)
                        {
                            face.UpdateTextureVertexIndex(moving.Index, newIndex);
                        }
                    });

                    // Write the faces
                    chunkFaceList.ForEach(f => writer.WriteLine(f));
                }
        }
Beispiel #21
0
        /// <summary>
        /// Parses and loads a line from an OBJ file.
        /// Currently only supports V, VT, F and MTLLIB prefixes
        /// </summary>
        private void processLine(string line)
        {
            string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length > 0)
            {
                switch (parts[0])
                {
                case "usemtl":
                    UseMtl = parts[1];
                    if (CurrentGroup == null)
                    {
                        GroupFaces.Add(new gf());
                        CurrentGroup      = GroupFaces[GroupFaces.Count - 1];
                        CurrentGroup.name = parts[1];
                        CurrentObject.groups.Add(CurrentGroup);
                    }
                    CurrentGroup.materialName = UseMtl;
                    break;

                case "mtllib":
                    Mtl = parts[1];
                    if (Mtl.IndexOf("\\") == -1)
                    {
                        Mtl = Path.GetDirectoryName(ObjPath) + "\\" + Mtl;
                    }
                    break;

                case "o":
                    //check if we dont already have an active object, aka we arent on the first one
                    if (oVerified)
                    {
                        Objects.Add(new obj());
                    }
                    else
                    {
                        oVerified = true;
                    }
                    //set global to updated object
                    CurrentObject      = Objects[Objects.Count() - 1];
                    CurrentObject.name = parts[1];
                    //now any new v, vt, f or g will be added into this object
                    break;

                case "v":
                    Vertex v = new Vertex();
                    v.LoadFromStringArray(parts);
                    //VertexList.Add(v);
                    //v.Index = VertexList.Count();
                    //because we are now doing it my way, we only add to the current object
                    CurrentObject.vertexList.Add(v);
                    break;

                case "vt":
                    TextureVertex vt = new TextureVertex();
                    vt.LoadFromStringArray(parts);
                    CurrentObject.textureList.Add(vt);
                    break;

                case "g":
                    if (gVerified)
                    {
                        GroupFaces.Add(new gf());
                    }
                    else
                    {
                        gVerified = true;
                    }
                    CurrentGroup      = GroupFaces[GroupFaces.Count - 1];
                    CurrentGroup.name = parts[1];
                    CurrentObject.groups.Add(CurrentGroup);
                    break;

                case "f":
                    Face f = new Face();
                    f.LoadFromStringArray(parts);
                    f.UseMtl = UseMtl;
                    //FaceList.Add(f);
                    CurrentGroup.faces.Add(f);
                    break;
                }
            }
        }
Beispiel #22
0
        public static bool Init()
        {
            if (WasInit)
            {
                return(true);
            }

            Vertices = new TextureVertex[4];
            //Bottom Left
            Vertices[0] = new TextureVertex()
            {
                Position = new Vector3(-0.5f, -0.5f, 0.0f),
                TexCoord = new Vector2(0.0f, 0.0f)
            };
            //Top Left
            Vertices[1] = new TextureVertex()
            {
                Position = new Vector3(-0.5f, 0.5f, 0.0f),
                TexCoord = new Vector2(0.0f, 1.0f)
            };
            //Bottom Right
            Vertices[2] = new TextureVertex()
            {
                Position = new Vector3(0.5f, -0.5f, 0.0f),
                TexCoord = new Vector2(1.0f, 0.0f)
            };
            //Top Right
            Vertices[3] = new TextureVertex()
            {
                Position = new Vector3(0.5f, 0.5f, 0.0f),
                TexCoord = new Vector2(1.0f, 1.0f)
            };

            ProgramID = Scene.LoadProgramFromStrings(vsSource, fsSource);
            if (ProgramID == -1)
            {
                Logger.LogError("Error loading Texture Preview Shader Program.\n");
                return(false);
            }

            AttribPosition     = GL.GetAttribLocation(ProgramID, "Position");
            AttribTexCoord     = GL.GetAttribLocation(ProgramID, "TexCoord");
            UniformMatrix      = GL.GetUniformLocation(ProgramID, "Matrix");
            UniformTextureSize = GL.GetUniformLocation(ProgramID, "Size");
            UniformTexture     = GL.GetUniformLocation(ProgramID, "Texture");

            if (AttribPosition == -1 || AttribTexCoord == -1 || UniformMatrix == -1 || UniformTextureSize == -1 || UniformTexture == -1)
            {
                Logger.LogError("Error geting Texture Preview Shader Attribute/Uniform Locations\n");
                Logger.LogError(string.Format("\tPosition: {0}, TexCoord: {1}, Matrix: {2}, Size: {3}, Texture: {4}\n", AttribPosition, AttribTexCoord, UniformMatrix, UniformTextureSize, UniformTexture));
                return(false);
            }

            ArrayID = GL.GenVertexArray();
            GL.BindVertexArray(ArrayID);

            BufferID = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, BufferID);

            Type vType = Vertices[0].GetType();
            int  vSize = Marshal.SizeOf(vType);

            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vSize * VertexCount), Vertices, BufferUsageHint.StaticDraw);

            GL.EnableVertexAttribArray(AttribPosition);
            GL.VertexAttribPointer(AttribPosition, 3, VertexAttribPointerType.Float, false, vSize, Marshal.OffsetOf(vType, "Position"));

            GL.EnableVertexAttribArray(AttribTexCoord);
            GL.VertexAttribPointer(AttribTexCoord, 2, VertexAttribPointerType.Float, false, vSize, Marshal.OffsetOf(vType, "TexCoord"));

            GL.BindVertexArray(0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            WasInit = true;
            return(true);
        }