public override Chunk parse(BinaryReader reader) { ShapeNodeChunk chunk = new ShapeNodeChunk(); chunk.bytesInChunk = reader.ReadInt32(); chunk.bytesInChildren = reader.ReadInt32(); chunk.nodeId = reader.ReadInt32(); chunk.attributes = MagicaDictionary.readDictionary(reader); int numberOfChildNodes = reader.ReadInt32(); for (int i = 0; i < numberOfChildNodes; i++) { MagicaModel model = new MagicaModel(); model.modelId = reader.ReadInt32(); model.attributes = MagicaDictionary.readDictionary(reader); chunk.childModels.Add(model); } long currentPosition = reader.BaseStream.Position; while (reader.BaseStream.Position < currentPosition + chunk.bytesInChildren) { chunk.children.Add(Chunk.createChunk(reader)); } return(chunk); }
public MeshAndColors createMesh(VoxelModelChunk voxelChunk, ShapeNodeChunk shape) { Vector3 ve = rotateVector(new Vector3(voxelChunk.sizeChunk.sizeX, voxelChunk.sizeChunk.sizeY, voxelChunk.sizeChunk.sizeZ), shape.transform); int sizeX = (int)Math.Abs(ve.x); int sizeY = (int)Math.Abs(ve.y); int sizeZ = (int)Math.Abs(ve.z); // WTF? Dont drink and code!!! Vector3 correction = new Vector3((ve.x < 0) ? Math.Abs(ve.x) - 1 : 0, (ve.y < 0) ? Math.Abs(ve.y) - 1 : 0, (ve.z < 0) ? Math.Abs(ve.z) - 1 : 0); RenderVoxel[,,] voxelArray = new RenderVoxel[sizeX, sizeY, sizeZ]; float maxX = 0; float maxY = 0; float maxZ = 0; float minX = sizeX; float minY = sizeY; float minZ = sizeZ; foreach (Voxel voxel in voxelChunk.voxels) { Vector3 rotVec = rotateVector(new Vector3(voxel.x, voxel.y, voxel.z), shape.transform) + correction; voxelArray[(int)rotVec.x, (int)rotVec.y, (int)rotVec.z] = new RenderVoxel(voxel.colorIndex); if (rotVec.x < minX) { minX = rotVec.x; } if (rotVec.y < minY) { minY = rotVec.y; } if (rotVec.z < minZ) { minZ = rotVec.z; } if (rotVec.x > maxX) { maxX = rotVec.x; } if (rotVec.y > maxY) { maxY = rotVec.y; } if (rotVec.z > maxZ) { maxZ = rotVec.z; } } shape.singleCenter = new Vector3((float)Math.Ceiling(minX + (maxX - minX) / 2f), minZ, (float)Math.Ceiling(minY + (maxY - minY) / 2f)); Vector3 shifts = shape.singleCenter; MeshAndColors meshAndColors = createMeshFromVoxelArray(voxelArray, shifts); return(meshAndColors); }
/// <summary> /// Count the size of all nSHP chunks /// </summary> /// <returns></returns> private int CountShapeChunkSize() { int size = 0; List <int> shapeIds = new List <int>(); for (int i = 0; i < _models.Count; i++) { for (int j = 0; j < _models[i].shapeNodeChunks.Count; j++) { ShapeNodeChunk shapeNode = _models[i].shapeNodeChunks[j]; int id = (shapeNode.id + (i * 2000) + 2); if (!shapeIds.Contains(id)) { shapeIds.Add(id); size += Encoding.UTF8.GetByteCount(nSHP) + 28; } } } return(size); }
/// <summary> /// Main loop for write all chunks /// </summary> /// <param name="writer"></param> private int WriteChunks(BinaryWriter writer) { int byteWritten = 0; int RGBA = WritePaletteChunk(writer); int MATL = 0; for (int i = 0; i < 256; i++) { if (_usedIndexColors.ContainsKey(i)) { KeyValuePair <int, int> modelIndex = _usedIndexColors[i]; if (_models[modelIndex.Key].materialChunks.Count > modelIndex.Value - 1) { MATL += WriteMaterialChunk(writer, _models[modelIndex.Key].materialChunks[modelIndex.Value - 1], i + 1); } } else if (_models[0].materialChunks.Count > 0) { MATL += WriteMaterialChunk(writer, _models[0].materialChunks[0], i + 1); } } int SIZE = 0; int XYZI = 0; Console.WriteLine("[LOG] Step [1/2]: Started to write SIZE and XYZI..."); using (var progressbar = new ProgressBar()) { int totalModels = CountTotalModels(); int indexProgression = 0; foreach (VoxModel model in _models) { for (int j = 0; j < model.voxelFrames.Count; j++) { SIZE += WriteSizeChunk(writer, model.voxelFrames[j].GetVolumeSize()); XYZI += WriteXyziChunk(writer, model, j); float progress = indexProgression / (float)totalModels; progressbar.Report(progress); indexProgression++; } } } Console.WriteLine("[LOG] Done."); int nGRP = 0; int nTRN = 0; int nSHP = 0; int mnTRN = WriteMainTransformChunk(writer); int indexChunk = 2; List <int> mainGroupIds = new List <int>(); mainGroupIds.Add(2); for (int i = 0; i < _models.Count - 1; i++) { int max = _models[i].transformNodeChunks.Max(t => t.id); int transformId = max + (max % 2 == 0 ? 2 : 1) + mainGroupIds.Last(); mainGroupIds.Add(transformId); } int mnGRP = WriteMainGroupChunk(writer, mainGroupIds); Console.WriteLine("[LOG] Step [2/2]: Started to write nTRN, nGRP and nSHP chunks..."); using (var progressbar = new ProgressBar()) { int indexProgression = 0; int totalTransform = CountTotalTransforms(); Dictionary <int, int> modelIds = new Dictionary <int, int>(); Dictionary <int, int> shapeIds = new Dictionary <int, int>(); int indexModel = 0; mainGroupIds.Clear(); mainGroupIds.Add(2); for (int i = 0; i < _models.Count; i++) { for (int j = 0; j < _models[i].transformNodeChunks.Count; j++) { int childId = _models[i].transformNodeChunks[j].childId; int transformIndexUnique = indexChunk++; ShapeNodeChunk shapeNode = _models[i].shapeNodeChunks.FirstOrDefault(t => t.id == childId); if (shapeNode != null) { int modelId = shapeNode.models[0].modelId + i; int modelIndexUnique = modelId + (i * 2000); //Hack ... if (!modelIds.ContainsKey(modelIndexUnique)) { modelIds.Add(modelIndexUnique, indexModel); indexModel++; } int shapeIndexUnique = (shapeNode.id + ((i + 1) * 2000) + 2); //Hack nTRN += WriteTransformChunk(writer, _models[i].transformNodeChunks[j], transformIndexUnique, shapeIds.ContainsKey(shapeIndexUnique) ? shapeIds[shapeIndexUnique] : indexChunk); if (!shapeIds.ContainsKey(shapeIndexUnique)) { shapeIds.Add(shapeIndexUnique, indexChunk); nSHP += WriteShapeChunk(writer, indexChunk, modelIds[modelIndexUnique]); indexChunk++; } } else { GroupNodeChunk groupNode = _models[i].groupNodeChunks.FirstOrDefault(t => t.id == childId); int groupUniqueIndex = indexChunk++; List <int> childIds = groupNode.childIds.ToList(); for (int index = 0; index < childIds.Count; index++) { childIds[index] += mainGroupIds.Last(); } nTRN += WriteTransformChunk(writer, _models[i].transformNodeChunks[j], transformIndexUnique, groupUniqueIndex); nGRP += WriteGroupChunk(writer, groupUniqueIndex, childIds); } progressbar.Report(indexProgression / (float)totalTransform); indexProgression++; } int max = _models[i].transformNodeChunks.Max(t => t.id); mainGroupIds.Add(max + (max % 2 == 0 ? 2 : 1) + mainGroupIds.Last()); } } Console.WriteLine("[LOG] Written RGBA: " + RGBA); Console.WriteLine("[LOG] Written MATL: " + MATL); Console.WriteLine("[LOG] Written SIZE: " + SIZE); Console.WriteLine("[LOG] Written XYZI: " + XYZI); Console.WriteLine("[LOG] Written nGRP: " + nGRP); Console.WriteLine("[LOG] Written nTRN: " + nTRN); Console.WriteLine("[LOG] Written nSHP: " + nSHP); Console.WriteLine("[LOG] Written mnTRN: " + mnTRN); Console.WriteLine("[LOG] Written mnGRP: " + mnGRP); byteWritten = RGBA + MATL + SIZE + XYZI + nGRP + nTRN + nSHP + mnTRN + mnGRP; return(byteWritten); }