Example #1
0
Imath::Box3f ObjectSource::computeBound( const SceneNode::ScenePath &path, const Gaffer::Context *context, const ScenePlug *parent ) const
{
	Imath::Box3f result;
	IECore::ConstObjectPtr object = sourcePlug()->getValue();

	if( const IECore::VisibleRenderable *renderable = IECore::runTimeCast<const IECore::VisibleRenderable>( object.get() ) )
	{
		result = renderable->bound();
	}
	else if( object->isInstanceOf( IECore::Camera::staticTypeId() ) )
	{
		result = Imath::Box3f( Imath::V3f( -0.5, -0.5, 0 ), Imath::V3f( 0.5, 0.5, 2.0 ) );
	}
	else if( object->isInstanceOf( IECore::CoordinateSystem::staticTypeId() ) )
	{
		result = Imath::Box3f( Imath::V3f( 0 ), Imath::V3f( 1 ) );
	}
	else
	{
		result = Imath::Box3f( Imath::V3f( -0.5 ), Imath::V3f( 0.5 ) );
	}

	if( path.size() == 0 )
	{
		result = Imath::transform( result, transformPlug()->matrix() );
	}
	return result;
}
Example #2
0
		virtual task *execute()
		{
			ScenePlug::PathScope pathScope( m_sceneGadget->m_context.get(), m_scenePath );

			// Update attributes, and compute visibility.

			const bool previouslyVisible = m_sceneGraph->m_visible;
			if( m_dirtyFlags & AttributesDirty )
			{
				const IECore::MurmurHash attributesHash = m_sceneGadget->m_scene->attributesPlug()->hash();
				if( attributesHash != m_sceneGraph->m_attributesHash )
				{
					IECore::ConstCompoundObjectPtr attributes = m_sceneGadget->m_scene->attributesPlug()->getValue( &attributesHash );
					const IECore::BoolData *visibilityData = attributes->member<IECore::BoolData>( "scene:visible" );
					m_sceneGraph->m_visible = visibilityData ? visibilityData->readable() : true;

					IECore::ConstRunTimeTypedPtr glStateCachedTyped = IECoreGL::CachedConverter::defaultCachedConverter()->convert( attributes.get() );
					IECoreGL::ConstStatePtr glStateCached = IECore::runTimeCast<const IECoreGL::State>( glStateCachedTyped );



					IECoreGL::ConstStatePtr visState = NULL;

					deferReferenceRemoval( m_sceneGraph->m_attributesRenderable );
					m_sceneGraph->m_attributesRenderable = AttributeVisualiser::allVisualisations( attributes.get(), visState );

					deferReferenceRemoval( m_sceneGraph->m_state );
					if( visState )
					{
						IECoreGL::StatePtr glState = new IECoreGL::State( *glStateCached );
						glState->add( const_cast< IECoreGL::State* >( visState.get() ) );

						m_sceneGraph->m_state = glState;
					}
					else
					{
						m_sceneGraph->m_state = glStateCached;
					}


					m_sceneGraph->m_attributesHash = attributesHash;
				}
			}

			if( !m_sceneGraph->m_visible )
			{
				// No need to update further since we're not visible.
				return NULL;
			}
			else if( !previouslyVisible )
			{
				// We didn't perform any updates when we were invisible,
				// so we need to update everything now.
				m_dirtyFlags = AllDirty;
			}

			// Update the object - converting it into an IECoreGL::Renderable

			if( m_dirtyFlags & ObjectDirty )
			{
				const IECore::MurmurHash objectHash = m_sceneGadget->m_scene->objectPlug()->hash();
				if( objectHash != m_sceneGraph->m_objectHash )
				{
					IECore::ConstObjectPtr object = m_sceneGadget->m_scene->objectPlug()->getValue( &objectHash );
					deferReferenceRemoval( m_sceneGraph->m_renderable );
					if( !object->isInstanceOf( IECore::NullObjectTypeId ) )
					{
						m_sceneGraph->m_renderable = objectToRenderable( object.get() );
					}
					m_sceneGraph->m_objectHash = objectHash;
				}
			}

			// Update the transform and bound

			if( m_dirtyFlags & TransformDirty )
			{
				m_sceneGraph->m_transform = m_sceneGadget->m_scene->transformPlug()->getValue();
			}

			m_sceneGraph->m_bound = m_sceneGraph->m_renderable ? m_sceneGraph->m_renderable->bound() : Box3f();

			// Update the expansion state

			const bool previouslyExpanded = m_sceneGraph->m_expanded;
			if( m_dirtyFlags & ExpansionDirty )
			{
				m_sceneGraph->m_expanded = m_sceneGadget->m_minimumExpansionDepth >= m_scenePath.size();
				if( !m_sceneGraph->m_expanded )
				{
					m_sceneGraph->m_expanded = m_sceneGadget->m_expandedPaths->readable().match( m_scenePath ) & Filter::ExactMatch;
				}
			}

			// If we're not expanded, then we can early out after creating a bounding box.

			deferReferenceRemoval( m_sceneGraph->m_boundRenderable );
			if( !m_sceneGraph->m_expanded )
			{
				// We're not expanded, so we early out before updating the children.
				// We do however need to see if we have any children, and arrange to
				// draw their bounding box if we do.
				bool haveChildren = m_sceneGraph->m_children.size();
				if( m_dirtyFlags & ChildNamesDirty || !previouslyExpanded )
				{
					IECore::ConstInternedStringVectorDataPtr childNamesData = m_sceneGadget->m_scene->childNamesPlug()->getValue();
					haveChildren = childNamesData->readable().size();
				}

				m_sceneGraph->clearChildren();

				m_sceneGraph->m_bound.extendBy( m_sceneGadget->m_scene->boundPlug()->getValue() );

				if( haveChildren )
				{
					IECore::CurvesPrimitivePtr curvesBound = IECore::CurvesPrimitive::createBox( m_sceneGraph->m_bound );
					m_sceneGraph->m_boundRenderable = boost::static_pointer_cast<const IECoreGL::Renderable>(
						IECoreGL::CachedConverter::defaultCachedConverter()->convert( curvesBound.get() )
					);
				}
				return NULL;
			}

			// We are expanded, so we need to visit all the children
			// and update those too.

			if( !previouslyExpanded )
			{
				m_dirtyFlags = AllDirty;
			}

			// Make sure we have a child for each child name

			if( m_dirtyFlags & ChildNamesDirty )
			{
				IECore::ConstInternedStringVectorDataPtr childNamesData = m_sceneGadget->m_scene->childNamesPlug()->getValue();
				const std::vector<IECore::InternedString> &childNames = childNamesData->readable();
				if( !existingChildNamesValid( childNames ) )
				{
					m_sceneGraph->clearChildren();

					for( std::vector<IECore::InternedString>::const_iterator it = childNames.begin(), eIt = childNames.end(); it != eIt; ++it )
					{
						SceneGraph *child = new SceneGraph();
						child->m_name = *it;
						m_sceneGraph->m_children.push_back( child );
					}

					m_dirtyFlags = AllDirty; // We've made brand new children, so they need a full update.
				}
			}

			// And then update each child

			if( m_sceneGraph->m_children.size() )
			{
				set_ref_count( 1 + m_sceneGraph->m_children.size() );

				ScenePlug::ScenePath childPath = m_scenePath;
				childPath.push_back( IECore::InternedString() ); // space for the child name
				for( std::vector<SceneGraph *>::const_iterator it = m_sceneGraph->m_children.begin(), eIt = m_sceneGraph->m_children.end(); it != eIt; ++it )
				{
					childPath.back() = (*it)->m_name;
					UpdateTask *t = new( allocate_child() ) UpdateTask( m_sceneGadget, *it, m_dirtyFlags, childPath );
					spawn( *t );
				}

				wait_for_all();
			}

			// Finally compute our bound from the child bounds.

			for( std::vector<SceneGraph *>::const_iterator it = m_sceneGraph->m_children.begin(), eIt = m_sceneGraph->m_children.end(); it != eIt; ++it )
			{
				const Box3f childBound = transform( (*it)->m_bound, (*it)->m_transform );
				m_sceneGraph->m_bound.extendBy( childBound );
			}

			return NULL;
		}