Page 1 of 1
[2.3] display/hide submesh
Posted: Sat Nov 14, 2020 1:37 am
by rrl
I create a static mesh like so ...
Code: Select all
Ogre::MeshPtr mp = createStaticMesh(typ);
Ogre::Item *item = sceneManager->createItem(mp, Ogre::SCENE_DYNAMIC);
item->setDatablock(block);
item->setName(name);
Ogre::SceneNode *rootSceneNode =
sceneManager->getRootSceneNode(Ogre::SCENE_DYNAMIC)->
createChildSceneNode(Ogre::SCENE_DYNAMIC);
rootSceneNode->attachObject(item);
rootSceneNode->setPosition(Ogre::Vector3(0.0f, 0.0f, 0.0f));
rootSceneNode->setScale(Ogre::Vector3(3.0f, 3.0f, 3.0f));
And this appears to work fine. Then later I get the mesh just created and I want to add a several submeshes to it so I'll have a few of these.
Code: Select all
Ogre::MeshPtr mp = meshes.get_meshptr();
createStaticSubMesh(mp);
Where the createStaticSubMesh() looks like ...
Code: Select all
void GS::createStaticSubMesh(Ogre::MeshPtr mesh)
{
Ogre::RenderSystem *renderSystem = root->getRenderSystem();
Ogre::VaoManager *vaoManager = renderSystem->getVaoManager();
/* The mesh has already been created at this point, so just
create submesh.
*/
Ogre::SubMesh *subMesh = mesh->createSubMesh();
// vertex declarations, fill data, vertex buffers, index buffers, etc...
}
After having done this, I display the main mesh, but would like to show and hide the submeshes. I have used
to turn on and off the submesh, but with several submeshes I believe this turns them all on or off since I call createItem(mp) on the entire mesh object.
I would just like to show and hide a single submesh from several submeshes within a mesh object. How is that done? Should I be able to add a submesh to an item?
Re: [2.3] display/hide submesh
Posted: Sat Nov 14, 2020 3:43 am
by cc9cii
There was a suggested workaround
viewtopic.php?p=548444#p548444 but I've not tried it.
Re: [2.3] display/hide submesh
Posted: Sat Nov 14, 2020 11:55 pm
by rrl
Thanks, though, if it matters, I'm not using v1::SubEntity, I am using Ogre::Item which is not part of Entity::mRenderables. Though it sounds like you're saying the fix is the same, to remove and attach items to hide and display. But then, that's what Item::isVisible() is for and it works, just not on a submesh, but the Item.
So my issue is, how does one add/remove a submesh from an item (or can a submesh be it's own Item, though I've not been able to see that). I see I can add/remove the item from a scene node, but this is a submesh added to a mesh which is a single item that was added to the scene node and I don't see that a submesh can be removed. Destroyed yes, but removed?
Also, how does one find the SubMesh within a Mesh? If I'm not mistaken, submeshes can only be named if you know the index. How does one get the index from an already created SubMesh?
Am I missing any better ways?
Re: [2.3] display/hide submesh
Posted: Sun Nov 15, 2020 2:30 am
by cc9cii
Sorry, didn't read the original question carefully and didn't realise you're talking about an Item. Having said that:
Code: Select all
Ogre::SubMesh *subMesh = mesh->createSubMesh();
You're creating the submesh, so can't you name them and/or store the pointers to them for later access? Anyway, what I understand from the suggested workaround is that you're basically manipulating what the Item thinks are the sub-meshes to render (which are stored in mRenderables). So by setting up the Item with
your mRenderables that excludes the hidden sub-mesh you'll the the end result you desire.
Again, I've not tested this.
Re: [2.3] display/hide submesh
Posted: Mon Nov 16, 2020 1:25 pm
by ExPeTe
Solution 1:
You could set a transparent unlit material with an alpha value of 0 to the submesh. This might be bad for performance if you have a lot of submeshes that you want to make invisible or if the submeshes are big. I don`t know if Ogre has optimizations for the special case of alpha = 0.
Solution 2:
So my issue is, how does one add/remove a submesh from an item (or can a submesh be it's own Item, though I've not been able to see that). I see I can add/remove the item from a scene node, but this is a submesh added to a mesh which is a single item that was added to the scene node and I don't see that a submesh can be removed. Destroyed yes, but removed?
You don`t have to remove the submesh. Keep it, but remove it`s vao(s) and replace it/them with empty vao(s).
Code:
Code: Select all
myItem->getMesh()->getSubMesh(0)->mVao[Ogre::VpNormal].pop_back();
myItem->getMesh()->getSubMesh(0)->mVao[Ogre::VpNormal].push_back(emptyVao);
Of course you have to store the original vao, if you want to make it visible again.
I only used this without shadows and without different Lod levels. I guess you would have to repeat this if you have activated those.
Afterwards:
Code: Select all
myItem->_initialise(true);
myItem->setDatablockOrMaterialName(MaterialName);
The empty vao can be created at startup and reused:
Code: Select all
Ogre::VertexElement2Vec vertexElementsPosUV;
vertexElementsPosUV.push_back(Ogre::VertexElement2(Ogre::VET_FLOAT3, Ogre::VES_POSITION));
vertexElementsPosUV.push_back(Ogre::VertexElement2(Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES));
Ogre::IndexBufferPacked *emptyIndexBuffer = vaoManager->createIndexBuffer(Ogre::IndexBufferPacked::IT_16BIT, 0, Ogre::BT_DEFAULT, nullptr, false);
Ogre::VertexBufferPacked *emptyVertexBuffer = vaoManager->createVertexBuffer(vertexElementsPosUV, 0, Ogre::BT_DEFAULT, nullptr, false);
Ogre::VertexBufferPackedVec emptyVertexBuffers;
emptyVertexBuffers.push_back(emptyVertexBuffer);
emptyVao = vaoManager->createVertexArrayObject(emptyVertexBuffers, emptyIndexBuffer, Ogre::OperationType::OT_TRIANGLE_LIST);
Also, how does one find the SubMesh within a Mesh? If I'm not mistaken, submeshes can only be named if you know the index. How does one get the index from an already created SubMesh?
Store the submesh or the index in your code, when you create it.
Re: [2.3] display/hide submesh
Posted: Tue Nov 17, 2020 12:35 am
by rrl
cc9cii wrote: Sun Nov 15, 2020 2:30 am
So by setting up the Item with
your mRenderables that excludes the hidden sub-mesh you'll the the end result you desire.
I understand what you're saying and liked the idea of doing this at a higher level, but I was unable to see a way to add a SubMesh to Item.mRenderables since SubMesh isn't in the inheritance diagram of Renderables.
ExPeTe wrote: Mon Nov 16, 2020 1:25 pm
Solution 2:
You don`t have to remove the submesh. Keep it, but remove it`s vao(s) and replace it/them with empty vao(s).
I went with option 2, seems to work.
I just wish it were as simple as item->getMesh->getSubMesh(i).setVisible(booVal);
Thanks for the help.
Re: [2.3] display/hide submesh
Posted: Tue Nov 17, 2020 7:57 am
by cc9cii
It's great you've got things to work.
Just thinking out loud - I think you can get the corresponding SubItem (which is a Renderable) by using SubItem::getSubMesh() but you might have to iterate all the elements in mRenderables to get the right one (if it is a frequent on/off thing then maybe keep an external map?).
Re: [2.3] display/hide submesh
Posted: Tue Nov 17, 2020 5:31 pm
by dark_sylinc
It is woth noting modifying the submesh will affect (i.e. hide) ALL instances, not just one
Re: [2.3] display/hide submesh
Posted: Fri Apr 09, 2021 11:15 pm
by dark_sylinc
I
just added Renderable::mRenderable Visible which adds support for this feature.
I'm still testing it works as expected but it should be fine.
Re: [2.3] display/hide submesh
Posted: Sun May 23, 2021 11:59 pm
by rrl
Just saw this. I'm going to dig in and test some of this as well. Big thanks.