public bool CombineMeshes(ObjectSelectionState objectSelectionState, out ErrorList errorMessages) { ModelCombiner modelValidator = new ModelCombiner(); var objs = objectSelectionState.SelectedObjects().Where(x => x is Rmv2MeshNode).Select(x => x as Rmv2MeshNode); if (!modelValidator.CanCombine(objs.ToList(), out errorMessages)) { return(false); } var command = new CombineMeshCommand(objectSelectionState.SelectedObjects()); _commandManager.ExecuteCommand(command); return(true); }
/// <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); }