commit x64 compilation from lulu cause the other branch dont seems to compile properly at home

This commit is contained in:
2026-07-17 16:08:20 +02:00
parent c0f3eeb00d
commit 0efa4ee6f7
625 changed files with 117283 additions and 4426 deletions

View File

@ -0,0 +1,821 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "physic_bullet/bullet_item.h"
#include "physic_bullet/bullet_world.h"
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
#include "physic_bullet/bullet_character_controller.h"
#include "physic/physic_item_desc.h"
#include "core/item.h"
#include "core/terrain.h"
#include "scene3d/mitem.h"
#include "math/matrix4.h"
#include "log/log.h"
using namespace GS;
using namespace GS::S3D;
//------------------------------------------------------------------------------
static Vector4 btTonVector(const btVector3 &v)
{ return Vector4(v.x(), v.y(), v.z()); }
static btVector3 nTobtVector(const Vector4 &v)
{ return btVector3(v.x, v.y, v.z); }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletMotionState::setWorldTransform(const btTransform &comt)
{
btTransform wt = comt;
const Vector4 &com = item->GetCenter();
wt.setOrigin(wt.getOrigin() - wt.getBasis() * btVector3(com.x, com.y, com.z));
item->TransformToMatrix4(wt, bullet_matrix);
bullet_matrix = bullet_matrix * Matrix4::ScaleMatrix(item->GetScale());
}
void BulletMotionState::getWorldTransform(btTransform &wt) const
{
item->TransformFromMatrix4(engine_matrix, wt);
const Vector4 &com = item->GetCenter();
wt.setOrigin(wt.getOrigin() + wt.getBasis() * btVector3(com.x, com.y, com.z));
}
BulletMotionState::BulletMotionState(BulletPhysicItem *_item) : item(_item)
{
MItem *mitem = (MItem *)_item->GetUserPointer();
bullet_matrix = mitem->GetBaseItem()->GetMatrix();
engine_matrix = bullet_matrix;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
uint BulletPhysicItem::GetSelfMask() const
{
btBroadphaseProxy *handle = NULL;
if (rigid_body)
handle = rigid_body->getBroadphaseHandle();
if (ghost_object)
handle = ghost_object->getBroadphaseHandle();
return handle ? handle->m_collisionFilterGroup : 0;
}
void BulletPhysicItem::SetSelfMask(uint m)
{
self_mask = m;
btBroadphaseProxy *handle = NULL;
if (rigid_body)
handle = rigid_body->getBroadphaseHandle();
if (ghost_object)
handle = ghost_object->getBroadphaseHandle();
if (handle)
{
handle->m_collisionFilterGroup = (short)m;
// Refresh pair cache.
btworld->getBroadphase()->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(handle, btworld->getDispatcher());
}
}
uint BulletPhysicItem::GetCollisionMask() const
{
btBroadphaseProxy *handle = NULL;
if (rigid_body)
handle = rigid_body->getBroadphaseHandle();
if (ghost_object)
handle = ghost_object->getBroadphaseHandle();
return handle ? handle->m_collisionFilterMask : 0;
}
void BulletPhysicItem::SetCollisionMask(uint m)
{
collision_mask = m;
btBroadphaseProxy *handle = NULL;
if (rigid_body)
handle = rigid_body->getBroadphaseHandle();
if (ghost_object)
handle = ghost_object->getBroadphaseHandle();
if (handle)
{
handle->m_collisionFilterMask = (short)m;
// Refresh pair cache.
btworld->getBroadphase()->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(handle, btworld->getDispatcher());
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::SetLinearDamping(float k)
{
if (rigid_body)
rigid_body->setDamping(1.f - k, rigid_body->getAngularDamping());
}
float BulletPhysicItem::GetLinearDamping() const
{
return rigid_body ? 1.f - rigid_body->getLinearDamping() : 0;
}
void BulletPhysicItem::SetAngularDamping(float k)
{
if (rigid_body)
rigid_body->setDamping(rigid_body->getLinearDamping(), 1.f - k);
}
float BulletPhysicItem::GetAngularDamping() const
{
return rigid_body ? 1.f - rigid_body->getAngularDamping() : 0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::SetLinearFactor(const Vector4 &k)
{
if (rigid_body)
rigid_body->setLinearFactor(btVector3(k.x, k.y, k.z));
}
void BulletPhysicItem::SetAngularFactor(const Vector4 &k)
{
if (rigid_body)
rigid_body->setAngularFactor(btVector3(k.x, k.y, k.z));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::TransformFromMatrix4(const Matrix4 &m, btTransform &transform)
{
btScalar scalar[15];
scalar[0] = m.m[0][0]; scalar[1] = m.m[1][0]; scalar[2] = m.m[2][0]; scalar[3] = 1;
scalar[4] = m.m[0][1]; scalar[5] = m.m[1][1]; scalar[6] = m.m[2][1]; scalar[7] = 1;
scalar[8] = m.m[0][2]; scalar[9] = m.m[1][2]; scalar[10] = m.m[2][2]; scalar[11] = 1;
scalar[12] = m.m[0][3]; scalar[13] = m.m[1][3]; scalar[14] = m.m[2][3];
transform.setFromOpenGLMatrix(scalar);
}
void BulletPhysicItem::TransformToMatrix4(const btTransform &transform, Matrix4 &m)
{
btScalar scalar[16];
transform.getOpenGLMatrix(scalar);
m.m[0][0] = scalar[0]; m.m[1][0] = scalar[1]; m.m[2][0] = scalar[2]; m.m[3][0] = 0;
m.m[0][1] = scalar[4]; m.m[1][1] = scalar[5]; m.m[2][1] = scalar[6]; m.m[3][1] = 0;
m.m[0][2] = scalar[8]; m.m[1][2] = scalar[9]; m.m[2][2] = scalar[10]; m.m[3][2] = 0;
m.m[0][3] = scalar[12]; m.m[1][3] = scalar[13]; m.m[2][3] = scalar[14]; m.m[3][3] = scalar[15];
}
void BulletPhysicItem::GetGraphicMatrix(Matrix4 &m)
{
if (ghost_object)
{
btTransform wt = ghost_object->getWorldTransform();
wt.setOrigin(wt.getOrigin() - wt.getBasis() * btVector3(center.x, center.y, center.z));
TransformToMatrix4(wt, m);
}
else
if (motion_state)
m = motion_state->GetGraphicMatrix();
}
void BulletPhysicItem::SetEngineMatrix(const Matrix4 &m)
{
if (motion_state)
motion_state->SetEngineMatrix(m);
}
void BulletPhysicItem::GetMatrix(Matrix4 &m)
{
if (ghost_object)
TransformToMatrix4(ghost_object->getWorldTransform(), m);
else
if (rigid_body)
TransformToMatrix4(rigid_body->getWorldTransform(), m);
}
void BulletPhysicItem::SetMatrix(const Matrix4 &m)
{
Vector4 p;
Matrix3 m3;
m.Decompose(&p, 0, &m3);
Matrix4 m4(Matrix4::FromMatrix3(m3));
m4.SetRow(3, p);
btTransform wt;
TransformFromMatrix4(m4, wt);
wt.setOrigin(wt.getOrigin() + wt.getBasis() * btVector3(center.x, center.y, center.z));
if (ghost_object)
ghost_object->setWorldTransform(wt);
else
if (rigid_body)
rigid_body->setWorldTransform(wt);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::SetSleeping(bool sleep)
{
if (!rigid_body)
return;
if (sleep)
rigid_body->setActivationState(WANTS_DEACTIVATION);
else rigid_body->activate();
}
bool BulletPhysicItem::IsSleeping() const
{ return rigid_body ? rigid_body->wantsSleeping() : false; }
void BulletPhysicItem::SetActive(bool active)
{
if (!rigid_body)
return;
if (active)
{
/*
Note the activation state MUST be changed from
DISABLE_SIMULATION or activate() will silently fail.
*/
rigid_body->getBroadphaseHandle()->m_collisionFilterGroup = self_mask;
rigid_body->getBroadphaseHandle()->m_collisionFilterMask = collision_mask;
rigid_body->forceActivationState(ACTIVE_TAG);
rigid_body->activate();
}
else
{
rigid_body->setActivationState(DISABLE_SIMULATION);
rigid_body->getBroadphaseHandle()->m_collisionFilterGroup = 0;
rigid_body->getBroadphaseHandle()->m_collisionFilterMask = 0;
}
}
bool BulletPhysicItem::GetActive() const
{ return rigid_body ? rigid_body->isActive() : false; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::VehicleSetForce(float F, uint i)
{
if (vehicle && (i < (uint)vehicle->getNumWheels()))
vehicle->applyEngineForce(F, i);
}
void BulletPhysicItem::VehicleSetBrake(float F, uint i)
{
if (vehicle && (i < (uint)vehicle->getNumWheels()))
vehicle->setBrake(F, i);
}
void BulletPhysicItem::VehicleSetSteering(float v, uint i)
{
if (vehicle && (i < (uint)vehicle->getNumWheels()))
vehicle->setSteeringValue(v, i);
}
void BulletPhysicItem::VehicleSetFriction(float f, uint i)
{
if (vehicle && (i < (uint)vehicle->getNumWheels()))
vehicle->getWheelInfo(i).m_frictionSlip = f;
}
Matrix4 BulletPhysicItem::VehicleGetWheelMatrix(uint i)
{
Matrix4 m(Matrix4::IdentityMatrix());
if (vehicle && (i < (uint)vehicle->getNumWheels()))
{
vehicle->updateWheelTransform(i, true);
TransformToMatrix4(vehicle->getWheelInfo(i).m_worldTransform, m);
}
return m;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::CharacterSetRotationMatrix(const Matrix3 &m)
{
if (ghost_object)
{
btMatrix3x3 basis
(
m.m[0][0], m.m[0][1], m.m[0][2],
m.m[1][0], m.m[1][1], m.m[1][2],
m.m[2][0], m.m[2][1], m.m[2][2]
);
ghost_object->getWorldTransform().setBasis(basis);
}
}
void BulletPhysicItem::CharacterSetVelocity(const Vector4 &v)
{
if (character_controller)
character_controller->setWalkDirection(nTobtVector(v));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::SetScale(const Vector4 &_scale)
{
scale = _scale;
if (compound)
compound->setLocalScaling(nTobtVector(scale));
}
Vector4 BulletPhysicItem::GetScale() const
{ return scale; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::ResetBody()
{
if (rigid_body)
{
rigid_body->setLinearVelocity(btVector3(0, 0, 0));
rigid_body->setAngularVelocity(btVector3(0, 0, 0));
rigid_body->clearForces();
}
}
void BulletPhysicItem::ForceUpdateMassShapePhysic(const PhysicItemDesc &desc, PhysicWorld *world)
{
float total_mass = 0;
if (!desc.shape_list.GetCount())
return;
Array <btScalar> mass_array;
mass_array.Allocate(desc.shape_list.GetCount());
center.Set(0, 0, 0);
btScalar *pmass_array = mass_array.c_ptr();
ListForeachPtr(PhysicShape *, shape, desc.shape_list)
{
Vector4 shape_center = shape->position;
center += shape_center * shape->mass;
total_mass += shape->mass;
*pmass_array++ = shape->mass;
}
center /= total_mass;
btTransform principal;
btVector3 body_inertia(0, 0, 0);
compound->calculatePrincipalAxisTransform(mass_array, principal, body_inertia);
rigid_body->setMassProps(total_mass, body_inertia);
rigid_body->updateInertiaTensor();
}
//------------------------------------------------------------------------------
float BulletPhysicItem::SetupCollisionShapes(const PhysicItemDesc &desc, Array <btScalar> &mass_array, PhysicWorld *world)
{
float total_mass = 0;
if (!desc.shape_list.GetCount())
return total_mass;
mass_array.Allocate(desc.shape_list.GetCount());
btScalar *pmass_array = mass_array.c_ptr();
// WTF man... can't Bullet handle COM offset by itself?
shapes.Allocate(desc.shape_list.GetCount());
center.Set(0, 0, 0);
uint n = 0;
ListForeachPtr(PhysicShape *, shape, desc.shape_list)
{
btCollisionShape *btshape = NULL;
Vector4 shape_center = shape->position;
switch (shape->GetType())
{
case PhysicShape::TypeNone:
break;
case PhysicShape::TypeHeightmap:
if (float *ph = shape->GetHeightmap())
{
float min, max;
min = max = ph[0];
for (int v = 0; v < shape->GetHeight(); ++v)
for (int u = 0; u < shape->GetWidth(); ++u)
{
if (ph[0] > max)
max = ph[0];
if (ph[0] < min)
min = ph[0];
ph++;
}
btshape = new btHeightfieldTerrainShape(shape->GetWidth(), shape->GetHeight(), (void *)shape->GetHeightmap(), 1.f, min, max, 1, PHY_FLOAT, false);
}
break;
case PhysicShape::TypeSphere:
btshape = new btSphereShape(shape->dimensions.x);
break;
case PhysicShape::TypeBox:
{
const Vector4 &d = shape->dimensions;
btshape = new btBoxShape(btVector3(d.x * 0.5f, d.y * 0.5f, d.z * 0.5f));
}
break;
case PhysicShape::TypeCapsule:
{
const Vector4 &d = shape->dimensions;
btshape = new btCapsuleShapeZ(d.x * 0.5f, d.z);
}
break;
case PhysicShape::TypeCylinder:
{
const Vector4 &d = shape->dimensions;
btshape = new btCylinderShapeZ(btVector3(d.x * 0.5f, d.y * 0.5f, d.z * 0.5f));
}
break;
case PhysicShape::TypeCone:
{
const Vector4 &d = shape->dimensions;
btshape = new btConeShapeZ(d.x * 0.5f, d.z * 0.5f);
}
break;
case PhysicShape::TypeConvex:
if (BulletConvex *convex = ((BulletWorld *)world)->LoadConvex(shape->path))
{
shapes[n].convex = convex;
shape_center = convex->center * shape->GetMatrix();
btshape = convex->convex;
}
break;
case PhysicShape::TypeMesh:
if (desc.physic_mode == PhysicItemDesc::Mode_Static)
{
/*
[EJ] 06/03/13 - Bullet SILENTLY rescales the cached mesh
vertices to comply with the item scale. In order to support
multiple scales on the same mesh the path is suffixed with
the item scale.
*/
String suffix = String::Format("%.02f_%.02f_%.02f", scale.x, scale.y, scale.z);
if (BulletMesh *mesh = ((BulletWorld *)world)->LoadMesh(shape->path, suffix))
{
shapes[n].mesh = mesh;
shape_center = mesh->center * shape->GetMatrix();
btshape = mesh->mesh;
}
}
break;
}
shapes[n].shape = btshape;
center += shape_center * shape->mass;
total_mass += shape->mass;
*pmass_array++ = shape->mass;
++n;
}
center /= total_mass;
if (desc.physic_mode == PhysicItemDesc::Mode_Vehicle)
center.Set(0, 0, 0);
n = 0;
ListForeachPtr(PhysicShape *, shape, desc.shape_list)
{
if (btCollisionShape *btshape = shapes[n].shape)
{
Vector4 shape_offset(0, 0, 0);
if (shape->GetType() == PhysicShape::TypeHeightmap)
{
float *ph = shape->GetHeightmap();
float min, max;
min = max = ph[0];
for (int v = 0; v < shape->GetHeight(); ++v)
for (int u = 0; u < shape->GetWidth(); ++u)
{
if (ph[0] > max) max = ph[0];
if (ph[0] < min) min = ph[0];
ph++;
}
btshape->setLocalScaling(btVector3(1, 1, 1));
// Damn... what a mess.
float hy = (max - min) * -0.5f;
shape_offset.Set(0, min - hy, 0);
}
Matrix4 m = Matrix4::TransformationMatrix(shape->position + shape_offset - center, shape->rotation, shape->scale);
btTransform transform;
TransformFromMatrix4(m, transform);
compound->addChildShape(transform, btshape);
}
++n;
}
return total_mass;
}
bool BulletPhysicItem::SetupCharacterController(const PhysicItemDesc &desc)
{
ghost_object = new btPairCachingGhostObject();
ghost_object->setUserPointer((PhysicItem *)this);
#if 0
convex_shape = new btCylinderShape(btVector3(desc.character.radius, desc.character.height * 0.5f, desc.character.radius));
center.Set(0, desc.character.height * 0.5f, 0);
#else
float height = Types::Max(desc.character.height - desc.character.radius * 2.f, 0.f);
convex_shape = new btCapsuleShape(desc.character.radius, height); // Height is the distance between the center of the two spheres whose convex hull is a capsule.
center.Set(0, (height + desc.character.radius * 2.f) * 0.5f, 0);
#endif
ghost_object->setCollisionShape(convex_shape);
ghost_object->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
#if 1
character_controller = new btKinematicCharacterController(ghost_object, convex_shape, desc.character.max_step);
#else
btCustomCharacterController *cc = new btCustomCharacterController(ghost_object, convex_shape, desc.character.max_step, btworld->getCollisionWorld());
character_controller = cc;
#endif
return true;
}
bool BulletPhysicItem::SetupKinematicDynamicBody(const PhysicItemDesc &desc, PhysicWorld *world)
{
// Setup collision shapes.
Array <btScalar> mass_array;
compound = new btCompoundShape;
float total_mass = SetupCollisionShapes(desc, mass_array, world);
if (!compound->getNumChildShapes())
return true;
// Initialize physic mode.
compound->setLocalScaling(nTobtVector(scale));
btVector3 body_inertia(0, 0, 0);
switch (desc.physic_mode)
{
case PhysicItemDesc::Mode_None:
break;
case PhysicItemDesc::Mode_Dynamic:
case PhysicItemDesc::Mode_Vehicle:
if (compound->getNumChildShapes())
{
btTransform principal;
compound->calculatePrincipalAxisTransform(mass_array, principal, body_inertia);
}
else
{
total_mass = 1;
body_inertia.setValue(1, 1, 1);
}
break;
case PhysicItemDesc::Mode_Static:
case PhysicItemDesc::Mode_Kinematic:
total_mass = 0;
break;
}
// Allocate motion state.
motion_state = new BulletMotionState(this);
// Create rigid body.
rigid_body = new btRigidBody(btRigidBody::btRigidBodyConstructionInfo(total_mass, motion_state, compound, body_inertia));
rigid_body->setUserPointer((PhysicItem *)this);
// Vehicle specialization.
if (desc.physic_mode == PhysicItemDesc::Mode_Vehicle)
{
rigid_body->setActivationState(DISABLE_DEACTIVATION);
vehicle_raycaster = new btDefaultVehicleRaycaster(btworld);
vehicle = new btRaycastVehicle(btRaycastVehicle::btVehicleTuning(), rigid_body, vehicle_raycaster);
vehicle->setCoordinateSystem(0, 1, 2);
// Add wheels.
ListForeachPtr(PhysicWheel *, wheel, desc.vehicle.wheel_list)
{
btRaycastVehicle::btVehicleTuning tuning;
tuning.m_suspensionStiffness = wheel->stiffness;
tuning.m_suspensionDamping = wheel->damping;
tuning.m_suspensionCompression = wheel->damping;
tuning.m_frictionSlip = wheel->friction;
tuning.m_maxSuspensionTravelCm = wheel->max_compression * 10.f; // m to cm.
Vector4 o = wheel->ref_matrix.GetRow(3),
u = wheel->ref_matrix.GetRow(1).Reversed(),
l = wheel->ref_matrix.GetRow(0).Reversed();
vehicle->addWheel(btVector3(o.x, o.y, o.z), btVector3(u.x, u.y, u.z), btVector3(l.x, l.y, l.z), wheel->rest_length, wheel->radius > 0.01f ? wheel->radius : 0.01f, tuning, false);
}
}
// Set defaults.
SetLinearFactor(desc.linear_factor);
SetAngularFactor(desc.angular_factor);
SetLinearDamping(desc.linear_damping);
SetAngularDamping(desc.angular_damping);
if (desc.shape_list.GetCount())
{
PhysicShape *shape = desc.shape_list.GetRoot()->Object();
rigid_body->setFriction(shape->static_friction);
rigid_body->setRestitution(shape->restitution);
}
if (desc.physic_mode == PhysicItemDesc::Mode_Kinematic)
{
rigid_body->setCollisionFlags(rigid_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
rigid_body->setActivationState(DISABLE_DEACTIVATION);
}
return true;
}
bool BulletPhysicItem::SetupBody(const PhysicItemDesc &desc, PhysicWorld *world)
{
// EJ 11/10
//
// - Bullet constraint holds strong/unmanaged reference to Bullet rigid bodies.
// - A Bullet rigid body is not meant to be radically modified once created.
// BulletWorld *world = (PhysicWorld *)world;
if (rigid_body || ghost_object)
return true;
DeleteBody();
switch (desc.physic_mode)
{
case PhysicItemDesc::Mode_None:
return true;
case PhysicItemDesc::Mode_Character:
if (!SetupCharacterController(desc))
return false;
btworld->addCollisionObject(ghost_object, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
btworld->addAction(character_controller);
break;
default:
if (!SetupKinematicDynamicBody(desc, world))
return false;
if (rigid_body)
{
btworld->addRigidBody(rigid_body);
const Vector4 &g(world->GetGravity());
rigid_body->setGravity(btVector3(g.x, g.y, g.z));
}
if (vehicle)
btworld->addVehicle(vehicle);
break;
}
SetCollisionMask(desc.collision_mask);
SetSelfMask(desc.self_mask);
return true;
}
void BulletPhysicItem::DeleteBody()
{
// Destroy all shapes.
if (compound)
while (compound->getNumChildShapes())
compound->removeChildShapeByIndex(0);
// The collision shape for mesh/convex are cached and should not be deleted here!
for (uint n = 0; n < shapes.GetCount(); ++n)
if (shapes[n].convex.IsValid() || shapes[n].mesh.IsValid())
shapes[n].shape.Detach();
shapes.Free();
// Destroy rigid body.
if (rigid_body)
btworld->removeRigidBody(rigid_body);
rigid_body = NULL;
if (vehicle)
btworld->removeVehicle(vehicle);
vehicle = NULL;
vehicle_raycaster = NULL;
if (ghost_object)
btworld->removeCollisionObject(ghost_object);
ghost_object = NULL;
if (character_controller)
btworld->removeAction(character_controller);
character_controller = NULL;
compound = NULL;
motion_state = NULL;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void BulletPhysicItem::SetGravity(const Vector4 &g)
{
if (rigid_body)
rigid_body->setGravity(btVector3(g.x, g.y, g.z));
}
Vector4 BulletPhysicItem::GetGravity() const
{
if (!rigid_body)
return Vector4(0, 0, 0);
btVector3 g = rigid_body->getGravity();
return Vector4(g.x(), g.y(), g.z());
}
void BulletPhysicItem::ApplyImpulse(const Vector4 &I, const Vector4 *p)
{
if (!rigid_body)
return;
SetSleeping(false);
if (p && (I.Len() > 0.0001))
{
btVector3 l(p->x, p->y, p->z);
btVector3 J(I.x, I.y, I.z);
btScalar k = rigid_body->computeImpulseDenominator(l, J.normalized());
rigid_body->applyImpulse(J / k, l - rigid_body->getCenterOfMassPosition());
}
else
{
btVector3 J(I.x, I.y, I.z);
rigid_body->applyCentralImpulse(J / rigid_body->getInvMass());
}
}
void BulletPhysicItem::ApplyForce(const Vector4 &F, const Vector4 *p)
{
if (!rigid_body)
return;
SetSleeping(false);
if (p)
rigid_body->applyForce(btVector3(F.x, F.y, F.z), btVector3(p->x, p->y, p->z) - rigid_body->getCenterOfMassPosition());
else rigid_body->applyCentralForce(btVector3(F.x, F.y, F.z));
}
void BulletPhysicItem::ApplyTorque(const Vector4 &T)
{
if (rigid_body)
rigid_body->applyTorque(rigid_body->getCenterOfMassTransform().getBasis() * btVector3(T.x, T.y, T.z));
}
void BulletPhysicItem::SetAngularVelocity(const Vector4 &w)
{
if (rigid_body)
rigid_body->setAngularVelocity(btVector3(w.x, w.y, w.z));
}
Vector4 BulletPhysicItem::GetAngularVelocity() const
{
if (!rigid_body)
return Vector4(0, 0, 0);
const btVector3 &v = rigid_body->getAngularVelocity();
return Vector4(v.x(), v.y(), v.z());
}
void BulletPhysicItem::SetLinearVelocity(const Vector4 &v)
{
if (rigid_body)
rigid_body->setLinearVelocity(btVector3(v.x, v.y, v.z));
}
Vector4 BulletPhysicItem::GetLinearVelocity() const
{
if (!rigid_body)
return Vector4(0, 0, 0);
const btVector3 &v = rigid_body->getLinearVelocity();
return Vector4(v.x(), v.y(), v.z());
}
Vector4 BulletPhysicItem::GetLocalPointVelocity(const Vector4 &p) const
{
if (!rigid_body)
return Vector4(0, 0, 0);
btVector3 v = rigid_body->getVelocityInLocalPoint(rigid_body->getCenterOfMassTransform().getBasis() * btVector3(p.x, p.y, p.z));
return Vector4(v.x(), v.y(), v.z());
}
Vector4 BulletPhysicItem::GetWorldPointVelocity(const Vector4 &wp) const
{
if (!rigid_body)
return Vector4(0, 0, 0);
btVector3 v = rigid_body->getVelocityInLocalPoint(btVector3(wp.x, wp.y, wp.z) - rigid_body->getCenterOfMassPosition());
return Vector4(v.x(), v.y(), v.z());
}
Vector4 BulletPhysicItem::GetCenterOfMass() const
{
if (!rigid_body)
return Vector4(0, 0, 0);
btVector3 p = rigid_body->getCenterOfMassPosition();
return Vector4(p.x(), p.y(), p.z());
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BulletPhysicItem::BulletPhysicItem(btDiscreteDynamicsWorld *w)
{
btworld = w;
center.Set(0, 0, 0);
scale.Set(1, 1, 1);
}
BulletPhysicItem::~BulletPhysicItem()
{
DeleteBody();
}
//----------------------------------------------------------------------------------