Пример #1
0
        private static int GetVertexComponentLength(VertexFlags flags)
        {
            switch (flags)
            {
            case VertexFlags.Position:
            case VertexFlags.BlendData:
                return(8);

            case VertexFlags.Normals:
            case VertexFlags.flag_0x80:
            case VertexFlags.TexCoords0:
            case VertexFlags.TexCoords1:
            case VertexFlags.TexCoords2:
            case VertexFlags.TexCoords7:
            case VertexFlags.flag_0x20000:
            case VertexFlags.DamageGroup:
                return(4);

            case VertexFlags.Tangent:
                return(0);

            case VertexFlags.flag_0x40000:
                return(12);

            default:
                return(-1);
            }
        }
        private void Init(VertexFlags flags, int i)
        {
            string text = string.Format("{0} LOD: {1}", Language.GetString("$MODEL_OPTIONS_TEXT"), i.ToString());

            ModelOptionsText.Text = text;

            options = new Dictionary <string, bool>();
            options.Add("NORMALS", false);
            options.Add("TANGENTS", false);
            options.Add("DIFFUSE", false);
            options.Add("UV1", false);
            options.Add("UV2", false);
            options.Add("AO", false);
            options.Add("FLIP_UV", false);
            options.Add("COLOR0", false);
            options.Add("COLOR1", false);

            ImportNormalBox.Enabled  = flags.HasFlag(VertexFlags.Normals);
            ImportTangentBox.Enabled = flags.HasFlag(VertexFlags.Tangent);
            ImportDiffuseBox.Enabled = flags.HasFlag(VertexFlags.TexCoords0);
            ImportUV1Box.Enabled     = flags.HasFlag(VertexFlags.TexCoords1);
            ImportUV2Box.Enabled     = flags.HasFlag(VertexFlags.TexCoords2);
            ImportAOBox.Enabled      = flags.HasFlag(VertexFlags.ShadowTexture);
            ImportColor0Box.Enabled  = flags.HasFlag(VertexFlags.Color);
            ImportColor1Box.Enabled  = flags.HasFlag(VertexFlags.Color1);
            FlipUVBox.Enabled        = false;
        }
Пример #3
0
        private BlockFacing(string code, byte flag, int index, int oppositeIndex, int horizontalAngleIndex, Vec3i facingVector, Vec3f planeCenter, EnumAxis axis, Cuboidf plane)
        {
            this.index                = index;
            this.meshDataIndex        = (byte)(index + 1);
            this.horizontalAngleIndex = horizontalAngleIndex;
            this.flag          = flag;
            this.code          = code;
            this.oppositeIndex = oppositeIndex;
            this.normali       = facingVector;
            this.normalf       = new Vec3f(facingVector.X, facingVector.Y, facingVector.Z);
            this.normald       = new Vec3d((double)facingVector.X, (double)facingVector.Y, (double)facingVector.Z);
            this.plane         = plane;

            normalPacked = NormalUtil.PackNormal(normalf.X, normalf.Y, normalf.Z);
            normalb      = (byte)(
                (axis == EnumAxis.Z ? 1 : 0) << 0
                    | (facingVector.Z < 0 ? 1 : 0) << 1

                    | (axis == EnumAxis.Y ? 1 : 0) << 2
                    | (facingVector.Y < 0 ? 1 : 0) << 3

                    | (axis == EnumAxis.X ? 1 : 0) << 4
                    | (facingVector.X < 0 ? 1 : 0) << 5
                );

            normalPackedFlags = VertexFlags.PackNormal(normalf);

            this.planeCenter = planeCenter;
            this.axis        = axis;
        }
Пример #4
0
        private static int GetVertexComponentLength(VertexFlags flags)
        {
            switch (flags)
            {
            case VertexFlags.Position:
            case VertexFlags.Skin:
                return(8);

            case VertexFlags.Normals:
            case VertexFlags.Color:
            case VertexFlags.TexCoords0:
            case VertexFlags.TexCoords1:
            case VertexFlags.TexCoords2:
            case VertexFlags.Unk05:
            case VertexFlags.ShadowTexture:
            case VertexFlags.Color1:
            case VertexFlags.DamageGroup:
                return(4);

            case VertexFlags.Tangent:
                return(0);

            case VertexFlags.BBCoeffs:
                return(12);

            default:
                return(-1);
            }
        }
 public FrameResourceModelOptions(VertexFlags flags, int i, bool is32bit)
 {
     InitializeComponent();
     Label_BufferType.Visible = is32bit;
     Init(flags, i);
     Localise();
 }
Пример #6
0
        public void DrawVectorImage(MeshGenerationContextUtils.RectangleParams rectParams)
        {
            VectorImage vectorImage = rectParams.vectorImage;

            Debug.Assert(vectorImage != null);
            VertexFlags vertexFlags        = (vectorImage.atlas != null) ? VertexFlags.IsSVGGradients : VertexFlags.IsSolid;
            int         settingIndexOffset = 0;
            bool        flag = vectorImage.atlas != null && this.m_VectorImageManager != null;

            if (flag)
            {
                GradientRemap gradientRemap = this.m_VectorImageManager.AddUser(vectorImage);
                vertexFlags        = (gradientRemap.isAtlassed ? VertexFlags.IsSVGGradients : VertexFlags.IsCustomSVGGradients);
                settingIndexOffset = gradientRemap.destIndex;
            }
            int count = this.m_Entries.Count;

            MeshGenerationContext.MeshFlags flags = MeshGenerationContext.MeshFlags.None;
            bool flag2 = vertexFlags == VertexFlags.IsSVGGradients;

            if (flag2)
            {
                flags = MeshGenerationContext.MeshFlags.IsSVGGradients;
            }
            else
            {
                bool flag3 = vertexFlags == VertexFlags.IsCustomSVGGradients;
                if (flag3)
                {
                    flags = MeshGenerationContext.MeshFlags.IsCustomSVGGradients;
                }
            }
            MeshBuilder.AllocMeshData meshAlloc = new MeshBuilder.AllocMeshData
            {
                alloc   = this.m_AllocThroughDrawMeshDelegate,
                texture = ((vertexFlags == VertexFlags.IsCustomSVGGradients) ? vectorImage.atlas : null),
                flags   = flags
            };
            int num;
            int num2;

            MeshBuilder.MakeVectorGraphics(rectParams, settingIndexOffset, meshAlloc, out num, out num2);
            Debug.Assert(count <= this.m_Entries.Count + 1);
            bool flag4 = count != this.m_Entries.Count;

            if (flag4)
            {
                this.m_SVGBackgroundEntryIndex = this.m_Entries.Count - 1;
                bool flag5 = num != 0 && num2 != 0;
                if (flag5)
                {
                    UIRStylePainter.Entry entry = this.m_Entries[this.m_SVGBackgroundEntryIndex];
                    entry.vertices = entry.vertices.Slice(0, num);
                    entry.indices  = entry.indices.Slice(0, num2);
                    this.m_Entries[this.m_SVGBackgroundEntryIndex] = entry;
                }
            }
        }
Пример #7
0
 private void Init(VertexFlags flags)
 {
     ImportNormalBox.Enabled = flags.HasFlag(VertexFlags.Normals);
     ImportUV0Box.Enabled    = flags.HasFlag(VertexFlags.TexCoords0);
     ImportUV1Box.Enabled    = flags.HasFlag(VertexFlags.TexCoords1);
     ImportUV2Box.Enabled    = flags.HasFlag(VertexFlags.TexCoords2);
     ImportUV7Box.Enabled    = flags.HasFlag(VertexFlags.ShadowTexture);
     FlipUVBox.Enabled       = false;
 }
Пример #8
0
        public override void OnJsonTesselation(ref MeshData sourceMesh, ref int[] lightRgbsByCorner, BlockPos pos, Block[] chunkExtBlocks, int extIndex3d)
        {
            base.OnJsonTesselation(ref sourceMesh, ref lightRgbsByCorner, pos, chunkExtBlocks, extIndex3d);

            for (int i = 0; i < sourceMesh.FlagsCount; i++)
            {
                sourceMesh.Flags[i] &= VertexFlags.ClearNormalBitMask;
                sourceMesh.Flags[i] |= VertexFlags.PackNormal(0, 1, 0);
            }
        }
Пример #9
0
 //Constructor
 public BSVertexDesc()
 {
     unchecked {
         vf1 = (byte)0;
         vf2 = (byte)0;
         vf3 = (byte)0;
         vf4 = (byte)0;
         vf5 = (byte)0;
         vertexAttributes = (VertexFlags)0;
         vf8 = (byte)0;
     }
 }
Пример #10
0
        private static void TessellateFilledFan(TessellationType tessellationType, Vector2 center, float radius, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly)
        {
            VertexFlags innerVertexFlags, outerVertexFlags;

            if (tessellationType == TessellationType.EdgeCorner)
            {
                innerVertexFlags = VertexFlags.IsEdge;
                outerVertexFlags = VertexFlags.IsSolid;
            }
            else
            {
                innerVertexFlags = vertexFlags;
                outerVertexFlags = vertexFlags;
            }

            if (countOnly)
            {
                vertexCount += (UInt16)(kSubdivisions + 1);
                indexCount  += (UInt16)((kSubdivisions - 1) * 3);
                return;
            }

            var p = new Vector2(center.x - radius, center.y);

            var verts = vertices.GetValueOrDefault();
            var inds  = indices.GetValueOrDefault();

            verts[vertexCount++] = new Vertex()
            {
                position = new Vector3(center.x, center.y, posZ), uv = p, tint = color, flags = (float)innerVertexFlags
            };
            verts[vertexCount++] = new Vertex()
            {
                position = new Vector3(p.x, p.y, posZ), uv = center, tint = color, flags = (float)outerVertexFlags
            };

            for (int k = 1; k < kSubdivisions; ++k)
            {
                float angle = (Mathf.PI / 2.0f) * ((float)k) / (kSubdivisions - 1);
                p = center + new Vector2(-Mathf.Cos(angle), -Mathf.Sin(angle)) * radius;
                verts[vertexCount++] = new Vertex()
                {
                    position = new Vector3(p.x, p.y, posZ), uv = center, tint = color, flags = (float)outerVertexFlags
                };

                inds[indexCount++] = (UInt16)(indexOffset + 0);
                inds[indexCount++] = (UInt16)(indexOffset + k + 1);
                inds[indexCount++] = (UInt16)(indexOffset + k);
            }

            indexOffset += (UInt16)(kSubdivisions + 1);
        }
Пример #11
0
 void GetVertexFormat(Mesh mesh, int boneCount, out VertexFlags flags, out int stride)
 {
     stride = 3;
     flags  = 0;
     if (mesh.HasNormals)
     {
         stride += 3;
         flags  |= VertexFlags.Normal;
     }
     if (mesh.HasTextureCoords(0))
     {
         stride += 2;
         flags  |= VertexFlags.TexCoord0;
     }
     if (mesh.HasTextureCoords(1))
     {
         stride += 2;
         flags  |= VertexFlags.TexCoord0;
     }
     if (mesh.HasTextureCoords(2))
     {
         stride += 2;
         flags  |= VertexFlags.TexCoord0;
     }
     if (mesh.HasTextureCoords(3))
     {
         stride += 2;
         flags  |= VertexFlags.TexCoord0;
     }
     if (mesh.HasVertexColors(0))
     {
         stride += 4;
         flags  |= VertexFlags.Color0;
     }
     if (mesh.HasVertexColors(1))
     {
         stride += 4;
         flags  |= VertexFlags.Color1;
     }
     if (mesh.HasVertexColors(2))
     {
         stride += 4;
         flags  |= VertexFlags.Color2;
     }
     if (mesh.HasVertexColors(3))
     {
         stride += 4;
         flags  |= VertexFlags.Color3;
     }
     stride += boneCount * 2;
 }
Пример #12
0
        public void ReadPrerequisites(string name)
        {
            using (BinaryReader reader = new BinaryReader(File.Open(name, FileMode.Open)))
            {
                ushort MeshFlags = reader.ReadUInt16();
                VertexDecleration = (VertexFlags)reader.ReadUInt32();

                int IndexSize = reader.ReadInt32();
                IndexBuffer = reader.ReadBytes(IndexSize);

                VertexCount = reader.ReadInt32();
                int VertexSize = reader.ReadInt32();
                VertexBuffer = reader.ReadBytes(VertexSize);
            }

            //VertexDecleration = (VertexFlags)134933;
            //Offset = new Vector3(-233.86592f, -642.7829f, -1.5614158f);
            //Scale = 0.013024263f;

            int vertexSize;
            Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = GetVertexOffsets(out vertexSize);

            int tempVertexSize = VertexBuffer.Length / VertexCount;

            Vertex[] Vertices = new Vertex[VertexCount];

            for (int x = 0; x != VertexCount; x++)
            {
                //declare data required and send to decompresser
                byte[] data = new byte[tempVertexSize];
                Array.Copy(VertexBuffer, (x * tempVertexSize), data, 0, tempVertexSize);
                Vertex decompressed = VertexTranslator.DecompressVertex(data, VertexDecleration, Vector3.Zero, 1.525879E-05f, vertexOffsets);
                Vertices[x] = decompressed;
            }

            Int3[] Triangles = new Int3[IndexBuffer.Length / 3];
            int    index     = 0;

            for (int y = 0; y != IndexBuffer.Length; y += 6)
            {
                int  X        = BitConverter.ToUInt16(IndexBuffer, y + 0);
                int  Y        = BitConverter.ToUInt16(IndexBuffer, y + 2);
                int  Z        = BitConverter.ToUInt16(IndexBuffer, y + 4);
                Int3 triangle = new Int3(X, Y, Z);
                Triangles[index] = triangle;
                index++;
            }

            File.WriteAllLines(name + ".obj", BuildMesh(Vertices, Triangles));
        }
Пример #13
0
        static VertexFormat GetVertexFormat(VertexFlags flags, int boneSlotCount)
        {
            uint elemCount = 0, f = (uint)flags;

            for (elemCount = 0; f != 0; elemCount++)
            {
                f &= f - 1;
            }
            var elems = new VertexElement[(int)elemCount + 1 + (boneSlotCount * 2)];

            int offset = 3, idx = 1;

            elems[0] = new VertexElement("Position", 0, 3);

            if ((flags & VertexFlags.Normal) != 0)
            {
                elems[idx++] = new VertexElement("Normal", offset, 3);
                offset      += 3;
            }
            for (var i = 0; i < 4; i++)
            {
                if (((int)flags & ((int)VertexFlags.TexCoord0 << i)) != 0)
                {
                    elems[idx++] = new VertexElement("TexCoord" + i, offset, 2);
                    offset      += 2;
                }
            }
            for (var i = 0; i < 4; i++)
            {
                if (((int)flags & ((int)VertexFlags.Color0 << i)) != 0)
                {
                    elems[idx++] = new VertexElement("Color" + i, offset, 4);
                    offset      += 4;
                }
            }
            for (var i = 0; i < boneSlotCount; i++)
            {
                elems[idx++] = new VertexElement("BoneWeight" + i, offset++, 1);
            }
            for (var i = 0; i < boneSlotCount; i++)
            {
                elems[idx++] = new VertexElement("BoneIndex" + i, offset++, 1);
            }
            return(new VertexFormat(offset, elems));
        }
Пример #14
0
        public void ReadPrerequisites()
        {
            VertexDecleration = (VertexFlags)134933;
            Offset            = new Vector3(-233.86592f, -642.7829f, -1.5614158f);
            Scale             = 0.013024263f;

            int vertexSize;
            Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = GetVertexOffsets(out vertexSize);

            VertexBuffer = File.ReadAllBytes("M3/VertexBuffer.bin");
            IndexBuffer  = File.ReadAllBytes("M3/IndexBuffer.bin");

            int tempVertexSize = VertexBuffer.Length / VertexCount;

            Vertex[] Vertices = new Vertex[VertexCount];

            for (int x = 0; x != VertexCount; x++)
            {
                //declare data required and send to decompresser
                byte[] data = new byte[tempVertexSize];
                Array.Copy(VertexBuffer, (x * tempVertexSize), data, 0, tempVertexSize);
                Vertex decompressed = VertexTranslator.DecompressVertex(data, VertexDecleration, Vector3.Zero, 1.525879E-05f, vertexOffsets);
                Vertices[x] = decompressed;
            }

            Int3[] Triangles = new Int3[IndexBuffer.Length / 3];
            int    index     = 0;

            for (int y = 0; y != IndexBuffer.Length; y += 6)
            {
                Int3 triangle = new Int3();
                triangle.X       = BitConverter.ToUInt16(IndexBuffer, y + 0);
                triangle.Y       = BitConverter.ToUInt16(IndexBuffer, y + 2);
                triangle.Z       = BitConverter.ToUInt16(IndexBuffer, y + 4);
                Triangles[index] = triangle;
                index++;
            }

            File.WriteAllLines("Test.obj", BuildMesh(Vertices, Triangles));
        }
Пример #15
0
        public static VertexFlags GetFlags(MeshSection meshSec)
        {
            VertexFlags flags = new VertexFlags();

            flags.TextureCoordinateFormat = (CoordinateFormat)GetBitFieldRange(meshSec.VertexFlags, 0, 2);
            flags.ColorFormat             = (ColorFormat)GetBitFieldRange(meshSec.VertexFlags, 2, 3);
            flags.NormalFormat            = (CoordinateFormat)GetBitFieldRange(meshSec.VertexFlags, 5, 2);
            flags.PositionFormat          = (CoordinateFormat)GetBitFieldRange(meshSec.VertexFlags, 7, 2);
            flags.WeightFormat            = (CoordinateFormat)GetBitFieldRange(meshSec.VertexFlags, 9, 2);
            flags.IndicesFormat           = (byte)GetBitFieldRange(meshSec.VertexFlags, 11, 2);
            flags.Unused1 = (byte)GetBitFieldRange(meshSec.VertexFlags, 13, 1) == 1;
            flags.SkinningWeightsCount = (byte)GetBitFieldRange(meshSec.VertexFlags, 14, 3);
            flags.Unused2               = (byte)GetBitFieldRange(meshSec.VertexFlags, 17, 1) == 1;
            flags.MorphWeightsCount     = (byte)GetBitFieldRange(meshSec.VertexFlags, 18, 3);
            flags.Unused3               = (byte)GetBitFieldRange(meshSec.VertexFlags, 21, 2);
            flags.SkipTransformPipeline = (byte)GetBitFieldRange(meshSec.VertexFlags, 23, 1) == 1;
            flags.UniformDiffuseFlag    = (byte)GetBitFieldRange(meshSec.VertexFlags, 24, 1) == 1;
            flags.Unknown1              = (byte)GetBitFieldRange(meshSec.VertexFlags, 25, 3);
            flags.Primitive             = (PrimitiveType)GetBitFieldRange(meshSec.VertexFlags, 28, 4);

            return(flags);
        }
Пример #16
0
        public void ReadFromFile(MemoryStream reader, bool isBigEndian)
        {
            distance          = reader.ReadSingle(isBigEndian);
            indexBufferRef    = new HashName(reader, isBigEndian);
            vertexDeclaration = (VertexFlags)reader.ReadUInt32(isBigEndian);
            vertexBufferRef   = new HashName(reader, isBigEndian);
            numVerts          = reader.ReadInt32(isBigEndian);
            nZero1            = reader.ReadInt32(isBigEndian);

            nPartition = reader.ReadInt32(isBigEndian);
            if (nPartition != 0)
            {
                partitionInfo.ReadFromFile(reader, isBigEndian);
            }

            matSplitType = reader.ReadInt32(isBigEndian);

            if (matSplitType != 0)
            {
                splitInfo.ReadFromFile(reader, isBigEndian, matSplitType);
            }

            zeroTail = reader.ReadInt32(isBigEndian);
        }
Пример #17
0
        public void ReadFromFile(BinaryReader reader)
        {
            distance          = reader.ReadSingle();
            indexBufferRef    = new Hash(reader);
            vertexDeclaration = (VertexFlags)reader.ReadUInt32();
            vertexBufferRef   = new Hash(reader);
            numVerts          = reader.ReadInt32();
            nZero1            = reader.ReadInt32();

            nPartition = reader.ReadInt32();
            if (nPartition != 0)
            {
                partitionInfo.ReadFromFile(reader);
            }

            matSplitType = reader.ReadInt32();

            if (matSplitType != 0)
            {
                splitInfo.ReadFromFile(reader, matSplitType);
            }

            zeroTail = reader.ReadInt32();
        }
Пример #18
0
		void GetVertexFormat (Mesh mesh, int boneCount, out VertexFlags flags, out int stride) {
			stride = 3;
			flags = 0;
			if (mesh.HasNormals) {
				stride += 3;
				flags |= VertexFlags.Normal;
			}
			if (mesh.HasTextureCoords(0)) {
				stride += 2;
				flags |= VertexFlags.TexCoord0;
			}
			if (mesh.HasTextureCoords(1)) {
				stride += 2;
				flags |= VertexFlags.TexCoord0;
			}
			if (mesh.HasTextureCoords(2)) {
				stride += 2;
				flags |= VertexFlags.TexCoord0;
			}
			if (mesh.HasTextureCoords(3)) {
				stride += 2;
				flags |= VertexFlags.TexCoord0;
			}
			if (mesh.HasVertexColors(0)) {
				stride += 4;
				flags |= VertexFlags.Color0;
			}
			if (mesh.HasVertexColors(1)) {
				stride += 4;
				flags |= VertexFlags.Color1;
			}
			if (mesh.HasVertexColors(2)) {
				stride += 4;
				flags |= VertexFlags.Color2;
			}
			if (mesh.HasVertexColors(3)) {
				stride += 4;
				flags |= VertexFlags.Color3;
			}
			stride += boneCount * 2;
		}
Пример #19
0
        public static void ReadMeshData(Stream stream, Pmo pmo, int MeshNumber = 0)
        {
            // Go to mesh position.
            if (MeshNumber == 0)
            {
                stream.Seek(pmo.PMO_StartPosition + pmo.header.MeshOffset0, SeekOrigin.Begin);
            }
            else
            {
                stream.Seek(pmo.PMO_StartPosition + pmo.header.MeshOffset1, SeekOrigin.Begin);
            }

            UInt16 VertCnt = 0xFFFF;

            while (VertCnt > 0)
            {
                MeshChunks meshChunk = new MeshChunks();
                meshChunk.MeshNumber = MeshNumber;

                meshChunk.SectionInfo = Mapping.ReadObject <MeshSection>(stream);

                // Exit if Vertex Count is zero.
                if (meshChunk.SectionInfo.VertexCount <= 0)
                {
                    break;
                }

                meshChunk.TextureID = meshChunk.SectionInfo.TextureID;
                VertexFlags flags = GetFlags(meshChunk.SectionInfo);

                bool isColorFlagRisen = flags.UniformDiffuseFlag;

                if (pmo.header.SkeletonOffset != 0)
                {
                    meshChunk.SectionInfo_opt1 = Mapping.ReadObject <MeshSectionOptional1>(stream);
                }
                if (isColorFlagRisen)
                {
                    meshChunk.SectionInfo_opt2 = Mapping.ReadObject <MeshSectionOptional2>(stream);
                }
                if (meshChunk.SectionInfo.TriangleStripCount > 0)
                {
                    meshChunk.TriangleStripValues = new UInt16[meshChunk.SectionInfo.TriangleStripCount];
                    for (int i = 0; i < meshChunk.SectionInfo.TriangleStripCount; i++)
                    {
                        meshChunk.TriangleStripValues[i] = stream.ReadUInt16();
                    }
                }

                // Get Formats.
                CoordinateFormat TexCoordFormat       = flags.TextureCoordinateFormat;
                CoordinateFormat VertexPositionFormat = flags.PositionFormat;
                CoordinateFormat WeightFormat         = flags.WeightFormat;
                ColorFormat      ColorFormat          = flags.ColorFormat;
                UInt32           SkinningWeightsCount = flags.SkinningWeightsCount;
                BinaryReader     r = new BinaryReader(stream);
                long             positionAfterHeader = stream.Position;

                if (meshChunk.SectionInfo.TriangleStripCount > 0)
                {
                    int vertInd = 0;
                    for (int p = 0; p < meshChunk.SectionInfo.TriangleStripCount; p++)
                    {
                        for (int s = 0; s < (meshChunk.TriangleStripValues[p] - 2); s++)
                        {
                            if (s % 2 == 0)
                            {
                                meshChunk.Indices.Add(vertInd + s + 0);
                                meshChunk.Indices.Add(vertInd + s + 1);
                                meshChunk.Indices.Add(vertInd + s + 2);
                            }
                            else
                            {
                                meshChunk.Indices.Add(vertInd + s + 0);
                                meshChunk.Indices.Add(vertInd + s + 2);
                                meshChunk.Indices.Add(vertInd + s + 1);
                            }
                        }

                        vertInd += meshChunk.TriangleStripValues[p];
                    }
                }
                else
                {
                    if (flags.Primitive == PrimitiveType.PRIMITIVE_TRIANGLE_STRIP)
                    {
                        for (int s = 0; s < (meshChunk.SectionInfo.VertexCount - 2); s++)
                        {
                            if (s % 2 == 0)
                            {
                                meshChunk.Indices.Add(s + 0);
                                meshChunk.Indices.Add(s + 1);
                                meshChunk.Indices.Add(s + 2);
                            }
                            else
                            {
                                meshChunk.Indices.Add(s + 1);
                                meshChunk.Indices.Add(s + 0);
                                meshChunk.Indices.Add(s + 2);
                            }
                        }
                    }
                }

                for (int v = 0; v < meshChunk.SectionInfo.VertexCount; v++)
                {
                    long vertexStartPos       = stream.Position;
                    int  vertexIncreaseAmount = 0;

                    // Vertex Weights.
                    if (pmo.header.SkeletonOffset != 0 && WeightFormat != CoordinateFormat.NO_VERTEX)
                    {
                        WeightData WeightList = new WeightData();
                        WeightList.weights      = new List <float>();
                        WeightList.coordFormart = WeightFormat;

                        for (int i = 0; i < (SkinningWeightsCount + 1); i++)
                        {
                            switch (WeightFormat)
                            {
                            case CoordinateFormat.NORMALIZED_8_BITS:
                                WeightList.weights.Add(stream.ReadByte() / 128.0f);
                                break;

                            case CoordinateFormat.NORMALIZED_16_BITS:
                                WeightList.weights.Add(stream.ReadUInt16() / 32768.0f);
                                break;

                            case CoordinateFormat.FLOAT_32_BITS:
                                WeightList.weights.Add(stream.ReadFloat());
                                break;

                            case CoordinateFormat.NO_VERTEX:
                                break;
                            }
                        }

                        meshChunk.jointWeights.Add(WeightList);
                    }

                    Vector2 currentTexCoord = new Vector2(0, 0);

                    switch (TexCoordFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        currentTexCoord.X = stream.ReadByte() / 128.0f;
                        currentTexCoord.Y = stream.ReadByte() / 128.0f;
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentTexCoord.X = stream.ReadUInt16() / 32768.0f;
                        currentTexCoord.Y = stream.ReadUInt16() / 32768.0f;
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentTexCoord.X = stream.ReadFloat();
                        currentTexCoord.Y = stream.ReadFloat();
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;

                    case CoordinateFormat.NO_VERTEX:
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;
                    }

                    Vector4 col;

                    if (isColorFlagRisen)
                    {
                        uint c = meshChunk.SectionInfo_opt2.DiffuseColor;
                        col.X = c % 0x100;
                        col.Y = (c >> 8) % 0x100;
                        col.Z = (c >> 16) % 0x100;
                        col.W = (c >> 24) % 0x100;

                        meshChunk.colors.Add(col);
                    }
                    else
                    {
                        switch (ColorFormat)
                        {
                        case Pmo.ColorFormat.NO_COLOR:
                            meshChunk.colors.Add(new Vector4(0xFF, 0xFF, 0xFF, 0xFF));
                            break;

                        case Pmo.ColorFormat.BGR_5650_16BITS:
                            stream.ReadUInt16();
                            break;

                        case Pmo.ColorFormat.ABGR_5551_16BITS:
                            stream.ReadUInt16();
                            break;

                        case Pmo.ColorFormat.ABGR_4444_16BITS:
                            stream.ReadUInt16();
                            break;

                        case Pmo.ColorFormat.ABGR_8888_32BITS:
                            vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                            stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                            col.X = stream.ReadByte();
                            col.Y = stream.ReadByte();
                            col.Z = stream.ReadByte();
                            col.W = stream.ReadByte();
                            meshChunk.colors.Add(col);
                            break;
                        }
                    }

                    Vector3 currentVertex;

                    // Handle triangles and triangle strips.
                    switch (VertexPositionFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        currentVertex.X = r.ReadSByte() / 128.0f;
                        currentVertex.Y = r.ReadSByte() / 128.0f;
                        currentVertex.Z = r.ReadSByte() / 128.0f;
                        meshChunk.vertices.Add(currentVertex);
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentVertex.X = (float)stream.ReadInt16() / 32768.0f;
                        currentVertex.Y = (float)stream.ReadInt16() / 32768.0f;
                        currentVertex.Z = (float)stream.ReadInt16() / 32768.0f;
                        meshChunk.vertices.Add(currentVertex);
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentVertex.X = stream.ReadFloat();
                        currentVertex.Y = stream.ReadFloat();
                        currentVertex.Z = stream.ReadFloat();
                        meshChunk.vertices.Add(currentVertex);
                        break;
                    }

                    stream.Seek(vertexStartPos + meshChunk.SectionInfo.VertexSize, SeekOrigin.Begin);

                    if (flags.Primitive == PrimitiveType.PRIMITIVE_TRIANGLE)
                    {
                        meshChunk.Indices.Add(v);
                    }
                }

                VertCnt = meshChunk.SectionInfo.VertexCount;
                pmo.Meshes.Add(meshChunk);

                // Find position of next data chunk.
                stream.Seek(positionAfterHeader + (meshChunk.SectionInfo.VertexCount * meshChunk.SectionInfo.VertexSize), SeekOrigin.Begin);
                stream.Seek(stream.Position % 4, SeekOrigin.Current);
            }
        }
Пример #20
0
 public Lod()
 {
     vertexDeclaration = 0;
 }
Пример #21
0
        private MeshData MakeWireMesh(Vec3f pos1, Vec3f pos2, long netId)
        {
            float t    = 0.015f;//thickness
            Vec3f dPos = pos2 - pos1;
            float dist = pos2.Distance(pos1);

            int nSec = (int)Math.Floor(dist * 2);//number of section

            nSec = nSec > 5 ? nSec : 5;

            MeshData mesh = new MeshData(4, 6);

            mesh.SetMode(EnumDrawMode.Triangles);


            MeshData mesh_top = new MeshData(4, 6);

            mesh_top.SetMode(EnumDrawMode.Triangles);

            MeshData mesh_bot = new MeshData(4, 6);

            mesh_bot.SetMode(EnumDrawMode.Triangles);

            MeshData mesh_side = new MeshData(4, 6);

            mesh_side.SetMode(EnumDrawMode.Triangles);

            MeshData mesh_side2 = new MeshData(4, 6);

            mesh_side2.SetMode(EnumDrawMode.Triangles);

            //out of plane translation vector:
            Vec3f b = new Vec3f(-dPos.Z, 0, dPos.X).Normalize();

            if (dPos.Z == 0 && dPos.X == 0)
            {
                b = new Vec3f(1, 0, 0);
            }
            int   color = debugColors[netId % debugColors.Length];
            Vec3f pos;

            mesh_top.Flags.Fill(0);
            mesh_bot.Flags.Fill(0);
            mesh_side.Flags.Fill(0);
            mesh_side2.Flags.Fill(0);

            //Add vertices
            for (int j = 0; j <= nSec; j++)
            {
                float x  = dPos.X / nSec * j;
                float y  = dPos.Y / nSec * j;
                float z  = dPos.Z / nSec * j;
                float l  = (float)Math.Sqrt(x * x + y * y + z * z);
                float dy = Catenary(l / dist, 1, 0.5f);
                pos = new Vec3f(x, y + dy, z);


                float du = dist / 2 / t / nSec;

                mesh_top.AddVertex(pos1.X + pos.X - b.X * t, pos1.Y + pos.Y + t, pos1.Z + pos.Z - b.Z * t, j * du, 0, color);
                mesh_top.AddVertex(pos1.X + pos.X + b.X * t, pos1.Y + pos.Y + t, pos1.Z + pos.Z + b.Z * t, j * du, 1, color);


                mesh_bot.AddVertex(pos1.X + pos.X - b.X * t, pos1.Y + pos.Y - t, pos1.Z + pos.Z - b.Z * t, j * du, 0, color);
                mesh_bot.AddVertex(pos1.X + pos.X + b.X * t, pos1.Y + pos.Y - t, pos1.Z + pos.Z + b.Z * t, j * du, 1, color);

                mesh_side.AddVertex(pos1.X + pos.X - b.X * t, pos1.Y + pos.Y + t, pos1.Z + pos.Z - b.Z * t, j * du, 1, color);
                mesh_side.AddVertex(pos1.X + pos.X - b.X * t, pos1.Y + pos.Y - t, pos1.Z + pos.Z - b.Z * t, j * du, 0, color);


                mesh_side2.AddVertex(pos1.X + pos.X + b.X * t, pos1.Y + pos.Y + t, pos1.Z + pos.Z + b.Z * t, j * du, 1, color);
                mesh_side2.AddVertex(pos1.X + pos.X + b.X * t, pos1.Y + pos.Y - t, pos1.Z + pos.Z + b.Z * t, j * du, 0, color);


                mesh_top.Flags[2 * j]     = VertexFlags.NormalToPackedInt(new Vec3f(0, 1, 0)) << 15;
                mesh_top.Flags[2 * j + 1] = VertexFlags.NormalToPackedInt(new Vec3f(0, 1, 0)) << 15;

                mesh_bot.Flags[2 * j]     = VertexFlags.NormalToPackedInt(new Vec3f(0, -1, 0)) << 15;
                mesh_bot.Flags[2 * j + 1] = VertexFlags.NormalToPackedInt(new Vec3f(0, -1, 0)) << 15;

                mesh_side.Flags[2 * j]     = VertexFlags.NormalToPackedInt(-b.X, -b.Y, -b.Z) << 15;
                mesh_side.Flags[2 * j + 1] = VertexFlags.NormalToPackedInt(-b.X, -b.Y, -b.Z) << 15;

                mesh_side2.Flags[2 * j]     = VertexFlags.NormalToPackedInt(b) << 15;
                mesh_side2.Flags[2 * j + 1] = VertexFlags.NormalToPackedInt(b) << 15;

                int flag = VertexFlags.LeavesWindWaveBitMask;

                if (j != 0 && j < nSec)
                {
                    //mesh_top.Flags[2 * j] = flag;
                    //mesh_top.Flags[2 * j+1] = flag;
                    //mesh_bot.Flags[2 * j] = flag;
                    //mesh_bot.Flags[2 * j + 1] = flag;
                    //mesh_side.Flags[2 * j] = flag;
                    //mesh_side.Flags[2 * j + 1] = flag;
                    //mesh_side2.Flags[2 * j] = flag;
                    //mesh_side2.Flags[2 * j + 1] = flag;
                }
            }
            //add indices
            for (int j = 0; j < nSec; j++)
            {
                //upper stripe
                int offset = 2 * j;
                mesh_top.AddIndex(offset);
                mesh_top.AddIndex(offset + 3);
                mesh_top.AddIndex(offset + 2);
                mesh_top.AddIndex(offset);
                mesh_top.AddIndex(offset + 1);
                mesh_top.AddIndex(offset + 3);

                //lower stripe
                mesh_bot.AddIndex(offset);
                mesh_bot.AddIndex(offset + 3);
                mesh_bot.AddIndex(offset + 1);
                mesh_bot.AddIndex(offset);
                mesh_bot.AddIndex(offset + 2);
                mesh_bot.AddIndex(offset + 3);

                //sides
                mesh_side.AddIndex(offset);
                mesh_side.AddIndex(offset + 3);
                mesh_side.AddIndex(offset + 1);
                mesh_side.AddIndex(offset);
                mesh_side.AddIndex(offset + 2);
                mesh_side.AddIndex(offset + 3);


                mesh_side2.AddIndex(offset);
                mesh_side2.AddIndex(offset + 3);
                mesh_side2.AddIndex(offset + 2);
                mesh_side2.AddIndex(offset);
                mesh_side2.AddIndex(offset + 1);
                mesh_side2.AddIndex(offset + 3);
            }

            mesh.AddMeshData(mesh_top);
            mesh.AddMeshData(mesh_bot);
            mesh.AddMeshData(mesh_side);
            mesh.AddMeshData(mesh_side2);
            mesh.Rgba.Fill((byte)255);


            return(mesh);
        }
Пример #22
0
        public static void WriteMeshData(Stream stream, Pmo pmo)
        {
            bool hasSwappedToSecondModel = false;

            // Write Mesh Data.
            for (int j = 0; j < pmo.Meshes.Count; j++)
            {
                if (!hasSwappedToSecondModel && pmo.Meshes[j].MeshNumber == 1 && pmo.header.MeshOffset0 != 0)
                {
                    hasSwappedToSecondModel = true;

                    for (uint b = 0; b < 0xC; b++)
                    {
                        stream.Write((byte)0x00);
                    }

                    for (uint b = 0; stream.Position % 0x10 != 0; b++)
                    {
                        stream.Write((byte)0x00);
                    }
                }

                MeshChunks chunk = pmo.Meshes[j];

                Mapping.WriteObject <Pmo.MeshSection>(stream, chunk.SectionInfo);
                if (chunk.SectionInfo_opt1 != null)
                {
                    Mapping.WriteObject <Pmo.MeshSectionOptional1>(stream, chunk.SectionInfo_opt1);
                }
                if (chunk.SectionInfo_opt2 != null)
                {
                    Mapping.WriteObject <Pmo.MeshSectionOptional2>(stream, chunk.SectionInfo_opt2);
                }

                if (chunk.TriangleStripValues.Length > 0)
                {
                    for (int z = 0; z < chunk.TriangleStripValues.Length; z++)
                    {
                        stream.Write((ushort)chunk.TriangleStripValues[z]);
                    }
                }

                for (int k = 0; k < pmo.Meshes[j].SectionInfo.VertexCount; k++)
                {
                    long vertexStartPos       = stream.Position;
                    int  vertexIncreaseAmount = 0;

                    VertexFlags flags = Pmo.GetFlags(chunk.SectionInfo);

                    // Write Joints.
                    if (flags.WeightFormat != CoordinateFormat.NO_VERTEX)
                    {
                        for (int w = 0; w < flags.SkinningWeightsCount + 1; w++)
                        {
                            int currentIndex = w + (k * (flags.SkinningWeightsCount + 1));

                            switch (flags.WeightFormat)
                            {
                            case CoordinateFormat.NORMALIZED_8_BITS:
                                stream.Write((byte)(chunk.jointWeights[k].weights[currentIndex] * 127.0f));
                                break;

                            case CoordinateFormat.NORMALIZED_16_BITS:
                                stream.Write((byte)(chunk.jointWeights[k].weights[currentIndex] * 32767.0f));
                                break;

                            case CoordinateFormat.FLOAT_32_BITS:
                                StreamExtensions.Write(stream, chunk.jointWeights[k].weights[currentIndex]);
                                break;
                            }
                        }
                    }

                    // Write Texture Coords.
                    switch (flags.TextureCoordinateFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        stream.Write((byte)(chunk.textureCoordinates[k].X * 128.0f));
                        stream.Write((byte)(chunk.textureCoordinates[k].Y * 128.0f));
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        stream.Write((ushort)(chunk.textureCoordinates[k].X * 32768.0f));
                        stream.Write((ushort)(chunk.textureCoordinates[k].Y * 32768.0f));
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, chunk.textureCoordinates[k].X);
                        StreamExtensions.Write(stream, chunk.textureCoordinates[k].Y);
                        break;
                    }

                    // Write colors.
                    switch (flags.ColorFormat)
                    {
                    case Pmo.ColorFormat.NO_COLOR:
                        break;

                    case Pmo.ColorFormat.BGR_5650_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_5551_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_4444_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_8888_32BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        stream.Write((byte)(chunk.colors[k].X));
                        stream.Write((byte)(chunk.colors[k].Y));
                        stream.Write((byte)(chunk.colors[k].Z));
                        stream.Write((byte)(chunk.colors[k].W));
                        break;
                    }

                    // Write vertices.
                    switch (flags.PositionFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].X * 128.0f));
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].Y * 128.0f));
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].Z * 128.0f));
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].X * 32768.0f));
                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].Y * 32768.0f));
                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].Z * 32768.0f));
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, chunk.vertices[k].X);
                        StreamExtensions.Write(stream, chunk.vertices[k].Y);
                        StreamExtensions.Write(stream, chunk.vertices[k].Z);
                        break;
                    }

                    int padding = ((int)vertexStartPos + chunk.SectionInfo.VertexSize) - (int)stream.Position;
                    for (int p = 0; p < padding; p++)
                    {
                        stream.Write((byte)0xAB);
                    }
                }

                // Remainder.
                uint remainder = (uint)stream.Position % 4;
                for (int p = 0; p < remainder; p++)
                {
                    stream.Write((byte)0x00);
                }

                if (j == (pmo.Meshes.Count - 1))
                {
                    for (uint b = 0; b < 0xC; b++)
                    {
                        try
                        {
                            stream.Write((byte)0x00);
                        }
                        catch (Exception ex)
                        {
                            ex.ToString();
                        }
                    }


                    int pd = (int)stream.Position % 0x10;

                    for (int n = 0; pd != 0; n++)
                    {
                        try
                        {
                            stream.Write((byte)0x00);
                        }
                        catch (Exception ex)
                        {
                            ex.ToString();
                        }

                        pd = (int)stream.Position % 0x10;
                    }
                }
            }
        }
Пример #23
0
 private static void TessellateBorderedRectInternal(Rect rect, Color color, float posZ, VertexFlags vertexFlags, BorderParameters border, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly = false)
 {
     if (IsSimpleRectangle(border))
     {
         UInt16 indexOffset = 0;
         TessellateQuad(rect, TessellationType.Content, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
     }
     else
     {
         TessellateRoundBorders(rect, color, posZ, vertexFlags, border, vertices, indices, ref vertexCount, ref indexCount, countOnly);
     }
 }
Пример #24
0
        private static void TessellateRoundBorders(Rect rect, Color color, float posZ, VertexFlags vertexFlags, BorderParameters border, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly)
        {
            // To tessellate the 4 corners, the rect is divided in 4 quadrants and every quadrant is computed as if they were the top-left corner.
            // The quadrants are then mirrored and the triangles winding flipped as necessary.
            UInt16 indexOffset = 0;
            UInt16 startVc = 0, startIc = 0;
            bool   hasBorder   = HasBorder(border);
            var    halfSize    = new Vector2(rect.width / 2.0f, rect.height / 2.0f);
            var    quarterRect = new Rect(rect.x, rect.y, halfSize.x, halfSize.y);

            // Top-left
            TessellateRoundedCorner(quarterRect, color, posZ, vertexFlags, border.topLeftRadius, border.leftWidth, border.topWidth, hasBorder, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);

            // Top-right
            startVc = vertexCount;
            startIc = indexCount;
            TessellateRoundedCorner(quarterRect, color, posZ, vertexFlags, border.topRightRadius, border.rightWidth, border.topWidth, hasBorder, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
            MirrorVertices(quarterRect, vertices, startVc, vertexCount - startVc, true);
            FlipWinding(indices, startIc, indexCount - startIc);

            // Bottom-right
            startVc = vertexCount;
            startIc = indexCount;
            TessellateRoundedCorner(quarterRect, color, posZ, vertexFlags, border.bottomRightRadius, border.rightWidth, border.bottomWidth, hasBorder, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
            MirrorVertices(quarterRect, vertices, startVc, vertexCount - startVc, true);
            MirrorVertices(quarterRect, vertices, startVc, vertexCount - startVc, false);

            // Bottom-left
            startVc = vertexCount;
            startIc = indexCount;
            TessellateRoundedCorner(quarterRect, color, posZ, vertexFlags, border.bottomLeftRadius, border.leftWidth, border.bottomWidth, hasBorder, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
            MirrorVertices(quarterRect, vertices, startVc, vertexCount - startVc, false);
            FlipWinding(indices, startIc, indexCount - startIc);
        }
Пример #25
0
        private static void TessellateBorderedFan(TessellationType tessellationType, Vector2 center, float radius, float leftWidth, float topWidth, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly)
        {
            VertexFlags innerVertexFlags, outerVertexFlags;

            if (tessellationType == TessellationType.EdgeCorner)
            {
                innerVertexFlags = VertexFlags.IsEdge;
                outerVertexFlags = VertexFlags.IsSolid;
            }
            else
            {
                innerVertexFlags = vertexFlags;
                outerVertexFlags = vertexFlags;
            }

            if (countOnly)
            {
                vertexCount += (UInt16)(kSubdivisions * 2);
                indexCount  += (UInt16)((kSubdivisions - 1) * 6);
                return;
            }

            var a = radius - leftWidth;
            var b = radius - topWidth;
            var p = new Vector2(center.x - radius, center.y);
            var q = new Vector2(center.x - a, center.y);

            var verts = vertices.GetValueOrDefault();
            var inds  = indices.GetValueOrDefault();

            verts[vertexCount++] = new Vertex {
                position = new Vector3(q.x, q.y, posZ), uv = q - p, tint = color, flags = (float)innerVertexFlags
            };
            verts[vertexCount++] = new Vertex {
                position = new Vector3(p.x, p.y, posZ), uv = p - q, tint = color, flags = (float)outerVertexFlags
            };

            for (int k = 1; k < kSubdivisions; ++k)
            {
                float percent = ((float)k) / (kSubdivisions - 1);
                float angle   = (Mathf.PI / 2.0f) * percent;
                p = center + new Vector2(-Mathf.Cos(angle), -Mathf.Sin(angle)) * radius;
                q = center + new Vector2(-a * Mathf.Cos(angle), -b * Mathf.Sin(angle));
                verts[vertexCount++] = new Vertex {
                    position = new Vector3(q.x, q.y, posZ), uv = q - p, tint = color, flags = (float)innerVertexFlags
                };
                verts[vertexCount++] = new Vertex {
                    position = new Vector3(p.x, p.y, posZ), uv = p - q, tint = color, flags = (float)outerVertexFlags
                };

                int i = k * 2;
                inds[indexCount++] = (UInt16)(indexOffset + (i - 2));
                inds[indexCount++] = (UInt16)(indexOffset + (i));
                inds[indexCount++] = (UInt16)(indexOffset + (i - 1));
                inds[indexCount++] = (UInt16)(indexOffset + (i - 1));
                inds[indexCount++] = (UInt16)(indexOffset + (i));
                inds[indexCount++] = (UInt16)(indexOffset + (i + 1));
            }

            indexOffset += (UInt16)(kSubdivisions * 2);
        }
Пример #26
0
 public FrameResourceModelOptions(VertexFlags flags)
 {
     InitializeComponent();
     Init(flags);
     Localise();
 }
Пример #27
0
        private static void TessellateQuad(Rect rect, TessellationType tessellationType, Color color, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly)
        {
            if (rect.width < kEpsilon || rect.height < kEpsilon)
            {
                return;
            }

            if (countOnly)
            {
                vertexCount += 4;
                indexCount  += 6;
                return;
            }

            float x0 = rect.x;
            float x3 = rect.xMax;
            float y0 = rect.y;
            float y3 = rect.yMax;

            Vector2 uv0, uv1, uv2, uv3;
            float   flags0, flags1, flags2, flags3;

            switch (tessellationType)
            {
            case TessellationType.EdgeHorizontal:
                // The uvs contain the displacement from the vertically opposed corner.
                uv0    = new Vector2(0, y0 - y3);
                uv1    = new Vector2(0, y0 - y3);
                uv2    = new Vector2(0, y3 - y0);
                uv3    = new Vector2(0, y3 - y0);
                flags0 = flags1 = (float)VertexFlags.IsSolid;
                flags2 = flags3 = (float)VertexFlags.IsEdge;
                break;

            case TessellationType.EdgeVertical:
                // The uvs contain the displacement from the horizontally opposed corner.
                uv0    = new Vector2(x0 - x3, 0);
                uv1    = new Vector2(x3 - x0, 0);
                uv2    = new Vector2(x0 - x3, 0);
                uv3    = new Vector2(x3 - x0, 0);
                flags0 = flags2 = (float)VertexFlags.IsSolid;
                flags1 = flags3 = (float)VertexFlags.IsEdge;
                break;

            case TessellationType.EdgeCorner:
                uv0    = uv1 = uv2 = uv3 = Vector2.zero;
                flags0 = flags1 = flags2 = flags3 = (float)VertexFlags.IsSolid;
                break;

            case TessellationType.Content:
                uv0    = uv1 = uv2 = uv3 = Vector2.zero;  // UVs are computed later for content
                flags0 = flags1 = flags2 = flags3 = (float)vertexFlags;
                break;

            default:
                throw new NotImplementedException();
            }

            var verts = vertices.GetValueOrDefault();

            verts[vertexCount++] = new Vertex {
                position = new Vector3(x0, y0, posZ), uv = uv0, tint = color, flags = flags0
            };
            verts[vertexCount++] = new Vertex {
                position = new Vector3(x3, y0, posZ), uv = uv1, tint = color, flags = flags1
            };
            verts[vertexCount++] = new Vertex {
                position = new Vector3(x0, y3, posZ), uv = uv2, tint = color, flags = flags2
            };
            verts[vertexCount++] = new Vertex {
                position = new Vector3(x3, y3, posZ), uv = uv3, tint = color, flags = flags3
            };

            var inds = indices.GetValueOrDefault();

            inds[indexCount++] = (UInt16)(indexOffset + 0);
            inds[indexCount++] = (UInt16)(indexOffset + 2);
            inds[indexCount++] = (UInt16)(indexOffset + 1);
            inds[indexCount++] = (UInt16)(indexOffset + 3);
            inds[indexCount++] = (UInt16)(indexOffset + 1);
            inds[indexCount++] = (UInt16)(indexOffset + 2);

            indexOffset += 4;
        }
Пример #28
0
        ///<summary>
        /// Tessellates the border OR the content:
        /// If any of the left/right/top/bottom border parameters is greater than Epsilon, we tessellate ONLY a border.
        /// Otherwise we tessellate ONLY the content.
        /// </summary>
        /// <param name="vertexFlags">Flags are only used for content, not for a border.</param>
        public static void TessellateBorderedRect(Rect rect, Rect texCoords, Color color, BorderParameters border, float posZ, VertexFlags vertexFlags, UIRMeshBuilder.AllocMeshData meshAlloc)
        {
            if (rect.width < kEpsilon || rect.height < kEpsilon)
            {
                return;
            }

            Profiler.BeginSample("TessellateBorderedRect");

            border = AdjustBorderParameters(rect, border);

            UInt16 vertexCount = 0, indexCount = 0;

            CountBorderedRectTriangles(rect, border, ref vertexCount, ref indexCount);

            var mesh = meshAlloc(vertexCount, indexCount);

            vertexCount = 0;
            indexCount  = 0;
            TessellateBorderedRectInternal(rect, color, posZ, vertexFlags, border, mesh.vertices, mesh.indices, ref vertexCount, ref indexCount);
            if (!HasBorder(border) && ((vertexFlags == VertexFlags.IsTextured) || (vertexFlags == VertexFlags.IsCustom)))
            {
                ComputeUVs(rect, texCoords, mesh.vertices);
            }

            Profiler.EndSample();
        }
Пример #29
0
 public Lod()
 {
     vertexDeclaration = 0;
     numUVChannels     = 4;
 }
Пример #30
0
        private MeshData[] GenContentMeshes(ITesselatorAPI tesselator)
        {
            ItemStack content = GetContents();

            if (content == null)
            {
                return(null);
            }

            Dictionary <string, MeshData[]> meshes = ObjectCacheUtil.GetOrCreate(Api, "plantContainerContentMeshes", () =>
            {
                return(new Dictionary <string, MeshData[]>());
            });

            MeshData[] meshwithVariants;
            string     containersize = this.ContainerSize;
            string     key           = GetContents()?.ToString() + "-" + containersize;

            if (meshes.TryGetValue(key, out meshwithVariants))
            {
                return(meshwithVariants);
            }

            curContProps = PlantContProps;
            if (curContProps == null)
            {
                return(null);
            }

            CompositeShape compoShape = curContProps.Shape;

            if (compoShape == null)
            {
                compoShape = content.Class == EnumItemClass.Block ? content.Block.Shape : content.Item.Shape;
            }
            ModelTransform transform = curContProps.Transform;

            if (transform == null)
            {
                transform = new ModelTransform().EnsureDefaultValues();
                transform.Translation.Y = Block.Attributes["fillHeight"].AsFloat(0.4f);
            }

            contentTexSource = content.Class == EnumItemClass.Block ? capi.Tesselator.GetTexSource(content.Block) : capi.Tesselator.GetTextureSource(content.Item);
            List <IAsset> assets;

            if (compoShape.Base.Path.EndsWith("*"))
            {
                assets = Api.Assets.GetMany(compoShape.Base.WithPathPrefixOnce("shapes/").Path.Substring(0, compoShape.Base.Path.Length - 1), compoShape.Base.Domain);
            }
            else
            {
                assets = new List <IAsset>();
                assets.Add(Api.Assets.TryGet(compoShape.Base.WithPathPrefixOnce("shapes/").WithPathAppendixOnce(".json")));
            }

            if (assets != null && assets.Count > 0)
            {
                meshwithVariants = new MeshData[assets.Count];

                for (int i = 0; i < assets.Count; i++)
                {
                    IAsset asset = assets[i];
                    Shape  shape = asset.ToObject <Shape>();
                    shapeTextures = shape.Textures;
                    MeshData mesh;

                    tesselator.TesselateShape("plant container content shape", shape, out mesh, this);

                    for (int j = 0; j < mesh.RenderPassCount; j++)
                    {
                        mesh.RenderPasses[j] = (int)EnumChunkRenderPass.OpaqueNoCull;
                    }

                    Block       block = GetContents()?.Block;
                    VertexFlags flags = block?.VertexFlags;
                    if (flags != null && flags.GrassWindWave)
                    {
                        int grassWave = VertexFlags.FoliageWindWaveBitMask | VertexFlags.WeakWaveBitMask;

                        for (int vertexNum = 0; vertexNum < mesh.GetVerticesCount(); vertexNum++)
                        {
                            float y = mesh.xyz[vertexNum * 3 + 1];
                            if (y > block.WaveFlagMinY)
                            {
                                mesh.Flags[vertexNum] |= grassWave;
                            }
                        }
                    }

                    mesh.ModelTransform(transform);
                    meshwithVariants[i] = mesh;
                }
            }
            else
            {
                Api.World.Logger.Error("Plant container, content asset {0} not found,", compoShape.Base.WithPathPrefixOnce("shapes/").WithPathAppendixOnce(".json"));
            }

            return(meshes[key] = meshwithVariants);
        }
Пример #31
0
        private static void TessellateRoundedCorner(Rect rect, Color color, float posZ, VertexFlags vertexFlags, float radius, float leftWidth, float topWidth, bool hasBorder, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 indexOffset, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly)
        {
            var cornerCenter = rect.position + new Vector2(radius, radius);
            var subRect      = Rect.zero;

            if (radius < kEpsilon)
            {
                if (!hasBorder)
                {
                    // Without radius and no borders, we use a single quad to fill the section
                    // -------
                    // |     |
                    // |     |
                    // -------
                    TessellateQuad(rect, TessellationType.Content, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                }
                else
                {
                    // Without radius with borders, we use two quads for the outlines
                    // ------------
                    // |   |  B   |
                    // | A |-------
                    // |   |
                    // |   |
                    // -----
                    if (leftWidth > kEpsilon)
                    {
                        // A
                        subRect = new Rect(rect.x, rect.y, leftWidth, rect.height);
                        TessellateQuad(subRect, TessellationType.EdgeVertical, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                    }
                    if (topWidth > kEpsilon)
                    {
                        // B
                        subRect = new Rect(rect.x + leftWidth, rect.y, rect.width - leftWidth, topWidth);
                        TessellateQuad(subRect, TessellationType.EdgeHorizontal, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                    }
                }
                return;
            }

            if (!hasBorder)
            {
                // Without borders, we can just fill the corner with radius, plus up to 2 quads to fill the remainder of the section
                //   _-------
                //  *\ |    |
                // *__\| A  |
                // |   |    |
                // | B |    |
                // |   |    |
                // ----------
                TessellateFilledFan(TessellationType.Content, cornerCenter, radius, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                if (radius < rect.width)
                {
                    // A
                    subRect = new Rect(rect.x + radius, rect.y, rect.width - radius, rect.height);
                    TessellateQuad(subRect, TessellationType.Content, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                }
                if (radius < rect.height)
                {
                    // B
                    subRect = new Rect(rect.x, rect.y + radius, radius < rect.width ? radius : rect.width, rect.height - radius);
                    TessellateQuad(subRect, TessellationType.Content, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                }
            }
            else
            {
                // With borders, we have to create a fan-shaped outline, plus up to 2 quads for the straight outlines
                // If the radius is smaller than the border width, we create a filled fan plus the required quads instead.
                if (radius < leftWidth || radius < topWidth)
                {
                    // A
                    TessellateFilledFan(TessellationType.EdgeCorner, cornerCenter, radius, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                    if (radius < leftWidth && radius < topWidth)
                    {
                        //      _______________
                        //   -*  |  |          |
                        //  * A\ | C|          |
                        // *____\|__|    F     |
                        // |    B   |          |
                        // |________|__________|
                        // |        |
                        // |   E    |
                        // |        |
                        // |________|

                        // B
                        subRect = new Rect(rect.x, rect.y + radius, leftWidth, topWidth - radius);
                        TessellateQuad(subRect, TessellationType.EdgeCorner, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);

                        // C
                        subRect = new Rect(rect.x + radius, rect.y, leftWidth - radius, radius);
                        TessellateQuad(subRect, TessellationType.EdgeCorner, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                    }
                    else if (radius < leftWidth)
                    {
                        //      ____________
                        //   -*  |  |  F    |
                        //  * A\ | B|_______|
                        // *____\|__|
                        // |        |
                        // |        |
                        // |   E    |
                        // |        |
                        // |        |
                        // |________|

                        // B
                        subRect = new Rect(rect.x + radius, rect.y, leftWidth - radius, Mathf.Max(radius, topWidth));
                        TessellateQuad(subRect, TessellationType.EdgeCorner, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                    }
                    else
                    {
                        //      ____________
                        //   -*  |          |
                        //  * A\ |          |
                        // *____\|    F     |
                        // |  B  |          |
                        // |_____|__________|
                        // |  |
                        // |E |
                        // |  |
                        // |__|

                        // B
                        subRect = new Rect(rect.x, rect.y + radius, Mathf.Max(radius, leftWidth), topWidth - radius);
                        TessellateQuad(subRect, TessellationType.EdgeCorner, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                    }
                }
                else
                {
                    //      _________
                    //   -*  |   F   |
                    //  * A\_|_______|
                    // *__/
                    // |  |
                    // |  |
                    // |E |
                    // |  |
                    // |__|

                    // A
                    TessellateBorderedFan(TessellationType.EdgeCorner, cornerCenter, radius, leftWidth, topWidth, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
                }

                // Tessellate the straight outlines
                // E
                float cornerSize = Mathf.Max(radius, topWidth);
                subRect = new Rect(rect.x, rect.y + cornerSize, leftWidth, rect.height - cornerSize);
                TessellateQuad(subRect, TessellationType.EdgeVertical, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);

                // F
                cornerSize = Mathf.Max(radius, leftWidth);
                subRect    = new Rect(rect.x + cornerSize, rect.y, rect.width - cornerSize, topWidth);
                TessellateQuad(subRect, TessellationType.EdgeHorizontal, color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly);
            }
        }
Пример #32
0
 /// <summary>
 /// Uninitialize OpenGL element array drawing.
 /// </summary>
 public static void UninitArrayState(VertexFlags types)
 {
     if ((types & VertexFlags.Pos) != 0)
     Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
       if ((types & VertexFlags.Normal) != 0)
     Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
       if ((types & VertexFlags.Color) != 0)
     Gl.glDisableClientState(Gl.GL_COLOR_ARRAY);
       if ((types & VertexFlags.Texture) != 0)
     Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
 }
Пример #33
0
		static VertexFormat GetVertexFormat (VertexFlags flags, int boneSlotCount) {
			uint elemCount = 0, f = (uint)flags;
			for (elemCount = 0; f != 0; elemCount++)
				f &= f - 1;
			var elems = new VertexElement[(int)elemCount + 1 + (boneSlotCount * 2)];

			int offset = 3, idx = 1;
			elems[0] = new VertexElement("Position", 0, 3);

			if ((flags & VertexFlags.Normal) != 0) {
				elems[idx++] = new VertexElement("Normal", offset, 3);
				offset += 3;
			}
			for (var i = 0; i < 4; i++) {
				if (((int)flags & ((int)VertexFlags.TexCoord0 << i)) != 0) {
					elems[idx++] = new VertexElement("TexCoord" + i, offset, 2);
					offset += 2;
				}
			}
			for (var i = 0; i < 4; i++) {
				if (((int)flags & ((int)VertexFlags.Color0 << i)) != 0) {
					elems[idx++] = new VertexElement("Color" + i, offset, 4);
					offset += 4;
				}
			}
			for (var i = 0; i < boneSlotCount; i++)
				elems[idx++] = new VertexElement("BoneWeight" + i, offset++, 1);
			for (var i = 0; i < boneSlotCount; i++)
				elems[idx++] = new VertexElement("BoneIndex" + i, offset++, 1);
			return new VertexFormat(offset, elems);
		}