public Mesh(string name, LmGeometry gmdlGeometry) { this.Name = name; this.GmdlGeometry = gmdlGeometry; }
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); }
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 } } }