NewtonCollisionInfoRecord - add custom data

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

NewtonCollisionInfoRecord - add custom data

Postby JernejL » Fri Nov 22, 2019 5:58 am

Is it possible, that 2-4 pointer-sized fields are added to NewtonCollisionInfoRecord?

I'd propose putting them between m_collisionType and union part of the struct, so it could be used on any shape, because i would need to store additional pointer next to userdata.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1521
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: NewtonCollisionInfoRecord - add custom data

Postby Julio Jerez » Fri Nov 22, 2019 11:24 am

ther collsion shape has a structure that can store lots of info on it
this could be use for what ever you want
Code: Select all
   typedef struct NewtonCollisionMaterial
   {
      void* m_userData;
      dLong m_userId;
      dLong m_userFlags0;
      dLong m_userFlags1;
      dFloat m_userParam[8];
   } NewtonCollisionMaterial;


there are these interface functions
Code: Select all
   void NewtonCollisionSetUserData (const NewtonCollision* const collision, void* const userData);
   void* NewtonCollisionGetUserData (const NewtonCollision* const collision);
   
   void NewtonCollisionSetUserID (const NewtonCollision* const collision, dLong id);
   dLong NewtonCollisionGetUserID (const NewtonCollision* const collision);

   void NewtonCollisionGetMaterial (const NewtonCollision* const collision, NewtonCollisionMaterial* const userData);
   void NewtonCollisionSetMaterial (const NewtonCollision* const collision, const NewtonCollisionMaterial* const userData);


the first four are for legacy and deal wit teh first tow member of the class
m_userData and m_userId;

by the last tow get you the entire structure and you can store and information you want there
the ints are 64 bit values and there are 8 float for making unilateral materials, sub shape material and anythong your logic demand.

m_userFlags0 and m_userFlags1 where 32 bit ints and jsut change ethe to 64 bit int you can store any info there. is not that enought?
Julio Jerez
Moderator
Moderator
 
Posts: 11086
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCollisionInfoRecord - add custom data

Postby JernejL » Sun Nov 24, 2019 2:02 pm

Yes this will be great, i didnt know i can use those fields at all
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1521
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: NewtonCollisionInfoRecord - add custom data

Postby JernejL » Mon Nov 25, 2019 2:41 am

I had some odd problem with the NewtonCollisionMaterial struct after this change, i found out that the record somehow has 4 extra padding bytes somewhere that i'm not sure where to put.

My pascal translation of this is correct regarding to members but not padding / alignment, this makes up 60 bytes:
Code: Select all
TNewtonCollisionMaterial = packed record
   m_userData: Pointer;
   m_userId: int64;
   m_userFlags0: int64;
   m_userFlags1: int64;
   m_userParam: array[0..7] of dfloat;
end;       

C++:
 
   typedef struct NewtonCollisionMaterial
   {
      void* m_userData;
      dLong m_userId;
      dLong m_userFlags0;
      dLong m_userFlags1;
      dFloat m_userParam[8];
   } NewtonCollisionMaterial;



In newton this record is 64 bytes long:

Code: Select all
   char msgbuf[50];

   sprintf(msgbuf, "NewtonCollisionMaterial is %d\n", sizeof(NewtonCollisionMaterial)); OutputDebugString(msgbuf);
   sprintf(msgbuf, "m_userData is %d\n", sizeof(NewtonCollisionMaterial().m_userData)); OutputDebugString(msgbuf);
   sprintf(msgbuf, "m_userFlags0 is %d\n", sizeof(NewtonCollisionMaterial().m_userFlags0)); OutputDebugString(msgbuf);
   sprintf(msgbuf, "m_userFlags1 is %d\n", sizeof(NewtonCollisionMaterial().m_userFlags1)); OutputDebugString(msgbuf);
   sprintf(msgbuf, "m_userId is %d\n", sizeof(NewtonCollisionMaterial().m_userId)); OutputDebugString(msgbuf);
   sprintf(msgbuf, "m_userParam is %d\n", sizeof(NewtonCollisionMaterial().m_userParam)); OutputDebugString(msgbuf);


Debug Output: 'm_userData is 4'
Debug Output: 'm_userFlags0 is 8'
Debug Output: 'm_userFlags1 is 8'
Debug Output: 'm_userId is 8'
Debug Output: 'm_userParam is 32'

Debug Output: 'NewtonCollisionMaterial is 64'


If i sum up all those sub-members it ends up being 60 bytes - same as my pascal version of this is, but somehow sizeof NewtonCollisionMaterial is 64 which means 4 bytes were padded in somewhere.. can you add a directive in that header to prevent padding from being added? This breaks all NewtonCollisionGetType calls because m_collisionType is not accessed at correct address, it is the first time that struct padding was a problem in newton for me.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1521
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: NewtonCollisionInfoRecord - add custom data

Postby Dave Gravel » Mon Nov 25, 2019 3:40 am

Hi JernejL, I'm not sure why you get 60 from pascal side.
Here when I test I get 64 from both side.

Edited:
I think it is because you use 32bits version and your pointer is in 32bits mode...
Maybe newton need a flag somewhere for set the pointer in 32bits mode when the 32bits config is in use.
Code: Select all
    TNewtonCollisionMaterial = Record
       m_userData: pointer;
        m_userId: int64;
       m_userFlags0: int64;
       m_userFlags1: int64;
       m_userParam: array[0..7] of single;
     end;

   writeln(Format('%d', [sizeof(TNewtonCollisionMaterial)]));
   result 64

  writeln(Format('%d', [sizeof(TNewtonCollisionMaterial.m_userData)]));
  result 8
  writeln(Format('%d', [sizeof(TNewtonCollisionMaterial.m_userId)]));
  result 8
  writeln(Format('%d', [sizeof(TNewtonCollisionMaterial.m_userFlags0)]));
  result 8
  writeln(Format('%d', [sizeof(TNewtonCollisionMaterial.m_userFlags1)]));
  result 8
  writeln(Format('%d', [sizeof(TNewtonCollisionMaterial.m_userParam)]));
  result 32
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://www.facebook.com/dave.gravel1
http://orionx3d.googlepages.com/
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 719
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: NewtonCollisionInfoRecord - add custom data

Postby Julio Jerez » Mon Nov 25, 2019 6:03 am

oh yes, alignment has caused problem in the pass and since I changed to int64, but the first member reminded a pointer, I can see how this could yield compiler alignment issues.

I made compiler independent of size and alignment by using union with a int64 for each menber
Code: Select all
   typedef struct NewtonCollisionMaterial
   {
      union {
         void* m_userData;
         dLong m_alignPad;
      };
      dLong m_userId;
      union {
         dLong m_intData;
         dFloat m_floatData;
      } m_userParam[6];
   } NewtonCollisionMaterial;

I also removed the two flags members since they can be one of the userParam.
this will make the struct a flat 64 bytes for all configurations.
I am not sure how you set union in pascal but I use union before, so it should be possible.

please try sync again.
Julio Jerez
Moderator
Moderator
 
Posts: 11086
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCollisionInfoRecord - add custom data

Postby JernejL » Mon Nov 25, 2019 7:11 am

Sadly pascal can only do one union in struct, and it has to be the last one in the struct (this was only used in NewtonCollisionInfoRecord and it was last entry so it was compatible).

I'm not sure how to process a record like this - can you please change it back to previous simple structure without union? since i know now that c++ padded after the pointer, i can use the previous structure more easily and set padding in compiler on my side to keep this more easily compatible.

Is it possible to use #pragma pack for this one record? (c++ can do push pop of this value so it can be just restored to previous pack value after record is declared)
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1521
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: NewtonCollisionInfoRecord - add custom data

Postby Julio Jerez » Mon Nov 25, 2019 7:39 am

let us do one thing at a time.
will it work if is was like this

Code: Select all
   typedef union
   {
      void* m_ptr;
      dLong m_int;
      dFloat m_float;
   } NewtonMaterialData;

   typedef struct NewtonCollisionMaterial
   {
      dLong m_userId;
      NewtonMaterialData m_userData;
      NewtonMaterialData m_userParam[6];
   } NewtonCollisionMaterial;
Julio Jerez
Moderator
Moderator
 
Posts: 11086
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCollisionInfoRecord - add custom data

Postby JernejL » Mon Nov 25, 2019 8:06 am

That could work

void* m_ptr;
dLong m_int;
dFloat m_float;

This would make record 32 bits long and 64 bit on 64 bit machines, correct?

To make things easier - you can just change it back to old version, i will just use proper alignment compiler settings (8 bytes) and it will work.
Code: Select all
   typedef struct NewtonCollisionMaterial
   {
      void* m_userData;
      dLong m_userId;
      dLong m_userFlags0;
      dLong m_userFlags1;
      dFloat m_userParam[8];
   } NewtonCollisionMaterial;
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1521
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: NewtonCollisionInfoRecord - add custom data

Postby Julio Jerez » Mon Nov 25, 2019 10:07 am

The union of void*, dlong and dfloat
In always 64 bit because dlong is 64 bit
Going back does not fix it because void*
Is 32 bit in 32 bit mode and 64 in 64 bit mode,
So padding does not fix it unless the padding was a void*

If the proposed solution does it, I will go ahead and use that.
Julio Jerez
Moderator
Moderator
 
Posts: 11086
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCollisionInfoRecord - add custom data

Postby Julio Jerez » Mon Nov 25, 2019 10:28 am

Ok it is all change to use this layout
Code: Select all
   typedef union
   {
      void* m_ptr;
      dLong m_int;
      dFloat m_float;
   } NewtonMaterialData;

   typedef struct NewtonCollisionMaterial
   {
      dLong m_userId;
      NewtonMaterialData m_userData;
      NewtonMaterialData m_userParam[6];
   } NewtonCollisionMaterial;


see if you can make compile and if so make another repro for the crash bug.
Julio Jerez
Moderator
Moderator
 
Posts: 11086
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonCollisionInfoRecord - add custom data

Postby JernejL » Mon Nov 25, 2019 3:07 pm

Ok, this worked:

Code: Select all

   typedef union
   {
      void* m_ptr;
      dLong m_int;
      dFloat m_float;
   } NewtonMaterialData;
   typedef struct NewtonCollisionMaterial
   {
      dLong m_userId;
      NewtonMaterialData m_userData;
      NewtonMaterialData m_userParam[6];
   } NewtonCollisionMaterial;



pascal version:

Code: Select all

// UNION compiles like this (as i it was a case inside a struct / record)
TNewtonMaterialData = packed record
case integer of
1: (
   m_ptr: Pointer;
);
2: (
   m_int: int64;
);
3: (
   m_float: dfloat;
);
end;
PNewtonMaterialData = ^TNewtonMaterialData;

TNewtonCollisionMaterial = packed record
   m_userId: int64;
   m_userData: TNewtonMaterialData;
   m_userParam: array[0..5] of TNewtonMaterialData;
end;
PNewtonCollisionMaterial = ^TNewtonCollisionMaterial;



Size for both is 64 bytes, alignment is perfect too!

I will use this and compile you a new demo to test the crash problem.
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1521
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 15 guests