A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by forestluo » Mon Sep 05, 2011 3:42 am
I created a ballsocket joint. I linked the joint with two boxes which both had 1 unit mass. So the joint could move with these two free boxes.
But I did not know how to change the position of the joint, If I dropped down the two boxes when I began simulation under normal gravity force.
I think the position of joint must not be a static value. But there is no callback function to update the absolution position of a joint.
Or how can I calculate the accurate position of a joint, when I starup the physics simulation ?
If I define two objects of joint, one is for child, the other is for parent.
What is the real meaning of the return value of following functions :
NewtonBallGetJointAngle
NewtonBallGetJointOmega
It is angle with child or parent or something else ?
Forest Luo
-
forestluo
-
- Posts: 13
- Joined: Mon Aug 15, 2011 5:03 am
by forestluo » Tue Sep 06, 2011 3:08 am
I have found a solution.
There are two acknowledge bases :
1. The angle of joint is the relative angle between joint and child object.
They are in a parallel axis system, so the relative direction is just in a reverse status.
2. The distance between joint and child object would not be changed.
They will keep a constant distance in physics simulation.
So, if I know the position of child, I can calculate the position of the joint according to those parameters.I add these calls in the callback function of joint.
Before simulation, you must keep the initialize relative position of child. This relative vector would be changed when simulation is running.
- Code: Select all
dVector value;
//Get angle.
::NewtonBallGetJointAngle(JOINT_INSTANCE(joint),&value[0]);
//Set angle of ball joint object.
((CBallJointObject *)object)->setAngle(D3DXVECTOR3(value.m_x,value.m_y,value.m_z));
//Get child object.
CWorldObject* child = object->getChild();
//Check result.
if(child != _NULL)
{
//Set quaternion.
D3DXQUATERNION rotate;
//Set eular rotation.
::SetEularAngles(((CBallJointObject *)object)->getAngle(),rotate);
//Matrix.
D3DXMATRIX matrix;
//Set rotation matrix.
D3DXMatrixRotationQuaternion(&matrix,&rotate);
//Direction.
D3DXVECTOR4 direction;
//Vector.
D3DXVECTOR3 vector = childDirection;
//Transform.
D3DXVec3Transform(&direction,&vector,&matrix);
//Set vector.
vector.x = direction.x / direction.w;
vector.y = direction.y / direction.w;
vector.z = direction.z / direction.w;
//Set position.
object->setPosition(child->getPosition() - vector);
}
Those code has been tested.
-
forestluo
-
- Posts: 13
- Joined: Mon Aug 15, 2011 5:03 am
by JoeJ » Tue Sep 06, 2011 3:20 am
So you want to change the pin position at runtime?
I recommend to use the User Joint (NewtonConstraintCreateUserJoint) instead of the older build in ball and socket.
You can specify a callback and inside there you can use both bodies matrices to create a pin position for each of them.
Then you add Linear Rows to feed the constraint solver and newton will glue them together for you.
The Joint Library coming with newton contains examples how to work with it.
Anything there (custom ball socket, custom hinge, ...) is done using the UserJoint.
EDIT: I wrote that before reding your solution

-

JoeJ
-
- Posts: 1489
- Joined: Tue Dec 21, 2010 6:18 pm
by forestluo » Tue Sep 06, 2011 8:45 pm
No, I just want to know the position of pin point.
Especilly when a ballsocket joint has both a movable parent object and a movable child object.
I want to know the new position of pin point when simulation is running.
-
forestluo
-
- Posts: 13
- Joined: Mon Aug 15, 2011 5:03 am
by forestluo » Sat Sep 10, 2011 7:28 am
Sorry !
I have mislead you all.
I found a correct solution :
It is a regid body, so the connection will be regidous too.
The key is : the relative position of joint will not be changed !!!
That means if you keep the relative position (in child object axis or in parent object axis or in both), this position vector will not be changed in physics simulation.
So you can calculate the right position and status of a joint according to the position of child or parent object.
I have checked it over and over, that's confirmed ! You need no more parameters. Just keep the original status of all the jointed object and calculate them in the future.
The formulor :
Before simulation, just keep the original relative position :
dVector childRelativePosition = jointWorldPosition - childWorldPosition;
dVector parentRelativePosition = jointWorldPosition - parentWorldPosition;
When in simulation:
dVector childContactPosition = childRelativePosition * childTransformMatrix;
dVector parentContactPosition = parentRelativePosition * childTransformMatrix;
If the joint would not be splitted, such as ballsocket, hinge.
The childContactPosition would be the same of parentContactPosition.
If the joint would be splitted, such as slider.
The slider direction would be the same of a vector which points from childContactPosition to parentContactPosition.
-
forestluo
-
- Posts: 13
- Joined: Mon Aug 15, 2011 5:03 am
by forestluo » Wed Sep 14, 2011 3:59 am
Oh, It is also real a hard work to calculate the rotation of the joint.
I have done it.
Quaternion originalRotation = child->getOriginalRotation(); //The initialize status of joint.
Quaternion currentRotation = child->getCurrentRotation(); //The status of joint when simulation is running.
Quaternion diffRotation = originalRotation.inverse().cross(currentRotation); //The different of orginal and current rotation.
You can calculate the correct direction of connection rod in the world.
For example:
Vector3 relativePosition = diffRotation.rotate(- child->getOriginalRelativeDirection()); //Rotate the original relative vector.
Vector3 contactPosition = relativePosition + child->getCurrentPosition();
And even the correct dirction of ANY predefined vector on the joint.
-
forestluo
-
- Posts: 13
- Joined: Mon Aug 15, 2011 5:03 am
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 1 guest