Example #1
0
 public Mesh(string name, LmGeometry gmdlGeometry)
 {
     this.Name         = name;
     this.GmdlGeometry = gmdlGeometry;
 }
Example #2
0
        public static Mesh Convert(LmMsgPck msg)
        {
            var name             = msg.ReadString();
            var u0               = msg.ReadByte();
            var boneIdTable      = LmBoneIdTable.Unpack(msg);
            var vertexLayoutType = (VertexLayoutType)msg.ReadInt();
            var geometry         = LmGeometry.Unpack(msg);

            var mesh = new Mesh(name, geometry);

            mesh.Setup(geometry);

            // TODO get Material
            var defaultMaterialHash = msg.ReadUint64();

            var gmdlMeshData = new GmdlMeshData();

            mesh.GmdlMeshData = gmdlMeshData;

            if (msg.Version >= 20140623)
            {
                gmdlMeshData.DrawPriorityOffset = msg.ReadInt();
                if (msg.ReadBool())
                {
                    gmdlMeshData.Flags |= 1;
                }

                if (msg.ReadBool())
                {
                    gmdlMeshData.Flags |= 2;
                }

                gmdlMeshData.LodNear = msg.ReadFloat();
                gmdlMeshData.LodFar  = msg.ReadFloat();
                gmdlMeshData.LodFade = msg.ReadFloat();

                if (gmdlMeshData.LodNear < gmdlMeshData.LodFar && (gmdlMeshData.LodNear > 0.0 || gmdlMeshData.LodFar < 3.4028235e38))
                {
                    gmdlMeshData.Flags |= 4u;
                }

                if (gmdlMeshData.LodFade > 0.0)
                {
                    gmdlMeshData.Flags |= 0x100u;
                }
            }

            if (msg.Version >= 20140814)
            {
                msg.ReadBool();
            }

            if (msg.Version >= 20141112 && msg.ReadBool())
            {
                gmdlMeshData.Flags |= 0x10u;
            }

            if (msg.Version >= 20140815)
            {
                gmdlMeshData.PartsId = msg.ReadUint();
            }

            if (msg.Version >= 20141115)
            {
                var gmdlMeshPartsDataCount = msg.ReadInt();
                for (var _ = 0; _ < gmdlMeshPartsDataCount; _++)
                {
                    var gmdlMeshPartData = GmdlMeshPartsData.Unpack(msg);
                    gmdlMeshData.GmdlMeshPartsDatas.Add(gmdlMeshPartData);
                }
            }

            if (msg.Version >= 20150413 && msg.ReadBool())
            {
                gmdlMeshData.Flags |= 0x20u;
            }

            if (msg.Version >= 20150430)
            {
                var flag = msg.ReadUint();
                if (msg.Version < 20151217)
                {
                    gmdlMeshData.Flags |= 0x200u;
                    if (boneIdTable.BoneIds.Count == 0)
                    {
                        gmdlMeshData.Flags |= 0x400u;
                    }
                }

                gmdlMeshData.Flags |= flag;
            }

            if (msg.Version >= 20150512 && msg.ReadBool())
            {
                gmdlMeshData.Flags |= 0x80u;
            }

            if (msg.Version < 20160420)
            {
                gmdlMeshData.BreakableBoneIndex    = 0xFFFFFFFF;
                gmdlMeshData.LowLodShadowCascadeNo = 2;
            }
            else
            {
                gmdlMeshData.BreakableBoneIndex    = msg.ReadUint();
                gmdlMeshData.LowLodShadowCascadeNo = (sbyte)msg.ReadUint();
            }

            gmdlMeshData.VertexLayoutType = vertexLayoutType;
            if ((gmdlMeshData.Flags & 0x80000) != 0)
            {
                var unk0 = msg.ReadBool();
                var unk1 = msg.ReadUint();
                var unk2 = msg.ReadUint();
            }

            // TODO SetupMeshLod

            return(mesh);
        }
Example #3
0
        private void Setup(LmGeometry geometry)
        {
            // Create index buffer
            var indexBufferDescription = new IndexBufferDesc(geometry.IdxBufferSize, geometry.IdxType);

            this.IndexBuffer = new IndexBuffer(geometry.IdxBuffer, indexBufferDescription);

            // Create vertex buffers
            this.VertexCount        = geometry.VtxNum;
            this.TotalTriangleCount = geometry.IdxNum / 3;
            this.TriangleCount      = this.VertexCount;

            var meshVertexDeclaration = new MeshVertexDeclaration();
            var readFunctions         = MakeReadFunctions();

            for (byte i = 0; i < geometry.VtxStreamGroupDesc.VtxStreamDescs.Count; i++)
            {
                var vtxStreamDesc    = geometry.VtxStreamGroupDesc.VtxStreamDescs[i];
                var structuredVBDesc = vtxStreamDesc.StructuredVBDesc;
                var vtxBufferDesc    = new VertexBufferDesc(structuredVBDesc.Stride * this.VertexCount);

                // Ugly hack
                var vtxBuffer = new VertexBuffer(null, vtxBufferDesc); // new VertexBuffer(new ArraySegment<byte>(geometry.VtxBuffer, (int)structuredVBDesc.StartOffset, (int)vtxBufferDesc.Size), vtxBufferDesc);
                this.VertexBuffers.Add(vtxBuffer);

                if (i >= 8)
                {
                    DefaultPrintFunction.Write("i<EBONY_COUNTOF(this->bufferStrides)");
                }

                // Add vertex elements
                foreach (var vtxElementDesc in structuredVBDesc.VtxElementDescs)
                {
                    var usage         = LmVertexElementDesc.GetUsageFromSemantic(vtxElementDesc.Semantic);
                    var size          = LmVertexElementDesc.FormatToVertexComponentCount(vtxElementDesc.Format);
                    var type          = LmVertexElementDesc.FormatToVertexType(vtxElementDesc.Format);
                    var vertexElement = new VertexElement(i, type, usage, 0, (ushort)vtxElementDesc.Offset, (ushort)size, vtxElementDesc.Semantic, 0);

                    meshVertexDeclaration.AddVertexElement(vertexElement, vtxBuffer);
                }

                // Parse vertex buffer
                //var vertexElementArrays = new Dictionary<string, IList>();
                foreach (var vtxElementDesc in structuredVBDesc.VtxElementDescs)
                {
                    var values = CreateVertexElementArray(vtxElementDesc.Format);
                    VertexElementArrays.Add(vtxElementDesc.Semantic, values);
                }

                var vertexBufferPosition = (int)structuredVBDesc.StartOffset;
                for (var j = 0; j < vtxBufferDesc.Size / structuredVBDesc.Stride; j++)
                {
                    foreach (var vtxElementDesc in structuredVBDesc.VtxElementDescs)
                    {
                        var readFunction = readFunctions[vtxElementDesc.Format];
                        var size         = LmVertexElementDesc.FormatToVertexComponentCount(vtxElementDesc.Format);
                        for (var _ = 0; _ < size; _++)
                        {
                            var value = readFunction(geometry.VtxBuffer, vertexBufferPosition, out int componentSize);
                            VertexElementArrays[vtxElementDesc.Semantic].Add(value);
                            vertexBufferPosition += componentSize;
                        }
                    }
                }

                this.MainStreamSet     = meshVertexDeclaration;
                this.BoneInstanceCount = geometry.InstanceNum;

                if (this.BoneInstanceCount != 0)
                {
                    // TODO instance buffer
                }
            }
        }