Quick fix for YABEE Exports (Blender to Egg)

No. Egg files in general only deal with the panda internal collision system. I vaguely remember that there is some way to convert panda3d collision shapes into bullet ones. Try searching around or ask on the forum or Discord.

Otherwise you can add custom tags and add code to make bullet shapes based on those tags after loading the model in.

I can do it in code no problem there is a method on bullet nodes to convert panda colliders, so its possible. No biggie. I could also use one of the other formats for level data. Still, not a big deal. Im just trying to wrap my head around the options and all their pros/cons so we can have a better illustration of the options on the documentation.

I just want to step in to say “thank you” to both of you! This updated version of YABEE–and only more so with the fix given in this thread–looks really promising!

I may have to actually update Blender one of these days! XD;

4 Likes

My personal reason for sticking with egg files is because there are a number of features that I rely on in my existing models that the gltf pipeline doesn’t have at this point. For example ModelNodes aka DSC nodes (nodes that resist a flatten), billboards, collision masks and object types. It is of course possible in the gltf pipeline to sort of implement similar things using tags that are read in code and your code adds those things manually, but IMHO I like the fixed properties of Egg that I just need to fill in.

2 Likes

@Maxwell175, as i mentioned before, im starting work on additions to the docs that cover blender to panda workflows. Im going to start with egg and egg exporters. So if you feel like sharing with me how you work, thos limitations of other formats you mentioned and egg benefits, ill write it up and submit a pr.

The information here may be a little outdated, but if you’re addressing the matter of egg-files and egg-exporters, I might suggest that you take a look at this thread of mine over in the “Pipeline” sub-forum:

1 Like

Thanks! Ive read it. Its great and appreciated. Id like to crystalize alot of this knowledge into the docs. This way people dont necessarily have to go to the forum. I think i saw an interesting thing moguri was working on, which was essentially blender as an editor suite of plugins. Serega has his pipeline as well. Alot of knowledgable ppl working in their own spaces, id like to pull some of that knowledge into the general space.

2 Likes

As others have noted and made efforts to resolve, new comers will be deterred by a lack of “scene editor”. But i dont necessarily believe we have to create one more then just good blender integrations and good illustrations of how to use it effectively.

1 Like

Tried out the parameters today, collisions specifically.

Works just fine:

 <Group> Cube.001 {
    <Collide> { box descend }
    <Transform> {
      <Matrix4> {
        1.0 0.0 0.0 0.0 
        0.0 11.486787796020508 0.0 0.0 
        0.0 0.0 1.0 0.0 
        -5.235357284545898 0.0 1.8232907056808472 1.0 
      }
    }

2 Likes

Whoa guys, TIL that if you dont apply the transformations in blender, the associated solid object will have incorrect dimensions but it will appear correctly when nested in a node!

Let me try to explain. I was working on translating the egg exported collision cube shown above (notice its scaled on the y?) into a rigid body node of the same dimensions. As you can see above it looks perfect on a normal node. But, in blender the transform was not applied.

So when i tried to convert it to a rigidbody shape with this:

self.playground = loader.loadModel("levels/playground.egg")
coll = self.playground.find("**/+CollisionNode")
coll.show()
self.playground.show()
self.playground.reparentTo(self.render)

solid = coll.node().getSolid(0)
box_shape = BulletBoxShape.makeFromSolid(solid)

 box = base.bullet_world_node_path.attachNewNode(BulletRigidBodyNode('Box'))
box.node().setMass(0)
box.node().addShape(box_shape)
box.node().setFriction(1)
box.setPos(10, 20, 0,)
box.setCollideMask(BitMask32.allOn())

base.bullet_world.attachRigidBody(box.node())

The solid from coll.node().getSolid(0) is of dimensions 1,1,1 which is incorrect! And the rigid bodies looked like cubes. But the original node appears correct when applied to defaut panda collisions node.

So only after applying transforms in blender, is it now correctly translated to rigidbody. What does default do with scale that doesnt effect the underlying solid?

You can see the expected difference in the egg above and the egg with transforms applied

<Group> Cube.001 {
    <Collide> { box descend }
    <Transform> {
      <Matrix4> {
        1.0 0.0 0.0 0.0 
        0.0 11.486787796020508 0.0 0.0 
        0.0 0.0 1.0 0.0 
        -5.235357284545898 0.0 1.8232907056808472 1.0 
      }
    }

<Group> Cube.001 {
    <Collide> { box descend }
    <Transform> {
      <Matrix4> {
        1.0 0.0 0.0 0.0 
        0.0 1.0 0.0 0.0 
        0.0 0.0 1.0 0.0 
        -5.235357284545898 0.0 1.8232907056808472 1.0 
      }
    }

My guess is, panda takes the scale in the matrix and applies it to extense of the solid somewhere but it doesnt actually change the solid itself. odd.

The problem is that in your code you do coll.node() which gets the actual CollisionNode behind “coll”, which is a NodePath. If the transforms are not applied they are stored on the NodePath, not the underlying Node.

To solve this, first of all attach the new BulletRigidBodyNode to the parent of the original “coll” (coll.parent) and second, copy the transform from the original NodePath to the new one: box.setMat(coll.getMat())

1 Like

Ahhh, this makes sense. Thanks for the elaboration. I am working on a algorithm that converts collisionsSolids to BulletShapes. Its working so far! I wonder if I can generalize it and hook it into loader so that egg, unofficially, supports bullet through loader extension.

1 Like

Ha, no problem man. Im happy to help Maxwell support the egg format. Its a nice format and easily readable. As I mentioned below, i need rigidbody support. So far Im working on an algorithm that can do that because panda collision solids can be converted. If I can figure out how to generalize it and hook into the loader, maybe ill make a module. Ill call it Robotnik, get it, because hes eggman? -b

And also, right back at you. You are in here all the time day after day helping ppl like me.

1 Like

@Maxwell175 where does the variable TEXTURE_PROCESSER get set in blender?

TEXTURE_PROCESSOR == 'BAKE' and mat.use_nodes:

Well im close, here are conversions for planes, boxes, spheres, and capsules. from egg to rigidbody. But, the capsule orientation is actually off, both the body and geom. Not sure why yet.

code:

base.bullet_world_node_path = self.render.attachNewNode('World')
        base.bullet_world = BulletWorld()
        base.bullet_world.setGravity(Vec3(0, 0, -14))

        playground = loader.loadModel("levels/playground12.egg")
        playground.reparentTo(base.render)
        collisions = playground.findAllMatches("**/+CollisionNode")
        for collision in collisions:
            collision.show()
            parent = collision.getParent()
            geom = parent.find("**/+GeomNode")
            solid = collision.node().getSolid(0)
            rb_node = None
            if isinstance(solid, CollisionBox):
                shape = BulletBoxShape.makeFromSolid(solid)
                rb_node = base.bullet_world_node_path.attachNewNode(BulletRigidBodyNode('Box'))
            elif isinstance(solid, CollisionSphere):
                shape = BulletSphereShape.makeFromSolid(solid)
                rb_node = base.bullet_world_node_path.attachNewNode(BulletRigidBodyNode('Sphere'))
            elif isinstance(solid, CollisionCapsule):
                shape = BulletCapsuleShape.makeFromSolid(solid)
                rb_node = base.bullet_world_node_path.attachNewNode(BulletRigidBodyNode('Capsule'))
            elif isinstance(solid, CollisionPlane):
                shape = BulletPlaneShape.makeFromSolid(solid)
                rb_node = base.bullet_world_node_path.attachNewNode(BulletRigidBodyNode('Plane'))
            elif isinstance(solid, CollisionPolygon):
                pass
            
            rb_node.reparentTo(parent)
            rb_node.setMat(parent.getMat())
            geom.reparentTo(rb_node)
            rb_node.node().setMass(0)
            rb_node.node().addShape(shape)
            rb_node.node().setFriction(1)
            rb_node.setCollideMask(BitMask32.allOn())
            base.bullet_world.attachRigidBody(rb_node.node())
            parent.reparentTo(base.bullet_world_node_path)
            collision.removeNode()
        playground.removeNode()
        base.render.ls()
1 Like

Yay, complex geometry support for rigidbodys exported via eggs!

2 Likes

last post on here, ill work on it and report separately. All “core” shapes are now exportable via egg and get converted to rigidbodies. Ill work towards finished the remainder of the shapes, generalizing the techniques to be more flexible and then modifying/making a loader. Thanks for the custom properties windows maxwell, works great.

1 Like

Really good work, I do feel, and well done on getting all of that working! :slight_smile:

Regarding the matter of scaling factors, this is tangential, but let me leave a note of caution regarding the scaling of collision/physics objects: it is, I believe, generally unwise to so scale; I think that it can potentially interfere with the objects interacting as expected.

Now, this isn’t necessarily something that your exporter would be expected to act on–it’s arguably a developer choice to take that chance. And you never know: perhaps an update to Bullet or to Panda’s collision system will render this advice obsolete–at which point it would be unexpected for the exporter to not export scaling factors!

I just wanted to mention it in case you were planning on applying scaling factors to physics objects in your own projects.

1 Like

@Thaumaturge ive heard this advice before. Can i ask for some clarification? Okay, so if i make an object in blender. Say a sphere mesh. And i scale it, but, i apply scale transform. Then i export and the collision is generated based on the geometry in the egg with a scale of 1 uniformely. This would not be applying scaling factors to physics objects right?