📄 gribparser.cpp
字号:
void RibParser::matrixMultiplyPoint( double dest[4], const double matrix[16], const double point[4] ){ double temp[4] = { 0, 0, 0, 0 }; uint i; for ( i = 0; i < 4; i++ ) for ( uint j = 0; j < 4; j++ ) temp[i] += matrix[ i*4 + j ] * point[ j ]; // Copy to the dest for ( i = 0; i < 4; i++ ) dest[i] = temp[i];}void RibParser::matrixTranspose( double dest[16], const double matrix[16] ){ double temp[16]; uint i; for ( i = 0; i < 4; i++ ) for ( uint j = 0; j < 4; j++ ) temp[ i*4 + j ] = matrix[ j*4 + i ]; for ( i = 0; i < 16; i++ ) dest[i] = temp[i];}void RibParser::matrixScaleAugRow( double matrix[32], int irow, double factor ){ int offset = irow * 8; for ( uint i = 0; i < 8; i++ ) matrix[ offset + i ] *= factor;}void RibParser::matrixAddScaledAugRow( double matrix[32], int source_row, int dest_row, double factor ){ int source_offset = source_row * 8; int dest_offset = dest_row * 8; for ( uint i = 0; i < 8; i++ ) matrix[ dest_offset + i ] += factor * matrix[ source_offset + i ];}bool RibParser::matrixInvert( double dest[16], const double matrix[16] ){ double val; double aug_matrix[32] = { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; int i, j; // Copy matrix to left block of augmented matrix for ( i = 0; i < 4; i++ ) for ( j = 0; j < 4; j++ ) aug_matrix[ i*8 + j ] = matrix[ i*4 + j ]; // Zero out below the diagonal for ( i=0; i<4; i++ ) { val = aug_matrix[i*8+i]; if (val==0.0) return 0; // too hard or non-invertible. matrixScaleAugRow( aug_matrix, i, 1.0/val ); aug_matrix[ i*8+i ] = 1.0; // Make sure it's exactly 1, like it should be. for ( uint j=i+1; j<4; j++ ) { val = aug_matrix[ j*8+i ]; if ( val == 0.0 ) continue; // Already zero'd out matrixAddScaledAugRow( aug_matrix, i, j, -val ); aug_matrix[ j*8+i ] = 0.0; // Make sure it's 0. } } // Zero out above the diagonal for ( i=3; i>=1; i-- ) { for ( j=i-1; j>=0; j-- ) { val = aug_matrix[ j*8 + i ]; if ( val == 0.0 ) continue; matrixAddScaledAugRow( aug_matrix, i, j, -val ); aug_matrix[ j*8 + i ] = 0.0; } } // Copy right block of the aug matrix to the dest for ( i = 0; i < 4; i++ ) for ( j = 0; j < 4; j++ ) dest[ i*4 + j ] = aug_matrix[ i*8 + j+4 ]; return true;}////////////////////// Rib Data////////////////////// By default, this will be an array.RibData::RibData() :type( NODE_ARRAY ), file_line( -1 ){}RibData::RibData(int type) :type( type ), file_line( -1 ){}RibData::RibData( const RibData& other ): type( other.type ), file_line( other.file_line ), dataPtr( other.dataPtr ), childVector( other.childVector ), valArray( other.valArray ){ // Note that we don't create the pointers vector, because most of the time it's not used. // If you're going to use it, make sure the lengths match first. // Or, you could always call recreatePointers();}RibData& RibData::operator=( const RibData& other ){ type = other.type; file_line = other.file_line; dataPtr = other.dataPtr; childVector = other.childVector; valArray = other.valArray; //recreatePointers(); return *this;}RibData::RibData( const char* data, bool quoted ): dataPtr( data ){ if ( quoted ) type = QUOTED_STRING; else type = UNDETECTED;}void RibData::append( const RibData& new_data ){#ifdef PARSER_DEBUG if ( type != NODE_ARRAY ) fprintf(stderr, "Trying to append datum to a non-nodearray RibData.\n");#endif childVector.push_back( new_data );}void RibData::appendVal( const char* new_val ){#ifdef PARSER_DEBUG if ( type != LEAF_ARRAY ) { fprintf(stderr, "Error: Trying to append a value to something that's not an Array\n"); }#endif valArray.push_back( new_val );}vector< const char* >& RibData::accessVals(){ return valArray;}std::vector< RibData >::iterator RibData::getBackIt(){#ifdef PARSER_DEBUG if ( childVector.empty() ) fprintf(stderr, "Trying to get the end of an empty RibData array\n"); if ( type != NODE_ARRAY ) fprintf(stderr, "Trying to get the back iterator from a non-nodearray RibData\n");#endif std::vector< RibData >::iterator retme = childVector.end(); --retme; return retme;}RibData& RibData::back(){#ifdef PARSER_DEBUG if ( type != NODE_ARRAY ) fprintf(stderr, "Trying to get the back of non-nodearray ribdata\n");#endif return childVector.back();}void RibData::clear(){ childVector.clear(); valArray.clear();}/*void RibData::recreatePointers(){ if ( childPtrs.size() != childList.size() ) { childPtrs.clear(); childPtrs.resize( childList.size(), (RibData*)0xbeefdeed ); int i = 0; for ( list< RibData >::iterator lit = childList.begin(); lit != childList.end(); ++lit, ++i ) childPtrs[ i ] = &*lit; }}*//*// This debugPrint isn't the cleanest..void RibData::debugPrint( ostream& out, int offset ) const {#ifdef PARSER_DEBUG string lines( "=== " ); string pad( offset, ' ' ); out << pad; if ( type == NODE_ARRAY || type == LEAF_ARRAY ) out << lines; out << "Type: "; switch( type ) { case QUOTED_STRING: out << "Quoted String"; break; case NODE_ARRAY: out << "Node"; break; case LEAF_ARRAY: out << "Leaf"; break; case UNDETECTED: out << "Data"; break; default: out << "Invalid"; break; } out << " Value: "; if ( type == NODE_ARRAY ) { out << endl; for ( vector< RibData >::const_iterator cit = childVector.begin(); cit != childVector.end(); ++cit ) { cit->debugPrint( out, offset + 3 ); } } else if ( type == LEAF_ARRAY ) { for ( vector< const char* >::const_iterator vit = valArray.begin(); vit != valArray.end(); ++vit ) out << *vit << " "; out << endl; } else { out << dataPtr << endl; }#endif}*/int RibData::size() const{ switch ( type ) { case NODE_ARRAY: return childVector.size(); case LEAF_ARRAY: return valArray.size(); default: fprintf(stderr, "Trying to get the size of a non-array RibData\n"); return 0; }}RibData& RibData::operator[]( int index ){#ifdef PARSER_DEBUG if ( type != NODE_ARRAY ) fprintf(stderr, "Trying to get an array element on a RibData that's not an Array\n");#endif return childVector[ index ];}const RibData& RibData::operator[]( int index ) const{#ifdef PARSER_DEBUG if ( type != NODE_ARRAY ) fprintf(stderr, "Trying to get an array element on a RibData that's not an Array\n");#endif return childVector[ index ];}double RibData::doubleVal( int index ) const{#ifdef PARSER_DEBUG if ( type != LEAF_ARRAY ) fprintf(stderr, "Trying to get a double val from a non-leafarray\n");#endif return atof( valArray[ index ] );}int RibData::intVal( int index ) const{#ifdef PARSER_DEBUG if ( type != LEAF_ARRAY ) fprintf(stderr, "Trying to get an int val from a non-leafarray\n");#endif return atoi( valArray[ index ] );}const char* RibData::stringVal( int index ) const{#ifdef PARSER_DEBUG if ( type != LEAF_ARRAY ) { fprintf(stderr, "Trying to get a string val from a non-leafarray\n"); return ""; }#endif if ( valArray[ index ][0] == '\"' ) return &valArray[ index ][ 1 ]; return valArray[ index ];}int RibData::getType() const{ return type;}void RibData::reserveCapacity( int new_capacity ){ if ( type == NODE_ARRAY ) childVector.reserve( new_capacity ); else if ( type == LEAF_ARRAY ) valArray.reserve( new_capacity );#ifdef PARSER_DEBUG else fprintf(stderr, "Trying to reserve capacity on non-array RibData\n");#endif}string RibData::asString() const{#ifdef PARSER_DEBUG if ( type == NODE_ARRAY || type == LEAF_ARRAY ) fprintf(stderr, "Trying to get a data value from an array.\n");#endif return string( dataPtr );};double RibData::asDouble() const{#ifdef PARSER_DEBUG if ( type == NODE_ARRAY || type == LEAF_ARRAY ) fprintf(stderr, "Trying to get a double from an array\n");#endif return atof( dataPtr );}int RibData::asInt() const{#ifdef PARSER_DEBUG if ( type == NODE_ARRAY || type == LEAF_ARRAY ) fprintf(stderr, "Trying to get an int from an array\n");#endif return atoi( dataPtr );}bool RibData::hasOptionalArg( const string& arg_name ) const{ if ( type != NODE_ARRAY ) return false; // Two iterators: next is always one greater than next. std::vector< RibData >::const_iterator curr = childVector.begin(); curr++; std::vector< RibData >::const_iterator next = curr; next++; if ( curr == childVector.end() ) return false; while ( next != childVector.end() ) { if ( curr->getType() == QUOTED_STRING && next->getType() == LEAF_ARRAY && curr->dataPtr == arg_name ) { return true; } next++; curr++; } return false;}const RibData& RibData::findOptionalArg( const string& arg_name ) const{ if ( type != NODE_ARRAY ) { fprintf(stderr, "findOptionalArg called on a non-nodearray RibData.\n"); //debugPrint( cerr, 3 ); return *this; } // Two iterators: next is always one greater than next. std::vector< RibData >::const_iterator curr = childVector.begin(); curr++; std::vector< RibData >::const_iterator next = curr; next++; if ( curr != childVector.end() ) { while ( next != childVector.end() ) { if ( curr->getType() == QUOTED_STRING && next->getType() == LEAF_ARRAY && curr->dataPtr == arg_name ) { return *next; } curr++; next++; } } fprintf(stderr, "findOptionalArg couldn't find requested arg %s - are you sure it's there?\n", arg_name.c_str()); //debugPrint( cerr, 3 ); return *this;}bool RibData::fillDoubleArrayFromOptionalArg( const string& arg_name, double* fill_me, int fill_size ) const{ if ( hasOptionalArg( arg_name ) ) { const RibData& sub_array = findOptionalArg( arg_name ); if ( sub_array.size() != fill_size ) { fprintf(stderr, "I have vs6\n"); // fprintf(stderr, "Bad size of arg: %s expected: %s, got %d, %s, fill_size.c_str(), sub_array.size(), arg_name.c_str()); //debugPrint( cerr, 3 ); return false; } for ( int i = 0; i < sub_array.size(); i++ ) { fill_me[ i ] = sub_array.doubleVal( i ); } return true; } // Didn't have that optional arg. return false;}////////////////////// State Block////////////////////StateBlock::StateBlock() :type( ROOTBLOCK ){ RibParser::matrixMakeIdentity( transform ); color[ 0 ] = color[ 1 ] = color[ 2 ] = 0.5; // Dull gray emissive_color[ 0 ] = emissive_color[ 1 ] = emissive_color[ 2 ] = 0.0; // Not a light material = NULL; // Set up the default attribute values. RibData default_renderType( RibData::LEAF_ARRAY ); RibData default_rayDepth( RibData::LEAF_ARRAY ); RibData default_toneMappingConstant( RibData::LEAF_ARRAY ); default_renderType.appendVal( "rayTracing" ); default_rayDepth.appendVal( "4" ); default_toneMappingConstant.appendVal( "1" ); setAttribute( "cs655Setting", "renderType", default_renderType ); setAttribute( "cs655Setting", "rayDepth", default_rayDepth ); setAttribute( "cs655Setting", "toneMappingConstant", default_toneMappingConstant );}StateBlock::StateBlock( int type, const StateBlock& parent ): type( type ){ uint i; for ( i = 0; i < 16; i++ ) transform[ i ] = parent.transform[ i ]; for ( i = 0; i < 3; i++ ) color[ i ] = parent.color[ i ]; for ( i = 0; i < 3; i++ ) emissive_color[ i ] = parent.emissive_color[ i ]; material = parent.material;}RibData& StateBlock::getAttribute( const string& attr_class, const string& attr_name, bool& success ){ std::pair< string, string > key( attr_class, attr_name ); std::map< std::pair< string, string>, RibData >::iterator it; it = attributes.find( key ); if ( it == attributes.end() ) { success = false; return (*(RibData*)(NULL)); } success = true; return it->second;}void StateBlock::setAttribute( const string& attr_class, const string& attr_name, const RibData& data ){ std::pair< string, string > key( attr_class, attr_name ); attributes[ key ] = data;}int StateBlock::getType() const{ return type;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -