Ejemplo n.º 1
0
/* static */
GfMatrix4d
GusdPrimWrapper::computeTransform( 
        const UsdPrim&              prim,
        UsdTimeCode                 time,
        const UT_Matrix4D&          houXform,
        const GusdSimpleXformCache& xformCache ) {

    // We need the transform into the prims space.
    // If the prim is in a hierarchy that we have written on this frame, 
    // its transform will be in the xformCache. Otherwise, we can read it 
    // from the global cache. 
    //
    // The transform cache is necessary because the gobal cache 
    // will only contain transform that we read from the stage and 
    // not anything that we have modified.

    UT_Matrix4D primXform;
    auto it = xformCache.find( prim.GetPath() );
    if( it != xformCache.end() ) {
        primXform = it->second;
    }
    else if( !GusdUSD_XformCache::GetInstance().GetLocalToWorldTransform( 
                        prim,
                        time,
                        primXform )) {
        TF_WARN( "Failed to get transform for %s.", prim.GetPath().GetText() );
        primXform.identity();
    }
    return GusdUT_Gf::Cast( houXform ) / GusdUT_Gf::Cast( primXform );
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
void
GusdGU_PackedUSD::setTransform( const UT_Matrix4D& mx )
{
    UT_Vector3D p;
    mx.getTranslates(p);
    
    GEO_PrimPacked *prim = getPrim();
    prim->setLocalTransform(UT_Matrix3D(mx));
    prim->setPos3(0, p );
}
Ejemplo n.º 4
0
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, &currentProgram );
	
	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 );
	}
}
Ejemplo n.º 5
0
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 ) );
        }
    }
}