Hinge Joint collision problem

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Re: Hinge Joint collision problem

Postby Neo » Sun Jul 15, 2012 7:59 am

Joej, you mean I have to set the matix maunaully!?
Neo
 
Posts: 127
Joined: Fri May 11, 2012 12:29 pm
Location: China,Sichuan

Re: Hinge Joint collision problem

Postby JoeJ » Sun Jul 15, 2012 3:46 pm

Neo wrote:you mean I have to set the matix maunaully!?


No, you don't have to... but you can (and should be able to do so) if you want.
Just wait on Julios responce.
And meanwhile you can setup a test scene without scaling?
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Hinge Joint collision problem

Postby JoeJ » Sun Jul 15, 2012 4:14 pm

hmmm... Julio's very busy, everyone is requesting stuff and this topic has nothing todo with physics.
Maybe i should halp you out there, saving him some time.

I'll try to update your code - i don't know your mathlib, i don't have experience with scaled bodies, but i'll try...

Code: Select all

IMeshSceneNode *floor=smgr->addCubeSceneNode(500);
   //
         add texture here
        //
        floor->setScale(vector3df(1,0.01f,1));//scale the y aixs,because I want a plate, not a cube box
        floor->setPosition(vector3df(0,-30,0));
   aabbox3df fbox=floor->getTransformedBoundingBox();
   vector3df sz=fbox.getExtent();
   matrix4 mt=floor->getRelativeTransformation();

// assign our axis vectors to that matrix
vector3df *x = (vector3df*)&mt.pointer()[0]; // 1st. row
vector3df *y = (vector3df*)&mt.pointer()[4]; // 2nd. row
vector3df *z = (vector3df*)&mt.pointer()[8];
// extract scale
float scaleX = x->length();
float scaleY = y->length();
float scaleZ = z->length();
// normalize matrix
*x /= scaleX;
*y /= scaleY;
*z /= scaleZ;

// matrix now ready for newton
   NewtonCollision*coll=NewtonCreateBox(nWorld,sz.X,sz.Y,sz.Z,shapeID++,NULL);

// but, we're back to a cube now, so scale the collision to become a plate as we want
 NewtonCollisionSetScale (coll, scaleX, scaleY, scaleZ);

   NewtonBody* floorBd=NewtonCreateBody(nWorld,coll,&mt.pointer()[0]);

   NewtonBodySetTransformCallback(floorBd,transformCallback);
   NewtonBodySetUserData(floorBd,static_cast<void*>(floor));




let me know if it works...
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Hinge Joint collision problem

Postby Neo » Sun Jul 15, 2012 9:01 pm

JoeJ wrote:i don't know your mathlib
let me know if it works...

Oops, It's just irrlicht class, in the CMatrix4,
So, let me paste the irrlicht source code here,
Code: Select all
template <class T>
   inline CMatrix4<T>& CMatrix4<T>::setRotationDegrees( const vector3d<T>& rotation )
   {
      return setRotationRadians( rotation * core::DEGTORAD );//const f32 DEGTORAD = PI / 180.0f;
   }
template <class T>
   inline CMatrix4<T>& CMatrix4<T>::setRotationRadians( const vector3d<T>& rotation )
   {
      const f64 cr = cos( rotation.X );
      const f64 sr = sin( rotation.X );
      const f64 cp = cos( rotation.Y );
      const f64 sp = sin( rotation.Y );
      const f64 cy = cos( rotation.Z );
      const f64 sy = sin( rotation.Z );

      M[0] = (T)( cp*cy );
      M[1] = (T)( cp*sy );
      M[2] = (T)( -sp );

      const f64 srsp = sr*sp;
      const f64 crsp = cr*sp;

      M[4] = (T)( srsp*cy-cr*sy );
      M[5] = (T)( srsp*sy+cr*cy );
      M[6] = (T)( sr*cp );

      M[8] = (T)( crsp*cy+sr*sy );
      M[9] = (T)( crsp*sy-sr*cy );
      M[10] = (T)( cr*cp );
#if defined ( USE_MATRIX_TEST )
      definitelyIdentityMatrix=false;
#endif
      return *this;
   }

template <class T>
   inline CMatrix4<T>& CMatrix4<T>::setScale( const vector3d<T>& scale )
   {
      M[0] = scale.X;
      M[5] = scale.Y;
      M[10] = scale.Z;
#if defined ( USE_MATRIX_TEST )
      definitelyIdentityMatrix=false;
#endif
      return *this;
   }

   template <class T>
   inline CMatrix4<T>& CMatrix4<T>::setTranslation( const vector3d<T>& translation )
   {
      M[12] = translation.X;
      M[13] = translation.Y;
      M[14] = translation.Z;
#if defined ( USE_MATRIX_TEST )
      definitelyIdentityMatrix=false;
#endif
      return *this;
   }

virtual core::matrix4 getRelativeTransformation() const
      {
         core::matrix4 mat;
         mat.setRotationDegrees(RelativeRotation);
         mat.setTranslation(RelativeTranslation);

         if (RelativeScale != core::vector3df(1.f,1.f,1.f))
         {
            core::matrix4 smat;
            smat.setScale(RelativeScale);
            mat *= smat;
         }

         return mat;
      }
Neo
 
Posts: 127
Joined: Fri May 11, 2012 12:29 pm
Location: China,Sichuan

Re: Hinge Joint collision problem

Postby JoeJ » Mon Jul 16, 2012 10:17 am

There's one more issue, it seems scale affects position too, if you use that getRelativeTransformation function to get the matrix.
You set the box position like that:
floor->setPosition(vector3df(0,-30,0));

But you plot the 4th row which contains position as:
0.00000000 -3.0000000 0.00000000 1.0000000

So the y value was scaled down from -30 to -3.
But you set the scale: (1, 0.01, 1).
Now i'm confused, because -30 * 0.01 doesn't equal -3
Maybe there's a typo somewhere?

Maybe you need to update again and modify position too
Code: Select all

    IMeshSceneNode *floor=smgr->addCubeSceneNode(500);
       //
             add texture here
            //
            floor->setScale(vector3df(1,0.01f,1));//scale the y aixs,because I want a plate, not a cube box
            floor->setPosition(vector3df(0,-30,0));
       aabbox3df fbox=floor->getTransformedBoundingBox();
       vector3df sz=fbox.getExtent();
       matrix4 mt=floor->getRelativeTransformation();

    // assign our axis vectors to that matrix
    vector3df *x = (vector3df*)&mt.pointer()[0]; // 1st. row
    vector3df *y = (vector3df*)&mt.pointer()[4]; // 2nd. row
    vector3df *z = (vector3df*)&mt.pointer()[8];
    // extract scale
    float scaleX = x->length();
    float scaleY = y->length();
    float scaleZ = z->length();
    // normalize matrix
    *x /= scaleX;
    *y /= scaleY;
    *z /= scaleZ;

// try to fix position too, if necessary...
 vector3df *pos = (vector3df*)&mt.pointer()[12]; // last row as vector
pos = floor->getPosition();
// or hardcode it for this single example: pos = vector3df(0,-30,0);

    // matrix now ready for newton
       NewtonCollision*coll=NewtonCreateBox(nWorld,sz.X,sz.Y,sz.Z,shapeID++,NULL);

    // but, we're back to a cube now, so scale the collision to become a plate as we want
    NewtonCollisionSetScale (coll, scaleX, scaleY, scaleZ);

       NewtonBody* floorBd=NewtonCreateBody(nWorld,coll,&mt.pointer()[0]);

       NewtonBodySetTransformCallback(floorBd,transformCallback);
       NewtonBodySetUserData(floorBd,static_cast<void*>(floor));




Can you implement that? are there any syntax problems you can't solve?
I strongly recommend to begin with cubes to see if visuals and physics really match up.
If you're sure that works try to add a little scaling like (1, 0.9, 1).

It looks like irrlicht is based on euler angles, a scale and a position vector for the nodes?
This is not good. Euler angles are unavoidable, because animaters need to edit keyframes and curves,
but engines should not use them for scene management.

Your learning experience will be better, if you take the matrices coming from newton as 'That defines, what's really going on',
and Irrlichts format as 'this is what i need to calculate from the matrix, to visualize my stuff properly'.
At the moment we do it the opposite way.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Hinge Joint collision problem

Postby Neo » Mon Jul 16, 2012 11:01 am

Thx JoeJ. Currently, I use irrlicht only for rendering, use irrlicht to update visual object would be more convinience..
And as for normalize, irrlicht vector3d has a member function for it,
so the code is like
Code: Select all
vector3df *x = (vector3df*)(&mt.pointer()[0]);// 1st. row
    vector3df *y = (vector3df*)(&mt.pointer()[4]); // 2nd. row
    vector3df *z = (vector3df*)(&mt.pointer()[8]);
x->normalize();
y->normalize();
z->normalize();

and as for postion:
Code: Select all
pos = floor->getPosition();
mat.setTransition(pos);

And I see that you set the collsion scale before make newton body, and pass the normalize matix to build the body.
Uh.. This is what I do in convex hull building function: scaling the collison, then making an indetity matrix, set rotation, set transition, , then use this matrix to build newton body. However assert error still occurs on the freak scale(the 0.001scale stuff....or sth like that) and very small thing (a bullet object which is a cube with only one unit's length). It seems that newton dynamics hate the small stuff.... :P
Neo
 
Posts: 127
Joined: Fri May 11, 2012 12:29 pm
Location: China,Sichuan

Re: Hinge Joint collision problem

Postby Julio Jerez » Mon Jul 16, 2012 11:38 am

where those teh assert happens?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Hinge Joint collision problem

Postby Neo » Mon Jul 16, 2012 12:19 pm

Julio Jerez wrote:where those teh assert happens?

Well, I have modified the floor object's scale to vector3df(1,0.1f,1), and everything work's right until I press the key to fire out a small object(an one-unit cube). Then the assert error happens.
Here's the cube creation code
Code: Select all
IMeshSceneNode *bullet=smgr->addCubeSceneNode(1);
   bullet->setMaterialFlag(video::EMF_LIGHTING,false);
   bullet->setMaterialTexture(0,driver->getTexture("F:/myGame/Irr/tankwar/tankwar/sfx/env/common/grass.jpg"));
   bullet->setPosition(vector3df(100,-20,70));
   bullet->setScale(vector3df(2,1,1));//you see a normal scale, not a freak one
   //Newton body
   aabbox3df fbox=bullet->getTransformedBoundingBox();
   vector3df sz=fbox.getExtent()*IrrToNewton;//for simulation purpose I set this value to 0.1
   matrix4 mt=bullet->getRelativeTransformation(),mat2;
   mt.setTranslation(mt.getTranslation()*IrrToNewton);
   NewtonCollision* coll=NewtonCreateCylinder(nWorld,sz.Y/2,sz.Z,100,NULL);
   NewtonBody* bulletBd=NewtonCreateBody(nWorld,coll,&mt.pointer()[0]);
   NewtonBodySetTransformCallback(bulletBd,transformCallback);
   NewtonBodySetUserData(bulletBd,static_cast<void*>(bullet));

and the assert error:
dgbody.h
Expression:dgAbsf(val-1.0f)<1.0e-5f
and something like before
again, program stops at the create newton body function
the matirx
Code: Select all
      
2.0000000  0.00000000  0.00000000  0.00000000
0.00000000  1.0000000  0.00000000  0.00000000
0.00000000  0.00000000  1.0000000  0.00000000
10.000000  -2.0000000  7.0000000  1.0000000
Neo
 
Posts: 127
Joined: Fri May 11, 2012 12:29 pm
Location: China,Sichuan

Re: Hinge Joint collision problem

Postby Neo » Mon Jul 16, 2012 12:22 pm

JoeJ wrote:So the y value was scaled down from -30 to -3.
But you set the scale: (1, 0.01, 1).
Now i'm confused, because -30 * 0.01 doesn't equal -3
Maybe there's a typo somewhere?

Sorry, Joej, I forgot to tell you that for simulation purpose the position and shape were multiplied by 0.1....And that is the reason why the y value is 10 times smaller than you expected. :oops:
Neo
 
Posts: 127
Joined: Fri May 11, 2012 12:29 pm
Location: China,Sichuan

Re: Hinge Joint collision problem

Postby JoeJ » Mon Jul 16, 2012 12:39 pm

No problem, but look at the first row of your ploted matrix:
2,0,0
is this unit length? Nooo... it has a length of 2!
It must be
1,0,0
Again you use a nonuniformaly scaled matrix :shock:
Look at my modiefied code of yours:
I cast a vector to each row and normalize it. (So matrix changes too)
Then create the body with the normalized matrix.

Your Lines should do that job:
vector3df *x = (vector3df*)(&mt.pointer()[0]);// 1st. row
vector3df *y = (vector3df*)(&mt.pointer()[4]); // 2nd. row
vector3df *z = (vector3df*)(&mt.pointer()[8]);
x->normalize();
y->normalize();
z->normalize();
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Hinge Joint collision problem

Postby belfegor » Mon Jul 16, 2012 1:09 pm

@neo
Why dont you prescale your models in modeling program instead in code?
Also why dont you use 1.0f (one) unit as 1 meter and then you can skip all "scale" conversion (IrrToNewton) ?
User avatar
belfegor
 
Posts: 53
Joined: Mon Sep 18, 2006 4:42 pm
Location: Serbia

Re: Hinge Joint collision problem

Postby Neo » Mon Jul 16, 2012 1:24 pm

OK, Joej, I modified it.
using
Code: Select all
mt.makeIdentity();
   mt.setTranslation(bullet->getPosition()*IrrToNewton);
   vector3df scale=bullet->getScale()*IrrToNewton;
   NewtonCollision* coll=NewtonCreateCylinder(nWorld,sz.Y/2,sz.Z,bulletShapeID++,NULL);
   NewtonCollisionSetScale(coll,scale.X,scale.Y,scale.Z);
   NewtonBody* bulletBd=NewtonCreateBody(nWorld,coll,&mt.pointer()[0]);

And that assert error didn't happen again. :D
But when then bullet bounce back from the joint and hit the floor(the floor is convex hull) another assert error happened:
dgCollisionConvex.cpp
Expression: dgAbsf(side0-plane.Evalue(m_vertex[firstEdge->m_vertex]))<dgFloat32(1.0e-5f)
.....
What's that?
Neo
 
Posts: 127
Joined: Fri May 11, 2012 12:29 pm
Location: China,Sichuan

Re: Hinge Joint collision problem

Postby JoeJ » Mon Jul 16, 2012 1:38 pm

I'm actually on OSX and can't access Newton source.
But i'd guess you did something illegal with that convex hull... :)
Or one of the edges from the mesh has zero length, or double sided polygons... something like that.
When posting assert also post Code Line Number and Stack Trace too, if possible.

EDIT: Keep belfegors tip in mind - it's always better to avoid scaling if possible.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Hinge Joint collision problem

Postby Neo » Mon Jul 16, 2012 1:43 pm

belfegor wrote:@neo
Why dont you prescale your models in modeling program instead in code?
Also why dont you use 1.0f (one) unit as 1 meter and then you can skip all "scale" conversion (IrrToNewton) ?

I would scale my mesh in real game...this is just test and I'm using the build-in code to create mesh for testing.
For the map, IrrEdit is the tool I used to create map model, but for the primitive objects, such as cube, IrrEdit's method is to create a square cube then store your scale infomation into map file, the node and vertex modifing is not provided in irrEdit....

As for unit scaling, uh, I first learning the integration from the newton wiki's tutorial. And the writer did the unit scaling in that tutorial... If use 1 as 1 meter is OK, sure, I will use it.
Neo
 
Posts: 127
Joined: Fri May 11, 2012 12:29 pm
Location: China,Sichuan

Re: Hinge Joint collision problem

Postby Neo » Mon Jul 16, 2012 1:57 pm

JoeJ wrote:I'm actually on OSX and can't access Newton source.
But i'd guess you did something illegal with that convex hull... :)
Or one of the edges from the mesh has zero length, or double sided polygons... something like that.
When posting assert also post Code Line Number and Stack Trace too, if possible.

EDIT: Keep belfegors tip in mind - it's always better to avoid scaling if possible.

Okey,
assert error:
file dgCollisionConvex.cpp
line 1501
Expression: dgAbsf(side0-plane.Evalue(m_vertex[firstEdge->m_vertex]))<dgFloat32(1.0e-5f)
trace stack(is this stuff?)
> newton_d.dll!0053c0ae()

newton_d.dll!0053c54d()
newton_d.dll!0053c54d()
newton_d.dll!0053c54d()
newton_d.dll!004cc3eb()
newton_d.dll!004e8c62()

When I change the floor object to the collsion primitive, nothing happened, but basicially everything in the scene is convex hull.
So when I change floor object back to convex hull, that error occurs again.
Neo
 
Posts: 127
Joined: Fri May 11, 2012 12:29 pm
Location: China,Sichuan

Previous

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 2 guests