private void Start() { if (definitions == null) { List<Mesh> meshes = GetMeshes(transform); definitions = new FoxMeshDefinition[meshes.Count]; for(int i = 0; i < meshes.Count; i++) { definitions[i] = new FoxMeshDefinition(); definitions[i].mesh = meshes[i]; definitions[i].meshGroup = meshes[i].name.Substring(4); definitions[i].material = "fox_3ddf_skin_tension_dirty"; definitions[i].materialType = "fox3DDF_Skin_Tension_Dirty"; } //for } //if } //Start
public GameObject GetDataFromFmdl(OldFmdl fmdl) { meshes = new UnityMesh[fmdl.section0Block3Entries.Count]; GameObject fmdlGameObject = new GameObject(); fmdlGameObject.name = fmdl.name; GameObject[] subFmdlGameObjects = new GameObject[fmdl.objects.Count]; Transform[] bones; //Matrix4x4[] bindPoses; Bounds[] bounds = new Bounds[fmdl.section0BlockDEntries.Count]; FoxModel foxModel = fmdlGameObject.AddComponent<FoxModel>(); foxModel.meshGroups = new FoxMeshGroup[fmdl.section0Block1Entries.Count]; foxModel.meshDefinitions = new FoxMeshDefinition[fmdl.objects.Count]; Material[] materials = new Material[fmdl.section0Block4Entries.Count]; if (fmdl.bonesIndex != -1) { bones = new Transform[fmdl.section0Block0Entries.Count]; //bindPoses = new Matrix4x4[fmdl.section0Block0Entries.Count]; } //if else { bones = new Transform[0]; //bindPoses = new Matrix4x4[0]; } //else //Mesh Groups for (int i = 0; i < fmdl.section0Block1Entries.Count; i++) { FoxMeshGroup foxMeshGroup = new FoxMeshGroup(); if (fmdl.stringsIndex != -1) foxMeshGroup.name = fmdl.strings[fmdl.section0Block1Entries[i].stringId]; else foxMeshGroup.name = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block1Entries[i].stringId]); foxMeshGroup.parent = (short)fmdl.section0Block1Entries[i].parentId; if (fmdl.section0Block1Entries[i].invisibilityFlag == 0) foxMeshGroup.visible = true; else foxMeshGroup.visible = false; foxModel.meshGroups[i] = foxMeshGroup; } //for //Materials for (int i = 0; i < fmdl.section0Block4Entries.Count; i++) { if (fmdl.stringsIndex != -1) materials[i] = new Material(Shader.Find($"FoxShaders/{fmdl.strings[fmdl.section0Block8Entries[fmdl.section0Block4Entries[i].materialId].typeId]}")); else materials[i] = new Material(Shader.Find($"FoxShaders/{Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block8Entries[fmdl.section0Block4Entries[i].materialId].typeId])}")); //materials[i].material = new Material(Shader.Find("Legacy Shaders/Transparent/Cutout/Bumped Diffuse")); //materials[i].material = new Material(Shader.Find("Standard")); if (fmdl.stringsIndex != -1) { materials[i].name = fmdl.strings[fmdl.section0Block4Entries[i].stringId]; for (int j = fmdl.section0Block4Entries[i].firstTextureId; j < fmdl.section0Block4Entries[i].firstTextureId + fmdl.section0Block4Entries[i].numTextures; j++) { string textureName = ""; string textureType = fmdl.strings[fmdl.section0Block7Entries[j].stringId]; int extensionLocation; textureName = fmdl.strings[fmdl.section0Block6Entries[fmdl.section0Block7Entries[j].referenceId].pathId] + fmdl.strings[fmdl.section0Block6Entries[fmdl.section0Block7Entries[j].referenceId].stringId]; //materials[i].textureType = fmdl.strings[fmdl.section0Block7Entries[fmdl.section0Block4Entries[i].firstTextureId].stringId]; extensionLocation = textureName.IndexOf('.'); textureName = textureName.Substring(0, extensionLocation); if (File.Exists(Globals.texturePath + "\\" + textureName + ".dds")) { Texture2D texture = LoadTextureDXT(Globals.texturePath + "\\" + textureName + ".dds"); texture.name = textureName + ".dds"; materials[i].SetTexture(textureType, texture); } //if else { Debug.Log("Could not find: " + Globals.texturePath + "\\" + textureName + ".dds"); } //else } //for for (int j = fmdl.section0Block4Entries[i].firstParameterId; j < fmdl.section0Block4Entries[i].firstParameterId + fmdl.section0Block4Entries[i].numParameters; j++) materials[i].SetVector(fmdl.strings[fmdl.section0Block7Entries[j].stringId], new Vector4(fmdl.materialParameters[fmdl.section0Block7Entries[j].referenceId].values.x, fmdl.materialParameters[fmdl.section0Block7Entries[j].referenceId].values.y, fmdl.materialParameters[fmdl.section0Block7Entries[j].referenceId].values.z, fmdl.materialParameters[fmdl.section0Block7Entries[j].referenceId].values.w)); } //if else { materials[i].name = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block4Entries[i].stringId]); if (fmdl.texturePathsIndex != -1) { for (int j = fmdl.section0Block4Entries[i].firstTextureId; j < fmdl.section0Block4Entries[i].firstTextureId + fmdl.section0Block4Entries[i].numTextures; j++) { string textureName = Hashing.TryGetPathName(fmdl.section0Block15Entries[fmdl.section0Block7Entries[j].referenceId]); string textureType = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block7Entries[j].stringId]); if (File.Exists(Globals.texturePath + "\\" + textureName + ".dds")) { Texture2D texture = LoadTextureDXT(Globals.texturePath + "\\" + textureName + ".dds"); texture.name = textureName + ".dds"; materials[i].SetTexture(textureType, texture); } //if else { Debug.Log("Could not find: " + Globals.texturePath + "\\" + textureName + ".dds"); } //else } //for } //if for (int j = fmdl.section0Block4Entries[i].firstParameterId; j < fmdl.section0Block4Entries[i].firstParameterId + fmdl.section0Block4Entries[i].numParameters; j++) materials[i].SetVector(Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block7Entries[j].stringId]), new Vector4(fmdl.materialParameters[fmdl.section0Block7Entries[j].referenceId].values[0], fmdl.materialParameters[fmdl.section0Block7Entries[j].referenceId].values[1], fmdl.materialParameters[fmdl.section0Block7Entries[j].referenceId].values[2], fmdl.materialParameters[fmdl.section0Block7Entries[j].referenceId].values[3])); } //else //Have to flip textures here because Texture2D.LoadRawData is bugged an imports DDS files upside down. for (int j = 0; j < ShaderUtil.GetPropertyCount(materials[i].shader); j++) if (ShaderUtil.GetPropertyType(materials[i].shader, j) == ShaderUtil.ShaderPropertyType.TexEnv) materials[i].SetTextureScale(ShaderUtil.GetPropertyName(materials[i].shader, j), new Vector2(1, -1)); } //for for (int i = 0; i < bounds.Length; i++) { bounds[i].SetMinMax(new Vector3(-fmdl.section0BlockDEntries[i].minX, fmdl.section0BlockDEntries[i].minY, fmdl.section0BlockDEntries[i].minZ), new Vector3(-fmdl.section0BlockDEntries[i].maxX, fmdl.section0BlockDEntries[i].maxY, fmdl.section0BlockDEntries[i].maxZ)); } //for Transform rootBone = new GameObject("[Root]").transform; //From what I can tell, the real name is "". But it looks kinda dumb having "" as its name; so using "[Root]" as a placeholder seems better. rootBone.parent = fmdlGameObject.transform; { BoxCollider collider = rootBone.gameObject.AddComponent<BoxCollider>(); collider.center = rootBone.InverseTransformPoint(bounds[0].center); //Have to convert these to local positions. They're stored as world positions. collider.size = bounds[0].size; } //code block for (int i = 0; i < bones.Length; i++) { bones[i] = new GameObject().transform; bones[i].position = new Vector3(-fmdl.section0Block0Entries[i].worldPositionX, fmdl.section0Block0Entries[i].worldPositionY, fmdl.section0Block0Entries[i].worldPositionZ); BoxCollider collider = bones[i].gameObject.AddComponent<BoxCollider>(); collider.center = bones[i].InverseTransformPoint(bounds[fmdl.section0Block0Entries[i].boundingBoxId].center); //Have to convert these to local positions. They're stored as world positions. collider.size = bounds[fmdl.section0Block0Entries[i].boundingBoxId].size; if (fmdl.stringsIndex != -1) bones[i].name = fmdl.strings[fmdl.section0Block0Entries[i].stringId]; else bones[i].name = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block0Entries[i].stringId]); if (fmdl.section0Block0Entries[i].parentId != 0xFFFF) bones[i].parent = bones[fmdl.section0Block0Entries[i].parentId]; else bones[i].parent = rootBone; } //for for (int i = 0; i < fmdl.objects.Count; i++) { int lod = 0; //Temporary solution. 0 loads the normal faces. 1 loads the first set of LOD faces. 2 loads the next set. Etc.... meshes[i].vertices = new Vector3[fmdl.objects[i].vertices.Length]; meshes[i].normals = new Vector3[fmdl.objects[i].additionalVertexData.Length]; meshes[i].tangents = new Vector4[fmdl.objects[i].additionalVertexData.Length]; meshes[i].colour = new Color[fmdl.objects[i].additionalVertexData.Length]; meshes[i].uv = new Vector2[fmdl.objects[i].additionalVertexData.Length]; meshes[i].uv2 = new Vector2[fmdl.objects[i].additionalVertexData.Length]; meshes[i].uv3 = new Vector2[fmdl.objects[i].additionalVertexData.Length]; meshes[i].uv4 = new Vector2[fmdl.objects[i].additionalVertexData.Length]; //meshes[i].faces = new int[fmdl.objects[i].faces.Length * 3]; meshes[i].faces = new int[fmdl.objects[i].lodFaces[lod].Length * 3]; meshes[i].boneWeights = new BoneWeight[fmdl.objects[i].additionalVertexData.Length]; //Position for (int j = 0; j < fmdl.objects[i].vertices.Length; j++) meshes[i].vertices[j] = new Vector3(-fmdl.objects[i].vertices[j].x, fmdl.objects[i].vertices[j].y, fmdl.objects[i].vertices[j].z); //Normals, Bone Weights, Bone Group Ids and UVs for (int j = 0; j < fmdl.objects[i].additionalVertexData.Length; j++) { meshes[i].normals[j] = new Vector3(-fmdl.objects[i].additionalVertexData[j].normalX, fmdl.objects[i].additionalVertexData[j].normalY, fmdl.objects[i].additionalVertexData[j].normalZ); meshes[i].tangents[j] = new Vector4(-fmdl.objects[i].additionalVertexData[j].tangentX, fmdl.objects[i].additionalVertexData[j].tangentY, fmdl.objects[i].additionalVertexData[j].tangentZ, fmdl.objects[i].additionalVertexData[j].tangentW); meshes[i].colour[j] = new Color(fmdl.objects[i].additionalVertexData[j].colourR, fmdl.objects[i].additionalVertexData[j].colourG, fmdl.objects[i].additionalVertexData[j].colourB, fmdl.objects[i].additionalVertexData[j].colourA); if (fmdl.bonesIndex != -1) { meshes[i].boneWeights[j].weight0 = fmdl.objects[i].additionalVertexData[j].boneWeightX; meshes[i].boneWeights[j].weight1 = fmdl.objects[i].additionalVertexData[j].boneWeightY; meshes[i].boneWeights[j].weight2 = fmdl.objects[i].additionalVertexData[j].boneWeightZ; meshes[i].boneWeights[j].weight3 = fmdl.objects[i].additionalVertexData[j].boneWeightW; meshes[i].boneWeights[j].boneIndex0 = fmdl.section0Block5Entries[fmdl.section0Block3Entries[i].boneGroupId].entries[fmdl.objects[i].additionalVertexData[j].boneGroup0Id]; meshes[i].boneWeights[j].boneIndex1 = fmdl.section0Block5Entries[fmdl.section0Block3Entries[i].boneGroupId].entries[fmdl.objects[i].additionalVertexData[j].boneGroup1Id]; meshes[i].boneWeights[j].boneIndex2 = fmdl.section0Block5Entries[fmdl.section0Block3Entries[i].boneGroupId].entries[fmdl.objects[i].additionalVertexData[j].boneGroup2Id]; meshes[i].boneWeights[j].boneIndex3 = fmdl.section0Block5Entries[fmdl.section0Block3Entries[i].boneGroupId].entries[fmdl.objects[i].additionalVertexData[j].boneGroup3Id]; } //if meshes[i].uv[j] = new Vector2(fmdl.objects[i].additionalVertexData[j].textureU, -fmdl.objects[i].additionalVertexData[j].textureV); meshes[i].uv2[j] = new Vector2(fmdl.objects[i].additionalVertexData[j].unknownU0, -fmdl.objects[i].additionalVertexData[j].unknownV0); meshes[i].uv3[j] = new Vector2(fmdl.objects[i].additionalVertexData[j].unknownU1, -fmdl.objects[i].additionalVertexData[j].unknownV1); meshes[i].uv4[j] = new Vector2(fmdl.objects[i].additionalVertexData[j].unknownU2, -fmdl.objects[i].additionalVertexData[j].unknownV2); } //for //Faces /*for (int j = 0, h = 0; j < fmdl.objects[i].faces.Length; j++, h += 3) { meshes[i].faces[h] = fmdl.objects[i].faces[j].vertex1Id; meshes[i].faces[h + 1] = fmdl.objects[i].faces[j].vertex2Id; meshes[i].faces[h + 2] = fmdl.objects[i].faces[j].vertex3Id; } //for*/ for (int j = 0, h = 0; j < fmdl.objects[i].lodFaces[lod].Length; j++, h += 3) { meshes[i].faces[h] = fmdl.objects[i].lodFaces[lod][j].vertex1Id; meshes[i].faces[h + 1] = fmdl.objects[i].lodFaces[lod][j].vertex2Id; meshes[i].faces[h + 2] = fmdl.objects[i].lodFaces[lod][j].vertex3Id; } //for //Render the mesh in Unity. subFmdlGameObjects[i] = new GameObject(); FoxMeshDefinition foxMeshDefinition = new FoxMeshDefinition(); foxMeshDefinition.alpha = (FoxMeshDefinition.Alpha)fmdl.section0Block3Entries[i].alphaEnum; foxMeshDefinition.shadow = (FoxMeshDefinition.Shadow)fmdl.section0Block3Entries[i].shadowEnum; //Get the mesh name. for (int j = 0; j < fmdl.section0Block2Entries.Count; j++) { if (i >= fmdl.section0Block2Entries[j].firstObjectId && i < fmdl.section0Block2Entries[j].firstObjectId + fmdl.section0Block2Entries[j].numObjects) { if (fmdl.stringsIndex != -1) subFmdlGameObjects[i].name = i + " - " + fmdl.strings[fmdl.section0Block1Entries[fmdl.section0Block2Entries[j].meshGroupId].stringId]; else subFmdlGameObjects[i].name = i + " - " + Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block1Entries[fmdl.section0Block2Entries[j].meshGroupId].stringId]); foxMeshDefinition.meshGroup = fmdl.section0Block2Entries[j].meshGroupId; break; } //if } //for subFmdlGameObjects[i].transform.parent = fmdlGameObject.transform; SkinnedMeshRenderer meshRenderer = subFmdlGameObjects[i].AddComponent<SkinnedMeshRenderer>(); meshRenderer.sharedMaterial = materials[fmdl.section0Block3Entries[i].materialInstanceId]; Mesh mesh = new Mesh(); mesh.vertices = meshes[i].vertices; mesh.uv = meshes[i].uv; mesh.uv2 = meshes[i].uv2; mesh.uv3 = meshes[i].uv3; mesh.uv4 = meshes[i].uv4; mesh.normals = meshes[i].normals; mesh.tangents = meshes[i].tangents; mesh.triangles = meshes[i].faces; mesh.boneWeights = meshes[i].boneWeights; //Sets up the model to only use weighted bones. Transform[] boneArray = bones; List<Transform> usedBones = new List<Transform>(0); BoneWeight[] weightArray = meshes[i].boneWeights; int boneCount = boneArray.Length; int weightCount = weightArray.Length; for (int j = 0; j < boneCount; j++) { bool found = false; for (int h = 0; h < weightCount; h++) { if (weightArray[h].boneIndex0 == j) { found = true; if (!usedBones.Contains(boneArray[j])) weightArray[h].boneIndex0 = usedBones.Count; else weightArray[h].boneIndex0 = usedBones.IndexOf(boneArray[j]); } //if if (weightArray[h].boneIndex1 == j) { found = true; if (!usedBones.Contains(boneArray[j])) weightArray[h].boneIndex1 = usedBones.Count; else weightArray[h].boneIndex1 = usedBones.IndexOf(boneArray[j]); } //if if (weightArray[h].boneIndex2 == j) { found = true; if (!usedBones.Contains(boneArray[j])) weightArray[h].boneIndex2 = usedBones.Count; else weightArray[h].boneIndex2 = usedBones.IndexOf(boneArray[j]); } //if if (weightArray[h].boneIndex3 == j) { found = true; if (!usedBones.Contains(boneArray[j])) weightArray[h].boneIndex3 = usedBones.Count; else weightArray[h].boneIndex3 = usedBones.IndexOf(boneArray[j]); } //if } //for if (found) if (!usedBones.Contains(boneArray[j])) usedBones.Add(boneArray[j]); } //for mesh.boneWeights = weightArray; meshRenderer.bones = usedBones.ToArray(); boneCount = usedBones.Count; List<Matrix4x4> bindPoses = new List<Matrix4x4>(0); for (int j = 0; j < boneCount; j++) { bindPoses.Add(usedBones[j].worldToLocalMatrix * subFmdlGameObjects[i].transform.localToWorldMatrix); } //for mesh.bindposes = bindPoses.ToArray(); meshRenderer.sharedMesh = mesh; foxMeshDefinition.mesh = meshRenderer.sharedMesh; foxModel.meshDefinitions[i] = foxMeshDefinition; subFmdlGameObjects[i].AddComponent<MeshCollider>(); } //for return fmdlGameObject; } //GetDataFromFmdl
public GameObject GetDataFromFmdl(Fmdl fmdl) { Globals.ReadTexturePath(); meshes = new UnityMesh[fmdl.section0Block3Entries.Count]; GameObject fmdlGameObject = new GameObject(); fmdlGameObject.name = fmdl.name; GameObject[] subFmdlGameObjects = new GameObject[fmdl.objects.Count]; Transform[] bones; Matrix4x4[] bindPoses; Bounds[] bounds = new Bounds[fmdl.section0BlockDEntries.Count]; fmdlGameObject.AddComponent <FoxModel>().definitions = new FoxMeshDefinition[fmdl.objects.Count]; UnityMaterial[] materials = new UnityMaterial[fmdl.section0Block4Entries.Count]; if (fmdl.bonesIndex != -1) { bones = new Transform[fmdl.section0Block0Entries.Count]; bindPoses = new Matrix4x4[fmdl.section0Block0Entries.Count]; } //if else { bones = new Transform[0]; bindPoses = new Matrix4x4[0]; } //else for (int i = 0; i < fmdl.section0Block4Entries.Count; i++) { materials[i].material = new Material(Shader.Find("FoxShaders/Base")); //materials[i].material = new Material(Shader.Find("Legacy Shaders/Transparent/Cutout/Bumped Diffuse")); //materials[i].material = new Material(Shader.Find("Standard")); if (fmdl.stringsIndex != -1) { materials[i].material.name = fmdl.strings[fmdl.section0Block4Entries[i].stringId]; materials[i].materialName = fmdl.strings[fmdl.section0Block8Entries[fmdl.section0Block4Entries[i].materialId].stringId]; materials[i].materialType = fmdl.strings[fmdl.section0Block8Entries[fmdl.section0Block4Entries[i].materialId].typeId]; for (int j = fmdl.section0Block4Entries[i].firstTextureId; j < fmdl.section0Block4Entries[i].firstTextureId + fmdl.section0Block4Entries[i].numTextures; j++) { string textureName = ""; int extensionLocation; textureName = fmdl.strings[fmdl.section0Block6Entries[fmdl.section0Block7Entries[j].referenceId].pathId] + fmdl.strings[fmdl.section0Block6Entries[fmdl.section0Block7Entries[j].referenceId].stringId]; //materials[i].textureType = fmdl.strings[fmdl.section0Block7Entries[fmdl.section0Block4Entries[i].firstTextureId].stringId]; extensionLocation = textureName.IndexOf('.'); textureName = textureName.Substring(0, extensionLocation); if (File.Exists(Globals.texturePath + "\\" + textureName + ".dds")) { Texture2D texture = LoadTextureDXT(Globals.texturePath + "\\" + textureName + ".dds"); texture.name = textureName + ".dds"; if (fmdl.strings[fmdl.section0Block7Entries[j].stringId] == "Base_Tex_SRGB") { materials[i].material.mainTexture = texture; } else if (fmdl.strings[fmdl.section0Block7Entries[j].stringId] == "NormalMap_Tex_NRM") { materials[i].material.SetTexture("_BumpMap", texture); } else if (fmdl.strings[fmdl.section0Block7Entries[j].stringId] == "SpecularMap_Tex_LIN") { materials[i].material.SetTexture("_SRM", texture); } else if (fmdl.strings[fmdl.section0Block7Entries[j].stringId] == "Layer_Tex_SRGB") { materials[i].material.SetTexture("_LayerTex", texture); } else if (fmdl.strings[fmdl.section0Block7Entries[j].stringId] == "LayerMask_Tex_LIN") { materials[i].material.SetTexture("_LayerMask", texture); } //_MainTex = Diffuse. _BumpMap = Normal Map. _Color = Main Colour. _SpecColor = Specular Map. _Shininess. } //if else { UnityEngine.Debug.Log("Could not find: " + Globals.texturePath + "\\" + textureName + ".dds"); } //else } //for } //if else { materials[i].material.name = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block4Entries[i].stringId]); materials[i].materialName = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block8Entries[fmdl.section0Block4Entries[i].materialId].stringId]); materials[i].materialType = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block8Entries[fmdl.section0Block4Entries[i].materialId].typeId]); if (fmdl.texturePathsIndex != -1) { for (int j = fmdl.section0Block4Entries[i].firstTextureId; j < fmdl.section0Block4Entries[i].firstTextureId + fmdl.section0Block4Entries[i].numTextures; j++) { if (File.Exists(Globals.texturePath + "\\" + Hashing.TryGetPathName(fmdl.section0Block15Entries[fmdl.section0Block7Entries[j].referenceId]) + ".dds")) { Texture2D texture = LoadTextureDXT(Globals.texturePath + "\\" + Hashing.TryGetPathName(fmdl.section0Block15Entries[fmdl.section0Block7Entries[j].referenceId]) + ".dds"); texture.name = Hashing.TryGetPathName(fmdl.section0Block15Entries[fmdl.section0Block7Entries[j].referenceId]) + ".dds"; //materials[i].textureType = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block7Entries[fmdl.section0Block4Entries[i].firstTextureId].stringId]); if (Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block7Entries[j].stringId]) == "Base_Tex_SRGB") { materials[i].material.mainTexture = texture; } else if (Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block7Entries[j].stringId]) == "NormalMap_Tex_NRM") { materials[i].material.SetTexture("_BumpMap", texture); } else if (Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block7Entries[j].stringId]) == "SpecularMap_Tex_LIN") { materials[i].material.SetTexture("_SRM", texture); } else if (Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block7Entries[j].stringId]) == "Layer_Tex_SRGB") { materials[i].material.SetTexture("_LayerTex", texture); } else if (Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block7Entries[j].stringId]) == "LayerMask_Tex_LIN") { materials[i].material.SetTexture("_LayerMask", texture); } } //if else { UnityEngine.Debug.Log("Could not find: " + Globals.texturePath + "\\" + Hashing.TryGetPathName(fmdl.section0Block15Entries[fmdl.section0Block7Entries[j].referenceId]) + ".dds"); } //else } //for } //if } //else } //for for (int i = 0; i < bounds.Length; i++) { bounds[i].SetMinMax(new Vector3(fmdl.section0BlockDEntries[i].minZ, fmdl.section0BlockDEntries[i].minY, fmdl.section0BlockDEntries[i].minX), new Vector3(fmdl.section0BlockDEntries[i].maxZ, fmdl.section0BlockDEntries[i].maxY, fmdl.section0BlockDEntries[i].maxX)); } //for Transform rootBone = new GameObject("[Root]").transform; //From what I can tell, the real name is "". But it looks kinda dumb having "" as its name; so using "[Root]" as a placeholder seems better. rootBone.parent = fmdlGameObject.transform; { BoxCollider collider = rootBone.gameObject.AddComponent <BoxCollider>(); collider.center = rootBone.InverseTransformPoint(bounds[0].center); //Have to convert these to local positions. They're stored as world positions. collider.size = bounds[0].size; } //code block for (int i = 0; i < bones.Length; i++) { bones[i] = new GameObject().transform; bones[i].position = new Vector3(fmdl.section0Block0Entries[i].worldPositionZ, fmdl.section0Block0Entries[i].worldPositionY, fmdl.section0Block0Entries[i].worldPositionX); BoxCollider collider = bones[i].gameObject.AddComponent <BoxCollider>(); collider.center = bones[i].InverseTransformPoint(bounds[fmdl.section0Block0Entries[i].boundingBoxId].center); //Have to convert these to local positions. They're stored as world positions. collider.size = bounds[fmdl.section0Block0Entries[i].boundingBoxId].size; if (fmdl.stringsIndex != -1) { bones[i].name = fmdl.strings[fmdl.section0Block0Entries[i].stringId]; } else { bones[i].name = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block0Entries[i].stringId]); } if (fmdl.section0Block0Entries[i].parentId != 0xFFFF) { bones[i].parent = bones[fmdl.section0Block0Entries[i].parentId]; } else { bones[i].parent = rootBone; } } //for for (int i = 0; i < fmdl.objects.Count; i++) { int lod = 0; //Temporary solution. 0 loads the normal faces. 1 loads the first set of LOD faces. 2 loads the next set. Etc.... meshes[i].vertices = new Vector3[fmdl.objects[i].vertices.Length]; meshes[i].normals = new Vector3[fmdl.objects[i].additionalVertexData.Length]; meshes[i].tangents = new Vector4[fmdl.objects[i].additionalVertexData.Length]; meshes[i].colour = new Color[fmdl.objects[i].additionalVertexData.Length]; meshes[i].uv = new Vector2[fmdl.objects[i].additionalVertexData.Length]; meshes[i].uv2 = new Vector2[fmdl.objects[i].additionalVertexData.Length]; meshes[i].uv3 = new Vector2[fmdl.objects[i].additionalVertexData.Length]; meshes[i].uv4 = new Vector2[fmdl.objects[i].additionalVertexData.Length]; //meshes[i].faces = new int[fmdl.objects[i].faces.Length * 3]; meshes[i].faces = new int[fmdl.objects[i].lodFaces[lod].Length * 3]; meshes[i].boneWeights = new BoneWeight[fmdl.objects[i].additionalVertexData.Length]; //Position for (int j = 0; j < fmdl.objects[i].vertices.Length; j++) { meshes[i].vertices[j] = new Vector3(fmdl.objects[i].vertices[j].z, fmdl.objects[i].vertices[j].y, fmdl.objects[i].vertices[j].x); } //Normals, Bone Weights, Bone Group Ids and UVs for (int j = 0; j < fmdl.objects[i].additionalVertexData.Length; j++) { meshes[i].normals[j] = new Vector3(fmdl.objects[i].additionalVertexData[j].normalZ, fmdl.objects[i].additionalVertexData[j].normalY, fmdl.objects[i].additionalVertexData[j].normalX); meshes[i].tangents[j] = new Vector4(fmdl.objects[i].additionalVertexData[j].tangentZ, fmdl.objects[i].additionalVertexData[j].tangentY, fmdl.objects[i].additionalVertexData[j].tangentX, fmdl.objects[i].additionalVertexData[j].tangentW); meshes[i].colour[j] = new Color(fmdl.objects[i].additionalVertexData[j].colourR, fmdl.objects[i].additionalVertexData[j].colourG, fmdl.objects[i].additionalVertexData[j].colourB, fmdl.objects[i].additionalVertexData[j].colourA); if (fmdl.bonesIndex != -1) { meshes[i].boneWeights[j].weight0 = fmdl.objects[i].additionalVertexData[j].boneWeightX; meshes[i].boneWeights[j].weight1 = fmdl.objects[i].additionalVertexData[j].boneWeightY; meshes[i].boneWeights[j].weight2 = fmdl.objects[i].additionalVertexData[j].boneWeightZ; meshes[i].boneWeights[j].weight3 = fmdl.objects[i].additionalVertexData[j].boneWeightW; meshes[i].boneWeights[j].boneIndex0 = fmdl.section0Block5Entries[fmdl.section0Block3Entries[i].boneGroupId].entries[fmdl.objects[i].additionalVertexData[j].boneGroup0Id]; meshes[i].boneWeights[j].boneIndex1 = fmdl.section0Block5Entries[fmdl.section0Block3Entries[i].boneGroupId].entries[fmdl.objects[i].additionalVertexData[j].boneGroup1Id]; meshes[i].boneWeights[j].boneIndex2 = fmdl.section0Block5Entries[fmdl.section0Block3Entries[i].boneGroupId].entries[fmdl.objects[i].additionalVertexData[j].boneGroup2Id]; meshes[i].boneWeights[j].boneIndex3 = fmdl.section0Block5Entries[fmdl.section0Block3Entries[i].boneGroupId].entries[fmdl.objects[i].additionalVertexData[j].boneGroup3Id]; } //if meshes[i].uv[j] = new Vector2(fmdl.objects[i].additionalVertexData[j].textureU, fmdl.objects[i].additionalVertexData[j].textureV); meshes[i].uv2[j] = new Vector2(fmdl.objects[i].additionalVertexData[j].unknownU0, fmdl.objects[i].additionalVertexData[j].unknownV0); meshes[i].uv3[j] = new Vector2(fmdl.objects[i].additionalVertexData[j].unknownU1, fmdl.objects[i].additionalVertexData[j].unknownV1); meshes[i].uv4[j] = new Vector2(fmdl.objects[i].additionalVertexData[j].unknownU2, fmdl.objects[i].additionalVertexData[j].unknownV2); } //for //Faces /*for (int j = 0, h = 0; j < fmdl.objects[i].faces.Length; j++, h += 3) * { * meshes[i].faces[h] = fmdl.objects[i].faces[j].vertex1Id; * meshes[i].faces[h + 1] = fmdl.objects[i].faces[j].vertex2Id; * meshes[i].faces[h + 2] = fmdl.objects[i].faces[j].vertex3Id; * } //for*/ for (int j = 0, h = 0; j < fmdl.objects[i].lodFaces[lod].Length; j++, h += 3) { meshes[i].faces[h] = fmdl.objects[i].lodFaces[lod][j].vertex1Id; meshes[i].faces[h + 1] = fmdl.objects[i].lodFaces[lod][j].vertex2Id; meshes[i].faces[h + 2] = fmdl.objects[i].lodFaces[lod][j].vertex3Id; } //for //Render the mesh in Unity. subFmdlGameObjects[i] = new GameObject(); FoxMeshDefinition foxMeshDefinition = new FoxMeshDefinition(); //Get the mesh name. for (int j = 0; j < fmdl.section0Block2Entries.Count; j++) { if (i >= fmdl.section0Block2Entries[j].firstObjectId && i < fmdl.section0Block2Entries[j].firstObjectId + fmdl.section0Block2Entries[j].numObjects) { if (fmdl.stringsIndex != -1) { subFmdlGameObjects[i].name = i + " - " + fmdl.strings[fmdl.section0Block1Entries[fmdl.section0Block2Entries[j].meshGroupId].stringId]; foxMeshDefinition.meshGroup = fmdl.strings[fmdl.section0Block1Entries[fmdl.section0Block2Entries[j].meshGroupId].stringId]; } //if else { subFmdlGameObjects[i].name = i + " - " + Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block1Entries[fmdl.section0Block2Entries[j].meshGroupId].stringId]); foxMeshDefinition.meshGroup = Hashing.TryGetStringName(fmdl.section0Block16Entries[fmdl.section0Block1Entries[fmdl.section0Block2Entries[j].meshGroupId].stringId]); } //else break; } //if } //for subFmdlGameObjects[i].transform.parent = fmdlGameObject.transform; SkinnedMeshRenderer meshRenderer = subFmdlGameObjects[i].AddComponent <SkinnedMeshRenderer>(); meshRenderer.material = materials[fmdl.section0Block3Entries[i].materialInstanceId].material; foxMeshDefinition.material = materials[fmdl.section0Block3Entries[i].materialInstanceId].materialName; foxMeshDefinition.materialType = materials[fmdl.section0Block3Entries[i].materialInstanceId].materialType; Mesh mesh = new Mesh(); foxMeshDefinition.mesh = mesh; mesh.vertices = meshes[i].vertices; mesh.uv = meshes[i].uv; mesh.uv2 = meshes[i].uv2; mesh.uv3 = meshes[i].uv3; mesh.uv4 = meshes[i].uv4; mesh.normals = meshes[i].normals; mesh.tangents = meshes[i].tangents; mesh.triangles = meshes[i].faces; mesh.boneWeights = meshes[i].boneWeights; for (int j = 0; j < bones.Length; j++) { bindPoses[j] = bones[j].worldToLocalMatrix * subFmdlGameObjects[i].transform.localToWorldMatrix; } //for mesh.bindposes = bindPoses; meshRenderer.bones = bones; meshRenderer.sharedMesh = mesh; fmdlGameObject.GetComponent <FoxModel>().definitions[i] = foxMeshDefinition; subFmdlGameObjects[i].AddComponent <MeshCollider>(); } //for return(fmdlGameObject); } //GetDataFromFmdl