Since code like that give me access volation I realise that I need to provide a world instance.
- Code: Select all
NewtonReleaseCollision(NULL, coll);
And for now I'm just using a dummy world as you suggest.
I'm just curious. After I call NewtonCollisionMakeUnique(...) the collision is removed from specified world cache. From the user point of view this collision object can exist independiently from any other one so I even can destroy all remaining worlds, but still I will have and instance of collision. To release such I need to do an extra job (create dummy world). It is possible for NewtonReleaseCollision() to accept NULL as world for detached collisions?
I still have some doubts about this proposition, becouse users ofen are lazy and they may always use NULL instead of real object instance. That leads me to another issue.
Newton require from me to provide NewtonWorld while creating collision object. I might guess that is necessary from developer point of view, becouse new object have to be allocated using allocator provided for NewtonWorld. From user point of view it unnecessary dependence. Let's consider following API changes:
- Code: Select all
// NewtonCreateSphere() no longer require NewtonWorld. As a result
// of that NewtonCollision will be unique at creation time, becouse it is
// not added to NewtonWorld cache. Note that newly created object have only
// one reference. This is a single example but that change hits any collision
// creation method.
NewtonCollision* NewtonCreateSphere(dFloat radiusX, dFloat radiusY, dFloat radiusZ, int shapeID, const dFloat *offsetMatrix);
// NewtonReleaseCollision() no longer require NewtonWorld instance,
// that is becouse collision is unique at creation time and we are the one
// who may have an reference to an exisiting object.
void NewtonReleaseCollision(const NewtonCollision* collision);
// To be consistent for complete indepdendence from user point of view an
// allocator should be provided for collision system.
void NewtonSetCollisionAllocatorCallbacks(NewtonAllocMemory malloc, NewtonFreeMemory mfree);
What happens now in NewtonCreateSphere() is pretty obvious. But we need to take closer look at NewtonReleaseCollision(). This function allow User to release the reference that he own, but nothing more. Let's consider following scenario:
- Code: Select all
// An instance of newton world.
NewtonWorld* myWorld = ...;
// We create an unique instance of sphere collision,
// after we call this method refCount = 1.
NewtonCollision* mySphere = NewtonCreateSphere(...);
// Now we create a body. NewtonCreateBody() at first create a NewtonBody object
// instance. Reference counter to collision obejct is increased by body, so
// refCount = 2. After that collision is added to world collision cache.
NewtonBody* myBody = NewtonCreateBody(myWorld, mySphere);
// Let's assume that we don't need to create more spheres and we can
// release out instance of collision. After call refCount = 1.
NewtonReleaseCollision(mySphere);
...
// We used our body and we don't need it any more. NewtonDestroyBody() first
// removes collision attached to body from world collision cache. Then body
// decrease reference counter to collision, so refCount = 0 and collision is
// destroyed. As final part body is destroyed too.
NewtonDestroyBody(myWorld, myBody);
Pretty simple, but you may ask: ok, but what happens if I create many bodies with same collision, every time their are added to world collision cache?. In the matter of fact, yes. If world collision cache will have add/remove calls counter for collision object instance it will work. This will also work for multi-world approach and compound collisions.
In this consideration collision objects are not explicitly referenced to NewtonWorld instance and there is all what has change.
While reading forum topics I found an information that there may be other dependencies than allocator, but there is no way for me to know about such details. I'm aware of fact that above considerations can be blocked by those internal dependencies (at least in Newton 2.0).
As final word in this post I need to blame a little function NewtonDestroyBody(...). Since in API it can look like that:
- Code: Select all
void NewtonDestroyBody(const NewtonBody* body);
And implemented internally:
- Code: Select all
void NewtonDestroyBody(const NewtonBody* body)
{
NewtonDestroyBody(NewtonBodyGetWorld(body), body);
}
As an User I cannot understand such overheads. Nevertheless I'm quite convinient it was necessary at some point (Newton 1.x?).