Julio Jerez wrote:ah yes, I added now.
Thanks Julio! Another one I came across is:
in 3.xx:
- Code: Select all
dVector::DotProduct3(dVector v);
Is there an equivalent in 4.00 or just default to ndVector::DotProduct() ?
Moderators: Sascha Willems, walaber
Julio Jerez wrote:ah yes, I added now.
dVector::DotProduct3(dVector v);
Julio Jerez wrote:ndVector::DotProduct().GetScalar();
misho wrote:Julio Jerez wrote:ndVector::DotProduct().GetScalar();
Thanks Julio. A couple of other ones, if you can confirm:
NewtonCollision => ndShapeInstance
NewtonBody => ndBodyDynamic
NewtonJoint => ndContact
dCustomJoint => ?
Thanks!
misho wrote:Ok, to further clarify and simplify this test case, I have updated it to include 2 separate objects, a jet cargo aircraft, and a droppable fuel tank (shown in blue), attached to the red pylon (which is a part of the aircraft) on the left aircraft wing.
Test case source, Aircraft and Fuel tank FBX files can be found here:
ndMishoTestCase.cpp
SimpleCargoPlane.fbx
SimpleFuelTank.FBX
The code first loads the Aircraft and Fuel tank, and joins them with the hard ndJointFix6dof Joint. Both bodies are Dynamic type. You can use "P" key to destroy the joint and drop the tank, and "O" key to position and re-attach the fuel tank by re-creating the ndJointFix6dof joint.
There is also a matrix called FlightSimPosition, which basically represents the position and orientation of the aircraft which would be dictated (set) by Flight Simulator. This matrix does nothing in the default state of the test case.
Then - you can use "U" key to UNLOCK the setting of the position of the FlightSimPosition matrix. What this does is,
- MOVES the FlightSimPosition matrix horizontally by using I,J,K, and M keys
- APPLIES this matrix to the Aircraft body's position
You can use "L" key to again LOCK the moving and application of this matrix to Aircraft body. In the LOCKED mode, Aircraft and Fuel Tank are locked tightly to each other. You can grab and tumble the aircraft around with a mouse pointer, and the Fuel Tank will stay attached to it, as expected. In the UNLOCKED mode, when aircraft is moved using the keys, Fuel Tank follows but with a "rubber band" delay.
So basically, the ask is to have the plane in the UNLOCKED mode so that its position (and orientation, but I have not implemented that) can be set externally, (in my case, by a Flight Simulator flight model), but all the attached objects stay rigidly attached to it. I hope this test case simplifies it a bit more.
Julio Jerez wrote:you can use a dynamics body.
then in the notify call back, give a force and torque callback that translate the conversion of the changes in the trajectory to impulses.
that is, in each frame once you calculate:
- Code: Select all
v to move from p(body) to p(plane)
w to move from q(body) to q(plane)
you can calculate a Linear and angular impulse.
- Code: Select all
LinearImpulse = (v - v(body)) * inverseMass
angularImpulse = (w - w(body)) * inverseInertia
them use the function on the dynamics body to apply the impulse to the dynamic body representing the plane.
this is how was done in 3.xx, and I believe the will probably be simpler for you.
The plane will be a dynamics body and will work with everything that you are used to.
so it will be a full physics object.
// Phys_ProcessBodyImpulse() is a member function of the TBEntity class,
// and it is being applied to the CHILD (missile) object
// and called from ApplyForceAndTorqueCallback()
// Parent's (aircraft) "Attach point 0" is a 3D point on PARENT object in
// local space where missile is being attached
// Child's (missile) "Attach point 0" is a 3D point on CHILD object in
// local space where missile is being attached
void TBEntity::Phys_ProcessBodyImpulse(double dBodyTimeStep)
{
dVector vDeltaV(0.0, 0.0, 0.0, 1.0); // speed needed for linear impulse
dVector dvNull(0.0, 0.0, 0.0, 1.0); // null vector needed for angular impulse
dVector LinearImpulse(0.0, 0.0, 0.0, 1.0); // linear impulse vector
// Get the PARENT (aircraft) entity and its body matrix:
TBEntity *pParentEnt = NewtonGetUserEntity();
dMatrix ParentBodyMatrix;
NewtonBodyGetMatrix(pParentEnt->nBody, &ParentBodyMatrix[0][0]);
// Get the INVERSE body mass, basically GetCurrentBodyMass(bool bGetInverseMass)
// calls NewtonBodyGetInvMass() and returns inverse mass
double dInvBodyMass = GetCurrentBodyMass(true);
// Get position of where CHILD object should be
// (a point under the PARENT's wing)
// (parent pos + parent ap in global space)
dVector vParentAPPosition = pParentEnt->GetAttachPoint(0)->location;
dVector vParentPosition = pParentEnt->GetPosition() + ParentBodyMatrix.RotateVector(vParentAPPosition);
// Get position of where CHILD object is
// (current CHILD object pos + CHILD object ap in global space)
dVector vAPPosition = GetAttachPoint(0)->location;
dVector vPosition = GetPosition() + bodyMatrix.RotateVector(vAPPosition);
// calculate speed needed to get from where it is to where it should be:
vDeltaV = (vPosition - vParentPosition).Scale(1.0f / dBodyTimeStep);
// calculate impulse needed using this speed
LinearImpulse = (vDeltaV - GetVelocity()).Scale(dInvBodyMass);
// Finally, apply impulse
NewtonBodyApplyImpulsePair(nBody, &LinearImpulse[0], &dvNull[0], dBodyTimeStep);
}
misho wrote:although I am not certain what exactly is Inverse Mass being applied to it.
JoeJ wrote:
Looking up the code you got it wrong:
double dInvBodyMass = GetCurrentBodyMass(true);
should be the inverse mass, so 1 / mass.
I think there is a function to return this directly, to spare a division.
// Get the INVERSE body mass, basically GetCurrentBodyMass(bool bGetInverseMass)
// calls NewtonBodyGetInvMass() and returns inverse mass
double dInvBodyMass = GetCurrentBodyMass(true);
double TBEntity::GetCurrentBodyMass(bool bInverse)
{
dFloat Ixx;
dFloat Iyy;
dFloat Izz;
dFloat mass;
if (nBody)
{
if (bInverse)
NewtonBodyGetInvMass(nBody, &mass, &Ixx, &Iyy, &Izz);
else
NewtonBodyGetMass(nBody, &mass, &Ixx, &Iyy, &Izz);
}
return mass;
}
Vec3 targetVel = (missile.pos - airplane.pos) / timestep;
Vec3 curVel = missile.vel;
Vec3 accel = (targetVel - curVel) / timestep;
Vec3 force = accel * missile.mass;
// hopefully that's right ;)
JoeJ wrote:You could apply this force instead the impulse. I assume technically there should be no difference, but not sure.
// Try velocity/force...
TBEntity *pParentEnt = NewtonGetUserEntity();
dMatrix ParentBodyMatrix;
// get the Body Matrix;
NewtonBodyGetMatrix(pParentEnt->nBody, &ParentBodyMatrix[0][0]);
// Get position of where object should be
// (parent pos + parent ap in global space)
dVector vParentAPPosition = pParentEnt->GetAttachPoint(0)->location;
dVector vParentPosition = pParentEnt->GetPosition() + ParentBodyMatrix.RotateVector(vParentAPPosition);
// Get position of where object is
// (current object pos + object ap in global space)
dVector vAPPosition = GetAttachPoint(0)->location;
dVector vPosition = GetPosition() + bodyMatrix.RotateVector(vAPPosition);
// Get velocity, acceleration, and then the force
dVector vTargetVel = (vPosition - vParentPosition).Scale(1.0/dBodyTimeStep);
dVector vCurVel = GetVelocity();
dVector vAccel = (vTargetVel - vCurVel).Scale(1.0/dBodyTimeStep);
dVector vForce = vAccel.Scale(GetCurrentBodyMass());
if(vLength(vForce))
GlobalPropulsionForce = vForce;
dgAssert (dgAbs(relCentr) < dgFloat32 (4.0f));
Users browsing this forum: No registered users and 42 guests