private static void CreateDispSurface() { GameObject BSP_DispSurface = new GameObject(WorldController.MapName + "_disp"); Dictionary <int, List <int> > subMeshData = new Dictionary <int, List <int> >(); for (int i = 0; i < BSP_Faces.Count; i++) { if (!subMeshData.ContainsKey(BSP_Texdata[BSP_Texinfo[BSP_Faces[i].texinfo].texdata].nameStringTableID)) { subMeshData.Add(BSP_Texdata[BSP_Texinfo[BSP_Faces[i].texinfo].texdata].nameStringTableID, new List <int>()); } subMeshData[BSP_Texdata[BSP_Texinfo[BSP_Faces[i].texinfo].texdata].nameStringTableID].Add(i); } for (int i = 0; i < BSP_TexStrData.Count; i++) { if (!subMeshData.ContainsKey(i)) { continue; } List <Vector3> vertices = new List <Vector3>(); List <Vector2> uv = new List <Vector2>(); List <int> triangles = new List <int>(); for (int k = 0; k < subMeshData[i].Count; k++) { if (BSP_Faces[subMeshData[i][k]].dispinfo != -1) { face f = CreateDispSurface(BSP_Faces[subMeshData[i][k]].dispinfo); int pointOffset = vertices.Count; for (int j = 0; j < f.triangles.Length; j++) { triangles.Add(f.triangles[j] + pointOffset); } vertices.AddRange(f.points); uv.AddRange(f.uv); } } if (vertices.Count > 0) { GameObject submesh = new GameObject(BSP_TexStrData[i]); submesh.transform.localScale = new Vector3(1, 1, -1); submesh.transform.parent = BSP_DispSurface.transform; MeshRenderer meshRenderer = submesh.AddComponent <MeshRenderer>(); MeshFilter meshFilter = submesh.AddComponent <MeshFilter>(); WorldController.CurrentTexPath = WorldController.DefaultTexPath; if (BSP_TexStrData[i].Contains(WorldController.MapName)) { WorldController.CurrentTexPath = WorldController.PakTexPath; } meshRenderer.sharedMaterial = ValveTextureLoader.LoadMaterial(BSP_TexStrData[i]); meshFilter.sharedMesh = new Mesh(); meshFilter.sharedMesh.vertices = vertices.ToArray(); meshFilter.sharedMesh.triangles = triangles.ToArray(); meshFilter.sharedMesh.uv = uv.ToArray(); meshFilter.sharedMesh.RecalculateNormals(); meshFilter.sharedMesh.Optimize(); } } }
private static void ParseVtxFile() { List <BoneWeight> pBoneWeight = new List <BoneWeight>(); List <Vector3> pVertices = new List <Vector3>(); List <Vector3> pNormals = new List <Vector3>(); List <Vector2> pUvBuffer = new List <Vector2>(); // Load necessary information mstudiomodel_t pModel = MDL_Models[0]; mstudiomesh_t pStudioMesh; BodyPartHeader_t vBodypart = CRead.ReadType <BodyPartHeader_t>(VTX_Header.bodyPartOffset); int ModelInputFilePosition = VTX_Header.bodyPartOffset + vBodypart.modelOffset; ModelHeader_t vModel = CRead.ReadType <ModelHeader_t>(ModelInputFilePosition); int ModelLODInputFilePosition = ModelInputFilePosition + vModel.lodOffset; ModelLODHeader_t vLod = CRead.ReadType <ModelLODHeader_t>(ModelLODInputFilePosition); int MeshInputFilePosition = ModelLODInputFilePosition + vLod.meshOffset; VTX_Meshes.AddRange(CRead.ReadType <MeshHeader_t>(MeshInputFilePosition, vLod.numMeshes)); // Get bone weight's, vertices, normals, uv for (int i = 0; i < pModel.numvertices; i++) { pBoneWeight.Add(GetBoneWeight(VVD_Vertexes[pModel.vertexindex + i].m_BoneWeights)); pVertices.Add(WorldController.SwapZY(VVD_Vertexes[pModel.vertexindex + i].m_vecPosition * WorldController.WorldScale)); pNormals.Add(WorldController.SwapZY(VVD_Vertexes[pModel.vertexindex + i].m_vecNormal)); pUvBuffer.Add(VVD_Vertexes[pModel.vertexindex + i].m_vecTexCoord); } GameObject meshObject = new GameObject(new string(pModel.name)); meshObject.transform.parent = ModelObject.transform; SkinnedMeshRenderer smr = meshObject.AddComponent <SkinnedMeshRenderer>(); smr.materials = new Material[vLod.numMeshes]; // Calculate bindposes Matrix4x4[] bindPoses = new Matrix4x4[MDL_Bones.Count]; for (int i = 0; i < bindPoses.Length; i++) { MDL_Bones[i].localPosition = Vector3.zero; bindPoses[i] = MDL_Bones[i].worldToLocalMatrix * ModelObject.transform.localToWorldMatrix; } // Generate skin mesh smr.sharedMesh = new Mesh(); smr.sharedMesh.name = new string(pModel.name); smr.sharedMesh.subMeshCount = vLod.numMeshes; smr.sharedMesh.vertices = pVertices.ToArray(); smr.sharedMesh.normals = pNormals.ToArray(); smr.sharedMesh.uv = pUvBuffer.ToArray(); smr.sharedMesh.boneWeights = pBoneWeight.ToArray(); smr.sharedMesh.bindposes = bindPoses; smr.sharedMesh.Optimize(); smr.bones = MDL_Bones.ToArray(); smr.updateWhenOffscreen = true; for (int i = 0; i < vLod.numMeshes; i++) { List <int> pIndices = new List <int>(); List <StripGroupHeader_t> StripGroups = new List <StripGroupHeader_t>(); int StripGroupFilePosition = MeshInputFilePosition + (Marshal.SizeOf(typeof(MeshHeader_t)) * i) + VTX_Meshes[i].stripGroupHeaderOffset; StripGroups.AddRange(CRead.ReadType <StripGroupHeader_t>(StripGroupFilePosition, VTX_Meshes[i].numStripGroups)); pStudioMesh = MDL_Meshes[i]; // Get indices for model for (int l = 0; l < VTX_Meshes[i].numStripGroups; l++) { List <Vertex_t> pVertexBuffer = new List <Vertex_t>(); pVertexBuffer.AddRange(CRead.ReadType <Vertex_t>(StripGroupFilePosition + (Marshal.SizeOf(typeof(StripGroupHeader_t)) * l) + StripGroups[l].vertOffset, StripGroups[l].numVerts)); List <ushort> Indices = new List <ushort>(); Indices.AddRange(CRead.ReadType <ushort>(StripGroupFilePosition + (Marshal.SizeOf(typeof(StripGroupHeader_t)) * l) + StripGroups[l].indexOffset, StripGroups[l].numIndices)); for (int n = 0; n < Indices.Count; n++) { pIndices.Add(pVertexBuffer[Indices[n]].origMeshVertID + pStudioMesh.vertexoffset); } } smr.sharedMesh.SetTriangles(pIndices.ToArray(), i); smr.materials[i].name = MDL_Textures[pStudioMesh.material]; string pathToTex = null; Material material = null; // Find path to mesh material for (int l = 0; l < MDL_TDirectories.Count; l++) { if (File.Exists(WorldController.DefaultTexPath + MDL_TDirectories[l] + MDL_Textures[pStudioMesh.material] + ".vmt")) { pathToTex = WorldController.DefaultTexPath + MDL_TDirectories[l] + MDL_Textures[pStudioMesh.material] + ".vmt"; } } if (pathToTex != null) { material = ValveTextureLoader.LoadMaterial(pathToTex.Replace(WorldController.DefaultTexPath, "")); } // Apply loaded material to mesh if (material != null) { smr.materials[i].CopyPropertiesFromMaterial(material); smr.materials[i].shader = material.shader; } } }
private static void CreateModel(int index) { Dictionary <int, List <int> > subMeshData = new Dictionary <int, List <int> >(); GameObject model = new GameObject("*" + index); model.transform.parent = BSP_WorldSpawn.transform; int firstFace = BSP_Models[index].firstface; int faces = BSP_Models[index].numfaces; for (int i = firstFace; i < firstFace + faces; i++) { if (!subMeshData.ContainsKey(BSP_Texdata[BSP_Texinfo[BSP_Faces[i].texinfo].texdata].nameStringTableID)) { subMeshData.Add(BSP_Texdata[BSP_Texinfo[BSP_Faces[i].texinfo].texdata].nameStringTableID, new List <int>()); } subMeshData[BSP_Texdata[BSP_Texinfo[BSP_Faces[i].texinfo].texdata].nameStringTableID].Add(i); } for (int i = 0; i < BSP_TexStrData.Count; i++) { if (!subMeshData.ContainsKey(i)) { continue; } List <Vector3> vertices = new List <Vector3>(); List <Vector2> uv = new List <Vector2>(); List <int> triangles = new List <int>(); List <face> faceList = new List <face>(); for (int k = 0; k < subMeshData[i].Count; k++) { // Get points, indices, UV's if (BSP_Faces[subMeshData[i][k]].dispinfo == -1) { face f = CreateFace(subMeshData[i][k]); int pointOffset = vertices.Count; for (int j = 0; j < f.triangles.Length; j++) { triangles.Add(f.triangles[j] + pointOffset); } vertices.AddRange(f.points); uv.AddRange(f.uv); faceList.Add(f); } } GameObject submesh = new GameObject(BSP_TexStrData[i]); submesh.transform.parent = model.transform; MeshRenderer meshRenderer = submesh.AddComponent <MeshRenderer>(); MeshFilter meshFilter = submesh.AddComponent <MeshFilter>(); List <Vector2> uv2 = new List <Vector2>(); Texture2D lightMap = new Texture2D(0, 0); // Load lightmaps and generate atlas CreateLightMap(faceList, ref lightMap, ref uv2); WorldController.CurrentTexPath = WorldController.DefaultTexPath; if (BSP_TexStrData[i].Contains(WorldController.MapName)) { WorldController.CurrentTexPath = WorldController.PakTexPath; } // Load material for this object meshRenderer.sharedMaterial = ValveTextureLoader.LoadMaterial(BSP_TexStrData[i]); meshRenderer.sharedMaterial.SetTexture("_LightMap", lightMap); if (BSP_TexStrData[i].Contains("TOOLS/")) { meshRenderer.enabled = false; } // Generate submesh meshFilter.sharedMesh = new Mesh(); meshFilter.sharedMesh.vertices = vertices.ToArray(); meshFilter.sharedMesh.triangles = triangles.ToArray(); meshFilter.sharedMesh.uv = uv.ToArray(); meshFilter.sharedMesh.uv2 = uv2.ToArray(); meshFilter.sharedMesh.RecalculateNormals(); meshFilter.sharedMesh.Optimize(); } }