clone() for rigid bodies & shapes ?

Post Reply
Digitalghost
Posts: 25
Joined: Thu Dec 20, 2007 4:03 am

clone() for rigid bodies & shapes ?

Post by Digitalghost »

Hey all,

I'm using the Collada importer to load physics information for my models. I want to load the collada information up front for all types of obejcts and then create copies of the rigid bodies and (maybe?) shapes for each instance. So in other words, if I have a hundred swords, I want to load a collada file for the sword physics model once, and then clone that model for the swords in the game.

Is there a clone() function in btRigidBody or btCollisionShape? How can I make a duplicate of a rigid body? Is there an easier way to do this?
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: clone() for rigid bodies & shapes ?

Post by sparkprime »

I encapsulate the btCollisionShape* (whatever shape(s) it happens to represent) with a class I call CollisionMesh that also contains all the stuff like mass, inertia, friction, etc that I need to make a btRigidBody.

Then I construct rigid bodies from the CollisionMesh.

If I wanted to clone a rigid body i'd just do new RigidBody(rb->mesh) or something similar.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: clone() for rigid bodies & shapes ?

Post by Erwin Coumans »

It is best to re-use collision shapes among several rigid bodies, and not clone/duplicate them. This saves memory and increases performance.

So for 100 sword instances, you only need 1 sword collision shape.

For btRigidBody there is no clone functionality right now.
Thanks,
Erwin
Digitalghost
Posts: 25
Joined: Thu Dec 20, 2007 4:03 am

Re: clone() for rigid bodies & shapes ?

Post by Digitalghost »

Erwin Coumans wrote:It is best to re-use collision shapes among several rigid bodies, and not clone/duplicate them. This saves memory and increases performance.

So for 100 sword instances, you only need 1 sword collision shape.

For btRigidBody there is no clone functionality right now.
Thanks,
Erwin
Thanks for the reply,

Do you think you might support a clone function in the future to satisfy this situation?

Also, I just found out that btRigidBody does not have a name field. When I load a collada file, is there any way to know what the names of the rigid bodies were in the file? Is there a map that connects names to rigid bodies in the Collada importer?

I'm just trying to find an way to shorten my physics pipeline. Right now, when I want to tweak my physics model for a character or object, I need to modify the model, export from blender as a collada file, and then manually go through and copy sections of the file into another xml file that creates the physics models in bullet. If I could just rely on the collada importer, it would be great. The big problems right now are that I can't clone rigid bodies and that I have no way to attach metadata (i.e., give a name) to the rigid bodies while in blender so that they show up in bullet.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: clone() for rigid bodies & shapes ?

Post by Erwin Coumans »

Digitalghost wrote:Do you think you might support a clone function in the future to satisfy this situation?
[...]
The big problems right now are that I can't clone rigid bodies
That is possible. Especially if several developer express interest we can add such utility functions (or accept contributions). Can you explain when/how you need cloning exactly?
Also, I just found out that btRigidBody does not have a name field. When I load a collada file, is there any way to know what the names of the rigid bodies were in the file? Is there a map that connects names to rigid bodies in the Collada importer?
There is a hash map that connects btRigidBody to the COLLADA DOM internal representation. 'findRigidBodyColladaInfo' will return this info, and it allows to find the name like this:

Code: Select all

domInstance_rigid_body* rigidBodyInstance = converter.findRigidBodyColladaInfo(rigidBody);
const char* rbName = rigidBodyInstance->getTarget().getID();
Thanks for the feedback, hope this helps,
Erwin
Digitalghost
Posts: 25
Joined: Thu Dec 20, 2007 4:03 am

Re: clone() for rigid bodies & shapes ?

Post by Digitalghost »

At a high level, here's how I would like my system to work:

1. Each object type has it's own collada file. At initialization, load one of each object type, using the collada file to create rigid bodies. This one object works as a template. This way, I don't have to load the collada file more than once per object type.

2. As objects are instantiated in the world, I clone the rigid body for the new instance and add it to the dynamics world.

I guess one thing I'm not sure about is if any rigidbody information is added from the collada file. If not, i can just ignore the rigidbody created by the collada import and create a new body from scratch.

In general, I would like to use the collada files to create templates, and then create instances from these templates. Does this make sense? Is there a way to do this without needing a clone function in btRigidBody?
Erwin Coumans wrote:
Digitalghost wrote:Do you think you might support a clone function in the future to satisfy this situation?
[...]
The big problems right now are that I can't clone rigid bodies
That is possible. Especially if several developer express interest we can add such utility functions (or accept contributions). Can you explain when/how you need cloning exactly?

Thanks for the feedback, hope this helps,
Erwin
devmelon
Posts: 19
Joined: Thu Nov 27, 2008 1:44 pm

Re: clone() for rigid bodies & shapes ?

Post by devmelon »

Hello.

We are currently working with bullet v2.72 and we would really apprechiate support for cloning rigid bodies. We realize this is an old thread but we might just aswell bump it up rather than start a new.

We have entities in our game which are composed of components. The procedure to create new entities are not to derive from Entity (and thus not bloat with subclasses nor nasty heirarchies), but rather use behaviour composition through components. This means that instantiating another "class" of entity is done runtime through cloning prototypes through a factory. As such, there is no "Sword" class or "Player"/"Monster"/"Badguy" class. There are instead 4 instances of Entity with different graphics and different components. These serve as the "class" of these types, or prototypes rather.

Our problem is this:

During the creation of usable instances from the prototype, a clone process is performed. We clone the entity, all the entitys components, scene node and ultimately its rigid body. While there might be other feasible solutions such as only storing the construction info (for the construction process), we have ideas for in-game editors which makes clones of the running instances from the game to the editor. This means we need working copies of the entities in two different places behaving in the same manner. One is then edited and saved (or discarded) so we really need two sets of the data in rigid body.

Another workaround solution for the time being would perhaps be just pulling all the data from the old rigidbody and pushing it onto the new rigidbody. Will this cause problems, or are all the implementation details exposed to the public interface? Does it manage its own internal state which can't be copied from the outside?

We ask for cloning functionality if it is possible, please. Also, we'd like to know if we can do this workaround with predictable results.

Thanks for your time.
devmelon
Posts: 19
Joined: Thu Nov 27, 2008 1:44 pm

Re: clone() for rigid bodies & shapes ?

Post by devmelon »

Bumping thread. We'd really like some hints about if this is planned to get implemented "anytime soon".
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: clone() for rigid bodies & shapes ?

Post by sparkprime »

Why can't you just make a new rigid body and initialise it with values from the existing one?
devmelon
Posts: 19
Joined: Thu Nov 27, 2008 1:44 pm

Re: clone() for rigid bodies & shapes ?

Post by devmelon »

sparkprime wrote:Why can't you just make a new rigid body and initialise it with values from the existing one?
Because a RigidBody has a pointer to a shape. What happens here is type slicing. Without cloning features, this becomes quickly a bit of a hazzle. We make use of compound shapes in some places, but all we know about is a pointer to a "shape".

While it is possible to just share the pointer to the shape aswell (as you should try to do), we make use of cloning to create copies of a prototype, or a running component. This means that if we remove one of the shapes from the compound shape, several entities will become affected. I am sure there are other workarounds. Also, I am not sure what data needs to be copied across copies of RigidBodies.

As I wrote:
Also, we'd like to know if we can do this workaround with predictable results.
We are looking for stuff like your proposal, but we need to know that the second rigid body constructed with the information from the first rigid body behaves exactly like the first rigid body. We are unsure about how to copy the dynamic information (motionstate, shape) because we can't tell which type object is being held at the pointer. If you could shed more light on this, we would be grateful. :)
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: clone() for rigid bodies & shapes ?

Post by sparkprime »

So it sounds what you really want is the ability to clone shapes, not rigid bodies. This might be useful for example when destroying a particular instance of a chair. I don't see why this can't be added to bullet itself but it would require changes to all of the shapes, and there might be issues if the shapes are backed by other datastructures like triangle meshes. Perhaps it would be sufficient to have a function which clones only btCompoundObjects, aliasing their non-compound contents? Would that work for you?
devmelon
Posts: 19
Joined: Thu Nov 27, 2008 1:44 pm

Re: clone() for rigid bodies & shapes ?

Post by devmelon »

sparkprime wrote:So it sounds what you really want is the ability to clone shapes, not rigid bodies.
Well, no, not really. But to clone a body, you would need to clone its shape. A body has more than just a position and rotation, it has mass, velocity and other things (if I remember correctly, I'm working on another subset right now). Also, it has a MotionState which also doesn't support cloning. Meaning, that if I could clone the shape, and make a shallow copy of the rigid body, I still would have problems with the pointer to the MotionState which points to an object of unknown type. For some types, this wouldn't become a problem. These are classes with no instance data. For others, it would. And then there's the whole business of constraints attached to the bodies. The problem is that if we start playing around in the code, adding requirements to the interfaces, ALL derived classes would break. This would include third party solutions.
sparkprime wrote:I don't see why this can't be added to bullet itself but it would require changes to all of the shapes, and there might be issues if the shapes are backed by other datastructures like triangle meshes. Perhaps it would be sufficient to have a function which clones only btCompoundObjects, aliasing their non-compound contents? Would that work for you?
Well, it would surely help, but for that to work I still need to check the type of the shape to determine if it is a compound shape or not, and then cast the pointer to get access to the member function. But on the other hand, I suppose that if we would go about type checking and casting, we could just get all the shapes from the compound shape and construct a new compound shape to insert all the found shapes into it.

I am willing to make my own workaround to this problem as long it doesn't require extreme time dedicated to it. I am not sure if I can just rip the data off the body, or if I need to check some internals of the engine that might be bound to the body. It doesn't help that I am a newbie to this library, I suppose I should read through all the source code. What a hazzle. I wish this functionality was there from the beginning :) But it's best just to make the best of the situation.
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: clone() for rigid bodies & shapes ?

Post by sparkprime »

I don't see how you intend to clone the motion state. You'd also have to clone the graphical representation and so on, which bullet knows nothing about. All of your requirements are very application-specific so I don't think Bullet is the right place to meet them.

You would indeed need to be checking dynamic types and downcasting, but that's not a problem. If there is data that is not accessible from a Bullet class, it is easy to extend the class to get access to it.

Using a library like this in a serious application is rarely a case of just plugging it in. There are always bugs to fix, performance problems, and mismatch between the features it provides and the features you want. This is no fault of Bullet, it's just what happens if you use a general purpose framework in a very specific situation.

Nothing you've described sounds like a show-stopper though. You just need to write some wrapper code to turn Bullet into what you want it to be. Many people do this in serious projects with specific requirements. If nothing else, it allows you to "plug in" a different physics engine at a later date. I've written 3500 lines of "wrapper" code including Lua bindings, a simpler and more powerful stepSimulation API, and support for reading collision mesh data from my own text format. If I wanted to clone rigidbodies, I would do it via the wrappers.
devmelon
Posts: 19
Joined: Thu Nov 27, 2008 1:44 pm

Re: clone() for rigid bodies & shapes ?

Post by devmelon »

sparkprime wrote:I don't see how you intend to clone the motion state. You'd also have to clone the graphical representation and so on, which bullet knows nothing about. All of your requirements are very application-specific so I don't think Bullet is the right place to meet them.
Of course I would have to clone the graphical representation. I don't know your milage, but you could check out the Prototype Pattern if you want more detail on why anyone ever would want a clone() :).

Here's a little psuedo code about the intended usage.

Code: Select all

newEntity = myEntity->clone();

Entity* Enitity::clone()
{
   return new Entity(*this);
}

Entity::Entity(const Entity& entity)
{
   mName = entity.mName;
   mWhateverCopyByValueData = entity.mWhateverCopyByValueData;

   mGraphicsRepresentation = entity.mGraphicsRepresentation->clone(); // gfx representation does clone too
   mRigidBody = entity.mRigidBody; // We can't share the same rigid body! There is no way to create a copy of the rigid body afaik
   mWhateverCopyByReferenceData = entity.mWhateverCopyByReferenceData->clone();
}
sparkprime wrote:You would indeed need to be checking dynamic types and downcasting, but that's not a problem. If there is data that is not accessible from a Bullet class, it is easy to extend the class to get access to it.
This holds true as long as we are 100% sure of all the concrete implementations that is available.. And I would still think it's more of a hazzle to create wrappers for the classes, test types, cast, extract data from the objects to do stuff with them than to have a simple clone() and let the object do the work for you. - From a users perspective :) Obviously it would burden the API writers today.
sparkprime wrote:Using a library like this in a serious application is rarely a case of just plugging it in. There are always bugs to fix, performance problems, and mismatch between the features it provides and the features you want. This is no fault of Bullet, it's just what happens if you use a general purpose framework in a very specific situation.
I'm not saying it's a fault (even if I think it's a flaw). I am just asking if there is any plans on implementing this in the near future. This is a request from one developer (me) as Erwin Coumans asked developers who wants this functionality to express interest. This was discussed a while ago in this same thread:
Erwin Coumans wrote:
Digitalghost wrote:Do you think you might support a clone function in the future to satisfy this situation?
[...]
The big problems right now are that I can't clone rigid bodies
That is possible. Especially if several developer express interest we can add such utility functions (or accept contributions). Can you explain when/how you need cloning exactly?
sparkprime wrote:Nothing you've described sounds like a show-stopper though. You just need to write some wrapper code to turn Bullet into what you want it to be. Many people do this in serious projects with specific requirements. If nothing else, it allows you to "plug in" a different physics engine at a later date. I've written 3500 lines of "wrapper" code including Lua bindings, a simpler and more powerful stepSimulation API, and support for reading collision mesh data from my own text format. If I wanted to clone rigidbodies, I would do it via the wrappers.
I am not sure it just takes some wrapper code. I'll have to check into it deeply to try and find a solution. For the moment being, it is a show-stopper. We don't have alot of time to go changing in the engine. I am sure we just are going to have to change our design a bit.
Post Reply