/// <summary> /// Gets Unity Mesh from previously combined model data. /// </summary> /// <param name="dfUnity">DaggerfallUnity singleon for loading content.</param> /// <param name="combiner">ModelCombiner to build from.</param> /// <param name="cachedMaterialsOut">Array of cached materials in order of submesh.</param> /// <param name="textureKeysOut">Array of original texture keys in order of submesh.</param> /// <param name="hasAnimationsOut">True if one or more materials have animations.</param> /// <param name="solveTangents">Solve tangents for this mesh.</param> /// <param name="lightmapUVs">Add secondary lightmap UVs to this mesh.</param> /// <returns>Mesh object or null.</returns> public Mesh GetCombinedMesh( DaggerfallUnity dfUnity, ModelCombiner combiner, out CachedMaterial[] cachedMaterialsOut, out int[] textureKeysOut, out bool hasAnimationsOut, bool solveTangents = false, bool lightmapUVs = false) { cachedMaterialsOut = null; hasAnimationsOut = false; textureKeysOut = null; // Ready check if (!IsReady) { return(null); } // Get combined model ModelCombiner.CombinedModel combinedModel; if (!combiner.GetCombinedModel(out combinedModel)) { return(null); } // Load materials cachedMaterialsOut = new CachedMaterial[combinedModel.SubMeshes.Length]; textureKeysOut = new int[combinedModel.SubMeshes.Length]; for (int i = 0; i < combinedModel.SubMeshes.Length; i++) { int archive = combinedModel.SubMeshes[i].TextureArchive; int record = combinedModel.SubMeshes[i].TextureRecord; textureKeysOut[i] = MaterialReader.MakeTextureKey((short)archive, (byte)record, (byte)0); // Add material to array CachedMaterial cachedMaterial; dfUnity.MaterialReader.GetCachedMaterial(archive, record, 0, out cachedMaterial); cachedMaterialsOut[i] = cachedMaterial; // Set animation flag if (cachedMaterial.singleFrameCount > 1 && !hasAnimationsOut) { hasAnimationsOut = true; } } // Create mesh Mesh mesh = new Mesh(); mesh.name = "CombinedMesh"; mesh.vertices = combinedModel.Vertices; mesh.normals = combinedModel.Normals; mesh.uv = combinedModel.UVs; mesh.subMeshCount = combinedModel.SubMeshes.Length; // Set submesh triangles for (int s = 0; s < mesh.subMeshCount; s++) { var sub = combinedModel.SubMeshes[s]; int[] triangles = new int[sub.PrimitiveCount * 3]; for (int t = 0; t < sub.PrimitiveCount * 3; t++) { triangles[t] = combinedModel.Indices[sub.StartIndex + t]; } mesh.SetTriangles(triangles, s); } // Finalise mesh if (solveTangents) { TangentSolver(mesh); } if (lightmapUVs) { AddLightmapUVs(mesh); } mesh.RecalculateBounds(); return(mesh); }
/// <summary> /// Gets Unity Mesh from Daggerfall model. /// </summary> /// <param name="dfUnity">DaggerfallUnity singleon for loading content.</param> /// <param name="modelID">Daggerfall model ID to load..</param> /// <param name="cachedMaterialsOut">Array of cached materials in order of submesh.</param> /// <param name="textureKeysOut">Array of original texture keys in order of submesh.</param> /// <param name="hasAnimationsOut">True if one or more materials have animations.</param> /// <param name="solveTangents">Solve tangents for this mesh.</param> /// <param name="lightmapUVs">Add secondary lightmap UVs to this mesh.</param> /// <returns>Mesh object or null.</returns> public Mesh GetMesh( DaggerfallUnity dfUnity, uint modelID, out CachedMaterial[] cachedMaterialsOut, out int[] textureKeysOut, out bool hasAnimationsOut, bool solveTangents = false, bool lightmapUVs = false) { cachedMaterialsOut = null; hasAnimationsOut = false; textureKeysOut = null; // Ready check if (!IsReady) { return(null); } // Get model data ModelData model; if (!GetModelData(modelID, out model)) { DaggerfallUnity.LogMessage(string.Format("Unknown ModelID {0}.", modelID.ToString()), true); return(null); } // Load materials cachedMaterialsOut = new CachedMaterial[model.SubMeshes.Length]; textureKeysOut = new int[model.SubMeshes.Length]; for (int i = 0; i < model.SubMeshes.Length; i++) { int archive = model.DFMesh.SubMeshes[i].TextureArchive; int record = model.DFMesh.SubMeshes[i].TextureRecord; textureKeysOut[i] = MaterialReader.MakeTextureKey((short)archive, (byte)record, (byte)0); // Add material to array CachedMaterial cachedMaterial; dfUnity.MaterialReader.GetCachedMaterial(archive, record, 0, out cachedMaterial); cachedMaterialsOut[i] = cachedMaterial; // Set animation flag if (cachedMaterial.singleFrameCount > 1 && !hasAnimationsOut) { hasAnimationsOut = true; } } // Create mesh Mesh mesh = new Mesh(); mesh.name = modelID.ToString(); mesh.vertices = model.Vertices; mesh.normals = model.Normals; mesh.uv = model.UVs; mesh.subMeshCount = model.SubMeshes.Length; // Set submesh triangles for (int s = 0; s < mesh.subMeshCount; s++) { var sub = model.SubMeshes[s]; int[] triangles = new int[sub.PrimitiveCount * 3]; for (int t = 0; t < sub.PrimitiveCount * 3; t++) { triangles[t] = model.Indices[sub.StartIndex + t]; } mesh.SetTriangles(triangles, s); } // Finalise mesh if (solveTangents) { TangentSolver(mesh); } if (lightmapUVs) { AddLightmapUVs(mesh); } mesh.RecalculateBounds(); mesh.Optimize(); return(mesh); }