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 GetIndex(IResourceProvider provider, string filePath, string mapName = null) { StudioModelFile mdl; using (var mdlStream = provider.OpenFile(filePath)) { mdl = new StudioModelFile(mdlStream); } var parts = new JArray(); for (var bodyPartIndex = 0; bodyPartIndex < mdl.BodyPartCount; ++bodyPartIndex) { var models = new JArray(); var modelIndex = 0; foreach (var model in mdl.GetModels(bodyPartIndex)) { var meshes = new JArray(); foreach (var mesh in mdl.GetMeshes(model.MeshIndex, model.NumMeshes)) { meshes.Add(new JObject { { "material", mesh.Material }, { "center", mesh.Center.ToJson() } }); } var meshDataAction = mapName == null?nameof(GetVpkMeshData) : nameof(GetPakMeshData); models.Add(new JObject { { "name", model.Name }, { "radius", model.BoundingRadius }, { "meshDataUrl", GetActionUrl(meshDataAction, ResourcePath(filePath), Replace("mapName", mapName), Replace("bodyPart", bodyPartIndex), Replace("model", modelIndex), Replace("lod", 0)) }, { "meshes", meshes } }); ++modelIndex; } parts.Add(new JObject { { "name", mdl.GetBodyPartName(bodyPartIndex) }, { "models", models } }); } var materials = new JArray(); for (var i = 0; i < mdl.NumTextures; ++i) { var vmtPath = provider is ValveBspFile.PakFileLump ? mdl.GetMaterialName(i, provider, Resources) : mdl.GetMaterialName(i, provider); if (!vmtPath.Contains("/")) { var mdlDir = Path.GetDirectoryName(filePath); vmtPath = Path.Combine(mdlDir, vmtPath).Replace('\\', '/'); } var vmt = mapName == null ? VmtUtils.OpenVmt(vmtPath) : VmtUtils.OpenVmt(BspController.GetBspFile(Request, mapName), vmtPath); materials.Add(vmt == null ? null : VmtUtils.SerializeVmt(Request, vmt, vmtPath)); } return(new JObject { { "materials", materials }, { "bodyParts", parts } }); }
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); }