private static MESH_CULLING SerializeMeshCulling(MESH_FILE file, ShaderDataHelper shaderData, MeshCulling meshCulling) { var culling = new MESH_CULLING { Type = (int)meshCulling.Type, FromVertex = meshCulling.FromVertex, VertexCount = meshCulling.VertexCount, FromIndex = meshCulling.FromIndex, IndexCount = meshCulling.IndexCount }; if (meshCulling.ReplacementMesh != null) { culling.AlternateMesh = SerializeMeshGeometry(file, shaderData, meshCulling.ReplacementMesh); } if (meshCulling.Studs != null && meshCulling.Studs.Any()) { culling.Studs = meshCulling.Studs.Select(x => x.Serialize()).ToArray(); } if (meshCulling.AdjacentStuds != null && meshCulling.AdjacentStuds.Any()) { culling.AdjacentStuds = meshCulling.AdjacentStuds.Select(x => x.Serialize()).ToArray(); } return(culling); }
private static MESH_CULLING ReadCullingInfo(BinaryReaderEx br, MESH_FILE meshFile, long boneMappingPosition) { long startPosition = br.BaseStream.Position; int cullingDataSize = br.ReadInt32(); var culling = new MESH_CULLING() { Type = br.ReadInt32(), FromVertex = br.ReadInt32(), VertexCount = br.ReadInt32(), FromIndex = br.ReadInt32(), IndexCount = br.ReadInt32() }; int alternateMeshOffset = br.ReadInt32(); int connectorReferenceFlag = br.ReadInt32(); if (connectorReferenceFlag >= 1) { culling.Studs = ReadCustom2DFieldReferences(br); } else { culling.Studs = new CUSTOM2DFIELD_REFERENCE[0]; } if (connectorReferenceFlag >= 2) { culling.AdjacentStuds = ReadCustom2DFieldReferences(br); } else { culling.AdjacentStuds = new CUSTOM2DFIELD_REFERENCE[0]; } if (connectorReferenceFlag > 2) { Trace.WriteLine($"Unexpected connector reference flag: {connectorReferenceFlag}"); } if (alternateMeshOffset != 0) { if (startPosition + alternateMeshOffset != br.BaseStream.Position) { Trace.WriteLine("Incorrect data size read"); br.BaseStream.Position = startPosition + alternateMeshOffset; } long meshDataSize = cullingDataSize - alternateMeshOffset; culling.AlternateMesh = ReadAlternateMesh(br, meshFile, boneMappingPosition, meshDataSize); } return(culling); }
private static void WriteCullingInfo(BinaryWriterEx bw, MESH_CULLING culling) { void WriteVector3(Vector3 v) { bw.WriteSingle(v.X); bw.WriteSingle(v.Y); bw.WriteSingle(v.Z); } void WriteVector2(Vector2 v) { bw.WriteSingle(v.X); bw.WriteSingle(v.Y); } long startPos = bw.BaseStream.Position; WriteSizedBlock(bw, () => { bw.WriteInt32(culling.Type); bw.WriteInt32(culling.FromVertex); bw.WriteInt32(culling.VertexCount); bw.WriteInt32(culling.FromIndex); bw.WriteInt32(culling.IndexCount); long vertexOffsetPos = bw.BaseStream.Position; bw.Write(0);//dummy offset; int extraDataVal = 0; if (culling.AdjacentStuds != null && culling.AdjacentStuds.Length > 0) { extraDataVal = 2; } else if (culling.Studs != null && culling.Studs.Length > 0) { extraDataVal = 1; } bw.Write(extraDataVal); if (extraDataVal > 0) { WriteSizedBlock(bw, () => { int itemCount = culling.Studs?.Length ?? 0; bw.Write(itemCount); for (int i = 0; i < itemCount; i++) { WriteSizedBlock(bw, () => { bw.Write(culling.Studs[i].ConnectorIndex); bw.Write(culling.Studs[i].Indices.Length); for (int j = 0; j < culling.Studs[i].Indices.Length; j++) { bw.Write(culling.Studs[i].Indices[j].ArrayIndex); bw.Write(culling.Studs[i].Indices[j].Value2); bw.Write(culling.Studs[i].Indices[j].Value3); bw.Write(culling.Studs[i].Indices[j].Value4); } }); } }); } if (extraDataVal > 1) { WriteSizedBlock(bw, () => { int itemCount = culling.AdjacentStuds?.Length ?? 0; bw.Write(itemCount); for (int i = 0; i < itemCount; i++) { WriteSizedBlock(bw, () => { bw.Write(culling.AdjacentStuds[i].ConnectorIndex); bw.Write(culling.AdjacentStuds[i].Indices.Length); for (int j = 0; j < culling.AdjacentStuds[i].Indices.Length; j++) { bw.Write(culling.AdjacentStuds[i].Indices[j].ArrayIndex); bw.Write(culling.AdjacentStuds[i].Indices[j].Value2); bw.Write(culling.AdjacentStuds[i].Indices[j].Value3); bw.Write(culling.AdjacentStuds[i].Indices[j].Value4); } }); } }); } if (culling.AlternateMesh != null) { var cullingGeom = culling.AlternateMesh.Value; long currentPos = bw.BaseStream.Position; bw.BaseStream.Position = vertexOffsetPos; bw.Write((int)(currentPos - startPos)); bw.BaseStream.Position = currentPos; bw.WriteInt32(cullingGeom.Positions.Length); bw.WriteInt32(cullingGeom.Indices.Length); foreach (var pos in cullingGeom.Positions) { WriteVector3(pos); } foreach (var norm in cullingGeom.Normals) { WriteVector3(norm); } if (cullingGeom.UVs != null && cullingGeom.UVs.Length > 0) { foreach (var uv in cullingGeom.UVs) { WriteVector2(uv); } } foreach (var index in cullingGeom.Indices) { bw.WriteInt32(index.VertexIndex); } foreach (var index in cullingGeom.Indices) { bw.WriteInt32(index.AverageNormalIndex); } foreach (var index in cullingGeom.Indices) { bw.WriteInt32(index.REShaderOffset); } } }); }