/// <summary> /// Build Lods from retrieved data. /// </summary> public void BuildLods(FrameGeometry frameGeometry, FrameMaterial frameMaterial, VertexBuffer[] vertexBuffers, IndexBuffer[] indexBuffers) { lods = new Lod[frameGeometry.NumLods]; for (int i = 0; i != lods.Length; i++) { FrameLOD frameLod = frameGeometry.LOD[i]; lods[i] = new Lod { VertexDeclaration = frameGeometry.LOD[i].VertexDeclaration }; IndexBuffer indexBuffer = indexBuffers[i]; VertexBuffer vertexBuffer = vertexBuffers[i]; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = frameLod.GetVertexOffsets(out vertexSize); lods[i].Vertices = new Vertex[frameLod.NumVerts]; if (vertexSize * frameLod.NumVerts != vertexBuffer.Data.Length) { throw new System.Exception(); } for (int v = 0; v != lods[i].Vertices.Length; v++) { //declare data required and send to decompresser byte[] data = new byte[vertexSize]; Array.Copy(vertexBuffers[i].Data, (v * vertexSize), data, 0, vertexSize); lods[i].Vertices[v] = VertexTranslator.DecompressVertex(data, frameGeometry.LOD[i].VertexDeclaration, frameGeometry.DecompressionOffset, frameGeometry.DecompressionFactor, vertexOffsets); } lods[i].Indices = indexBuffer.GetData(); MaterialStruct[] materials = frameMaterial.Materials[i]; lods[i].Parts = new ModelPart[materials.Length]; for (int x = 0; x != materials.Length; x++) { if (string.IsNullOrEmpty(materials[x].MaterialName)) { var material = MaterialsManager.LookupMaterialByHash(materials[x].MaterialHash); materials[x].MaterialName = material.GetMaterialName(); } ModelPart modelPart = new ModelPart(); modelPart.Material = materials[x].MaterialName; modelPart.StartIndex = (uint)materials[x].StartIndex; modelPart.NumFaces = (uint)materials[x].NumFaces; lods[i].Parts[x] = modelPart; } } }
/// <summary> /// Build Lods from retrieved data. /// </summary> public void BuildLods(FrameGeometry frameGeometry, FrameMaterial frameMaterial, VertexBuffer[] vertexBuffers, IndexBuffer[] indexBuffers) { lods = new Lod[frameGeometry.NumLods]; for (int i = 0; i != lods.Length; i++) { FrameLOD frameLod = frameGeometry.LOD[i]; lods[i] = new Lod { VertexDeclaration = frameGeometry.LOD[i].VertexDeclaration }; IndexBuffer indexBuffer = indexBuffers[i]; VertexBuffer vertexBuffer = vertexBuffers[i]; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = frameLod.GetVertexOffsets(out vertexSize); lods[i].NumUVChannels = 4; lods[i].Vertices = new Vertex[frameLod.NumVertsPr]; for (int v = 0; v != lods[i].Vertices.Length; v++) { Vertex vertex = new Vertex(); vertex.UVs = new Half2[lods[i].NumUVChannels]; if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; vertex.Position = VertexTranslator.ReadPositionDataFromVB(vertexBuffer.Data, startIndex, frameGeometry.DecompressionFactor, frameGeometry.DecompressionOffset); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; vertex.Tangent = VertexTranslator.ReadTangentDataFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Normals].Offset; vertex.Normal = VertexTranslator.ReadNormalDataFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Skin)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Skin].Offset; vertex.BlendWeight = VertexTranslator.ReadBlendWeightFromVB(vertexBuffer.Data, startIndex); vertex.BoneID = VertexTranslator.ReadBlendIDFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Color)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Color].Offset; vertex.Color0 = VertexTranslator.ReadColorFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords0].Offset; vertex.UVs[0] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords1].Offset; vertex.UVs[1] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords2].Offset; vertex.UVs[2] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.ShadowTexture].Offset; vertex.UVs[3] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Color1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Color1].Offset; vertex.Color1 = VertexTranslator.ReadColorFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.BBCoeffs)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.BBCoeffs].Offset; vertex.BBCoeffs = VertexTranslator.ReadBBCoeffsVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.DamageGroup)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.DamageGroup].Offset; vertex.DamageGroup = VertexTranslator.ReadDamageGroupFromVB(vertexBuffer.Data, startIndex); } if (lods[i].NormalMapInfoPresent) { vertex.BuildBinormals(); } lods[i].Vertices[v] = vertex; lods[i].Indices = indexBuffer.Data; MaterialStruct[] materials = frameMaterial.Materials[i]; lods[i].Parts = new ModelPart[materials.Length]; for (int x = 0; x != materials.Length; x++) { ModelPart modelPart = new ModelPart(); modelPart.Material = materials[x].MaterialHash.ToString(); modelPart.StartIndex = (uint)materials[x].StartIndex; modelPart.NumFaces = (uint)materials[x].NumFaces; lods[i].Parts[x] = modelPart; } } } }
/// <summary> /// Build Lods from retrieved data. /// </summary> public void BuildLods(FrameGeometry frameGeometry, FrameMaterial frameMaterial, VertexBuffer[] vertexBuffers, IndexBuffer[] indexBuffers) { lods = new Lod[frameGeometry.NumLods]; for (int i = 0; i != lods.Length; i++) { FrameLOD frameLod = frameGeometry.LOD[i]; lods[i] = new Lod { VertexDeclaration = frameGeometry.LOD[i].VertexDeclaration }; IndexBuffer indexBuffer = indexBuffers[i]; VertexBuffer vertexBuffer = vertexBuffers[i]; int vertexSize; Dictionary <VertexFlags, FrameLOD.VertexOffset> vertexOffsets = frameLod.GetVertexOffsets(out vertexSize); lods[i].Vertices = new Vertex[frameLod.NumVertsPr]; if (vertexSize * frameLod.NumVertsPr != vertexBuffer.Data.Length) { throw new System.Exception(); } for (int v = 0; v != lods[i].Vertices.Length; v++) { Vertex vertex = new Vertex(); vertex.UVs = new Half2[4]; if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Position)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; var output = VertexTranslator.ReadPositionDataFromVB(vertexBuffer.Data, startIndex, frameGeometry.DecompressionFactor, frameGeometry.DecompressionOffset); vertex.Position = Vector3Extenders.FromVector4(output); vertex.Binormal = new Vector3(output.X); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Tangent)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Position].Offset; vertex.Tangent = VertexTranslator.ReadTangentDataFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Normals)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Normals].Offset; vertex.Normal = VertexTranslator.ReadNormalDataFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Skin)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Skin].Offset; vertex.BoneWeights = VertexTranslator.ReadWeightsFromVB(vertexBuffer.Data, startIndex); vertex.BoneIDs = VertexTranslator.ReadBonesFromVB(vertexBuffer.Data, startIndex + 4); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Color)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Color].Offset; vertex.Color0 = VertexTranslator.ReadColorFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.Color1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.Color1].Offset; vertex.Color1 = VertexTranslator.ReadColorFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords0)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords0].Offset; vertex.UVs[0] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords1)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords1].Offset; vertex.UVs[1] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.TexCoords2)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.TexCoords2].Offset; vertex.UVs[2] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.ShadowTexture)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.ShadowTexture].Offset; vertex.UVs[3] = VertexTranslator.ReadTexcoordFromVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.BBCoeffs)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.BBCoeffs].Offset; vertex.BBCoeffs = VertexTranslator.ReadBBCoeffsVB(vertexBuffer.Data, startIndex); } if (lods[i].VertexDeclaration.HasFlag(VertexFlags.DamageGroup)) { int startIndex = v * vertexSize + vertexOffsets[VertexFlags.DamageGroup].Offset; vertex.DamageGroup = VertexTranslator.ReadDamageGroupFromVB(vertexBuffer.Data, startIndex); } lods[i].Vertices[v] = vertex; } lods[i].Indices = indexBuffer.Data; MaterialStruct[] materials = frameMaterial.Materials[i]; lods[i].Parts = new ModelPart[materials.Length]; for (int x = 0; x != materials.Length; x++) { if (string.IsNullOrEmpty(materials[x].MaterialName)) { var material = MaterialsManager.LookupMaterialByHash(materials[x].MaterialHash); materials[x].MaterialName = material.MaterialName; } ModelPart modelPart = new ModelPart(); modelPart.Material = materials[x].MaterialName; modelPart.StartIndex = (uint)materials[x].StartIndex; modelPart.NumFaces = (uint)materials[x].NumFaces; lods[i].Parts[x] = modelPart; } } }