Files
2026-02-02 04:50:13 +01:00

734 lines
22 KiB
C++

/* Copyright (c) <2003-2011> <Julio Jerez, Newton Game Dynamics>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*/
#if !defined(AFX_DGBODY_H__C16EDCD6_53C4_4C6F_A70A_591819F7187E__INCLUDED_)
#define AFX_DGBODY_H__C16EDCD6_53C4_4C6F_A70A_591819F7187E__INCLUDED_
#include "dgBodyMasterList.h"
#include "hpl1/engine/libraries/newton/core/dg.h"
class dgLink;
class dgBody;
class dgWorld;
class dgCollision;
class dgBroadPhaseCell;
#define DG_MIN_SPEED_ATT dgFloat32(0.0f)
#define DG_MAX_SPEED_ATT dgFloat32(0.02f)
#define DG_INFINITE_MASS dgFloat32(1.0e15f)
#define DG_FREEZE_MAG dgFloat32(0.1f)
#define DG_FREEZE_MAG2 dgFloat32(DG_FREEZE_MAG *DG_FREEZE_MAG)
#define DG_ErrTolerance (1.0e-2f)
#define DG_ErrTolerance2 (DG_ErrTolerance * DG_ErrTolerance)
DG_MSC_VECTOR_ALIGMENT
struct dgLineBox {
dgVector m_l0;
dgVector m_l1;
dgVector m_boxL0;
dgVector m_boxL1;
} DG_GCC_VECTOR_ALIGMENT;
class dgConvexCastReturnInfo {
public:
dgFloat32 m_point[4]; // collision point in global space
dgFloat32 m_normal[4]; // surface normal at collision point in global space
dgFloat32 m_normalOnHitPoint[4]; // surface normal at the surface of the hit body,
// is the same as the normal calculate by a raycast passing by the hit point in the direction of the cast
dgFloat32 m_penetration; // contact penetration at collision point
dgInt32 m_contaID; // collision ID at contact point
const dgBody *m_hitBody; // body hit at contact point
};
typedef void(dgApi *OnBodyDestroy)(const NewtonBody *const me);
typedef void(dgApi *OnApplyExtForceAndTorque)(NewtonBody *const me, dFloat timestep, int32 threadIndex);
typedef void(dgApi *OnMatrixUpdateCallback)(const NewtonBody *const body, const dFloat *const matrix, int32 threadIndex);
typedef dgUnsigned32(dgApi *OnRayPrecastAction)(const NewtonBody *const body, const NewtonCollision *const collision, void *const userData);
typedef dgFloat32(dgApi *OnRayCastAction)(const NewtonBody *const body, const dFloat *const hitNormal, int collisionID, void *const userData, dFloat intersectParam);
typedef dgUnsigned32(dgApi *GetBuoyancyPlane)(const int32 collisionID, void *const context, const dFloat *const globalSpaceMatrix, dFloat *const globalSpacePlane);
#define OverlapTest(body0, body1) dgOverlapTest((body0)->m_minAABB, (body0)->m_maxAABB, (body1)->m_minAABB, (body1)->m_maxAABB)
//#define OverlapTest_SSE(body0,body1) dgOverlapTest_SSE ((body0)->m_minAABB, (body0)->m_maxAABB, (body1)->m_minAABB, (body1)->m_maxAABB)
class dgBroadPhaseList {
public:
dgBroadPhaseCell *m_cell;
void *m_axisArrayNode[3];
void reset() {
m_cell = NULL;
for (uint i = 0; i < ARRAYSIZE(m_axisArrayNode); i++) m_axisArrayNode[i] = NULL;
}
};
DG_MSC_VECTOR_ALIGMENT
class dgBody {
public:
DG_CLASS_ALLOCATOR(allocator)
dgBody();
~dgBody();
void AddForce(const dgVector &force);
void AddTorque(const dgVector &torque);
void AttachCollision(dgCollision *collision);
void SetGroupID(dgUnsigned32 id);
void SetMatrix(const dgMatrix &matrix);
void SetMatrixIgnoreSleep(const dgMatrix &matrix);
void SetUserData(void *const userData);
void SetForce(const dgVector &force);
void SetTorque(const dgVector &torque);
void SetOmega(const dgVector &omega);
void SetVelocity(const dgVector &velocity);
void SetLinearDamping(dgFloat32 linearDamp);
void SetAngularDamping(const dgVector &angularDamp);
void SetCentreOfMass(const dgVector &com);
void SetAparentMassMatrix(const dgVector &massMatrix);
void SetMassMatrix(dgFloat32 mass, dgFloat32 Ix, dgFloat32 Iy, dgFloat32 Iz);
// void SetGyroscopicTorqueMode (bool mode);
void SetCollisionWithLinkedBodies(bool state);
// void SetFreezeTreshhold (dgFloat32 freezeAccel2, dgFloat32 freezeAlpha2, dgFloat32 freezeSpeed2, dgFloat32 freezeOmega2);
void SetContinuesCollisionMode(bool mode);
void SetDestructorCallback(OnBodyDestroy destructor);
void SetMatrixUpdateCallback(OnMatrixUpdateCallback callback);
OnMatrixUpdateCallback GetMatrixUpdateCallback() const;
// void SetAutoactiveNotify (OnActivation activate);
void SetExtForceAndTorqueCallback(OnApplyExtForceAndTorque callback);
OnApplyExtForceAndTorque GetExtForceAndTorqueCallback() const;
dgConstraint *GetFirstJoint() const;
dgConstraint *GetNextJoint(const dgConstraint *joint) const;
dgConstraint *GetFirstContact() const;
dgConstraint *GetNextContact(const dgConstraint *joint) const;
void *GetUserData() const;
dgWorld *GetWorld() const;
const dgVector &GetMass() const;
const dgVector &GetInvMass() const;
const dgVector &GetAparentMass() const;
const dgVector &GetOmega() const;
const dgVector &GetVelocity() const;
const dgVector &GetForce() const;
const dgVector &GetTorque() const;
const dgVector &GetNetForce() const;
const dgVector &GetNetTorque() const;
dgCollision *GetCollision() const;
dgUnsigned32 GetGroupID() const;
const dgMatrix &GetMatrix() const;
const dgVector &GetPosition() const;
const dgQuaternion &GetRotation() const;
dgFloat32 GetLinearDamping() const;
dgVector GetAngularDamping() const;
dgVector GetCentreOfMass() const;
bool IsInEquelibrium() const;
void GetAABB(dgVector &p0, dgVector &p1) const;
bool GetSleepState() const;
bool GetAutoSleep() const;
void SetAutoSleep(bool state);
bool GetFreeze() const;
void SetFreeze(bool state);
void Freeze();
void Unfreeze();
dgInt32 GetUniqueID() const;
bool GetCollisionWithLinkedBodies() const;
bool GetContinuesCollisionMode() const;
void AddBuoyancyForce(dgFloat32 fluidDensity, dgFloat32 fluidLinearViscousity, dgFloat32 fluidAngularViscousity,
const dgVector &gravityVector, GetBuoyancyPlane buoyancyPlane, void *const context);
dgVector CalculateInverseDynamicForce(const dgVector &desiredVeloc, dgFloat32 timestep) const;
// dgFloat32 RayCast (const dgVector& globalP0, const dgVector& globalP1,
dgFloat32 RayCast(const dgLineBox &line,
OnRayCastAction filter, OnRayPrecastAction preFilter, void *const userData, dgFloat32 minT) const;
// dgFloat32 RayCastSimd (const dgVector& globalP0, const dgVector& globalP1,
// OnRayCastAction filter, OnRayPrecastAction preFilter, void* userData, dgFloat32 minT) const;
void CalcInvInertiaMatrix();
void CalcInvInertiaMatrixSimd();
const dgMatrix &GetCollisionMatrix() const;
dgBodyMasterList::dgListNode *GetMasterList() const;
void InvalidateCache();
private:
void SetMatrixOriginAndRotation(const dgMatrix &matrix);
void CalculateContinueVelocity(dgFloat32 timestep, dgVector &veloc, dgVector &omega) const;
void CalculateContinueVelocitySimd(dgFloat32 timestep, dgVector &veloc, dgVector &omega) const;
dgVector GetTrajectory(const dgVector &veloc, const dgVector &omega) const;
void IntegrateVelocity(dgFloat32 timestep);
void UpdateMatrix(dgFloat32 timestep, dgInt32 threadIndex);
void UpdateCollisionMatrix(dgFloat32 timestep, dgInt32 threadIndex);
void UpdateCollisionMatrixSimd(dgFloat32 timestep, dgInt32 threadIndex);
void ApplyExtenalForces(dgFloat32 timestep, dgInt32 threadIndex);
void AddImpulse(const dgVector &pointVeloc, const dgVector &pointPosit);
void ApplyImpulseArray(dgInt32 count, dgInt32 strideInBytes, const dgFloat32 *const impulseArray, const dgFloat32 *const pointArray);
// void AddGyroscopicTorque();
void AddDamingAcceleration();
dgMatrix CalculateInertiaMatrix() const;
dgMatrix CalculateInvInertiaMatrix() const;
dgMatrix m_matrix;
dgMatrix m_collisionWorldMatrix;
dgMatrix m_invWorldInertiaMatrix;
dgQuaternion m_rotation;
dgVector m_veloc;
dgVector m_omega;
dgVector m_accel;
dgVector m_alpha;
dgVector m_netForce;
dgVector m_netTorque;
dgVector m_prevExternalForce;
dgVector m_prevExternalTorque;
dgVector m_mass;
dgVector m_invMass;
dgVector m_aparentMass;
dgVector m_localCentreOfMass;
dgVector m_globalCentreOfMass;
dgVector m_minAABB;
dgVector m_maxAABB;
dgVector m_dampCoef;
dgInt32 m_index;
dgInt32 m_uniqueID;
dgInt32 m_bodyGroupId;
dgInt32 m_genericLRUMark;
dgInt32 m_sleepingCounter;
dgUnsigned32 m_dynamicsLru;
dgUnsigned32 m_isInDerstruionArrayLRU;
dgUnsigned32 m_freeze : 1;
dgUnsigned32 m_sleeping : 1;
dgUnsigned32 m_autoSleep : 1;
dgUnsigned32 m_isInWorld : 1;
dgUnsigned32 m_equilibrium : 1;
dgUnsigned32 m_continueCollisionMode : 1;
dgUnsigned32 m_spawnnedFromCallback : 1;
dgUnsigned32 m_collideWithLinkedBodies : 1;
dgUnsigned32 m_solverInContinueCollision : 1;
dgUnsigned32 m_inCallback : 1;
void *m_userData;
dgWorld *m_world;
dgCollision *m_collision;
dgBroadPhaseList m_collisionCell;
dgBodyMasterList::dgListNode *m_masterNode;
OnBodyDestroy m_destructor;
OnMatrixUpdateCallback m_matrixUpdate;
OnApplyExtForceAndTorque m_applyExtForces;
void reset();
friend class dgWorld;
friend class dgContact;
friend class dgCollision;
friend class dgBodyChunk;
friend class dgSortArray;
friend class dgConstraint;
friend class dgContactArray;
friend class dgContactSolver;
friend class dgBroadPhaseCell;
friend class dgCollisionConvex;
friend class dgCollisionEllipse;
friend class dgCollisionCompound;
friend class dgCollisionUserMesh;
friend class dgWorldDynamicUpdate;
friend class dgCollisionConvexHull;
friend class dgCollisionScene;
friend class dgCollisionBVH;
friend class dgBodyMasterList;
friend class dgJacobianMemory;
friend class dgBilateralConstraint;
friend class dgBroadPhaseCollision;
friend class dgSolverWorlkerThreads;
friend class dgCollisionConvexModifier;
friend class dgCollidingPairCollector;
friend class dgAABBOverlapPairList;
friend class dgParallelSolverClear;
friend class dgParallelSolverUpdateForce;
friend class dgParallelSolverUpdateVeloc;
friend class dgParallelSolverBodyInertia;
friend class dgBroadPhaseApplyExternalForce;
friend class dgParallelSolverBuildJacobianRows;
friend class dgParallelSolverBuildJacobianMatrix;
} DG_GCC_VECTOR_ALIGMENT;
// *****************************************************************************
//
// Implementation
//
// *****************************************************************************
inline void dgBody::reset() {
m_matrix = dgGetZeroMatrix();
m_collisionWorldMatrix = dgGetZeroMatrix();
m_invWorldInertiaMatrix = dgGetZeroMatrix();
m_rotation = dgQuaternion(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_veloc = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_omega = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_accel = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_alpha = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_netForce = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_netTorque = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_prevExternalForce = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_prevExternalTorque = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_mass = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_invMass = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_aparentMass = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_localCentreOfMass = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_globalCentreOfMass = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_minAABB = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_maxAABB = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_dampCoef = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_index = 0;
m_uniqueID = 0;
m_bodyGroupId = 0;
m_genericLRUMark = 0;
m_sleepingCounter = 0;
m_dynamicsLru = 0;
m_isInDerstruionArrayLRU = 0;
m_freeze = 0;
m_sleeping = 0;
m_autoSleep = 0;
m_isInWorld = 0;
m_equilibrium = 0;
m_continueCollisionMode = 0;
m_spawnnedFromCallback = 0;
m_collideWithLinkedBodies = 0;
m_solverInContinueCollision = 0;
m_inCallback = 0;
m_userData = NULL;
m_world = NULL;
m_collision = NULL;
m_collisionCell.reset();
m_masterNode = NULL;
m_destructor = NULL;
m_matrixUpdate = NULL;
m_applyExtForces = NULL;
}
inline void dgBody::SetAutoSleep(bool state) {
m_autoSleep = dgUnsigned32(state);
if (m_autoSleep == 0) {
m_sleeping = false;
}
}
inline bool dgBody::GetAutoSleep() const {
return m_autoSleep;
}
inline bool dgBody::GetSleepState() const {
return m_sleeping;
}
/*
inline bool dgBody::GetActive () const
{
return m_active;
}
*/
inline bool dgBody::GetCollisionWithLinkedBodies() const {
return m_collideWithLinkedBodies;
}
inline void dgBody::SetCollisionWithLinkedBodies(bool state) {
m_collideWithLinkedBodies = dgUnsigned32(state);
}
inline void dgBody::SetUserData(void *const userData) {
m_userData = userData;
}
inline void *dgBody::GetUserData() const {
return m_userData;
}
inline dgWorld *dgBody::GetWorld() const {
return m_world;
}
inline dgUnsigned32 dgBody::GetGroupID() const {
return dgUnsigned32(m_bodyGroupId);
}
inline void dgBody::SetGroupID(dgUnsigned32 id) {
m_bodyGroupId = dgInt32(id);
}
inline void dgBody::SetDestructorCallback(OnBodyDestroy destructor) {
m_destructor = destructor;
}
inline void dgBody::SetExtForceAndTorqueCallback(OnApplyExtForceAndTorque callback) {
m_applyExtForces = callback;
}
inline OnApplyExtForceAndTorque dgBody::GetExtForceAndTorqueCallback() const {
return m_applyExtForces;
}
/*
inline void dgBody::SetAutoactiveNotify (OnActivation activate)
{
m_activation = activate;
if (m_activation) {
m_activation (*this, m_active ? 1 : 0);
}
}
*/
inline void dgBody::SetMatrixUpdateCallback(OnMatrixUpdateCallback callback) {
m_matrixUpdate = callback;
}
inline OnMatrixUpdateCallback dgBody::GetMatrixUpdateCallback() const {
return m_matrixUpdate;
}
/*
inline void dgBody::SetFreezeTreshhold (dgFloat32 freezeAccel2, dgFloat32 freezeAlpha2, dgFloat32 freezeSpeed2, dgFloat32 freezeOmega2)
{
m_freezeAccel2 = GetMax (freezeAccel2, dgFloat32(DG_FREEZE_MAG2));
m_freezeAlpha2 = GetMax (freezeAlpha2, dgFloat32(DG_FREEZE_MAG2));
m_freezeSpeed2 = GetMax (freezeSpeed2, dgFloat32(DG_FREEZE_MAG2));
m_freezeOmega2 = GetMax (freezeOmega2, dgFloat32(DG_FREEZE_MAG2));
}
inline void dgBody::GetFreezeTreshhold (dgFloat32& freezeAccel2, dgFloat32& freezeAlpha2, dgFloat32& freezeSpeed2, dgFloat32& freezeOmega2) const
{
freezeAccel2 = m_freezeAccel2;
freezeAlpha2 = m_freezeAlpha2;
freezeSpeed2 = m_freezeSpeed2;
freezeOmega2 = m_freezeOmega2;
}
*/
inline void dgBody::SetOmega(const dgVector &omega) {
m_omega = omega;
}
inline void dgBody::SetVelocity(const dgVector &velocity) {
m_veloc = velocity;
}
inline void dgBody::SetCentreOfMass(const dgVector &com) {
m_localCentreOfMass.m_x = com.m_x;
m_localCentreOfMass.m_y = com.m_y;
m_localCentreOfMass.m_z = com.m_z;
m_localCentreOfMass.m_w = dgFloat32(1.0f);
m_globalCentreOfMass = m_matrix.TransformVector(m_localCentreOfMass);
}
inline void dgBody::AddForce(const dgVector &force) {
SetForce(m_accel + force);
}
inline void dgBody::AddTorque(const dgVector &torque) {
SetTorque(torque + m_alpha);
}
inline const dgVector &dgBody::GetMass() const {
return m_mass;
}
inline const dgVector &dgBody::GetAparentMass() const {
return m_aparentMass;
}
inline const dgVector &dgBody::GetInvMass() const {
return m_invMass;
}
inline const dgVector &dgBody::GetOmega() const {
return m_omega;
}
inline const dgVector &dgBody::GetVelocity() const {
return m_veloc;
}
inline const dgVector &dgBody::GetForce() const {
return m_accel;
}
inline const dgVector &dgBody::GetTorque() const {
return m_alpha;
}
inline const dgVector &dgBody::GetNetForce() const {
return m_netForce;
}
inline const dgVector &dgBody::GetNetTorque() const {
return m_netTorque;
}
inline dgCollision *dgBody::GetCollision() const {
return m_collision;
}
inline const dgVector &dgBody::GetPosition() const {
return m_matrix.m_posit;
}
inline const dgQuaternion &dgBody::GetRotation() const {
return m_rotation;
}
inline const dgMatrix &dgBody::GetMatrix() const {
return m_matrix;
}
inline dgVector dgBody::GetCentreOfMass() const {
return m_localCentreOfMass;
}
inline void dgBody::GetAABB(dgVector &p0, dgVector &p1) const {
p0.m_x = m_minAABB.m_x;
p0.m_y = m_minAABB.m_y;
p0.m_z = m_minAABB.m_z;
p1.m_x = m_maxAABB.m_x;
p1.m_y = m_maxAABB.m_y;
p1.m_z = m_maxAABB.m_z;
}
/*
inline void dgBody::SetGyroscopicTorqueMode (bool mode)
{
m_applyGyroscopic = mode;
}
inline bool dgBody::GetGyroscopicTorqueMode () const
{
return m_applyGyroscopic;
}
*/
inline const dgMatrix &dgBody::GetCollisionMatrix() const {
return m_collisionWorldMatrix;
}
inline void dgBody::SetContinuesCollisionMode(bool mode) {
m_continueCollisionMode = dgUnsigned32(mode);
}
inline bool dgBody::GetContinuesCollisionMode() const {
return m_continueCollisionMode;
}
inline void dgBody::ApplyExtenalForces(dgFloat32 timestep, dgInt32 threadIndex) {
m_accel = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
m_alpha = dgVector(dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f), dgFloat32(0.0f));
if (m_applyExtForces) {
m_applyExtForces(reinterpret_cast<NewtonBody *>(this), timestep, threadIndex);
}
}
inline dgFloat32 dgBody::GetLinearDamping() const {
// return (m_linearDampCoef - DG_MIN_SPEED_ATT) / (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT);
return (m_dampCoef.m_w - DG_MIN_SPEED_ATT) / (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT);
}
inline dgVector dgBody::GetAngularDamping() const {
return dgVector((m_dampCoef.m_x - DG_MIN_SPEED_ATT) / (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT),
(m_dampCoef.m_y - DG_MIN_SPEED_ATT) / (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT),
(m_dampCoef.m_z - DG_MIN_SPEED_ATT) / (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT), dgFloat32(0.0f));
}
inline void dgBody::SetLinearDamping(dgFloat32 linearDamp) {
linearDamp = ClampValue(linearDamp, dgFloat32(0.0f), dgFloat32(1.0f));
m_dampCoef.m_w = DG_MIN_SPEED_ATT + (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT) * linearDamp;
}
inline void dgBody::SetAngularDamping(const dgVector &angularDamp) {
dgFloat32 tmp;
tmp = ClampValue(angularDamp.m_x, dgFloat32(0.0f), dgFloat32(1.0f));
m_dampCoef.m_x = DG_MIN_SPEED_ATT + (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT) * tmp;
tmp = ClampValue(angularDamp.m_y, dgFloat32(0.0f), dgFloat32(1.0f));
m_dampCoef.m_y = DG_MIN_SPEED_ATT + (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT) * tmp;
tmp = ClampValue(angularDamp.m_z, dgFloat32(0.0f), dgFloat32(1.0f));
m_dampCoef.m_z = DG_MIN_SPEED_ATT + (DG_MAX_SPEED_ATT - DG_MIN_SPEED_ATT) * tmp;
}
inline void dgBody::AddDamingAcceleration() {
m_veloc -= m_veloc.Scale(m_dampCoef.m_w);
dgVector omega(m_matrix.UnrotateVector(m_omega));
omega -= omega.CompProduct(m_dampCoef);
m_omega = m_matrix.RotateVector(omega);
}
/*
inline void dgBody::AddGyroscopicTorque()
{
NEWTON_ASSERT (0);
if (m_applyGyroscopic) {
const dgVector inertia = m_mass;
dgVector omega (m_matrix.UnrotateVector (m_omega));
m_alpha -= m_matrix.RotateVector(omega.CompProduct(inertia) * omega);
}
}
*/
inline void dgBody::SetForce(const dgVector &force) {
dgFloat32 errMag2;
dgVector error;
m_accel = force;
error = m_accel - m_prevExternalForce;
errMag2 = (error % error) * m_invMass[3] * m_invMass[3];
if (errMag2 > DG_ErrTolerance2) {
m_sleepingCounter = 0;
}
}
inline void dgBody::SetTorque(const dgVector &torque) {
dgFloat32 errMag2;
dgVector error;
m_alpha = torque;
error = m_alpha - m_prevExternalTorque;
errMag2 = (error % error) * m_invMass[3] * m_invMass[3];
if (errMag2 > DG_ErrTolerance2) {
m_sleepingCounter = 0;
}
}
// inline int dgBody::GetApplicationFreezeState() const
//{
// return m_aplycationFreeze ? 1 : 0;
// }
// inline void dgBody::SetApplicationFreezeState(dgInt32 state)
//{
// m_aplycationFreeze = state ? true : false;
// }
inline dgBodyMasterList::dgListNode *dgBody::GetMasterList() const {
return m_masterNode;
}
inline bool dgBody::GetFreeze() const {
return m_freeze;
}
inline dgInt32 dgBody::GetUniqueID() const {
return m_uniqueID;
}
inline bool dgBody::IsInEquelibrium() const {
dgFloat32 invMassMag2 = m_invMass[3] * m_invMass[3];
if (m_equilibrium) {
dgVector error(m_accel - m_prevExternalForce);
dgFloat32 errMag2 = (error % error) * invMassMag2;
if (errMag2 < DG_ErrTolerance2) {
error = m_alpha - m_prevExternalTorque;
errMag2 = (error % error) * invMassMag2;
if (errMag2 < DG_ErrTolerance2) {
errMag2 = (m_netForce % m_netForce) * invMassMag2;
if (errMag2 < DG_ErrTolerance2) {
errMag2 = (m_netTorque % m_netTorque) * invMassMag2;
if (errMag2 < DG_ErrTolerance2) {
errMag2 = m_veloc % m_veloc;
if (errMag2 < DG_ErrTolerance2) {
errMag2 = m_omega % m_omega;
if (errMag2 < DG_ErrTolerance2) {
return true;
}
}
}
}
}
}
}
return false;
}
inline void dgBody::SetMatrixOriginAndRotation(const dgMatrix &matrix) {
m_matrix = matrix;
#ifdef _DEBUG
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
NEWTON_ASSERT(dgCheckFloat(m_matrix[i][j]));
}
}
int j0 = 1;
int j1 = 2;
for (dgInt32 i = 0; i < 3; i++) {
dgFloat32 val;
NEWTON_ASSERT(m_matrix[i][3] == 0.0f);
val = m_matrix[i] % m_matrix[i];
NEWTON_ASSERT(dgAbsf(val - 1.0f) < 1.0e-5f);
dgVector tmp(m_matrix[j0] * m_matrix[j1]);
val = tmp % m_matrix[i];
NEWTON_ASSERT(dgAbsf(val - 1.0f) < 1.0e-5f);
j0 = j1;
j1 = i;
}
#endif
m_rotation = dgQuaternion(m_matrix);
m_globalCentreOfMass = m_matrix.TransformVector(m_localCentreOfMass);
// matrix.m_front = matrix.m_front.Scale (dgRsqrt (matrix.m_front % matrix.m_front));
// matrix.m_right = matrix.m_front * matrix.m_up;
// matrix.m_right = matrix.m_right.Scale (dgRsqrt (matrix.m_right % matrix.m_right));
// matrix.m_up = matrix.m_right * matrix.m_front;
}
#endif // !defined(AFX_DGBODY_H__C16EDCD6_53C4_4C6F_A70A_591819F7187E__INCLUDED_)