Unlimited world

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Re: Unlimited world

Postby Julio Jerez » Tue Jan 21, 2014 2:33 pm

JackMK wrote:1) My world consists of several small terrains á 512x512 that are loaded at runtime based on camera position. I want use collision detection and therefore I took a look at NewtonCreateHeightFieldCollision function and it looks to me like the up direction must be Y-axis for the heightfield but in my case I am using the Z-axis. Because of that I´m not sure if I can still use newton heightfield collision primitive. What could I use instead in order to load/unload terrains efficiently while the player is moving?

the constrution of the highfield is the x, y plane yes, but that is no relevan because you cna set the locat matrix of the collision to any oriention you want.
tah alowen you to place teh collsion anywhen and in any orientation.

JackMK wrote:2) What would be the best way to offset the whole world by some distance. The thought is when the player is far way from the origin I want to reposition him and also the world too. I did not found any function for that.

you can can the transformation matrix of any body, at any time. by yo uhave to do it yorself using funtion iterators NetwonGetFirstBody() an dNetwonGetNesgBody()

JackMK wrote:3) What is the advantage of using a scene collision with many compound collisions for all static geometries in a world over many static rigid bodies, one for each geometry? By using one rigid body for each geometry, could it be a problem when a lot of them are in the world?

if you have lot of static mesh, lot of bbuidning lot of terratin patchs, and yo uadd the to teh workd each as a rigid body, tnen many part of eth engien will be activated and do lot of work of those bodies.
if you place then in a scene collision, then the engine will skip lot of work on those bodies, and ti will also save lot of memory.

you can make one scene collision and add everything static, but you can also
make more than one and use then for organizing you world.
For example one for terrains tiles, one for buildings, one for triggers, and so on.
sub shapes in a scene collsion can me added, removed and relocated at will.
basically a scene collsion is line a mini world for static shapes.

if you are new to Netwon and you are in C++, you can try teh CNetwon Class.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Thu Jan 23, 2014 8:14 am

ha, it is changed. I also changed the pointer to the node as well, thank you.

Yes you can keep the pointer returned by NewtonAddSubcollsionMatrix, that a handler to a container node, it is not a collision
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Fri Jan 24, 2014 7:06 am

do you move terrain time every frame?
when you move object in a scene collision you need to do it from scene Begin/end block, you do it outside a newton update and you move all of the


movable object that move by physics are not candidate for scene collision, this is for static objects
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Fri Jan 24, 2014 11:51 am

Oh I see,
you are right you do no ge the sub node in the raycast call back

The Scene Compound Collision need this own set of call back for RayCast,
they already have one OnCompoundCollisionPrefilter for collision but not for rays.

I will add a way to get that information for ray casting too, I can no do right now I do it tonight.

I either extend the existing call back or add a new set for compounds. My inclination and to add a new Set.


about moving object in the scene, you should be able to do that with problems. the vehicle in the engine are compound collision that move the tire shape all the time
this is teh set of functions to call for doing in

Code: Select all
   void NewtonSceneCollisionBeginAddRemove (NewtonCollision* const sceneCollision);   
   void NewtonSceneCollisionSetSubCollisionMatrix (NewtonCollision* const sceneCollision, const void* const collisionNode, const dFloat* const matrix);   
   void NewtonSceneCollisionEndAddRemove (NewtonCollision* const sceneCollision);   


you need to do that for all the shape you need to move at once, do no do it for each shape one at a time because is more expensive.
also you can have more than one scene collision. make one for the terrain and another for other static objects.

Scene collision allow to spacialy classify your world.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Fri Jan 24, 2014 12:19 pm

Oh I see, I take what I said back.

yes there is a way to get the sub collision in a raycast callback, here is how, a;ls this exten to all callbacks


when you are making you scene, or compound collision each time you add add a sub shape, you get the collision sub from the sub shape and you save the subshape handle as the user data
Code: Select all
NewtonCollision* collision NewtonSceneCollisionGetCollisionFromNode (NewtonCollision* const sceneCollision, const void* const collisionNode);
NewtonCollisionSetUserData (collision, collisionNode);


then in the call back you get the collision type, and if it is a scene or a compound then you can get the user data form the sub shape, and that will be the node.

I will add that test to the compound and scene demos, to make sure is correct.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Sat Jan 25, 2014 10:58 am

Hold, I was thinking that that using the user data is not the better way to get that information.
The use data in teh collision should be for the user.

Instead I am adding a new pointe member to the collision instance that is identical to the user data, but this point will be set to the node that point to that instance in In a compound

then there will be a direct function to get that information form the collision.
void* NewtonCollisionGetSubCollisionHandle (const NewtonCollision* const collision);

I am adding that now, I will check it in today
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Sun Jan 26, 2014 3:12 pm

Ok now there are two function now in the
void* NewtonCollisionGetSubCollisionHandle (const NewtonCollision* const collision);
NewtonCollision* NewtonCollisionGetParentInstance (const NewtonCollision* const collision);

you use them like this,
Code: Select all
   static unsigned RayCastPrefilter (const NewtonBody* body,  const NewtonCollision* const collision, void* const userData)
   {
      // ray cannot pick trigger volumes
      //return NewtonCollisionIsTriggerVolume(collision) ? 0 : 1;

      const NewtonCollision* const parent = NewtonCollisionGetParentInstance(collision);
      if (parent) {
         // you can use this to filter sub collision shapes. 
         dAssert (NewtonCollisionGetSubCollisionHandle (collision));
      }

      return (NewtonBodyGetType(body) == NEWTON_DYNAMIC_BODY) ? 1 : 0;
   }

   static dFloat RayCastFilter (const NewtonBody* const body, const NewtonCollision* const collisionHit, const dFloat* const contact, const dFloat* const normal, dLong collisionID, void* const userData, dFloat intersetParam)
   {
      dFloat mass;
      dFloat Ixx;
      dFloat Iyy;
      dFloat Izz;

      // check if we are hitting a sub shape
      const NewtonCollision* const parent = NewtonCollisionGetParentInstance(collisionHit);
      if (parent) {
         // you can use this to filter sub collision shapes. 
         dAssert (NewtonCollisionGetSubCollisionHandle (collisionHit));
      }



      dMousePickClass* const data = (dMousePickClass*) userData;
      NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
      if ((mass > 0.0f) || (NewtonBodyGetType(body) == NEWTON_KINEMATIC_BODY)) {
         data->m_body = body;
      }

      
      if (intersetParam < data->m_param) {
         data->m_param = intersetParam;
         data->m_normal = dVector (normal[0], normal[1], normal[2]);
      }
      return intersetParam;
   }


later I will add the to the collision and convex cast interface as well.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Mon Jan 27, 2014 11:58 am

JackMK wrote:It is realy important that material collision callback will work for scene collisions. Scene collisions are realy fast and I like to use it.


I beleive it work for collision, these function s

typedef void (*NewtonContactsProcess) (const NewtonJoint* const contact, dFloat timestep, int threadIndex);
typedef int (*NewtonOnCompoundSubCollisionAABBOverlap) (const NewtonMaterial* const material, const NewtonBody* const body0, const void* const collsionNode0, const NewtonBody* const body1, const void* const collsionNode1, int threadIndex);


provide the const NewtonMaterial* const material, and form there you cna get teh colliding shape using thsi function
NewtonCollision* NewtonMaterialGetBodyCollidingShape (const NewtonMaterial* const material, const NewtonBody* const body);

for what I can see they only thing that still need to be refactered is the convex cast, collsions call back be should be working

for an example, in demo: ../applications\demosSandbox\sdkDemos\demos\CompoundCollision.cpp check function
static void GetCollisionSubShape(const NewtonJoint* const contactJoint, NewtonBody* const body)
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Mon Jan 27, 2014 2:15 pm

but
Code: Select all
typedef int  (*NewtonOnCompoundSubCollisionAABBOverlap) (const NewtonMaterial* const material, const NewtonBody* const body0, const void* const collsionNode0, const NewtonBody* const body1, const void* const collsionNode1, int threadIndex);

provide the direct nodes,
The one thing I can do is to change the prototype to report the collision shape,
now that ther are function to ge the handle from the shape. That will be more consistent with the other callback.

I do not knwo what you are doing wrong, I knwo fo ra fact that tah callback works, It is use in teh CNewton Class.


if you look at teh place when teh callback is called form you cn asee tha it is passin teh node pointers.

here is part of the scene collision broad phase collssion
Code: Select all
void dgCollisionScene::CollideCompoundPair (dgCollidingPairCollector::dgPair* const pair, dgCollisionParamProxy& proxy) const
{
   const dgNodeBase* stackPool[4 * DG_COMPOUND_STACK_DEPTH][2];

   dgContact* const constraint = pair->m_contact;
   dgBody* const myBody = constraint->GetBody1();
   dgBody* const otherBody = constraint->GetBody0();

   dgAssert (myBody == proxy.m_floatingBody);
   dgAssert (otherBody == proxy.m_referenceBody);

   dgCollisionInstance* const myCompoundInstance = myBody->m_collision;
   dgCollisionInstance* const otherCompoundInstance = otherBody->m_collision;

   dgAssert (myCompoundInstance->GetChildShape() == this);
   dgAssert (otherCompoundInstance->IsType (dgCollision::dgCollisionCompound_RTTI));
   dgCollisionCompound* const otherCompound = (dgCollisionCompound*)otherCompoundInstance->GetChildShape();

   const dgContactMaterial* const material = constraint->GetMaterial();

   dgMatrix myMatrix (myCompoundInstance->GetLocalMatrix() * myBody->m_matrix);
   dgMatrix otherMatrix (otherCompoundInstance->GetLocalMatrix() * otherBody->m_matrix);
   dgOOBBTestData data (otherMatrix * myMatrix.Inverse());

   dgInt32 stack = 1;
   stackPool[0][0] = m_root;
   stackPool[0][1] = otherCompound->m_root;

   const dgVector& hullVeloc = otherBody->m_veloc;
   dgFloat32 baseLinearSpeed = dgSqrt (hullVeloc % hullVeloc);

   dgFloat32 closestDist = dgFloat32 (1.0e10f);
   if (proxy.m_continueCollision && (baseLinearSpeed > dgFloat32 (1.0e-6f))) {
      dgAssert (0);
   } else {
      while (stack) {
         stack --;
         const dgNodeBase* const me = stackPool[stack][0];
         const dgNodeBase* const other = stackPool[stack][1];

         dgAssert (me && other);

         if (me->BoxTest (data, other)) {

            if ((me->m_type == m_leaf) && (other->m_type == m_leaf)) {
               dgAssert (!me->m_right);

               bool processContacts = true;
               if (material->m_compoundAABBOverlap) {
                  processContacts = material->m_compoundAABBOverlap (*material, myBody, me->m_myNode, otherBody, other->m_myNode, proxy.m_threadIndex);
               }

you can place a break point at line 281 an see what happen afte that.
if (material->m_compoundAABBOverlap) {
processContacts = material->m_compoundAABBOverlap (*material, myBody, me->m_myNode, otherBody, other->m_myNode, proxy.m_threadIndex);
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Mon Jan 27, 2014 2:19 pm

Code: Select all
NewtonCollision *seneCollision = NewtonBodyGetCollision(body0);
NewtonCollision *collision = NewtonSceneCollisionGetCollisionFromNode(seneCollision, collsionNode0);
void *applicationNode = NewtonCollisionGetUserData(collision);


    you need to use the pointers to ther sub child nodes that are passed in the callback
    body0, will point to the root collision
    const void* const collsionNode0 if not NULL will point the child collision node, of a compound collsion of body0

    body1, will point to the other body root collision
    const void* const collsionNode1 if not NULL will point the child collision node, of a compound collsion of body1
sorry my mistake, it look lie you have it right that looks correct, I will try to place that code in demo,
../applications\demosSandbox\sdkDemos\demos\CompoundCollision.cpp

funtion
static int OnSubShapeAABBOverlapTest (const NewtonMaterial* const material, const NewtonBody* const body0, const void* const collsionNode0, const NewtonBody* const body1, const void* const collsionNode1, int threadIndex)
and see why is does no work for you,
If you can build the demos, you can try yourself and see why is wrong, I am at work now and can no do it until I get home.
I know that this works, becaus I use on othe wrapers.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Mon Jan 27, 2014 2:29 pm

there is another thing you have to do. you need to test i fthe node pointer are NULL.
for example if a compound collide with othe not compound body one of the pointer will be node will be NULL.
body0 and body1 are not alway compound bodies, either or both will be compound in not special order.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Unlimited world

Postby Julio Jerez » Mon Jan 27, 2014 5:21 pm

what do you mean dgCollisionScene::CollidePair is called for a diffirent place?
collide pair will be called from the broardPhase, and OnContactOverlap will be called from that funtion

you can see that in tah funtion wh eth collsion is with another single collsion shape, teh secudn parameter is NULL

if (material->m_compoundAABBOverlap) {
processContacts = material->m_compoundAABBOverlap (*material, sceneBody, me->m_myNode, otherBody, NULL, proxy.m_threadIndex);
}


the other place that the callback can be called if in the same file
void dgCollisionScene::CollideCompoundPair (dgCollidingPairCollector::dgPair* const pair, dgCollisionParamProxy& proxy) const
and the will also call teh callback when two compound collide.
that should be very eassy to verify
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest

cron