📄 gribparser.cpp
字号:
bool RibParser::handleTransform( const RibData& data ){ if ( data[ 1 ].getType() != RibData::LEAF_ARRAY ) { fprintf(stderr, "Bad Transform Syntax\n"); return false; } const RibData& arr = data[ 1 ]; if ( arr.size() != 16 ) { fprintf(stderr, "Array is not of size 16\n"); return false; } double tempmatrix[16]; for ( uint i = 0; i < 16; i++ ) tempmatrix[i] = arr.doubleVal( i ); matrixTranspose( tempmatrix, tempmatrix ); setObjectTransform( tempmatrix ); return true;}bool RibParser::handleConcatTransform( const RibData& data ){ if ( data[ 1 ].getType() != RibData::LEAF_ARRAY ) { fprintf(stderr, "Bad Transform Syntax"); return false; } const RibData& arr = data[ 1 ]; if ( arr.size() != 16 ) { fprintf(stderr, "Array is not of size 16\n"); return false; } double tempmatrix[16]; for ( uint i = 0; i < 16; i++ ) tempmatrix[i] = arr.doubleVal( i ); matrixTranspose( tempmatrix, tempmatrix ); multiplyTransform( tempmatrix ); return true;}bool RibParser::handleTranslate( const RibData& data ){ if ( data.size() < 4 ) { fprintf(stderr, "Bad translate syntax. Expected dx dy dz, only have %d arguments", data.size() - 1); //data.debugPrint( cerr, 3 ); return false; } else { double translate[16]; matrixMakeIdentity( translate ); translate[ 3 ] = data[ 1 ].asDouble(); translate[ 7 ] = data[ 2 ].asDouble(); translate[ 11 ] = data[ 3 ].asDouble(); multiplyTransform( translate ); return true; }}bool RibParser::handleReadArchive( const RibData& data ){ if ( data.size() < 2 ) { fprintf(stderr, "ReadArchive needs 1 argument, only has %d\n", data.size() - 1); //data.debugPrint( cerr, 3 ); return false; } string filename = baseDir + data[1].asString(); // Store the old baseDir, it gets clobbered. string old_baseDir = baseDir; baseDir = ""; // Let's hear it for recursion bool success = createScene(filename); baseDir = old_baseDir; return success;}bool RibParser::handleObjectBegin( const RibData& data ){ if ( data.size() < 2 ) { fprintf(stderr, "Error in RIB: ObjectBegin requires 1 argument, has %d\n", data.size() - 1); return false; } // These variables are acted on in handleLine in_object_definition = true; curr_object = data[ 1 ].asInt(); return true;}bool RibParser::handleObjectEnd( const RibData& data ){ in_object_definition = false; return true;}bool RibParser::handleObjectInstance( const RibData& data ){ if ( data.size() < 2 ) { fprintf(stderr, "Error in RIB: ObjectBegin requires 1 argument, has %d\n", data.size() - 1); return false; } bool success = true; int instanced_object = data[ 1 ].asInt(); RibData &object = getObjectDefinition( instanced_object ); //object.recreatePointers(); for ( int i = 0; i < object.size(); i++ ) { //object[ i ].recreatePointers(); success = handleLine( object[ i ] ) && success; } return success;}bool RibParser::handleFormat( const RibData& data ){ if ( data.size() < 4 ) { fprintf(stderr, "Format requires 3 arguments, %d provided.\n", data.size() - 1); return false; } else { // Because these aren't attached to the camera in Rib like Dart wants, we'll // just store them, and then when we're done parsing, go back and set the // values on the camera image_width = data[ 1 ].asInt(); image_height = data[ 2 ].asInt(); // We could get the pixel aspect ratio here if we wanted it. // We'll just assume square pixels return true; }}bool RibParser::handlePixelSamples( const RibData& data ){ if ( data.size() < 3 ) { fprintf(stderr, "Format requires 2 arguments, %d provided.\n", data.size() - 1); return false; } else { int pixel_samples_x = data[ 1 ].asInt(); int pixel_samples_y = data[ 2 ].asInt(); pixel_samples = pixel_samples_x * pixel_samples_y; m_pScene->GetCamera()->SetRaysPerPixel(pixel_samples); return true; }}bool RibParser::handleImager( const RibData& data ){ // I'll just assume that they're using the 'background' imager, if they're using anything. double background_color[ 4 ] = { 0, 0, 0, 1 }; bool success = data.fillDoubleArrayFromOptionalArg( "background", background_color, 3 ); m_pScene->SetBackgroundColor(0, background_color[0], background_color[1], background_color[2]); return success;}bool RibParser::handleProjection( const RibData& data ){ // I'll just assume that they're using perspective. if ( data.hasOptionalArg( "fov" ) ) { // This is much the same deal as the resolution - store for later double fov_as_degrees; if ( data.fillDoubleArrayFromOptionalArg( "fov", &fov_as_degrees, 1 ) ) { // Only set the fov if we successfully get one. // Convert to radians fov = fov_as_degrees / 180.0 * 3.141592653589793238462643; } } return true;}bool RibParser::handleDepthOfField( const RibData& data ){ if ( data.size() < 4 ) { fprintf(stderr, "Bad number of arguments to DepthOfField. Requires at least 3, has %d\n", data.size() - 1); //data.debugPrint( cerr, 3 ); return false; } else { double fstop; double focal_length; fstop = data[1].asDouble(); focal_length = data[2].asDouble(); focal_distance = data[3].asDouble(); // Compute lens diameter lens_diameter = focal_length / fstop; } return true;}bool RibParser::handleAttribute( const RibData& data ){ if ( data.size() < 4 ) { fprintf(stderr, "Bad number of arguments to Attribute. Requires at least 3, has %d\n", data.size() - 1); //data.debugPrint( cerr, 3 ); return false; } else { string attr_class = data[ 1 ].asString(); string attr_name = data[ 2 ].asString(); setAttribute( attr_class, attr_name, data[ 3 ] ); return true; }}bool RibParser::handleColor( const RibData& data ){ if ( data.size() < 2 || data[1].size() != 3 ) { fprintf(stderr, "Color command invalid argument sizes\n"); //data.debugPrint( cerr, 3 ); return false; } else { double temp_color[3]; for ( uint icolor = 0; icolor < 3; icolor++ ) temp_color[ icolor ] = data[ 1 ].doubleVal( icolor ); setColor( temp_color ); return true; }}bool RibParser::handleSurface( const RibData& data ){ // Colors, and their defaults double cd[ 4 ] = { .5, .5, .5, 1 }; double cs[ 4 ] = { 1, 1, 1, 1 }; double cr[ 4 ] = { 1, 1, 1, 1 }; double ct[ 4 ] = { 0, 0, 0, 1 }; double ca[ 4 ] = { .1, .1, .1, 1 }; double ce[ 4 ] = { 0, 0, 0, 1 }; // This emissive color comes from the state block, via the command AreaLightSource // Scalar properties, and their defaults double ior = 1.0; // index of refraction double phong = 1.0; double glossiness = 1.0; double translucency = 0.0; if ( data.size() < 2 ) { fprintf(stderr, "Bad number of arguments to Surface. Requires at least 1, has %d\n", data.size() - 1); //data.debugPrint( cerr, 3 ); return false; } else { string surface_type = data[ 1 ].asString(); if ( surface_type == "cs655surface" ) { getColor( cd ); // Diffuse color is from a previous command. data.fillDoubleArrayFromOptionalArg( "specularcolor", cs, 3 ); data.fillDoubleArrayFromOptionalArg( "reflectedcolor", cr, 3 ); data.fillDoubleArrayFromOptionalArg( "transmittedcolor", ct, 3 ); data.fillDoubleArrayFromOptionalArg( "ambientcolor", ca, 3 ); data.fillDoubleArrayFromOptionalArg( "indexofrefraction", &ior, 1 ); data.fillDoubleArrayFromOptionalArg( "phong", &phong, 1 ); data.fillDoubleArrayFromOptionalArg( "glossiness", &glossiness, 1 ); data.fillDoubleArrayFromOptionalArg( "translucency", &translucency, 1 ); // Emissive color comes from the AreaLightSource shader for ( uint irgb = 0; irgb < 3; irgb++ ) ce[ irgb ] = state.back().emissive_color[ irgb ]; } else { fprintf(stderr, "Unhandled surface shader %s\n", surface_type.c_str()); //data.debugPrint( cerr, 3 ); return false; } // Make the material GRayTraceMaterial* pMaterial = new GRayTraceMaterial(); m_pScene->AddMaterial(pMaterial); pMaterial->SetColor(GRayTraceMaterial::Diffuse, cd[0], cd[1], cd[2]); pMaterial->SetColor(GRayTraceMaterial::Specular, cs[0], cs[1], cs[2]); pMaterial->SetColor(GRayTraceMaterial::Reflective, cr[0], cr[1], cr[2]); pMaterial->SetColor(GRayTraceMaterial::Transmissive, ct[0], ct[1], ct[2]); pMaterial->SetColor(GRayTraceMaterial::Ambient, ca[0], ca[1], ca[2]); pMaterial->SetColor(GRayTraceMaterial::Emissive, ce[0], ce[1], ce[2]); pMaterial->SetIndexOfRefraction(ior); pMaterial->SetSpecularExponent(phong); pMaterial->SetGlossiness(glossiness); pMaterial->SetCloudiness(translucency); // It should be noted that this way of doing textures isn't really RIB friendly. // But it's easier than parsing Pixar's .tex format. if ( data.hasOptionalArg( "texturefile" ) ) { GImage* pTextureImage = new GImage(); const RibData& filename_data = data.findOptionalArg( "texturefile" ); string filename = baseDir + filename_data.stringVal( 0 ); if(pTextureImage->LoadFile(const_cast< char* >(filename.c_str()))) pMaterial->SetTextureImage(pTextureImage, true); else { fprintf(stderr, "Unable to load file %s as a texture\n", filename.c_str()); delete(pTextureImage); } } // Set the current material in the parser state setMaterial(pMaterial); return true; }}bool RibParser::handleLight( const RibData& data ){ bool is_ambient = false, is_directional = false, is_point = false; double color[ 4 ] = { 1, 1, 1, 1 }; double direction[ 4 ] = { 0, 0, 1, 1 }; double location[ 4 ] = { 0, 0, 0, 1 }; double jitter = 0; uint i; if ( data.size() < 3 ) { fprintf(stderr, "Bad number of arguments to LightSource. Requires at least 1, has %d\n", data.size() - 1); //data.debugPrint( cerr, 3 ); return false; } else { string light_type = data[ 1 ].asString(); if ( light_type == "cs655ambientLight" ) { is_ambient = true; data.fillDoubleArrayFromOptionalArg( "lightcolor", color, 3 ); } else if ( light_type == "cs655directionalLight" ) { is_directional = true; data.fillDoubleArrayFromOptionalArg( "lightcolor", color, 3 ); data.fillDoubleArrayFromOptionalArg( "to", direction, 3 ); // Reverse the 'to' to become the direction for ( uint idir = 0; idir < 3; idir++ ) direction[idir] = -direction[idir]; data.fillDoubleArrayFromOptionalArg( "jitter", &jitter, 1 ); } else if ( light_type == "cs655pointLight" ) { is_point = true; data.fillDoubleArrayFromOptionalArg( "lightcolor", color, 3 ); data.fillDoubleArrayFromOptionalArg( "from", location, 3 ); data.fillDoubleArrayFromOptionalArg( "jitter", &jitter, 1 ); } else if ( light_type == "pointlight" ) { // This is an example of supporting other shader types with our model. // We just need to fill the global params of the function, and tell it // that we want to create a point light. is_point = true; double intensity; // This is a multiplier for color. data.fillDoubleArrayFromOptionalArg( "intensity", &intensity, 1 ); data.fillDoubleArrayFromOptionalArg( "lightcolor", color, 3 ); data.fillDoubleArrayFromOptionalArg( "from", location, 3 ); // Multiply in the intensity. for ( i = 0; i < 3; i++ ) color[i] *= intensity; // That's all we need to do to support Renderman's default pointlight shader. } else if ( light_type == "distantlight" ) { // This is Renderman's built-in directional light shader is_directional = true; double intensity; double from[3] = { 0, 0, 0 }; double to[3] = { 0, 0, 1 }; data.fillDoubleArrayFromOptionalArg( "intensity", &intensity, 1 ); data.fillDoubleArrayFromOptionalArg( "lightcolor", color, 3 ); data.fillDoubleArrayFromOptionalArg( "from", from, 3 ); data.fillDoubleArrayFromOptionalArg( "to", to, 3 ); for ( i = 0; i < 3; i++ ) color[i] *= intensity; // Subtract to and from to get the direction for ( i = 0; i < 3; i++ ) direction[ i ] = from[ i ] - to[ i ]; } else if ( light_type == "mtorDirectionalLight" ) { // This is mtor's default directional light shader is_directional = true; double intensity; data.fillDoubleArrayFromOptionalArg( "intensity", &intensity, 1 ); data.fillDoubleArrayFromOptionalArg( "lightcolor", color, 3 ); data.fillDoubleArrayFromOptionalArg( "float intensity", &intensity, 1 ); data.fillDoubleArrayFromOptionalArg( "color lightcolor", color, 3 ); for ( i = 0; i < 3; i++ ) color[i] *= intensity; // The direction of this light is based on the current transformation. double direction_point[4] = { 0, 0, -1, 1 }; double transform[16]; getObjectTransform( transform ); matrixMultiplyPoint( direction, transform, direction_point ); } else { fprintf(stderr, "Unhandled light shader: %s\n", light_type.c_str()); //data.debugPrint( cerr, 3 ); return false; } // At this point, we know the light params, and just need to build it. if ( is_ambient ) m_pScene->SetAmbientLight(color[0], color[1], color[2]); if ( is_directional ) { m_pScene->AddLight(new GRayTraceDirectionalLight(direction[0], direction[1], direction[2], color[0], color[1], color[2], jitter)); } if ( is_point ) { m_pScene->AddLight(new GRayTracePointLight(location[0], location[1], location[2], color[0], color[1], color[2], jitter)); } return true; }}bool RibParser::handleSphere( const RibData& data ){ // We only pay attention to the radius double radius = 1.0; if ( data.size() < 3 ) { fprintf(stderr, "Bad number of arguments to Sphere. Requires at least 1, has %d\n", data.size() - 1); //data.debugPrint( cerr, 3 ); return false; } else { radius = data[ 1 ].asDouble(); // Probably take a point at the origin of object space, and translate it with the object-to-world matrix // This will let us find the position of the center of the sphere in world space double point[4] = { 0, 0, 0, 1 }; double curr_transform[16]; getObjectTransform( curr_transform ); matrixMultiplyPoint( point, curr_transform, point ); // Create the sphere GRayTraceMaterial* pMaterial = getMaterial(); GRayTraceSphere* pSphere = new GRayTraceSphere(pMaterial, point[0], point[1], point[2], radius); m_pScene->AddObject(pSphere); if(pMaterial) { GRayTraceColor* pEmissive = pMaterial->GetColor(GRayTraceMaterial::Emissive, NULL); if ( !pEmissive->IsBlack() ) { GRayTraceAreaLight* pAreaLight = new GRayTraceAreaLight(pSphere, pEmissive->r, pEmissive->g, pEmissive->b); m_pScene->AddLight( pAreaLight ); } } return true; }}bool RibParser::handleNuPatch( const RibData& data ){ // We don't actually expect you to handle nurbs patches.. // This is just a hack to easily produce files with spheres. // Any nurbs patch will be replaced with a unit sphere at the origin of the current object space // So, as long as your nurbs patches are unit spheres at the origin, this should be correct.. :) RibData hack_sphere; hack_sphere.append( RibData( "Sphere" ) ); hack_sphere.append( RibData( "1.0" ) ); hack_sphere.append( RibData( "-1.0" ) ); hack_sphere.append( RibData( "1.0" ) ); hack_sphere.append( RibData( "360.0" ) ); return handleSphere( hack_sphere );}bool RibParser::handlePointsGeneralPolygons( const RibData& data ){ uint npolys; uint npoints; uint nnormals = 0; uint ntexcoords = 0; vector< uint > nvertices; vector< vector< uint > > vertex_indices; double *points = NULL; double *normals = NULL; double *texcoords = NULL; bool homogeneous; uint ipt; uint ipoly; if ( data.size() < 6 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -