// buffer offset util protected int GetNextBlock(out ChunkInd dataChunk, BinaryReader reader, FileFlags flags) { bool swap = false; bool varies = false; if ((flags & FileFlags.EndianSwap) == FileFlags.EndianSwap) { swap = true; } if ((flags & FileFlags.BitsVaries) == FileFlags.BitsVaries) { varies = true; } if (swap) { throw new NotImplementedException(); } dataChunk = new ChunkInd(); if (IntPtr.Size == 8) { if (varies) { ChunkPtr4 c = new ChunkPtr4(reader); dataChunk = new ChunkInd(ref c); } else { ChunkPtr8 c = new ChunkPtr8(reader); dataChunk = new ChunkInd(ref c); } } else { if (varies) { throw new NotImplementedException(); } else { ChunkPtr4 c = new ChunkPtr4(reader); dataChunk = new ChunkInd(ref c); } } if (dataChunk.Length < 0) { return(-1); } return(dataChunk.Length + ChunkUtils.GetOffset(flags)); }
private long FindDnaChunk(BinaryReader reader) { var stream = reader.BaseStream; int i = 0; while (i < stream.Length) { stream.Position = i; // looking for the data's starting position // and the start of SDNA decls byte[] codeData = reader.ReadBytes(4); string code = Encoding.ASCII.GetString(codeData); if (_dataStart == 0 && code.Equals("REND")) { _dataStart = stream.Position; } if (code == "DNA1") { // read the DNA1 block and extract SDNA stream.Position = i; if (GetNextBlock(reader) != null) { string sdnaname = Encoding.ASCII.GetString(reader.ReadBytes(8)); if (sdnaname == "SDNANAME") { return(i + ChunkUtils.GetChunkSize(Flags)); } } } else if (code == "SDNA") { // Some Bullet files are missing the DNA1 block // In Blender it's DNA1 + ChunkUtils.GetOffset() + SDNA + NAME // In Bullet tests its SDNA + NAME return(i); } i++; } Console.WriteLine("Failed to find DNA1+SDNA pair"); return(-1); }
protected override void ReadChunks() { bool brokenDna = (Flags & FileFlags.BrokenDna) != 0; _dataStart = SizeOfBlenderHeader; long chunkPtr = _dataStart; Stream stream = ChunkReader.BaseStream; stream.Position = chunkPtr; ChunkInd chunk = GetNextBlock(ChunkReader); while (chunk.Code != DnaID.Dna) { long chunkDataOffset = chunkPtr + ChunkUtils.GetChunkSize(Flags); if (!brokenDna || chunk.Code != DnaID.QuantizedBvh) { // One behind if (chunk.Code == DnaID.Sdna) { break; } byte[] chunkData; if (chunk.StructIndex >= 0) { _chunks.Add(chunk); chunkData = ReadChunkData(chunk, chunkDataOffset); switch (chunk.Code) { case DnaID.CollisionObject: CollisionObjects.Add(chunkData); break; case DnaID.Constraint: Constraints.Add(chunkData); break; case DnaID.DynamicsWorld: DynamicsWorldInfo.Add(chunkData); break; case DnaID.MultiBody: MultiBodies.Add(chunkData); break; case DnaID.SoftBody: case DnaID.TriangleInfoMap: throw new NotImplementedException(); case DnaID.QuantizedBvh: Bvhs.Add(chunkData); break; case DnaID.RigidBody: RigidBodies.Add(chunkData); break; case DnaID.Shape: CollisionShapes.Add(chunkData); break; } } else { #if DEBUG Console.WriteLine("unknown chunk " + chunk.Code); #endif chunkData = new byte[chunk.Length]; ChunkReader.Read(chunkData, 0, chunk.Length); } LibPointers.Add(chunk.OldPtr, chunkData); } else { #if DEBUG Console.WriteLine("skipping B3_QUANTIZED_BVH_CODE due to broken DNA"); #endif } chunkPtr = chunkDataOffset + chunk.Length; stream.Position = chunkPtr; chunk = GetNextBlock(ChunkReader); if (chunk.Length < 0) { break; } } }
public override void ParseData() { //Console.WriteLine("Building datablocks"); //Console.WriteLine("Chunk size = {0}", CHUNK_HEADER_LEN); //Console.WriteLine("File chunk size = {0}", ChunkUtils.GetOffset(_flags)); bool brokenDna = (_flags & FileFlags.BrokenDna) != 0; bool swap = (_flags & FileFlags.EndianSwap) != 0; MemoryStream memory = new MemoryStream(_fileBuffer, false); BinaryReader reader = new BinaryReader(memory); _dataStart = 12; long dataPtr = _dataStart; memory.Position = dataPtr; ChunkInd dataChunk; int seek = GetNextBlock(out dataChunk, reader, _flags); if (swap) { throw new NotImplementedException(); //swapLen(dataPtr); } while (dataChunk.Code != DnaID.Dna) { if (!brokenDna || dataChunk.Code != DnaID.QuantizedBvh) { // One behind if (dataChunk.Code == DnaID.Sdna) { break; } // same as (BHEAD+DATA dependency) long dataPtrHead = dataPtr + ChunkUtils.GetOffset(_flags); if (dataChunk.DnaNR >= 0) { byte[] id = ReadStruct(reader, dataChunk); //m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk); _libPointers.Add(dataChunk.OldPtr, id); _chunks.Add(dataChunk); switch (dataChunk.Code) { case DnaID.CollisionObject: CollisionObjects.Add(id); break; case DnaID.Constraint: Constraints.Add(id); break; case DnaID.DynamicsWorld: DynamicsWorldInfo.Add(id); break; case DnaID.MultiBody: MultiBodies.Add(id); break; case DnaID.SoftBody: case DnaID.TriangleInfoMap: throw new NotImplementedException(); case DnaID.QuantizedBvh: Bvhs.Add(id); break; case DnaID.RigidBody: RigidBodies.Add(id); break; case DnaID.Shape: CollisionShapes.Add(id); break; } } else { #if DEBUG Console.WriteLine("unknown chunk " + dataChunk.Code); #endif byte[] data = new byte[dataChunk.Length]; reader.Read(data, 0, dataChunk.Length); _libPointers.Add(dataChunk.OldPtr, data); } } else { #if DEBUG Console.WriteLine("skipping B3_QUANTIZED_BVH_CODE due to broken DNA"); #endif } dataPtr += seek; memory.Position = dataPtr; seek = GetNextBlock(out dataChunk, reader, _flags); if (swap) { throw new NotImplementedException(); //swapLen(dataPtr); } if (seek < 0) { break; } } reader.Dispose(); memory.Dispose(); }
protected void ParseInternal(FileVerboseMode verboseMode, byte[] memDna) { if ((_flags & FileFlags.OK) != FileFlags.OK) { return; } ChunkInd dna = new ChunkInd(); dna.OldPtr = 0; MemoryStream memory = new MemoryStream(_fileBuffer, false); BinaryReader reader = new BinaryReader(memory); int i = 0; while (memory.Position < memory.Length) { // looking for the data's starting position // and the start of SDNA decls byte[] code = reader.ReadBytes(4); string codes = ASCIIEncoding.ASCII.GetString(code); if (_dataStart == 0 && codes.Equals("REND")) { _dataStart = memory.Position; } if (codes.Equals("DNA1")) { // read the DNA1 block and extract SDNA reader.BaseStream.Position = i; if (GetNextBlock(out dna, reader, _flags) > 0) { string sdnaname = ASCIIEncoding.ASCII.GetString(reader.ReadBytes(8)); if (sdnaname.Equals("SDNANAME")) { dna.OldPtr = i + ChunkUtils.GetOffset(_flags); } else { dna.OldPtr = 0; } } else { dna.OldPtr = 0; } } else if (codes.Equals("SDNA")) { // Some Bullet files are missing the DNA1 block // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME // In Bullet tests its SDNA + NAME dna.OldPtr = i; dna.Length = (int)memory.Length - i; // Also no REND block, so exit now. if (_version == 276) { break; } } if (_dataStart != 0 && dna.OldPtr != 0) { break; } i++; memory.Position = i; } if (dna.OldPtr == 0 || dna.Length == 0) { //Console.WriteLine("Failed to find DNA1+SDNA pair"); _flags &= ~FileFlags.OK; reader.Dispose(); memory.Dispose(); return; } _fileDna = new Dna(); // _fileDna.Init will convert part of DNA file endianness to current CPU endianness if necessary memory.Position = dna.OldPtr; _fileDna.Init(reader, (_flags & FileFlags.EndianSwap) != 0); if (_version == 276) { for (i = 0; i < _fileDna.NumNames; i++) { if (_fileDna.GetName(i).Equals("int")) { _flags |= FileFlags.BrokenDna; } } if ((_flags & FileFlags.BrokenDna) == FileFlags.BrokenDna) { //Console.WriteLine("warning: fixing some broken DNA version"); } } //if ((verboseMode & FileVerboseMode.DumpDnaTypeDefinitions) == FileVerboseMode.DumpDnaTypeDefinitions) // _fileDna.DumpTypeDefinitions(); _memoryDna = new Dna(); using (MemoryStream memory2 = new MemoryStream(memDna, false)) { using (BinaryReader reader2 = new BinaryReader(memory2)) { _memoryDna.Init(reader2, !BitConverter.IsLittleEndian); } } if (_memoryDna.NumNames != _fileDna.NumNames) { _flags |= FileFlags.VersionVaries; //Console.WriteLine ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform"); } if (_memoryDna.LessThan(_fileDna)) { //Console.WriteLine ("Warning, file DNA is newer than built in."); } _fileDna.InitCmpFlags(_memoryDna); ParseData(); ResolvePointers(verboseMode); UpdateOldPointers(); reader.Dispose(); memory.Dispose(); }