void GR_CortexPrimitive::update( RE_Render *r, const GT_PrimitiveHandle &primh, const GR_UpdateParms &p ) { GA_Offset offset = p.geometry.primitiveOffset( m_primId ); const GU_CortexPrimitive *prim = dynamic_cast<const GU_CortexPrimitive *>( p.geometry.getGEOPrimitive( offset ) ); if ( !prim ) { m_scene = 0; m_renderable = 0; return; } m_renderable = IECore::runTimeCast<const IECore::Renderable>( prim->getObject() ); if ( !m_renderable ) { m_scene = 0; return; } IECoreGL::RendererPtr renderer = new IECoreGL::Renderer(); renderer->setOption( "gl:mode", new IECore::StringData( "deferred" ) ); renderer->setOption( "gl:drawCoordinateSystems", new IECore::BoolData( true ) ); renderer->worldBegin(); renderer->transformBegin(); UT_Matrix4D transform; memcpy( transform.data(), r->getUniform( RE_UNIFORM_OBJECT_MATRIX )->getValue(), sizeof(double) * 16 ); renderer->setTransform( IECore::convert<Imath::M44f>( transform ) ); if ( p.dopts.boundBox() ) { const IECore::VisibleRenderable *visible = IECore::runTimeCast<const IECore::VisibleRenderable>( m_renderable ); if ( visible ) { IECore::MeshPrimitive::createBox( visible->bound() )->render( renderer ); } } else { m_renderable->render( renderer ); } renderer->transformEnd(); renderer->worldEnd(); m_scene = renderer->scene(); m_scene->setCamera( 0 ); // houdini will be providing the camera }
void GR_CortexPrimitive::render( RE_Render *r, GR_RenderMode render_mode, GR_RenderFlags flags, const GR_DisplayOption *opt, const RE_MaterialList *materials ) { if ( !m_scene ) { return; } UT_Matrix4D transform; memcpy( transform.data(), r->getUniform( RE_UNIFORM_OBJECT_MATRIX )->getValue(), sizeof(double) * 16 ); GLint currentProgram = 0; glGetIntegerv( GL_CURRENT_PROGRAM, ¤tProgram ); IECoreGL::State *state = getState( render_mode, flags, opt ); if ( render_mode == GR_RENDER_OBJECT_PICK ) { const IECoreGL::Shader *shader = state->get<IECoreGL::ShaderStateComponent>()->shaderSetup()->shader(); glUseProgram( shader->program() ); #if UT_MAJOR_VERSION_INT < 14 glUniform1i( shader->uniformParameter( "objectPickId" )->location, r->getObjectPickID() ); #else /// \todo: this suggestion was provided by SideFx but does not seem to work, // or at least, this change in itself does not enable object picking. I'm // leaving it here for now so we don't lose track of their advice. int *ids = (int*)r->getUniform( RE_UNIFORM_PICK_BASE_ID )->getValue( 0 ); glUniform1i( shader->uniformParameter( "objectPickId" )->location, ids[1] ); #endif } #if UT_MAJOR_VERSION_INT < 14 r->pushMatrix(); r->multiplyMatrix( transform ); m_scene->render( state ); r->popMatrix(); #else UT_Matrix4D proj, view; memcpy( proj.data(), r->getUniform( RE_UNIFORM_PROJECT_MATRIX )->getValue(), sizeof(double) * 16 ); memcpy( view.data(), r->getUniform( RE_UNIFORM_VIEW_MATRIX )->getValue(), sizeof(double) * 16 ); glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadMatrixd( proj.data() ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadMatrixd( (transform * view).data() ); m_scene->render( state ); glPopMatrix(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); #endif if ( render_mode == GR_RENDER_OBJECT_PICK ) { glUseProgram( currentProgram ); } }
void GusdRefinerCollector::finish( GusdRefiner& refiner ) { // If we are building a point instancer, as packed prims are added they // have been collected into m_instancePrims sorted by "srcPrimPath". // Build a GT_PointPrimMesh for each entry in this map. for( auto const & instancerMapIt : m_instancePrims ) { const SdfPath &instancerPrimPath = instancerMapIt.first; const vector<InstPrimEntry>& primArray = instancerMapIt.second; size_t nprims = primArray.size(); DBG( cerr << "Create point instancers for \"" << instancerPrimPath << "\" with " << nprims << " entries" << endl); GT_AttributeListHandle pAttrs = new GT_AttributeList( new GT_AttributeMap() ); // Allocate storage for all the attributes we want to copy. // Assume all entries in the primArray have the same set of attributes. // (They all came from the same detail). const GT_PrimitiveHandle& prim = primArray[0].prim; auto instPtAttrs = prim->getPointAttributes(); GT_Real32Array* pivotArray = nullptr; if( instPtAttrs ) { for( size_t j = 0; j < instPtAttrs->entries(); ++j ) { // Filter attributes that begin with an underscore const char *n = instPtAttrs->getName(j); if( !n || strlen( n ) < 1 || n[0] == '_' ) { continue; } GT_Storage storage = instPtAttrs->get( j )->getStorage(); GT_Size tupleSize = instPtAttrs->get( j )->getTupleSize(); GT_Type typeInfo = instPtAttrs->get( j )->getTypeInfo(); pAttrs = pAttrs->addAttribute( n, newDataArray( storage, nprims, tupleSize, typeInfo ), true ); } } bool hasInstanceIndices = false; if(auto packedUSD = dynamic_cast<const GusdGT_PackedUSD*>( prim.get() )) { if (packedUSD->getInstanceIndex() >= 0) { hasInstanceIndices = true; } } if( auto instUniAttrs = prim->getUniformAttributes() ) { for( size_t j = 0; j < instUniAttrs->entries(); ++j ) { // Filter out attributes that begin with an underscore and // usdprimpath (usdprimpath on instances will confuse the // instancerWrapper). const char *n = instUniAttrs->getName(j); if( !n || strlen( n ) < 1 || n[0] == '_' || string( n ) == GUSD_PRIMPATH_ATTR ) { continue; } if( !pAttrs->hasName( n ) ) { GT_Storage storage = instUniAttrs->get( j )->getStorage(); GT_Size tupleSize = instUniAttrs->get( j )->getTupleSize(); GT_Type typeInfo = instUniAttrs->get( j )->getTypeInfo(); pAttrs = pAttrs->addAttribute( n, newDataArray( storage, nprims, tupleSize, typeInfo ), true ); } } } // Allocate xform attribute used to communicate about the instances // with the instancerWrapper. GT_Real64Array* xformArray = new GT_Real64Array(nprims, 16); bool foundValidTransform = false; GT_Int64Array* instanceIndices = hasInstanceIndices ? new GT_Int64Array(nprims, 1) : NULL; for( size_t primIndex = 0; primIndex < nprims; ++primIndex ) { const GT_PrimitiveHandle& prim = primArray[primIndex].prim; // copy point attribute data from the src prims into prims for // the point instancer. auto instPtAttrs = prim->getPointAttributes(); if( instPtAttrs ) { for( size_t attrIndex = 0; attrIndex < instPtAttrs->entries(); ++attrIndex ) { const char *n = instPtAttrs->getName(attrIndex); if( !n || strlen( n ) < 1 || n[0] == '_' ) { continue; } auto srcData = instPtAttrs->get( attrIndex ); if( auto dstData = pAttrs->get( n ) ) { copyDataArrayItem( dstData, srcData, primIndex, primArray[primIndex].index ); } } if( pivotArray ) { if( auto pos = instPtAttrs->get( "P" ) ) { pivotArray->set( pos->getF32( 0, 0 ), primIndex, 0 ); pivotArray->set( pos->getF32( 0, 1 ), primIndex, 1 ); pivotArray->set( pos->getF32( 0, 2 ), primIndex, 2 ); } } if (hasInstanceIndices) { if(auto packedUSD = dynamic_cast<const GusdGT_PackedUSD*>( prim.get() )) { exint index = packedUSD->getInstanceIndex(); if (index >= 0) { instanceIndices->setTuple(&index, primIndex); } } } } // copy uniform attribute data from the src prims into prims for // the point instancer. auto instUniAttrs = prim->getUniformAttributes(); if( instUniAttrs ) { for( size_t attrIndex = 0; attrIndex < instUniAttrs->entries(); ++attrIndex ) { const char *n = instUniAttrs->getName(attrIndex); if( !n || strlen( n ) < 1 || n[0] == '_' || string(n) == GUSD_PRIMPATH_ATTR ) { continue; } auto srcData = instUniAttrs->get( attrIndex ); if( auto dstData = pAttrs->get( n ) ) { copyDataArrayItem( dstData, srcData, primIndex, primArray[primIndex].index ); } } } // For USD packed prims or geometry packed prims with a usdprimpath // attributes, get the transforms and stuff them into arrays that // can be passed as attributes to the instancerWrapper. if( auto packedUSD = dynamic_cast<const GusdGT_PackedUSD *>( prim.get() )) { const SdfPath primpath(packedUSD->getPrimPath()); UT_Matrix4D xform; packedUSD->getPrimitiveTransform()->getMatrix(xform); xformArray->setTuple(xform.data(), primIndex ); foundValidTransform = true; } else if( auto instance = dynamic_cast<const GT_PrimInstance *>( prim.get() )) { UT_Matrix4D xform; instance->transforms()->get(primArray[primIndex].index)->getMatrix( xform ); xformArray->setTuple(xform.data(), primIndex ); foundValidTransform = true; } } if( foundValidTransform ) { pAttrs = pAttrs->addAttribute( "__instancetransform", xformArray, true ); } if ( hasInstanceIndices ) { pAttrs = pAttrs->addAttribute( "__instanceindex", instanceIndices, true ); } // If the instance prims have a "srcPrimPath" intrinsic (typically // because we are doing an overlay), set the "usdprimpath" attribute on // the point mesh prim so that the point instancer prim gets named properly. GT_AttributeListHandle uniformAttrs; if( !instancerPrimPath.IsEmpty() ) { uniformAttrs = new GT_AttributeList( new GT_AttributeMap() ); auto primPathArray = new GT_DAIndexedString(1); primPathArray->setString( 0, 0, instancerPrimPath.GetText() ); uniformAttrs = uniformAttrs->addAttribute( GUSD_PRIMPATH_ATTR, primPathArray, true ); } // Check for the usdprototypespath attribute in case it is not // a point or primitivie attribute. uniformAttrs = findAndAddStringAttribute(uniformAttrs, "usdprototypespath", prim); // Find and add a custom prototype scope attribute. uniformAttrs = findAndAddStringAttribute(uniformAttrs, "usdprototypesscope", prim); // Add the refined point instancer. If we are overlaying an old point // instancer make sure to use the old type (temporary). if (refiner.m_pointInstancerType == _tokens->PxPointInstancer) { refiner.addPrimitive( new GusdGT_OldPointInstancer( pAttrs, uniformAttrs ) ); } else { refiner.addPrimitive( new GusdGT_PointInstancer( pAttrs, uniformAttrs ) ); } } }