ogre icon indicating copy to clipboard operation
ogre copied to clipboard

Support for v-hacd library in OgreBullet? Or something...

Open slapin opened this issue 2 months ago • 13 comments

Currently OgreBullet lacks feature of generating convex-decomposed colliders like Godot and other engines. As export of colliders from Blender via blender2ogre is lacking that makes it quite hard to handle collisions of more complex scenery without huge manual labor of manual splitting meshes and manually composing btCompoundShapes for them. Also there is no CPU-only meshes so I have to generate colliders from meshes then discard the meshes, which is not nice thing... Looks like some tool is needed for these... Godot use patched v-hacd library to generate composite colliders which might be the solution. And/Or blender2ogre needs some way to support export of physics-only meshes (and Ogre support them)... Need a pointers for good pipeline setup...

slapin avatar Oct 21 '25 17:10 slapin

Basically what I want is I name my mesh in specific way and/or add custom properties to it in Blender and it ends up not creating any hw buffers and just goes to Bullet... I'd like it to work with GLTF and blender2ogre of course... because it is so nice to do collisions for Godot and it should not be that hard for Ogre...

slapin avatar Oct 21 '25 17:10 slapin

I think most of the problems can be resolved by filtering mesh data on loader level. I think some kind of "plugin" could be inserted between geometry loader and hardware buffer setup to discard non-GPU data. Also such "plugin" can optionally convert the geometry into physics collider format.

slapin avatar Oct 22 '25 07:10 slapin

https://dev.epicgames.com/documentation/en-us/unreal-engine/fbx-static-mesh-pipeline-in-unreal-engine#collision Unreal engine has the naming convention

Godot has conventions for naming: https://docs.godotengine.org/en/3.6/tutorials/assets_pipeline/importing_scenes.html#create-collisions-col-convcol-colonly-convcolonly

None use the geometry directly. I guess for .mesh + scene workflow there is need to make the exporter script produce intermediate format .collider and OgreBullet should support loading it and scene should support that as long as physics objects creation via scene, for .glb there should be a filter implemented which would generate collider instead of hardware buffer.

If that would be considered an option for Ogre, I'll work on implementation, otherwise I would implement it locally for custom loader.

slapin avatar Oct 22 '25 09:10 slapin

at some point blender was able to export .bullet files for colliders: https://www.youtube.com/watch?v=fv-Oq5oe8Nw

However this is all that I could still find regarding that: https://github.com/LaughingLeader-DOS2-Mods/dos2de_bullet_exporter?tab=readme-ov-file

maybe bullet still supports loading those files.

paroj avatar Oct 22 '25 19:10 paroj

Bullet has serializer/deserializer which works, but I think the file format is not a problem per se as Ogre could have own loader and provide Bullet with geometry and files could be generated with Python code in some uniform way (as otherwise we will have a problem of how to bind Blender's Bullet to Python). GLTF is more problematic case as Ogre has no way to filter-out stuff to not create hardware buffers from which is bigger problem here... However having separate files for colliders in the case of single .glb file are problematic and it is much better to generate colliders and bodies on gltf load. Also it is not impossible to create external tool to create a set of colliders for any Assimp mesh out there as long as things are named properly, but that would be extra mandatory step in already complex pipeline... I think blender2ogre should support creation of colliders of various types to be used with scene, that is for the best and that is most complex part of work, but Assimp loader should be able to not generate hardware buffers from some geometry and provide that geometry somehow as is (as vertices and indices at least) so the app can use these data with physics engine. There are a lot of pros with .glb-based workflow to ignore that...

slapin avatar Oct 23 '25 12:10 slapin

you can use Any for communicating back and forth with the Assimp Codec. See: https://github.com/OGRECave/ogre/blob/e0c437ca3f967fedf0e7c3112cf7bb63a5689cfc/Tools/AssimpConverter/main.cpp#L219

paroj avatar Oct 23 '25 19:10 paroj

also yes, I think having collider handling in blender2ogre/ OgreBullet would be useful.

paroj avatar Oct 23 '25 19:10 paroj

I was experimenting and hacking around blender2ogre and was able to reanimate the old physics support mechanism in there (grep for .subcollision). It sort of works but supports only 1 collision shape per entity, which is strange as compound shape gives much more power. So I ended up creating my hacky implementation which allows children of physics rigid body node (having .rigid_body not None) not be entity but just node with userData but saving mesh to file.

<scene author="slapin" formatVersion="1.1" >
  <nodes >
    <node name="boat" >
      <position x="0.000000" y="0.000000" z="-0.000000" />
      <rotation qw="1.000000" qx="0.000000" qy="0.000000" qz="-0.000000" />
      <scale x="1.000000" y="1.000000" z="1.000000" />
      <userData >
...
        <property data="compound" name="collisionType" type="str" />
      </userData>
      <entity meshFile="boat.mesh" name="boat" >
        <userData >
...
        </userData>
      </entity>
...
      <node name="deck-physics-1" >
        <position x="0.000000" y="0.000000" z="-0.000000" />
        <rotation qw="1.000000" qx="0.000000" qy="0.000000" qz="-0.000000" />
        <scale x="1.000000" y="1.000000" z="1.000000" />
        <userData >
          <property data="convexHull" name="collisionType" type="str" />
          <property data="_collision_boat_deck-physics-1" name="collisionFile" type="str" />
        </userData>
      </node>
      <node name="deck-physics-2" >
        <position x="0.000000" y="0.000000" z="-0.000000" />
        <rotation qw="1.000000" qx="0.000000" qy="0.000000" qz="-0.000000" />
        <scale x="1.000000" y="1.000000" z="1.000000" />
        <userData >
          <property data="convexHull" name="collisionType" type="str" />
          <property data="_collision_boat_deck-physics-2" name="collisionFile" type="str" />
        </userData>
      </node>
      <node name="deck-physics-3" >
        <position x="-0.960000" y="0.000000" z="-0.000000" />
        <rotation qw="1.000000" qx="0.000000" qy="0.000000" qz="-0.000000" />
        <scale x="1.000000" y="1.000000" z="1.000000" />
        <userData >
          <property data="convexHull" name="collisionType" type="str" />
          <property data="_collision_boat_deck-physics-2.001" name="collisionFile" type="str" />
        </userData>
      </node>
      <node name="deck-physics-4" >
        <position x="0.960000" y="0.000000" z="-0.000000" />
        <rotation qw="1.000000" qx="0.000000" qy="0.000000" qz="-0.000000" />
        <scale x="1.000000" y="1.000000" z="1.000000" />
        <userData >
          <property data="convexHull" name="collisionType" type="str" />
          <property data="_collision_boat_deck-physics-2.001" name="collisionFile" type="str" />
        </userData>
      </node>
      <node name="hull-physics" >
        <position x="0.000000" y="0.000000" z="-0.000000" />
        <rotation qw="1.000000" qx="0.000000" qy="0.000000" qz="-0.000000" />
        <scale x="1.000000" y="1.000000" z="1.000000" />
        <userData >
          <property data="convexHull" name="collisionType" type="str" />
          <property data="_collision_boat_hull-physics" name="collisionFile" type="str" />
        </userData>
      </node>
...

To load these data on the node with collisionType=compound prop one just need to pass through children nodes and collect all collision shapes. For a case where there is only one child shape and have identity transform no compound shape is needed, otherwise just add shapes to compound shape. All the configuration is taken from Blender physics settings, but I think custom props additionally can be used. I delete nodes used for physics as scene is loaded but I think the creation could be skipped or leave them be...

That works and I implemented loader for it but I guess to make it into something worth merging I think 2 things should be done

  1. Design xml a bit - is userData in node good place for things like that or some other construct should be used? See above for the output.
  2. I still think that using .mesh for collision data is not a good idea as it creates hardware buffer and shader for it on load which is not a good thing. Or some raw mesh loader is needed...
  3. Keep or delete/not create SceneNodes used to supply transforms needed for colliders?

As for _AssimpLoaderOptions I think that is great idea to use it for filtering and physics load... I think similar approach can be used for scene loader to support node name prefix and other cool stuff... Looks really good, this weekend will be fun!

slapin avatar Oct 23 '25 22:10 slapin

The actual .bullet export from Blender is impossible since removal of BGE as it was attached there. So that is not an option anymore. And as the format is binary, there is no much point emulating it and it is easier to export another binary format, like vertex + index, call it .physics, and implement custom loader in OgreBullet.

slapin avatar Oct 24 '25 06:10 slapin

To implement things properly with DotSceneLoader the hook system should be implemented for nodes for parser to do external calls. the simplest way would be

struct NodeHook {
    virtual bool operator()(Ogre::SceneNode *pNode ...) = 0;
}
std::vector<NodeHook> hooks;

but there is no way to implement this directly. It is possible to provide list of hooks using Any but that would require putting the struct somewhere visible in some header. DotScene plugin has no public headers so I wonder where this should go, as it should be available publically; need advice... Sounds like OgreSceneNode.h might be good but still not sure. Otherwise it would be fine to create new header instead...

slapin avatar Oct 24 '25 14:10 slapin

I implemented the hooks in https://github.com/OGRECave/ogre/pull/3471 please see if you agree with implementation

slapin avatar Oct 24 '25 15:10 slapin

Due to architecture issues I set this work on the pause but I implemented physics from blender2ogre in my custom scene loader and it made my life much better. Next comes the convex decomposition...

slapin avatar Oct 25 '25 10:10 slapin

Blocked by https://github.com/OGRECave/ogre/issues/3472

slapin avatar Oct 25 '25 12:10 slapin