void loadMeshes( const std::string& fn, const CalCoreModel* calCoreModel, MeshesVector& meshes ) throw (std::runtime_error) { FILE* f = fopen( fn.c_str(), "rb" ); if ( f == NULL ) { throw std::runtime_error( "Can't open " + fn ); } FileCloser closeOnExit( f ); // FileBuffer setReadBufferOfSize( f, 1*1024*1024 ); <- not so much difference // -- Check version -- int version; READ_I32( version ); if ( version != HW_MODEL_FILE_VERSION ) { fclose( f ); throw std::runtime_error( "Incorrect file version " + fn + ". Try rerun osgCalPreparer." ); } // -- Read mesh descriptions -- int meshesCount = 0; READ_I32( meshesCount ); meshes.resize( meshesCount ); for ( int i = 0; i < meshesCount; i++ ) { MeshData* m = new MeshData; meshes[i] = m; // -- Read name -- int nameBufSize; READ_I32( nameBufSize ); if ( nameBufSize > 1024 ) { throw std::runtime_error( "Too long mesh name (incorrect meshes.cache file?)." ); } char name[ 1024 ]; READ_( m->name, name, nameBufSize ); m->name = std::string( &name[0], &name[ nameBufSize ] ); // -- Read material -- int coreMaterialThreadId; READ_I32( coreMaterialThreadId ); m->coreMaterial = const_cast< CalCoreModel* >( calCoreModel )-> getCoreMaterial( coreMaterialThreadId ); // -- Read bone parameters -- READ_I32( m->rigid ); READ_I32( m->rigidBoneId ); READ_I32( m->maxBonesInfluence ); // -- Read bonesIndices -- int biSize = 0; READ_I32( biSize ); m->bonesIndices.resize( biSize ); for ( int bi = 0; bi < biSize; bi++ ) { READ_I32( m->bonesIndices[ bi ] ); } // -- Read boundingBox -- assert( sizeof ( m->boundingBox ) == 6 * 4 ); // must be 6 floats READ_STRUCT( m->boundingBox ); } // -- Read meshes buffers -- while ( !feof( f ) ) { readBuffer( meshes, f, fn ); } }
int read_thrift(char *ptr, int len, ThriftMessage *tm) { int off; int x; int fieldId; char fieldType; memset(tm, 0, sizeof(*tm)); off = 0; READ_I32(ptr, off, len, x); // ASSERT version stuff tm->messageType = x & 0xff; READ_STRING(ptr, off, len, tm->name_len, tm->name_ptr); READ_I32(ptr, off, len, tm->seqid); while(1) { READ_I8(ptr, off, len, fieldType); if(fieldType == T_STOP) break; READ_I16(ptr, off, len, fieldId); if(fieldId > MAX_FIELD_ID || fieldId < 0) { printf("Ignoring field with out of range id, id = %d, max = %d", MAX_FIELD_ID, fieldId); fieldId = -1; } if(fieldId >= 0) { tm->fields[fieldId].present = 1; tm->fields[fieldId].fieldType = fieldType; } switch(fieldType) { case T_STOP: break; case T_VOID: continue; case T_BOOL: // case T_BYTE: would be a dupe case T_I08: CHECK_LEN(off, len, 1); if(fieldId >= 0) { tm->fields[fieldId].val_len = 1; tm->fields[fieldId].val_ptr = ptr + off; tm->fields[fieldId].val_val = (int) ptr[off]; } off += 1; break; case T_I16: CHECK_LEN(off, len, 2); if(fieldId >= 0) { short s; tm->fields[fieldId].val_len = 2; tm->fields[fieldId].val_ptr = ptr + off; memcpy(&s, ptr + off, 2); tm->fields[fieldId].val_val = (int) ntohs(s); } off += 2; break; case T_I32: CHECK_LEN(off, len, 4); if(fieldId >= 0) { int i; tm->fields[fieldId].val_len = 4; tm->fields[fieldId].val_ptr = ptr + off; memcpy(&i, ptr + off, 4); tm->fields[fieldId].val_val = ntohl(i); } off += 4; break; case T_U64: case T_I64: case T_DOUBLE: CHECK_LEN(off, len, 8); if(fieldId >= 0) { tm->fields[fieldId].val_len = 8; tm->fields[fieldId].val_ptr = ptr + off; } off += 8; break; // Treat all of these as just length-delimited case T_STRING: // case T_UTF7: duplicate case T_STRUCT: case T_MAP: case T_SET: case T_LIST: case T_UTF8: case T_UTF16: if(fieldId >= 0) { READ_STRING(ptr, off, len, tm->fields[fieldId].val_len, tm->fields[fieldId].val_ptr); } else { char *p_ign; int l_ign; READ_STRING(ptr, off, len, l_ign, p_ign); } break; } } return off; too_short: return 0; }
static void readBuffer( MeshesVector& meshes, FILE* f, const std::string& fn ) { int32_t meshIndex; // READ_I32( meshIndex ); if ( fread( &meshIndex, 4, 1, f ) != 1 ) { if ( feof( f ) ) { return; // no error, file ended } else { throw std::runtime_error( "Can't read meshIndex" + std::string(" from ") + fn ); } } MeshData* m = meshes[ meshIndex ].get(); int bufferType; int bufferSize; READ_I32( bufferType ); READ_I32( bufferSize ); #define CASE( _type, _name, _data_type ) \ case BT_##_type: \ m->_name = new _data_type( bufferSize ); \ READ( m->_name ); \ break // printf( "reading %d mesh, buffer type = %d (0x%08X), buffer size = %d\n", // meshIndex, bufferType, bufferType, bufferSize ); // fflush( stdout ); switch ( bufferType & BT_MASK ) { case BT_INDEX: switch ( bufferType & ET_MASK ) { case ET_UBYTE: m->indexBuffer = new osg::DrawElementsUByte( osg::PrimitiveSet::TRIANGLES, bufferSize ); break; case ET_USHORT: m->indexBuffer = new osg::DrawElementsUShort( osg::PrimitiveSet::TRIANGLES, bufferSize ); break; case ET_UINT: m->indexBuffer = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, bufferSize ); break; default: { char err[ 1024 ]; sprintf( err, "Unknown index buffer element type %d (0x%08X)", bufferType & ET_MASK, bufferType & ET_MASK ); throw std::runtime_error( err ); } } READ( m->indexBuffer ); break; CASE( VERTEX, vertexBuffer, VertexBuffer ); CASE( WEIGHT, weightBuffer, WeightBuffer ); CASE( MATRIX_INDEX, matrixIndexBuffer, MatrixIndexBuffer ); CASE( NORMAL, normalBuffer, NormalBuffer ); CASE( TEX_COORD, texCoordBuffer, TexCoordBuffer ); CASE( TANGENT_AND_HANDEDNESS, tangentAndHandednessBuffer, TangentAndHandednessBuffer ); default: { char err[ 1024 ]; sprintf( err, "Unknown buffer type %d (0x%08X)", bufferType, bufferType ); throw std::runtime_error( err ); } } #undef CASE }