public override void Write(AssetWriter writer) { base.Write(writer); if (HasLODData(writer.Version)) { LODData.Write(writer); } else { if (HasUse16bitIndices(writer.Version)) { writer.Write(Use16BitIndices); } if (IsIndexBufferFirst(writer.Version)) { IndexBuffer.Write(writer); writer.AlignStream(AlignType.Align4); } SubMeshes.Write(writer); } if (HasBlendShapes(writer.Version)) { if (HasBlendChannels(writer.Version)) { Shapes.Write(writer); } else { BlendShapes.Write(writer); writer.AlignStream(AlignType.Align4); ShapeVertices.Write(writer); } } if (HasBindPose(writer.Version)) { if (IsBindPoseFirst(writer.Version)) { BindPose.Write(writer); } } if (HasBoneNameHashes(writer.Version)) { BoneNameHashes.Write(writer); writer.Write(RootBoneNameHash); } if (HasBonesAABB(writer.Version)) { BonesAABB.Write(writer); VariableBoneCountWeights.Write(writer); } if (HasMeshCompression(writer.Version)) { writer.Write((byte)MeshCompression); } if (HasStreamCompression(writer.Version)) { writer.Write(StreamCompression); } if (HasIsReadable(writer.Version)) { writer.Write(IsReadable); writer.Write(KeepVertices); writer.Write(KeepIndices); } if (IsAlignFlags(writer.Version)) { writer.AlignStream(AlignType.Align4); } if (HasIndexFormat(writer.Version)) { if (IsIndexFormatCondition(writer.Version)) { if (MeshCompression == MeshCompression.Off) { writer.Write((int)IndexFormat); } } else { writer.Write((int)IndexFormat); } } if (!HasLODData(writer.Version)) { if (!IsIndexBufferFirst(writer.Version)) { IndexBuffer.Write(writer); writer.AlignStream(AlignType.Align4); } } if (HasVertexData(writer.Version)) { if (!IsOnlyVertexData(writer.Version)) { if (MeshCompression != MeshCompression.Off) { Vertices.Write(writer); } } } else { Vertices.Write(writer); } if (HasSkin(writer.Version)) { Skin.Write(writer); } if (HasBindPose(writer.Version)) { if (!IsBindPoseFirst(writer.Version)) { BindPose.Write(writer); } } if (HasVertexData(writer.Version)) { if (IsOnlyVertexData(writer.Version)) { VertexData.Write(writer); } else { if (MeshCompression == MeshCompression.Off) { VertexData.Write(writer); } else { UV.Write(writer); UV1.Write(writer); Tangents.Write(writer); Normals.Write(writer); Colors.Write(writer); } } } else { UV.Write(writer); if (HasUV1(writer.Version)) { UV1.Write(writer); } if (HasTangentSpace(writer.Version)) { TangentSpace.Write(writer); } else { Tangents.Write(writer); Normals.Write(writer); } } if (IsAlignVertex(writer.Version)) { writer.AlignStream(AlignType.Align4); } if (HasCompressedMesh(writer.Version)) { CompressedMesh.Write(writer); } LocalAABB.Write(writer); if (!HasVertexData(writer.Version)) { Colors.Write(writer); } if (HasCollisionTriangles(writer.Version)) { CollisionTriangles.Write(writer); writer.Write(CollisionVertexCount); } if (HasMeshUsageFlags(writer.Version)) { writer.Write(MeshUsageFlags); } if (HasCollision(writer.Version)) { CollisionData.Write(writer); } if (HasMeshMetrics(writer.Version)) { writer.Write(MeshMetrics[0]); writer.Write(MeshMetrics[1]); } #if UNIVERSAL if (HasMeshOptimization(writer.Version, writer.Flags)) { if (IsMeshOptimizationFlags(writer.Version)) { writer.Write((int)MeshOptimizationFlags); } else { writer.Write(MeshOptimized); } } #endif if (HasStreamData(writer.Version)) { writer.AlignStream(AlignType.Align4); StreamData.Write(writer); } }
protected override YAMLMappingNode ExportYAMLRoot(IExportContainer container) { YAMLMappingNode node = base.ExportYAMLRoot(container); node.AddSerializedVersion(ToSerializedVersion(container.ExportVersion)); if (HasLODData(container.ExportVersion)) { node.Add(LODDataName, LODData.ExportYAML(container)); } else { if (HasUse16bitIndices(container.ExportVersion)) { node.Add(Use16BitIndicesName, Use16BitIndices); } if (IsIndexBufferFirst(container.ExportVersion)) { node.Add(IndexBufferName, IndexBuffer.ExportYAML()); } node.Add(SubMeshesName, SubMeshes.ExportYAML(container)); } if (HasBlendShapes(container.ExportVersion)) { if (HasBlendChannels(container.ExportVersion)) { node.Add(ShapesName, Shapes.ExportYAML(container)); } else { node.Add(ShapesName, BlendShapes.ExportYAML(container)); node.Add(ShapeVerticesName, ShapeVertices.ExportYAML(container)); } } if (HasBindPose(container.ExportVersion)) { if (IsBindPoseFirst(container.ExportVersion)) { node.Add(BindPoseName, BindPose.ExportYAML(container)); } } if (HasBoneNameHashes(container.ExportVersion)) { node.Add(BoneNameHashesName, BoneNameHashes.ExportYAML(true)); node.Add(RootBoneNameHashName, RootBoneNameHash); } if (HasBonesAABB(container.ExportVersion)) { node.Add(BonesAABBName, BonesAABB.ExportYAML(container)); node.Add(VariableBoneCountWeightsName, VariableBoneCountWeights.ExportYAML(container)); } if (HasMeshCompression(container.ExportVersion)) { node.Add(MeshCompressionName, (byte)MeshCompression); } if (HasStreamCompression(container.ExportVersion)) { node.Add(StreamCompressionName, StreamCompression); } if (HasIsReadable(container.ExportVersion)) { node.Add(IsReadableName, IsReadable); node.Add(KeepVerticesName, KeepVertices); node.Add(KeepIndicesName, KeepIndices); } if (HasIndexFormat(container.ExportVersion)) { node.Add(IndexFormatName, (int)IndexFormat); } if (!HasLODData(container.ExportVersion)) { if (!IsIndexBufferFirst(container.ExportVersion)) { node.Add(IndexBufferName, IndexBuffer.ExportYAML()); } } if (HasVertexData(container.ExportVersion)) { if (!IsOnlyVertexData(container.ExportVersion)) { if (MeshCompression != MeshCompression.Off) { node.Add(VerticesName, Vertices.ExportYAML(container)); } } } else { node.Add(VerticesName, Vertices.ExportYAML(container)); } if (HasSkin(container.ExportVersion)) { node.Add(SkinName, Skin.ExportYAML(container)); } if (HasBindPose(container.ExportVersion)) { if (!IsBindPoseFirst(container.ExportVersion)) { node.Add(BindPoseName, BindPose.ExportYAML(container)); } } if (HasVertexData(container.ExportVersion)) { if (IsOnlyVertexData(container.ExportVersion)) { node.Add(VertexDataName, VertexData.ExportYAML(container)); } else { if (MeshCompression == MeshCompression.Off) { node.Add(VertexDataName, VertexData.ExportYAML(container)); } else { node.Add(UVName, UV.ExportYAML(container)); node.Add(UV1Name, UV1.ExportYAML(container)); node.Add(TangentsName, Tangents.ExportYAML(container)); node.Add(NormalsName, Normals.ExportYAML(container)); node.Add(ColorsName, Colors.ExportYAML(container)); } } } else { node.Add(UVName, UV.ExportYAML(container)); if (HasUV1(container.ExportVersion)) { node.Add(UV1Name, UV1.ExportYAML(container)); } if (HasTangentSpace(container.ExportVersion)) { node.Add(TangentSpaceName, Tangents.ExportYAML(container)); } else { node.Add(TangentsName, Tangents.ExportYAML(container)); node.Add(NormalsName, Normals.ExportYAML(container)); } } if (HasCompressedMesh(container.ExportVersion)) { node.Add(CompressedMeshName, CompressedMesh.ExportYAML(container)); } node.Add(LocalAABBName, LocalAABB.ExportYAML(container)); if (!HasVertexData(container.ExportVersion)) { node.Add(ColorsName, Colors.ExportYAML(container)); } if (HasCollisionTriangles(container.ExportVersion)) { node.Add(CollisionTrianglesName, CollisionTriangles.ExportYAML(true)); node.Add(CollisionVertexCountName, CollisionVertexCount); } if (HasMeshUsageFlags(container.ExportVersion)) { node.Add(MeshUsageFlagsName, MeshUsageFlags); } if (HasCollision(container.ExportVersion)) { node.Add(BakedConvexCollisionMeshName, CollisionData.BakedConvexCollisionMesh.ExportYAML()); node.Add(BakedTriangleCollisionMeshName, CollisionData.BakedTriangleCollisionMesh.ExportYAML()); } if (HasMeshMetrics(container.ExportVersion)) { node.Add(MeshMetricsName + "[0]", MeshMetrics[0]); node.Add(MeshMetricsName + "[1]", MeshMetrics[1]); } if (HasMeshOptimization(container.ExportVersion, container.ExportFlags)) { if (IsMeshOptimizationFlags(container.ExportVersion)) { node.Add(MeshOptimizationFlagsName, (int)MeshOptimizationFlags); } else { node.Add(MeshOptimizedName, MeshOptimized); } } if (HasStreamData(container.ExportVersion)) { StreamingInfo streamData = new StreamingInfo(true); node.Add(StreamDataName, streamData.ExportYAML(container)); } return(node); }
// Create mesh with loaded flt and assign to Mesh public IEnumerator GenerateMeshesCoroutine() { Lods = new List <LODData>(); if (Flt == null) { yield break; } if (true) { //////////////////////////////////////////////////////////////////////////////// // this breaks LODs but makes models work for san diego var mesh = new UnityEngine.Mesh(); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; var lod_data = new LODData { mesh = mesh }; Lods.Add(lod_data); var submeshes = new List <Submesh>(); foreach (var flt_record in Flt.geometryRecords) { var id_record = flt_record as IdRecord; var rec_submeshes = id_record.Submeshes; /* * for (int i = 0; i < rec_submeshes.Count; ++i) * { * rec_submeshes[i].triangles.Reverse(); * rec_submeshes[i].triangles.AddRange(rec_submeshes[i].backfaceTriangles); * } */ rec_submeshes.AddRange(Flt.Submeshes); submeshes.AddRange(rec_submeshes); yield return(null); } Lods[0].mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; Lods[0].mesh.vertices = vertices; Lods[0].mesh.normals = normals; Lods[0].mesh.uv = uvs; if (submeshes == null) { Debug.LogError("[MeshManager] MeshEntry.GenerateMeshHelper() no meshes for " + Flt.Path); yield break; } var submeshes_temp = new List <Submesh>(); foreach (var submesh in submeshes) { if (submesh.material == null) { continue; } if (submesh.material.mainTexturePalette == null) { continue; } submeshes_temp.Add(submesh); } submeshes = submeshes_temp; Lods[0].mesh.subMeshCount = submeshes.Count; for (int i = 0; i < submeshes.Count; ++i) { submeshToTexturePatternIndex[i] = submeshes[i].material.mainTexturePalette.texturePatternIndex; Lods[0].mesh.SetTriangles(submeshes[i].triangles, i); Memory += submeshes[i].triangles.Count * sizeof(int); yield return(null); } /* * Lods[0].mesh.subMeshCount = submeshes.Count; * bool abort = false; * for (int i = 0; i < submeshes.Count; ++i) * { * //int texturePatternIndex = -1; // we have to have something here or the materials won't be created correctly * int texturePatternIndex = 0; * if (submeshes[i].material != null && submeshes[i].material.mainTexturePalette != null) * texturePatternIndex = submeshes[i].material.mainTexturePalette.texturePatternIndex; * submeshToTexturePatternIndex[i] = texturePatternIndex; * * for (int j = 0; j < submeshes[i].triangles.Count; ++j) * { * if (submeshes[i].triangles[j] > vertices.Length - 1) * { * Debug.LogError("[MeshManager] MeshEntry.GenerateMeshHelper() invalid vertex index for " + Flt.Path); * abort = true; * break; * } * } * if (abort) * break; * * Lods[0].mesh.SetTriangles(submeshes[i].triangles, i); * Memory += submeshes[i].triangles.Count * sizeof(int); * * // Recalculate bounds if needed. * // NOTE: in Unity, bounds are automatically recalculated when triangles are set * //Lods[lodIndex].mesh.RecalculateBounds(); * * yield return null; * } */ } else //////////////////////////////////////////////////////////////////////////////// { int lodIndex = 0; foreach (var record in Flt.geometryRecords) { var mesh = new UnityEngine.Mesh(); mesh.name = lodIndex.ToString(); var lodData = new LODData { mesh = mesh }; Lods.Add(lodData); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; var idRecord = record as IdRecord; var lodRecord = record as LevelOfDetail; if (lodRecord != null) { if (lodRecord.significantSize == 0f) { // significantSize undefined -> pre-15.8 lodData.switchInDistanceSq = (float)lodRecord.switchInDistance * (float)lodRecord.switchInDistance; lodData.switchOutDistanceSq = (float)lodRecord.switchOutDistance * (float)lodRecord.switchOutDistance; } else { lodData.CalculateFromSignificantSize((float)lodRecord.significantSize); } } else { lodData.switchInDistanceSq = 2500f * lodIndex * lodIndex;// TEMP - artificial distances for prototyping lodData.switchOutDistanceSq = 2500f * (lodIndex + 1) * (lodIndex + 1); } var submeshes = record.Submeshes; for (int i = 0; i < submeshes.Count; ++i) { submeshes[i].triangles.Reverse(); submeshes[i].triangles.AddRange(submeshes[i].backfaceTriangles); } // TODO: this isn't going to work right with LODs submeshes.AddRange(Flt.Submeshes); GenerateMeshHelper(lodIndex++, submeshes.ToArray(), vertices, normals, uvs); } } // Fix up switch-in distances. They should match the switch-out distances of the next highest quality LOD Lods[0].switchInDistanceSq = 0f; for (int i = 1; i < Lods.Count; ++i) { Lods[i].switchInDistanceSq = Lods[i - 1].switchOutDistanceSq; } Memory += vertices.Length * sizeof(float) * 3; Memory += normals.Length * sizeof(float) * 3; Memory += uvs.Length * sizeof(float) * 2; Flt = null; vertices = null; normals = null; uvs = null; }