How do you make a light pole

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Re: How do you make a light pole

Postby beroc » Mon Aug 03, 2009 5:52 pm

After much searching, I went back to the basics and started off everything centered pretty much around NewtonConstraintCreateUserJoint. Assuming that it basically created a linked joint, but gave no constraints, it would appear that the joint did nothing. However, it seems to be the basis for all the custom joints in the library. That being said, I went off in search of how to make this function work for me. Here is what I found:

Code: Select all
void SubmitConstraints(const NewtonJoint* me, dFloat timestep, int threadIndex);
void GetInfo (const NewtonJoint* me, NewtonJointRecord* info);
class myJoint
{
protected:
   NewtonBody* mChild;
   NewtonBody* mParent;
   NewtonJoint* mJoint;
   NewtonWorld* mWorld;
   bool mNotCreated;
   dMatrix mChildMatrix;
   dMatrix mParentMatrix;

public:

   myJoint(void){
      mJoint=NULL;
      mWorld=NULL;
      mChild=NULL;
      mParent=NULL;
   
   }
   void makeBallAndSocket(NewtonBody* Child, NewtonBody* Parent,
      Vector3 pos=Vector3(0,0,0),Quaternion rot=Quaternion::IDENTITY)
   {
      Matrix3 m;
      Vector3 xcol, ycol, zcol;
      rot.ToRotationMatrix(m);
      xcol = m.GetColumn(0);
      ycol = m.GetColumn(1);
      zcol = m.GetColumn(2);
      dMatrix matrix(
         dVector(xcol.x,ycol.x,zcol.x,0),
         dVector(xcol.y,ycol.y,zcol.y,0),
         dVector(xcol.z,ycol.z,zcol.z,0),
         dVector(pos.x,pos.y,pos.z,1));
      
      
      if(Child==NULL)return;
      mChild=Child;
      mParent=Parent;
      mNotCreated=false;
      CalculateLocalMatrix (matrix, mChildMatrix, mParentMatrix);
      
      mWorld=NewtonBodyGetWorld(Child);
      mJoint=NewtonConstraintCreateUserJoint(mWorld, 6, SubmitConstraints,
         GetInfo, mChild, mParent);
      NewtonJointSetUserData (mJoint, this);
   }
   void CalculateLocalMatrix (const dMatrix& pinsAndPivotFrame, dMatrix& localMatrix0,
      dMatrix& localMatrix1) const
   {
      dMatrix matrix0;

      // Get the global matrices of each rigid body.
      NewtonBodyGetMatrix(mChild, &matrix0[0][0]);
      dMatrix matrix1(GetIdentityMatrix());
      if (mParent) {
         NewtonBodyGetMatrix(mParent, &matrix1[0][0]);
      }
      localMatrix0 = pinsAndPivotFrame * matrix0.Inverse();
      localMatrix1 = pinsAndPivotFrame * matrix1.Inverse();
   }

   void CalculateGlobalMatrix (dMatrix& localMatrix0, dMatrix& localMatrix1,
      dMatrix& matrix0, dMatrix& matrix1)
   {
      if(mNotCreated)return;
      dMatrix childMatrix;
      // Get the global matrices of each rigid body.
      NewtonBodyGetMatrix(mChild, &childMatrix[0][0]);

      dMatrix parentMatrix (GetIdentityMatrix());
      if (mParent) {
         NewtonBodyGetMatrix(mParent, &parentMatrix[0][0]);
      }
      
      matrix0 = localMatrix0 * childMatrix;
      matrix1 = localMatrix1 * parentMatrix;
   }

   void jointSubmitConstraints(dFloat timestep, int threadIndex)
   {
      if(mNotCreated)return;
      //split these out for different joint types
      //if(mJointType==JT_BALLANDSOCKET)BallAndSocketSubmitConstraints(dFloat timestep, int threadIndex);
      dMatrix matrix0;
      dMatrix matrix1;
      // calculate the position of the pivot point and the jacobian direction vectors, in global space.
      CalculateGlobalMatrix (mChildMatrix, mParentMatrix, matrix0, matrix1);

      // Restrict the movement on the pivot point along all tree orthonormal direction
      NewtonUserJointAddLinearRow (mJoint, &matrix0.m_posit[0], &matrix1.m_posit[0], &matrix0.m_front[0]);
      NewtonUserJointAddLinearRow (mJoint, &matrix0.m_posit[0], &matrix1.m_posit[0], &matrix0.m_up[0]);
      NewtonUserJointAddLinearRow (mJoint, &matrix0.m_posit[0], &matrix1.m_posit[0], &matrix0.m_right[0]);
   }
};

   void  SubmitConstraints (const NewtonJoint* me, dFloat timestep, int threadIndex)
   {
      myJoint* joint = (myJoint*) NewtonJointGetUserData(me);
      joint->jointSubmitConstraints(timestep, threadIndex);
   }

   void GetInfo (const NewtonJoint* me, NewtonJointRecord* info)
   {
   }


myJoint joint;
joint.makeBallAndSocket(body1,body2,Vector3(0.5,10.5,0),Quaternion::IDENTITY);


This code is pretty much bastardized to not use the joint library. It does however, use the core CustomJoint and the CustomBallAndSocket. Which basically means that it will restrict all linear movement, but allow all rotational movement. After all this, I found that it does have an affect on my simulation. Basically, I have 2 boxes stacked offset, and joined them in the middle. If this was correctly done, the ball joint should just simply allow the bodies to overlap or rotate through each other.

OK, my video representation of it:


I wanted to test it in 3 different states to see what the differences were. I found that each state reacted differently in the simulation. Both separate acted normally. When I linked them together, they fell through each other as if they didn't exist in each other's world. Finally I tested it with the Child linked to NULL. This should have prevented it from dropping all the way. Such was not the case, but oddly it gained more force coming down. Dunno how that happened.

Mind you, this was all a test of the jointSubmitConstraints function, and to see if the NewtonConstraintCreateUserJoint actually created a link and how it reacted in the world.

So in conclusion, I don't have a clue how the jointSubmitConstraints actually preforms the operation. :D
beroc
 
Posts: 13
Joined: Mon Aug 28, 2006 2:54 pm

Re: How do you make a light pole

Postby beroc » Mon Aug 03, 2009 10:18 pm

GOT IT!!!!

It was some weird error that happened only when I tried to create a joint from within a class and it referenced the class that was creating it in it's user data. Probably why Julio made create functions for all the joints. What messed me up was when he put everything into containing classes.

It actually stems around these lines in the CustomJoint.cpp file

Code: Select all
NewtonJointSetUserData (m_joint, this);

NewtonCustomJoint* joint;
joint = (NewtonCustomJoint*) NewtonJointGetUserData (me);


It took me a while to find it. I could only see it when debugging and was looking at the pointer values and data during the calls. The GetUserData returned the right pointer, but the data was not the same as when it was in the SetUserData.

This all means that the constraint data never got posted into the scene.. ;)

So... oddly enough I had to resort to the create function outside of the class.

beroc
 
Posts: 13
Joined: Mon Aug 28, 2006 2:54 pm

Re: How do you make a light pole

Postby Julio Jerez » Mon Aug 03, 2009 10:27 pm

Glad you have something going,
You are doing so many things you got me all lost. :D
But it is all good.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: How do you make a light pole

Postby beroc » Tue Aug 04, 2009 12:16 am

OK, finally onto the breakage testing...



If you notice in the video, it doesn't break.. This was posted with a max torque and max force of like 0.001, cos yeah, I want it to break.. but it doesn't.

I did testing in the ConstraintCallaback and found that the values being returned by NewtonUserJointGetRowForce are always Zero. So it never receives torque or force.

It does have odd physics, like it is stretching.

Code: Select all
float test=0;
          float comperaMax = mMaxForce * 0.9f;
          for (int i = 0; i < 3; i ++) {
test+=NewtonUserJointGetRowForce(mJoint,i);
             if (fabsf (NewtonUserJointGetRowForce (mJoint, i) > comperaMax)) {
                // join broke;
                delete this;
                return ;
             }
          }

          // check is the joint violated the torque limit
          comperaMax = mMaxTorque * 0.9f;
          for (int i = 0; i < 3; i ++) {
test+=NewtonUserJointGetRowForce(mJoint,i+3);
             if (fabsf (NewtonUserJointGetRowForce (mJoint, i + 3) > comperaMax)) {
                // join broke;
                delete this;
                return ;
             }
          }
if(test!=0)
   test=5;


I put a break point on the last line so I could debug it, it never broke. That would mean that the total summed force on the joint never was not zero.

Any ideas?

Edit:
I just put the same tester into the ball and joint callback, got the same results.
beroc
 
Posts: 13
Joined: Mon Aug 28, 2006 2:54 pm

Re: How do you make a light pole

Postby Julio Jerez » Tue Aug 04, 2009 2:05 am

Like I said I did no test the joint, my mistake :oops:

There is an actual bug in function NewtonUserJointGetRowForce, I fixed now download Beta 2.05
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: How do you make a light pole

Postby beroc » Tue Aug 04, 2009 4:33 am

HAH 3 hours of converting my code to sdl... LOL



Breakage!!! awesome, thanks man.

OH, for the others who are along in this path, and are not quite looking for a spring break, like what you have there.

Add this into your customJoint:

Code: Select all
Protected:
bool m_breakable;
dFloat m_minForce, m_maxForce;

in the construtor:
Add to constructor incoming variables:
bool breakable, dFloat maxForce, dFloat minForce

In the code:
      m_breakable = breakable;
      m_maxForce = fabsf (maxForce);
      m_maxTorque = fabsf (maxTorque);

In the SubmitConstrainst:

      if(m_breakable){
         float comperaMax = m_maxForce * 0.9f;
         for (int i = 0; i < 3; i ++) {
            if (fabsf (NewtonUserJointGetRowForce (m_joint, i) > comperaMax)) {
               // join broke;
               delete this;
               return ;
            }
         }

         // check is the joint violated the torque limit
         comperaMax = m_maxTorque * 0.9f;
         for (int i = 0; i < 3; i ++) {
            if (fabsf (NewtonUserJointGetRowForce (m_joint, i + 3) > comperaMax)) {
               // join broke;
               delete this;
               return ;
            }
         }
      }


maxForce and maxTorque numbers for those range between about 0.001 to about 0.05. test the settings out u should get some good results.
beroc
 
Posts: 13
Joined: Mon Aug 28, 2006 2:54 pm

Re: How do you make a light pole

Postby beroc » Tue Aug 04, 2009 2:13 pm

and integration is complete.



Thanks alot Juliio
beroc
 
Posts: 13
Joined: Mon Aug 28, 2006 2:54 pm

Previous

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 48 guests

cron