[2.3] display/hide submesh

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Post Reply
rrl
Halfling
Posts: 77
Joined: Sun Jun 04, 2017 12:33 am

[2.3] display/hide submesh

Post 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

Code: Select all

item->setVisible(booVal);
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?

User avatar
cc9cii
Halfling
Posts: 95
Joined: Tue Sep 18, 2018 4:53 am
x 20

Re: [2.3] display/hide submesh

Post by cc9cii »

There was a suggested workaround viewtopic.php?p=548444#p548444 but I've not tried it.

rrl
Halfling
Posts: 77
Joined: Sun Jun 04, 2017 12:33 am

Re: [2.3] display/hide submesh

Post 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?

User avatar
cc9cii
Halfling
Posts: 95
Joined: Tue Sep 18, 2018 4:53 am
x 20

Re: [2.3] display/hide submesh

Post 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.

ExPeTe
Gnoblar
Posts: 14
Joined: Mon Feb 04, 2019 8:53 pm
x 3

Re: [2.3] display/hide submesh

Post 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.

rrl
Halfling
Posts: 77
Joined: Sun Jun 04, 2017 12:33 am

Re: [2.3] display/hide submesh

Post 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.

User avatar
cc9cii
Halfling
Posts: 95
Joined: Tue Sep 18, 2018 4:53 am
x 20

Re: [2.3] display/hide submesh

Post 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?).

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 4572
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 962
Contact:

Re: [2.3] display/hide submesh

Post by dark_sylinc »

It is woth noting modifying the submesh will affect (i.e. hide) ALL instances, not just one

Post Reply