Skip to content

Commit

Permalink
Ogre Instancing: Major overhaul to the OgreWorld instancing internal …
Browse files Browse the repository at this point in the history
…state book keeping. This fixes meshes with multiple submeshes in them and makes the internals a faster when instances are destroyed by EC_Mesh.
  • Loading branch information
Jonne Nauha committed Jun 11, 2013
1 parent 26c4b7d commit b3f7250
Show file tree
Hide file tree
Showing 3 changed files with 291 additions and 226 deletions.
41 changes: 28 additions & 13 deletions src/Core/OgreRenderingModule/EC_Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ void EC_Mesh::RemoveMesh()
}
if (world.get() && instancedEntity_)
{
world->DestroyInstances(instancedEntity_);
world->DestroyInstance(instancedEntity_);
instancedEntity_ = 0;
}
}
Expand Down Expand Up @@ -740,8 +740,13 @@ void EC_Mesh::DetachEntity()
Ogre::SceneNode* node = placeable->GetSceneNode();
if (entity_)
adjustmentNode_->detachObject(entity_);
else if (instancedEntity_)
else if (instancedEntity_ && world_.lock())
{
adjustmentNode_->detachObject(instancedEntity_);
QList<Ogre::InstancedEntity*> children = world_.lock()->ChildInstances(instancedEntity_);
foreach(Ogre::InstancedEntity *child, children)
if (child) adjustmentNode_->detachObject(child);
}
node->removeChild(adjustmentNode_);

attached_ = false;
Expand All @@ -757,8 +762,13 @@ void EC_Mesh::AttachEntity()
node->addChild(adjustmentNode_);
if (entity_)
adjustmentNode_->attachObject(entity_);
else if (instancedEntity_)
else if (instancedEntity_ && world_.lock())
{
adjustmentNode_->attachObject(instancedEntity_);
QList<Ogre::InstancedEntity*> children = world_.lock()->ChildInstances(instancedEntity_);
foreach(Ogre::InstancedEntity *child, children)
if (child) adjustmentNode_->attachObject(child);
}

// Honor the EC_Placeable's isVisible attribute by enforcing its values on this mesh.
adjustmentNode_->setVisible(placeable->visible.Get());
Expand Down Expand Up @@ -853,19 +863,10 @@ void EC_Mesh::CreateInstance(const AssetPtr &meshAsset)
if (world_.expired())
return;

instancedEntity_ = world_.lock()->CreateInstance(meshAsset.get() != 0 ? meshAsset : this->meshAsset->Asset(), meshMaterial.Get());
instancedEntity_ = world_.lock()->CreateInstance(this, meshAsset.get() != 0 ? meshAsset : this->meshAsset->Asset(), meshMaterial.Get(), drawDistance.Get(), castShadows.Get());
if (!instancedEntity_)
return;

instancedEntity_->setRenderingDistance(drawDistance.Get());
instancedEntity_->setCastShadows(castShadows.Get());
instancedEntity_->setUserAny(Ogre::Any(static_cast<IComponent *>(this)));

// Set UserAny also on sub instances
/// @todo Implement!
//for(uint i = 0; i < entity_->getNumSubEntities(); ++i)
// instancedEntity_->getSubEntity(i)->setUserAny(entity_->getUserAny());

// Make sure adjustment node is up to date
Transform newTransform = nodeTransformation.Get();
adjustmentNode_->setPosition(newTransform.pos);
Expand Down Expand Up @@ -966,6 +967,13 @@ void EC_Mesh::AttributesChanged()
{
if (entity_)
entity_->setRenderingDistance(drawDistance.Get());
else if (instancedEntity_ && world_.lock().get())
{
instancedEntity_->setRenderingDistance(drawDistance.Get());
QList<Ogre::InstancedEntity*> children = world_.lock()->ChildInstances(instancedEntity_);
foreach(Ogre::InstancedEntity *child, children)
if (child) child->setRenderingDistance(drawDistance.Get());
}
}
if (castShadows.ValueChanged())
{
Expand All @@ -980,6 +988,13 @@ void EC_Mesh::AttributesChanged()
attachmentEntities_[i]->setCastShadows(castShadows.Get());
}
}
else if (instancedEntity_ && world_.lock().get())
{
instancedEntity_->setCastShadows(castShadows.Get());
QList<Ogre::InstancedEntity*> children = world_.lock()->ChildInstances(instancedEntity_);
foreach(Ogre::InstancedEntity *child, children)
if (child) child->setCastShadows(castShadows.Get());
}
}
if (nodeTransformation.ValueChanged())
{
Expand Down
Loading

0 comments on commit b3f7250

Please sign in to comment.