Question about NewtonCollisionMakeUnique()

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Question about NewtonCollisionMakeUnique()

Postby thedmd » Fri Oct 23, 2009 7:04 am

Hello,

I have a little problem. Let's consider scenario:
Code: Select all
NewtonWorld* world = ...;

// After we create collision object reference count is set to 2.
// One is owned by NewtonWorld and one by me.
NewtonCollision* coll = NewtonCreateSphere(world, ...);

// Now we release NewtonWorld reference so only mine left.
NewtonCollisionMakeUnique(world, coll);

// There is a question, how to release my reference without
// creating a body? Maybe:
NewtonReleaseCollision(NULL, coll);


Unfortunatelly above code don't work (I got access volation).

Is there another way to release such reference without creating artifical NewtonWorld and one NewtonBody to do the job?
thedmd
 

Re: Question about NewtonCollisionMakeUnique()

Postby Julio Jerez » Fri Oct 23, 2009 1:29 pm

With the exception of the last line, the code is right

NewtonReleaseCollision(NULL, coll);

should be
NewtonReleaseCollision(world, coll);

The reason the world is needed is because the cache leaves in the world,
if you are using collision for other purposes or you are caching then yourself,
you could use and Dummy world or any world to release them.
Once you make then Unique, they become orphan and the would cache will no find them.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Question about NewtonCollisionMakeUnique()

Postby thedmd » Fri Oct 23, 2009 9:41 pm

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

Re: Question about NewtonCollisionMakeUnique()

Postby Julio Jerez » Fri Oct 23, 2009 10:29 pm

thedmd wrote: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.

This is correct, however collision shape have a significan memory overhead, this is why I cache them, you nee to make sure you will no makeing unnessray shapes when they can be shared.

The only dependecy of collision shaped on teh world is the cache.
Removing a shape for cache and it become Orphan,
No all shape are cached, collision tree and compound are not.

basically when you make a body with a compound the world make a copy of the compound. thsi si so tah you cna craete many bodies with the same conmpound.
you can get all this information by calling the function CollisionGetInfo().
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Question about NewtonCollisionMakeUnique()

Postby thedmd » Sat Oct 24, 2009 1:19 am

Let me use some code for explanation:
Code: Select all
NewtonWorld*     myWorld  = ...;
NewtonCollision* mySphere = NewtonCreateSphere(myWorld, ...);

NewtonBody* myBodyA = NewtonCreateBody(myWorld, mySphere);
NewtonBody* myBodyB = NewtonCreateBody(myWorld, mySphere);

NewtonCollisionMakeUnique(myWorld, mySphere);

NewtonBody* myBodyC = NewtonCreateBody(myWorld, mySphere);
NewtonBody* myBodyD = NewtonCreateBody(myWorld, mySphere);

After calling NewtonCollisionMakeUnique(...) I expected that Newton will create a copy od mySphere for bodies myBodyC and myBodyD, since mySphere was removed from world cache. But debugger say that all bodies have same NewtonCollision. Is it correct behaviour?
thedmd
 

Re: Question about NewtonCollisionMakeUnique()

Postby Julio Jerez » Sat Oct 24, 2009 5:52 am

Code: Select all
NewtonWorld*     myWorld  = ...;
NewtonCollision* mySphere = NewtonCreateSphere(myWorld, ...);                 // ref = 2 one of rteh world and one for creation
NewtonBody* myBodyA = NewtonCreateBody(myWorld, mySphere);                // bodyA add one ref = 3
NewtonBody* myBodyB = NewtonCreateBody(myWorld, mySphere);                // bodyB add one ref = 4
NewtonCollisionMakeUnique(myWorld, mySphere);                                      // the shape is release for teh world ref = 3   
NewtonBody* myBodyC = NewtonCreateBody(myWorld, mySphere);              //   the shape is release for teh world ref = 4   
NewtonBody* myBodyD = NewtonCreateBody(myWorld, mySphere);              //   the shape is release for the world ref = 5 
// you need to realse the body
NewtonRelaseCollision (world, mySphere)                                                  // ref = 4  one for each body 


you can use GetInfo to verify this.
what make unique does is that if you create another sphere with the same parameters after calling Make unique,
the world will not find it is the cache and l make a new one instead of giving you a reference to mySphere
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Question about NewtonCollisionMakeUnique()

Postby thedmd » Sat Oct 24, 2009 8:04 am

Ok. Now I unserstand what kind of caching it is. There is a little prove:
Code: Select all
Calling NewtonCreate(NULL, NULL)...
  [0x00100000] NewtonWorld created.
  [0x00100000] Body count:   0

Calling NewtonCreateSphere([0x00100000], 1.0f, 1.0f, 1.0f, 1, NULL)...
  [0x00200000] NewtonCollision created.
  [0x00200000] Name:         Sphere A
  [0x00200000] Type:         SERIALIZE_ID_SPHERE
  [0x00200000] References:   2

Calling NewtonCreateSphere([0x00100000], 1.0f, 1.0f, 1.0f, 1, NULL)...
  [0x00200000] NewtonCollision created.
  [0x00200000] Name:         Sphere B
  [0x00200000] Type:         SERIALIZE_ID_SPHERE
  [0x00200000] References:   3

Calling NewtonCollisionMakeUnique([0x00100000], [0x00200000])...
  [0x00100000] Body count:   0
  [0x00200000] Name:         Sphere A
  [0x00200000] Type:         SERIALIZE_ID_SPHERE
  [0x00200000] References:   2

Calling NewtonCreateSphere([0x00100000], 1.0f, 1.0f, 1.0f, 1, NULL)...
  [0x00300000] NewtonCollision created.
  [0x00300000] Name:         Sphere C
  [0x00300000] Type:         SERIALIZE_ID_SPHERE
  [0x00300000] References:   2

Calling NewtonCreateSphere([0x00100000], 1.0f, 1.0f, 1.0f, 1, NULL)...
  [0x00300000] NewtonCollision created.
  [0x00300000] Name:         Sphere D
  [0x00300000] Type:         SERIALIZE_ID_SPHERE
  [0x00300000] References:   3

Calling NewtonReleaseCollision([0x00100000], [0x00200000])...
  [0x00100000] Body count:   0
  [0x00200000] Name:         Sphere A
  [0x00200000] Type:         SERIALIZE_ID_SPHERE
  [0x00200000] References:   0

Calling NewtonReleaseCollision([0x00100000], [0x00200000])...
  [0x00100000] Body count:   0
  [0x00200000] Name:         Sphere B
  [0x00200000] Type:         SERIALIZE_ID_SPHERE
  [0x00200000] References:   -1

Calling NewtonReleaseCollision([0x00100000], [0x00300000])...
  [0x00100000] Body count:   0
  [0x00300000] Name:         Sphere C
  [0x00300000] Type:         SERIALIZE_ID_SPHERE
  [0x00300000] References:   2

Calling NewtonReleaseCollision([0x00100000], [0x00300000])...
  [0x00100000] Body count:   0
  [0x00300000] Name:         Sphere D
  [0x00300000] Type:         SERIALIZE_ID_SPHERE
  [0x00300000] References:   1

Calling NewtonDestroyAllBodies([0x00100000])...
  [0x00100000] Body count:   0

Calling NewtonDestroy([0x00100000])...

I replaced real pointer addresses with a more readable versions.

However results I got are different from expected ones in case of two NewtonReleaseCollision(...) calls. Please look what happens:
  • I call NewtonReleaseCollision(...) for Sphere A. Reference counter is 0, but should be 1;
  • I call NewtonReleaseCollision(...) for Sphere B. Reference counter is -1, but should be 0. This is the moment when NewtonCollision should be destroyed and my program should cause access volation but nothing that happens.
May I be a bug in Newton?
thedmd
 

Re: Question about NewtonCollisionMakeUnique()

Postby Julio Jerez » Sat Oct 24, 2009 10:27 am

There is not bug there this is a trivial and standard ref count stuff when a shape ref count reach 1 if it is in the cache then it is removed.
Don't you used D3d before?

this are the internala functions

Code: Select all
void dgWorld::RemoveFromCache (dgCollision* collision)
{
   dgBodyCollisionList::dgTreeNode* node;

   node = dgBodyCollisionList::Find (collision->m_signature);
   if (node) {
      _ASSERTE (node->GetInfo() == collision);
      collision->Release();
      dgBodyCollisionList::Remove (node);
   }
}

void NewtonCollisionMakeUnique(const NewtonWorld* newtonWorld, const NewtonCollision* collisionPtr)
{
   Newton *world;
   dgCollision* collision;

   TRACE_FUNTION(__FUNCTION__);
   world = (Newton *)newtonWorld;
   collision = (dgCollision*) collisionPtr;
   world->RemoveFromCache (collision);
}


Code: Select all
void dgWorld::ReleaseCollision(dgCollision* collision)
{
   dgInt32 ref;
   dgBodyCollisionList::dgTreeNode* node;

   if (m_destroyCollision) {
      if (collision->GetRefCount() == 1) {
         m_destroyCollision (collision);
      }
   }

   ref = collision->Release();
   if (ref == 1) {
      node = dgBodyCollisionList::Find (collision->m_signature);
      if (node) {
         _ASSERTE (node->GetInfo() == collision);
         if (m_destroyCollision) {
            m_destroyCollision (collision);
         }
         collision->Release();
         dgBodyCollisionList::Remove (node);
      }
   }
}

int NewtonAddCollisionReference(const NewtonCollision* collisionPtr)
{
   dgCollision* collision;
   collision = (dgCollision*) collisionPtr;

   TRACE_FUNTION(__FUNCTION__);
   collision->AddRef();
   return collision->GetRefCount();
}


void NewtonReleaseCollision(const NewtonWorld* newtonWorld, const NewtonCollision* collisionPtr)
{
   Newton *world;
   dgCollision* collision;


   TRACE_FUNTION(__FUNCTION__);
   world = (Newton *)newtonWorld;
   collision = (dgCollision*) collisionPtr;
   world->ReleaseCollision (collision);
}
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Question about NewtonCollisionMakeUnique()

Postby thedmd » Sat Oct 24, 2009 11:39 am

This code fails sillently in special case. For Debug version of Newton my code will hit _ASSERTE(node->GetInfo() == collision) in dgWorld::ReleaseCollision(). You can try it for yourself I include sources of test program.
What happens. I create two identicall NewtonCollision objects (A and B), then I call NewtonCollisionMakeUnique() for one of them (so I hold two references). I create a new NewtonCollision (C) which is also identical to previous ones, it is added to world cache. When I call NewtonReleaseCollision() for A those things happens:
  • ref counter will be decreased to 1
  • I hit if (ref == 1) { }
  • dgBodyCollisionList::Find(collision->m_signature) returns a node (C node exacly, but I call for A)
  • ref counter is decreased to 0 and collision is destroyed
I never should hit cache but I did becouse all three collisions have identical signatures.

Code: Select all
# include "newton.h"

# include <iostream>
# include <sstream>
# include <iomanip>

using namespace std;

std::string ptrToHex(void* ptr)
{
  ostringstream str;
  str << "0x" << setfill('0') << setw(8) << hex << ptr;
  return str.str();
}

void collisionConstructor(const NewtonCollision* collision, const std::string& name = "")
{
  cout << " +  [" << ptrToHex((void*)collision) << "] " << name << " created." << endl;
}

void collisionDestructor(const NewtonCollision* collision)
{
  cout << " -  [" << ptrToHex((void*)collision) << "] destroyed." << endl;
}

int main()
{
  NewtonWorld* myWorld  = NewtonCreate(NULL, NULL);

  NewtonSetCollisionDestructor(myWorld, collisionDestructor);

  NewtonCollision* myCollisionA = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);
  collisionConstructor(myCollisionA, "A");

  //cout << "Call NewtonCollisionMakeUnique() for A" << endl;
  //NewtonCollisionMakeUnique(myWorld, myCollisionA);

  NewtonCollision* myCollisionB = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);
  collisionConstructor(myCollisionB, "B");

  //cout << "Call NewtonCollisionMakeUnique() for A" << endl;
  //NewtonCollisionMakeUnique(myWorld, myCollisionA);

  NewtonCollision* myCollisionC = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);
  collisionConstructor(myCollisionC, "C");

  cout << "Call NewtonCollisionMakeUnique() for A" << endl;
  NewtonCollisionMakeUnique(myWorld, myCollisionA);

  cout << " >  NewtonReleaseCollision() for A" << endl;
  NewtonReleaseCollision(myWorld, myCollisionA);
  cout << " <  NewtonReleaseCollision() for A" << endl;

  cout << " >  NewtonReleaseCollision() for B" << endl;
  NewtonReleaseCollision(myWorld, myCollisionB);
  cout << " <  NewtonReleaseCollision() for B" << endl;

  cout << " >  NewtonReleaseCollision() for C" << endl;
  NewtonReleaseCollision(myWorld, myCollisionC);
  cout << " <  NewtonReleaseCollision() for C" << endl;

  NewtonDestroy(myWorld);

  return 0;
}
thedmd
 

Re: Question about NewtonCollisionMakeUnique()

Postby Julio Jerez » Sat Oct 24, 2009 12:31 pm

with out running, thsi is what happens

Code: Select all
# include "newton.h"

# include <iostream>
# include <sstream>
# include <iomanip>

using namespace std;

std::string ptrToHex(void* ptr)
{
  ostringstream str;
  str << "0x" << setfill('0') << setw(8) << hex << ptr;
  return str.str();
}

void collisionConstructor(const NewtonCollision* collision, const std::string& name = "")
{
  cout << " +  [" << ptrToHex((void*)collision) << "] " << name << " created." << endl;
}

void collisionDestructor(const NewtonCollision* collision)
{
  cout << " -  [" << ptrToHex((void*)collision) << "] destroyed." << endl;
}

int main()
{
  NewtonWorld* myWorld  = NewtonCreate(NULL, NULL);

  NewtonSetCollisionDestructor(myWorld, collisionDestructor);

  NewtonCollision* myCollisionA = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);   //ref = 2
  collisionConstructor(myCollisionA, "A");

  //cout << "Call NewtonCollisionMakeUnique() for A" << endl;
  //NewtonCollisionMakeUnique(myWorld, myCollisionA);

  NewtonCollision* myCollisionB = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);   //ref = 3    myCollisionB == myCollisionA 
  collisionConstructor(myCollisionB, "B");

  //cout << "Call NewtonCollisionMakeUnique() for A" << endl;
  //NewtonCollisionMakeUnique(myWorld, myCollisionA);

  NewtonCollision* myCollisionC = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);    //ref = 4    myCollisionC == myCollisionB == myCollisionA 
   collisionConstructor(myCollisionC, "C");

  cout << "Call NewtonCollisionMakeUnique() for A" << endl;                                                 
  NewtonCollisionMakeUnique(myWorld, myCollisionA);                                                          //ref = 3    myCollisionC == myCollisionB == myCollisionA 

  cout << " >  NewtonReleaseCollision() for A" << endl;
  NewtonReleaseCollision(myWorld, myCollisionA);                                                               //ref = 2
  cout << " <  NewtonReleaseCollision() for A" << endl;

  cout << " >  NewtonReleaseCollision() for B" << endl;
  NewtonReleaseCollision(myWorld, myCollisionB);                                                               //ref = 1
  cout << " <  NewtonReleaseCollision() for B" << endl;

  cout << " >  NewtonReleaseCollision() for C" << endl;
  NewtonReleaseCollision(myWorld, myCollisionC);                                                               //ref = 0    ashape is detroyed
  cout << " <  NewtonReleaseCollision() for C" << endl;

  NewtonDestroy(myWorld);                                     

  return 0;
}


like I said call GetInfo so you can read teh ReF cound as it changes.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Question about NewtonCollisionMakeUnique()

Postby thedmd » Sat Oct 24, 2009 1:12 pm

Ups! I commented problematic code. Now this code below will show you a problem. I will put predicted ref count value and actual one.

Code: Select all
# include "newton.h"

# include <iostream>
# include <sstream>
# include <iomanip>

using namespace std;

std::string ptrToHex(void* ptr)
{
  ostringstream str;
  str << "0x" << setfill('0') << setw(8) << hex << ptr;
  return str.str();
}

void collisionConstructor(const NewtonCollision* collision, const std::string& name = "")
{
  cout << " +  [" << ptrToHex((void*)collision) << "] " << name << " created." << endl;
}

void collisionDestructor(const NewtonCollision* collision)
{
  cout << " -  [" << ptrToHex((void*)collision) << "] destroyed." << endl;
}

int main()
{
  NewtonWorld* myWorld  = NewtonCreate(NULL, NULL);

  NewtonSetCollisionDestructor(myWorld, collisionDestructor);

  NewtonCollision* myCollisionA = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);
  // Predicted: A::ref == 2   B::ref == 0   C::ref = 0
  // Actual:    A::ref == 2   B::ref == 0   C::ref = 0
  collisionConstructor(myCollisionA, "A");

  NewtonCollision* myCollisionB = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);
  // Predicted: A::ref == 3   B::ref == 3   C::ref = 0
  // Actual:    A::ref == 3   B::ref == 3   C::ref = 0
  collisionConstructor(myCollisionB, "B");

  cout << "Call NewtonCollisionMakeUnique() for A" << endl;
  // Predicted: A::ref == 2   B::ref == 2   C::ref = 0
  // Actual:    A::ref == 2   B::ref == 2   C::ref = 0
  NewtonCollisionMakeUnique(myWorld, myCollisionA);

  NewtonCollision* myCollisionC = NewtonCreateSphere(myWorld, 1.0f, 1.0f, 1.0f, 1, NULL);
  // Predicted: A::ref == 2   B::ref == 2   C::ref = 2
  // Actual:    A::ref == 2   B::ref == 2   C::ref = 2
  collisionConstructor(myCollisionC, "C");

  cout << " >  NewtonReleaseCollision() for A" << endl;
  NewtonReleaseCollision(myWorld, myCollisionA);
  // Predicted: A::ref == 1   B::ref == 1   C::ref = 2
  // Actual:    A::ref == 0   B::ref == 0   C::ref = 2
  // Now supprise, C is removed from cache. I'm quite sure about that.
  cout << " <  NewtonReleaseCollision() for A" << endl;

  cout << " >  NewtonReleaseCollision() for B" << endl;
  NewtonReleaseCollision(myWorld, myCollisionB);
  // Predicted: A::ref == 0   B::ref == 0   C::ref = 2
  // Actual:    A::ref == -1  B::ref == -1  C::ref = 2
  cout << " <  NewtonReleaseCollision() for B" << endl;

  cout << " >  NewtonReleaseCollision() for C" << endl;
  NewtonReleaseCollision(myWorld, myCollisionC);
  // Predicted: A::ref == 0   B::ref == 0   C::ref = 1
  // Actual:    A::ref == -1   B::ref == -1   C::ref = 1
  cout << " <  NewtonReleaseCollision() for C" << endl;

  NewtonDestroy(myWorld);
  // Predicted: A::ref == 0   B::ref == 0   C::ref = 0
  // Actual:    A::ref == -1   B::ref == -1   C::ref = 1
  // C::ref is one, becouse it was removed from cache and world don't nothing know about it

  return 0;
}
thedmd
 

Re: Question about NewtonCollisionMakeUnique()

Postby Julio Jerez » Sat Oct 24, 2009 2:29 pm

Oh now I see it.

if you remove a shape from the cache and the you make a new one with the same parameters, then the cache get a shape with the same the same signature, and anything that matches it will be asumed to be in the cache,
if see the Bug now. I will fix it, remove from chache have chnge the signatue of the removed shape.

I will also change MakeUnique to UncacheCollision.
you will get it with Beta 11.
Thanks for exposing that Bug.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Question about NewtonCollisionMakeUnique()

Postby thedmd » Sat Oct 24, 2009 2:41 pm

You're welcome.

I will then prepare my code for 2.11 version instead of making some workarounds. Thanks Julio.
thedmd
 


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron