static FoamModel LoadMdl(string FilePath) { FilePath = FilePath.Substring(0, FilePath.Length - Path.GetExtension(FilePath).Length); StudioModelFile Mdl = StudioModelFile.FromProvider(FilePath + ".mdl", VFS); if (Mdl == null) { throw new FileNotFoundException("File not found", FilePath + ".mdl"); } ValveVertexFile Verts = ValveVertexFile.FromProvider(FilePath + ".vvd", VFS); ValveTriangleFile Tris = ValveTriangleFile.FromProvider(FilePath + ".dx90.vtx", Mdl, Verts, VFS); // Foam stuff List <FoamMaterial> FoamMaterials = new List <FoamMaterial>(); string[] TexNames = Mdl.TextureNames.ToArray(); for (int i = 0; i < Mdl.MaterialCount; i++) { string MatName = Mdl.GetMaterialName(i, VFS); string ShortMatName = Path.GetFileNameWithoutExtension(MatName); ValveMaterialFile VMF = ValveMaterialFile.FromProvider(MatName, VFS); FoamMaterials.Add(new FoamMaterial(ShortMatName, new FoamTexture[] { new FoamTexture(TexNames[i], FoamTextureType.Diffuse) })); } List <FoamMesh> FoamMeshes = new List <FoamMesh>(); List <FoamBone> FoamBones = new List <FoamBone>(); StudioModelFile.StudioBone[] Bones = Mdl.GetBones(); for (int i = 0; i < Bones.Length; i++) { string BoneName = Mdl.GetBoneName(i); FoamBones.Add(new FoamBone(BoneName, Bones[i].Parent, Matrix4x4.Identity)); } // BODIES for (int BodyPartIdx = 0; BodyPartIdx < Mdl.BodyPartCount; BodyPartIdx++) { StudioModelFile.StudioModel[] StudioModels = Mdl.GetModels(BodyPartIdx).ToArray(); // MODELS for (int ModelIdx = 0; ModelIdx < StudioModels.Length; ModelIdx++) { ref StudioModelFile.StudioModel StudioModel = ref StudioModels[ModelIdx]; StudioModelFile.StudioMesh[] StudioMeshes = Mdl.GetMeshes(ref StudioModel).ToArray(); // MESHES for (int MeshIdx = 0; MeshIdx < StudioMeshes.Length; MeshIdx++) { ref StudioModelFile.StudioMesh StudioMesh = ref StudioMeshes[MeshIdx]; StudioVertex[] StudioVerts = new StudioVertex[Tris.GetVertexCount(BodyPartIdx, ModelIdx, 0, MeshIdx)]; Tris.GetVertices(BodyPartIdx, ModelIdx, 0, MeshIdx, StudioVerts); int[] Indices = new int[Tris.GetIndexCount(BodyPartIdx, ModelIdx, 0, MeshIdx)]; Tris.GetIndices(BodyPartIdx, ModelIdx, 0, MeshIdx, Indices); // Foam converted List <FoamVertex3> FoamVerts = new List <FoamVertex3>(StudioVerts.Select(V => { // TODO: CCW nVector2 UV = new nVector2(V.TexCoordX, V.TexCoordY); return(new FoamVertex3(Conv(V.Position), UV, nVector2.Zero, Conv(V.Normal), nVector3.Zero, FoamColor.White)); })); List <FoamBoneInfo> FoamInfo = new List <FoamBoneInfo>(StudioVerts.Select(V => { FoamBoneInfo Info = new FoamBoneInfo(); Info.Bone1 = V.BoneWeights.Bone0; Info.Bone2 = V.BoneWeights.Bone1; Info.Bone3 = V.BoneWeights.Bone1; Info.Weight1 = V.BoneWeights.Weight0; Info.Weight2 = V.BoneWeights.Weight1; Info.Weight3 = V.BoneWeights.Weight2; return(Info); })); List <ushort> FoamInds = new List <ushort>(Indices.Select(I => (ushort)I)); if (ConvertToCCW) { FoamInds.Reverse(); } FoamMeshes.Add(new FoamMesh(FoamVerts.ToArray(), FoamInds.ToArray(), FoamInfo.ToArray(), StudioModel.Name + ";" + MeshIdx, StudioMesh.Material)); /*List<FoamVertex3> Vts = new List<FoamVertex3>(); * for (int i = 0; i < Indices.Length; i++) { * ref StudioVertex V = ref StudioVerts[Indices[i]]; * Vts.Add(new Vertex3(new Vector3(V.Position.X, V.Position.Y, V.Position.Z), new Vector2(V.TexCoordX, 1.0f - V.TexCoordY), Color.White)); * }*/ /*string MatName = MaterialNames[StudioMesh.Material]; * Material Mat = Engine.GetMaterial(MatName); * * if (Mat == Engine.GetMaterial("error")) { * Mat = ValveMaterial.CreateMaterial(MatName); * * if (Mat != Engine.GetMaterial("error")) * Engine.RegisterMaterial(Mat); * } * * libTechMesh Msh = new libTechMesh(Vts.ToArray(), Mat); * Msh.Name = StudioModel.Name; * Model.AddMesh(Msh);*/ } }
private JToken GetMeshData(IResourceProvider provider, int bodyPart, int model, int lod) { var mdlPath = FilePath.Replace(".mesh", ".mdl"); var vvdPath = FilePath.Replace(".mesh", ".vvd"); var vtxPath = FilePath.Replace(".mesh", ".dx90.vtx"); StudioModelFile mdl; using (var mdlStream = provider.OpenFile(mdlPath)) { mdl = new StudioModelFile(mdlStream); } ValveVertexFile vvd; using (var vvdStream = provider.OpenFile(vvdPath)) { vvd = new ValveVertexFile(vvdStream); } const MeshComponent components = MeshComponent.Position | MeshComponent.Uv | MeshComponent.Rgb; ValveTriangleFile vtx; using (var vtxStream = provider.OpenFile(vtxPath)) { vtx = new ValveTriangleFile(vtxStream, mdl, vvd); } var array = new JArray(); var meshCount = vtx.GetMeshCount(bodyPart, model, lod); for (var i = 0; i < meshCount; ++i) { int indexOffset, indexCount, vertexOffset, vertexCount; vtx.GetMeshData(bodyPart, model, lod, i, out indexOffset, out indexCount, out vertexOffset, out vertexCount); array.Add(new JObject { { "type", (int)PrimitiveType.TriangleList }, { "material", mdl.GetMesh(bodyPart, model, i).Material }, { "indexOffset", indexOffset }, { "indexCount", indexCount }, { "vertexOffset", vertexOffset }, { "vertexCount", vertexCount } }); } var indexArray = new int[vtx.GetIndexCount(bodyPart, model, lod)]; vtx.GetIndices(bodyPart, model, lod, indexArray); var vertArray = new StudioVertex[vtx.GetVertexCount(bodyPart, model, lod)]; vtx.GetVertices(bodyPart, model, lod, vertArray); return(new JObject { { "components", (int)components }, { "elements", array }, { "vertices", SerializeArray(vertArray, GetVertSerializer(components), false) }, { "indices", SerializeArray(indexArray) } }); }
public GameObject GenerateMesh(BspToUnity bspToUnity, string modelName, string vvdPath, string vtxPath, IResourceProvider resourceProvider) { Mdl = StudioModelFile.FromProvider(modelName, resourceProvider); Vvd = ValveVertexFile.FromProvider(vvdPath, resourceProvider); Vtx = ValveTriangleFile.FromProvider(vtxPath, Mdl, Vvd, resourceProvider); var parent = new GameObject(); for (int b = 0; b < Mdl.BodyPartCount; b++) { var models = Mdl.GetModels(b); var e = models.GetEnumerator(); var modelIndex = 0; while (e.MoveNext()) { var model = e.Current; var meshes = Mdl.GetMeshes(ref model); var meshIndex = 0; foreach (var m in meshes) { try { var vertexCount = Vtx.GetVertexCount(b, modelIndex, 0, meshIndex); var sv = new StudioVertex[vertexCount]; var indexCount = Vtx.GetIndexCount(b, modelIndex, 0, meshIndex); var indices = new int[indexCount]; Vtx.GetVertices(b, modelIndex, 0, meshIndex, sv); Vtx.GetIndices(b, modelIndex, 0, meshIndex, indices); var go = new GameObject(); go.transform.SetParent(parent.transform); go.transform.localPosition = UnityEngine.Vector3.zero; go.transform.localRotation = Quaternion.identity; go.transform.localScale = UnityEngine.Vector3.one; var mr = go.AddComponent <MeshRenderer>(); var mf = go.AddComponent <MeshFilter>(); var modelMesh = new Mesh(); var vertices = new List <UnityEngine.Vector3>(); var normals = new List <UnityEngine.Vector3>(); var uvs = new List <UnityEngine.Vector2>(); var tris = new List <int>(); mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; mr.receiveShadows = false; // verts, normals, uvs for (int j = 0; j < sv.Length; j++) { vertices.Add(sv[j].Position.ToUVector() * bspToUnity.Options.WorldScale); normals.Add(sv[j].Normal.ToUVector()); uvs.Add(new UnityEngine.Vector2(sv[j].TexCoordX, sv[j].TexCoordY)); } // tris tris.AddRange(indices); // build mesh modelMesh.SetVertices(vertices); modelMesh.SetUVs(0, uvs); modelMesh.SetNormals(normals); modelMesh.SetTriangles(tris, 0); modelMesh.RecalculateNormals(); mf.mesh = modelMesh; var matName = Mdl.GetMaterialName(m.Material, resourceProvider); var mat = bspToUnity.ApplyMaterial(mr, matName); go.name = matName; } catch { Debug.Log("NOPE: " + Vtx.NumLods); continue; } meshIndex++; } modelIndex++; } } return(parent); }