A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by JoshKlint » Sun Apr 07, 2019 11:00 am
I need to replace the command NewtonConvexCollisionCalculateBuoyancyAcceleration() with the new NewtonConvexCollisionCalculateBuoyancyVolume() function. This is my routine for adding buoyancy forces. How does the new function work?
- Code: Select all
void NewtonDynamicsBody::AddBuoyancyForce(const float nx, const float ny, const float nz, const float d, const float fluidDensity, const float fluidViscosity)
{
if (collision)
{
dFloat Ixx;
dFloat Iyy;
dFloat Izz;
dFloat mass;
const float m_waterToSolidVolumeRatio = 0.5;
dVector m_plane = dVector(0.0f, 1.0f, 0.0f, -world->waterheight);
NewtonBodyGetMass(body, &mass, &Ixx, &Iyy, &Izz);
if (mass > 0.0f)
{
dMatrix matrix;
dVector cog(0.0f);
dVector accelPerUnitMass(0.0f);
dVector torquePerUnitMass(0.0f);
const dVector gravity(0.0f, world->gravity.y, 0.0f, 0.0f);
NewtonBodyGetMatrix(body, &matrix[0][0]);
NewtonBodyGetCentreOfMass(body, &cog[0]);
Mat4 mat = Mat4((float*)&matrix[0][0]);
Mat4 identity;
Vec3 v = Transform::Point(cog[0], cog[1], cog[2], mat, identity);
cog[0] = v.x; cog[1] = v.y; cog[2] = v.z;
//cog = matrix.TransformVector(cog);
NewtonCollision* const collision = NewtonBodyGetCollision(body);
dFloat shapeVolume = NewtonConvexCollisionCalculateVolume(collision);
if (shapeVolume > 0.0f)
{
dFloat fluidDentity = 1.0f / (m_waterToSolidVolumeRatio * shapeVolume);
dFloat viscosity = 0.990f;
//NewtonConvexCollisionCalculateBuoyancyAcceleration(collision, &matrix[0][0], &cog[0], &gravity[0], &m_plane[0], fluidDentity, viscosity, &accelPerUnitMass[0], &torquePerUnitMass[0]);
dFloat center[3];
NewtonConvexCollisionCalculateBuoyancyVolume(collision, &matrix[0][0], &m_plane[0], ¢er[0]);
dVector force(accelPerUnitMass.Scale(mass));
dVector torque(torquePerUnitMass.Scale(mass));
dVector omega(0.0f);
NewtonBodyGetOmega(body, &omega[0]);
omega = omega.Scale(viscosity);
NewtonBodySetOmega(body, &omega[0]);
NewtonBodyGetVelocity(body, &omega[0]);
omega = omega.Scale(viscosity);
NewtonBodySetVelocity(body, &omega[0]);
NewtonBodyAddForce(body, &force[0]);
NewtonBodyAddTorque(body, &torque[0]);
}
}
}
}
-
JoshKlint
-
- Posts: 163
- Joined: Sun Dec 10, 2017 8:03 pm
-
by Julio Jerez » Sun Apr 07, 2019 11:26 am
it is far simpler now, the function return the volume under the water plane and the center of mass.
with that information the Archimedes force is just a text book problem.
basically the force is weight of the volume and the torque is the Archimedes force cross the center of mass of the volume under water minus the center of mass of the body.
the old method try to do that calculation for the user, by is has to make many assumptions that the end user is in better position to make.
look at demo ../applications\demosSandbox\sdkDemos\demos\ArchimedesBuoyancy.cpp
-
Julio Jerez
- Moderator
-
- Posts: 12249
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by JoshKlint » Sun Apr 07, 2019 1:09 pm
Thanks, it is working nicely now.
If you are using the Newton DLL you will need to recreate these internal functions for the math:
- Code: Select all
dVector dMatrixRotateVector(const dMatrix &m, const dVector &v) const
{
return dVector(v.m_x * m.m_front.m_x + v.m_y * m.m_up.m_x + v.m_z * m.m_right.m_x,
v.m_x * m.m_front.m_y + v.m_y * m.m_up.m_y + v.m_z * m.m_right.m_y,
v.m_x * m.m_front.m_z + v.m_y * m.m_up.m_z + v.m_z * m.m_right.m_z, 0.0f);
}
dVector dMatrixTransformVector(const dMatrix &m, const dVector &v) const
{
return m.m_posit + dMatrixRotateVector(m,v);
}
-
JoshKlint
-
- Posts: 163
- Joined: Sun Dec 10, 2017 8:03 pm
-
by Julio Jerez » Sun Apr 07, 2019 2:24 pm
why? those functions are part of the dMatrix class
dVector dMatrix::RotateVector (const dVector &v) const;
dVector dMatrix::TransformVector (const dVector &v) const;
-
Julio Jerez
- Moderator
-
- Posts: 12249
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 9 guests