void StringBuilder::clear() { len = 0; nextchar = 0; if (chunk == NULL) pushChunk(); while (chunk->next != NULL) popChunk(); }
bool Loader3ds::loadFile( const String &filename ) { //Try to open file File module = File::GetModule(); file = module.getRelativeFile( filename ); fileSize = (int) file.getSize(); if( !file.open( "rb" )) return false; //Read main chunk info ChunkInfo mainChunk; readChunkInfo( &mainChunk ); if( mainChunk.id != CHUNK_MAIN ) return false; pushChunk( mainChunk ); //Create root object node root = new Actor3D(); //Process sub-chunks while( !isChunkDone() ) { ChunkInfo subChunk; readChunkInfo( &subChunk ); pushChunk( subChunk ); switch( subChunk.id ){ case CHUNK_EDITOR: chunk_EDITOR(); break; case CHUNK_KEYFRAMER: chunk_KEYFRAMER(); break; default:; } popChunk(); } //End main chunk popChunk(); file.close(); return true; }
//--------------------------------------------------------------------- void StreamSerialiser::undoReadChunk(uint32 id) { Chunk* c = popChunk(id); checkStream(); mStream->seek(c->offset); OGRE_DELETE c; }
//--------------------------------------------------------------------- void StreamSerialiser::readChunkEnd(uint32 id) { Chunk* c = popChunk(id); checkStream(); // skip to the end of the chunk if we were not there already // this lets us quite reading a chunk anywhere and have the read marker // automatically skip to the next one if (mStream->tell() < (c->offset + CHUNK_HEADER_SIZE + c->length)) mStream->seek(c->offset + CHUNK_HEADER_SIZE + c->length); OGRE_DELETE c; }
void Loader3ds::chunk_MESH (const String &id) { //Create new mesh resource PolyMesh *mesh = new PolyMesh; resources.pushBack(mesh); //Create new shape object PolyMeshActor *shape = new PolyMeshActor; shape->setId (id); shape->setMesh (mesh); objects.pushBack (shape); root->addChild (shape); //Temporary lists VertArray verts; FaceArray faces; UVArray uvcoords; //Process sub-chunks while (!isChunkDone()) { ChunkInfo subChunk; readChunkInfo(&subChunk); pushChunk(subChunk); switch(subChunk.id) { case CHUNK_MESH_VERTEX_LIST: chunk_MESH_VERTEX_LIST (mesh, &verts); break; case CHUNK_MESH_TEX_COORD_LIST: chunk_MESH_TEX_COORD_LIST (mesh, &uvcoords); break; case CHUNK_MESH_FACE_LIST: chunk_MESH_FACE_LIST (mesh, &verts, &uvcoords, &faces); break; default:; } popChunk(); } //Apply tex coords to faces for (UintSize f=0; f<faces.size(); ++f) { } }
void Loader3ds::chunk_EDITOR () { //Process sub-chukns while(!isChunkDone()) { ChunkInfo subChunk; readChunkInfo(&subChunk); pushChunk(subChunk); switch(subChunk.id) { case CHUNK_OBJECT: chunk_OBJECT(); break; default:; } popChunk(); } }
void Loader3ds::chunk_OBJECT () { //get object name String id = readString(); //Proccess sub-chunks while (!isChunkDone()) { ChunkInfo subChunk; readChunkInfo(&subChunk); pushChunk(subChunk); switch(subChunk.id) { case CHUNK_MESH: chunk_MESH(id); break; default:; } popChunk(); } }
//--------------------------------------------------------------------- void StreamSerialiser::writeChunkEnd(uint32 id) { checkStream(false, false, true); Chunk* c = popChunk(id); // update the sizes size_t currPos = mStream->tell(); c->length = static_cast<uint32>(currPos - c->offset - CHUNK_HEADER_SIZE); // seek to 'length' position in stream for this chunk // skip id (32) and version (16) mStream->seek(c->offset + sizeof(uint32) + sizeof(uint16)); write(&c->length); // write updated checksum uint32 checksum = calculateChecksum(c); write(&checksum); // seek back to previous position mStream->seek(currPos); OGRE_DELETE c; }
StringBuilder::~StringBuilder() { while (chunk != NULL) popChunk(); }
void Loader3ds::chunk_MESH_FACE_LIST (PolyMesh *mesh, VertArray *verts, UVArray *uvcoords, FaceArray *faces) { //Read number of faces Int16 faceCount = 0; if (file.readLE(&faceCount, 2) != 2) return; for (int i=0; i<faceCount; ++i) { //Read vertex indices Int16 i1, i2, i3; Int16 flag; if (file.readLE(&i1, 2) != 2) return; if (file.readLE(&i2, 2) != 2) return; if (file.readLE(&i3, 2) != 2) return; if (file.readLE(&flag, 2) != 2) return; //Make sure indices are in vertex range if (i1 < 0 || i1 >= (Int16) verts->size()) return; if (i2 < 0 || i2 >= (Int16) verts->size()) return; if (i3 < 0 || i3 >= (Int16) verts->size()) return; //Add face to mesh PolyMesh::Vertex* v[3] = { verts->elementAt(i1), verts->elementAt(i2), verts->elementAt(i3) }; PolyMesh::Face* face = mesh->addFace(v, 3); faces->pushBack(face); //Make sure indices are in UV range if (i1 >= (Int16) uvcoords->size()) continue; if (i2 >= (Int16) uvcoords->size()) continue; if (i3 >= (Int16) uvcoords->size()) continue; //Apply UV coordinates //TODO: Add UV face instead //DMesh::HalfEdge *h = face->hedgeTo(v[0]); //if (h == NULL) return; //h->uv = uvcoords->elementAt(i1); //h->nextHedge()->uv = uvcoords->elementAt(i2); //h->nextHedge()->nextHedge()->uv = uvcoords->elementAt(i3); } //Process sub-chunks while (!isChunkDone()) { ChunkInfo subChunk; readChunkInfo(&subChunk); pushChunk(subChunk); switch(subChunk.id) { case CHUNK_MESH_FACE_SMOOTH_GROUP_LIST: chunk_MESH_FACE_SMOOTH_GROUP_LIST(mesh, faces); break; default:; } popChunk(); } }