Redesign of the Bullet <--> scene graph synchronisation.

This commit is contained in:
enn0x 2011-08-12 20:57:59 +00:00
parent 1bd2bac3ef
commit d0c8ccd901
19 changed files with 458 additions and 376 deletions

View File

@ -225,3 +225,29 @@ get_shape(int idx) const {
return _shapes[idx];
}
////////////////////////////////////////////////////////////////////
// Function: BulletBodyNode::set_debug_enabled
// Access: Published
// Description: Enables or disables the debug visualisation for
// this collision object. By default the debug
// visualisation is enabled.
////////////////////////////////////////////////////////////////////
INLINE void BulletBodyNode::
set_debug_enabled(const bool enabled) {
set_collision_flag(btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT, !enabled);
}
////////////////////////////////////////////////////////////////////
// Function: BulletBodyNode::is_debug_enabled
// Access: Published
// Description: Returns TRUE if the debug visualisation is enabled
// for this collision object, and FALSE if the debug
// visualisation is disabled.
////////////////////////////////////////////////////////////////////
INLINE bool BulletBodyNode::
is_debug_enabled() const {
return !get_collision_flag(btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT);
}

View File

@ -35,9 +35,6 @@ BulletBodyNode(const char *name) : PandaNode(name) {
// Shape
_shape = new btEmptyShape();
// Transform changed callback
_disable_transform_changed = false;
// Default collide mask
set_into_collide_mask(CollideMask::all_on());
}
@ -162,22 +159,6 @@ output(ostream &out) const {
if (is_kinematic()) out << " kinematic";
}
////////////////////////////////////////////////////////////////////
// Function: BulletBodyNode::transform_changed
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void BulletBodyNode::
transform_changed() {
// Apply scale to collision shape
CPT(TransformState) ts = this->get_transform();
if (ts->has_scale()) {
LVecBase3f scale = ts->get_scale();
_shape->setLocalScaling(LVecBase3f_to_btVector3(scale));
}
}
////////////////////////////////////////////////////////////////////
// Function: BulletBodyNode::add_shape
// Access: Published
@ -194,7 +175,7 @@ add_shape(BulletShape *shape, CPT(TransformState) ts) {
// Transform
btTransform trans = btTransform::getIdentity();
if (ts) {
trans = LMatrix4f_to_btTrans(ts->get_mat());
trans = TransformState_to_btTrans(ts);
}
// Root shape
@ -447,14 +428,14 @@ set_active(bool active, bool force) {
}
////////////////////////////////////////////////////////////////////
// Function: BulletBodyNode::set_disable_deactivation
// Function: BulletBodyNode::set_deactivation_enabled
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void BulletBodyNode::
set_disable_deactivation(bool disable, bool force) {
set_deactivation_enabled(const bool enabled, const bool force) {
int state = (disable) ? DISABLE_DEACTIVATION : WANTS_DEACTIVATION;
int state = (enabled) ? WANTS_DEACTIVATION : DISABLE_DEACTIVATION;
if (force) {
get_object()->forceActivationState(state);
@ -465,14 +446,14 @@ set_disable_deactivation(bool disable, bool force) {
}
////////////////////////////////////////////////////////////////////
// Function: BulletBodyNode::get_disable_deactivation
// Function: BulletBodyNode::is_deactivation_enabled
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
bool BulletBodyNode::
get_disable_deactivation() const {
is_deactivation_enabled() const {
return (get_object()->getActivationState() & DISABLE_DEACTIVATION) != 0;
return (get_object()->getActivationState() & DISABLE_DEACTIVATION) == 0;
}
////////////////////////////////////////////////////////////////////

View File

@ -78,8 +78,12 @@ PUBLISHED:
void set_deactivation_time(float dt);
float get_deactivation_time() const;
void set_disable_deactivation(bool disable, bool force=false);
bool get_disable_deactivation() const;
void set_deactivation_enabled(const bool enabled, const bool force=false);
bool is_deactivation_enabled() const;
// Debug Visualistion
INLINE void set_debug_enabled(const bool enabled);
INLINE bool is_debug_enabled() const;
// Friction and Restitution
INLINE float get_restitution() const;
@ -121,9 +125,6 @@ protected:
typedef PTA(PT(BulletShape)) BulletShapes;
BulletShapes _shapes;
bool _disable_transform_changed;
virtual void transform_changed();
private:
virtual void shape_changed();

View File

@ -24,17 +24,21 @@ TypeHandle BulletCharacterControllerNode::_type_handle;
BulletCharacterControllerNode::
BulletCharacterControllerNode(BulletShape *shape, float step_height, const char *name) : PandaNode(name) {
// Setup initial transform
// Synchronised transform
_sync = TransformState::make_identity();
_sync_disable = false;
// Initial transform
btTransform trans = btTransform::getIdentity();
// Get convex shape
// Get convex shape (for ghost object)
if (!shape->is_convex()) {
bullet_cat.error() << "a convex shape is required!" << endl;
}
btConvexShape *convex = dynamic_cast<btConvexShape *>(shape->ptr());
// Setup ghost object
// Ghost object
_ghost = new btPairCachingGhostObject();
_ghost->setUserPointer(this);
@ -43,25 +47,21 @@ BulletCharacterControllerNode(BulletShape *shape, float step_height, const char
_ghost->setCollisionShape(convex);
_ghost->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
// Setup up axis
// Up axis
_up = get_default_up_axis();
// Movement
// Initialise movement
_linear_velocity_is_local = false;
_linear_velocity.set(0.0f, 0.0f, 0.0f);
_angular_velocity = 0.0f;
// Setup character controller
// Character controller
_character = new btKinematicCharacterController(_ghost, convex, step_height, _up);
_character->setGravity((btScalar)9.81f);
// Retain a pointer to the shape
_shape = shape;
// The 'transform changed' hook has to be disabled when updating the node's
// transform from inside the post_step method!
_disable_transform_changed = false;
// Default collide mask
set_into_collide_mask(CollideMask::all_on());
}
@ -196,14 +196,17 @@ set_angular_velocity(float omega) {
}
////////////////////////////////////////////////////////////////////
// Function: BulletCharacterControllerNode::pre_step
// Function: BulletCharacterControllerNode::sync_p2b
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletCharacterControllerNode::
pre_step(float dt) {
sync_p2b(float dt) {
// Angular rotation
// Synchronise global transform
transform_changed();
// Angular rotation
btScalar angle = dt * deg_2_rad(_angular_velocity);
btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
@ -225,28 +228,32 @@ pre_step(float dt) {
}
_character->setVelocityForTimeInterval(v, dt);
//_character->setWalkDirection(v * dt);
_angular_velocity = 0.0f;
}
////////////////////////////////////////////////////////////////////
// Function: BulletCharacterControllerNode::post_step
// Function: BulletCharacterControllerNode::sync_b2p
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletCharacterControllerNode::
post_step() {
btTransform trans = _ghost->getWorldTransform();
CPT(TransformState) ts = btTrans_to_TransformState(trans);
_disable_transform_changed = true;
sync_b2p() {
NodePath np = NodePath::any_path((PandaNode *)this);
np.set_transform(np.get_top(), ts);
LVecBase3f scale = np.get_net_transform()->get_scale();
_disable_transform_changed = false;
btTransform trans = _ghost->getWorldTransform();
CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
LMatrix4f m_sync = _sync->get_mat();
LMatrix4f m_ts = ts->get_mat();
if (!m_sync.almost_equal(m_ts)) {
_sync = ts;
_sync_disable = true;
np.set_transform(NodePath(), ts);
_sync_disable = false;
}
}
////////////////////////////////////////////////////////////////////
@ -257,25 +264,36 @@ post_step() {
void BulletCharacterControllerNode::
transform_changed() {
if (_disable_transform_changed) return;
if (_sync_disable) return;
// Get translation and heading
NodePath np = NodePath::any_path((PandaNode *)this);
CPT(TransformState) ts = np.get_transform(np.get_top());
CPT(TransformState) ts = np.get_net_transform();
LPoint3f pos = ts->get_pos();
float heading = ts->get_hpr().get_x();
LMatrix4f m_sync = _sync->get_mat();
LMatrix4f m_ts = ts->get_mat();
// Set translation
_character->warp(LVecBase3f_to_btVector3(pos));
if (!m_sync.almost_equal(m_ts)) {
_sync = ts;
// Set Heading
btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
btVector3 up = m[_up];
// Get translation, heading and scale
LPoint3f pos = ts->get_pos();
float heading = ts->get_hpr().get_x();
LVecBase3f scale = ts->get_scale();
m = btMatrix3x3(btQuaternion(up, heading));
// Set translation
_character->warp(LVecBase3f_to_btVector3(pos));
_ghost->getWorldTransform().setBasis(m);
// Set Heading
btMatrix3x3 m = _ghost->getWorldTransform().getBasis();
btVector3 up = m[_up];
m = btMatrix3x3(btQuaternion(up, heading));
_ghost->getWorldTransform().setBasis(m);
// Set scale
_shape->set_local_scale(scale);
}
}
////////////////////////////////////////////////////////////////////
@ -408,25 +426,3 @@ set_use_ghost_sweep_test(bool value) {
return _character->setUseGhostSweepTest(value);
}
/*
////////////////////////////////////////////////////////////////////
// Function: BulletCharacterControllerNode::parents_changed
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void BulletCharacterControllerNode::
parents_changed() {
}
////////////////////////////////////////////////////////////////////
// Function: BulletCharacterControllerNode::children_changed
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void BulletCharacterControllerNode::
children_changed() {
}
*/

View File

@ -69,15 +69,16 @@ public:
INLINE btPairCachingGhostObject *get_ghost() const;
INLINE btKinematicCharacterController *get_character() const;
void pre_step(float dt);
void post_step();
void sync_p2b(float dt);
void sync_b2p();
protected:
//virtual void parents_changed();
//virtual void children_changed();
virtual void transform_changed();
private:
CPT(TransformState) _sync;
bool _sync_disable;
BulletUpAxis _up;
btKinematicCharacterController *_character;
@ -89,8 +90,6 @@ private:
bool _linear_velocity_is_local;
float _angular_velocity;
bool _disable_transform_changed;
////////////////////////////////////////////////////////////////////
public:
static TypeHandle get_class_type() {

View File

@ -186,12 +186,12 @@ draw_mask_changed() {
}
////////////////////////////////////////////////////////////////////
// Function: BulletDebugNode::post_step
// Function: BulletDebugNode::sync_b2p
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void BulletDebugNode::
post_step(btDynamicsWorld *world) {
sync_b2p(btDynamicsWorld *world) {
if (is_overall_hidden()) return;
@ -199,7 +199,7 @@ post_step(btDynamicsWorld *world) {
world->debugDrawWorld();
// Get inverse of this node's net transform
NodePath np = NodePath::any_path(this);
NodePath np = NodePath::any_path((PandaNode *)this);
LMatrix4f m = np.get_net_transform()->get_mat();
m.invert_in_place();
@ -348,7 +348,6 @@ drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, cons
void BulletDebugNode::DebugDraw::
drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &n0, const btVector3 &n1, const btVector3 &n2, const btVector3 &color, btScalar alpha) {
// TODO
bullet_cat.debug() << "drawTriangle(2) - not yet implemented!" << endl;
}
@ -374,7 +373,6 @@ drawContactPoint(const btVector3 &point, const btVector3 &normal, btScalar dista
void BulletDebugNode::DebugDraw::
draw3dText(const btVector3 &location, const char *text) {
// TODO
bullet_cat.debug() << "draw3dText - not yet implemented!" << endl;
}

View File

@ -49,7 +49,7 @@ public:
virtual bool safe_to_flatten_below() const;
private:
void post_step(btDynamicsWorld *world);
void sync_b2p(btDynamicsWorld *world);
struct Line {
LVecBase3f _p0;

View File

@ -25,19 +25,20 @@ TypeHandle BulletGhostNode::_type_handle;
BulletGhostNode::
BulletGhostNode(const char *name) : BulletBodyNode(name) {
// Setup initial transform
// Synchronised transform
_sync = TransformState::make_identity();
_sync_disable = false;
// Initial transform
btTransform trans = btTransform::getIdentity();
// Setup ghost object
// Ghost object
_ghost = new btPairCachingGhostObject();
_ghost->setUserPointer(this);
_ghost->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
_ghost->setWorldTransform(trans);
_ghost->setInterpolationWorldTransform(trans);
_ghost->setCollisionShape(_shape);
// Autosync is off by default
_sync_transform = false;
}
////////////////////////////////////////////////////////////////////
@ -51,35 +52,6 @@ get_object() const {
return _ghost;
}
////////////////////////////////////////////////////////////////////
// Function: BulletGhostNode::parents_changed
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void BulletGhostNode::
parents_changed() {
// Enable autosync if one of the parents is suited for this
Parents parents = get_parents();
for (int i=0; i < parents.get_num_parents(); ++i) {
PandaNode *parent = parents.get_parent(i);
TypeHandle type = parent->get_type();
if (BulletRigidBodyNode::get_class_type() == type ||
BulletSoftBodyNode::get_class_type() == type ||
BulletGhostNode::get_class_type() == type ||
BulletCharacterControllerNode::get_class_type() == type) {
_sync_transform = true;
return;
}
}
// None of the parents is suited for autosync
_sync_transform = false;
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: BulletGhostNode::transform_changed
// Access: Protected
@ -88,26 +60,64 @@ parents_changed() {
void BulletGhostNode::
transform_changed() {
if (_disable_transform_changed) return;
if (_sync_disable) return;
btTransform trans = btTransform::getIdentity();
get_node_transform(trans, this);
_ghost->setWorldTransform(trans);
_ghost->setInterpolationWorldTransform(trans);
NodePath np = NodePath::any_path((PandaNode *)this);
CPT(TransformState) ts = np.get_net_transform();
BulletBodyNode::transform_changed();
LMatrix4f m_sync = _sync->get_mat();
LMatrix4f m_ts = ts->get_mat();
if (!m_sync.almost_equal(m_ts)) {
_sync = ts;
btTransform trans = TransformState_to_btTrans(ts);
_ghost->setWorldTransform(trans);
_ghost->setInterpolationWorldTransform(trans);
if (ts->has_scale()) {
LVecBase3f scale = ts->get_scale();
for (int i=0; i<get_num_shapes(); i++) {
PT(BulletShape) shape = _shapes[i];
shape->set_local_scale(scale);
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: BulletGhostNode::pre_step
// Function: BulletGhostNode::sync_p2b
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletGhostNode::
pre_step() {
sync_p2b() {
if (_sync_transform) {
transform_changed();
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: BulletGhostNode::sync_b2p
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletGhostNode::
sync_b2p() {
NodePath np = NodePath::any_path((PandaNode *)this);
LVecBase3f scale = np.get_net_transform()->get_scale();
btTransform trans = _ghost->getWorldTransform();
CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
LMatrix4f m_sync = _sync->get_mat();
LMatrix4f m_ts = ts->get_mat();
if (!m_sync.almost_equal(m_ts)) {
_sync = ts;
_sync_disable = true;
np.set_transform(NodePath(), ts);
_sync_disable = false;
}
}

View File

@ -44,16 +44,17 @@ PUBLISHED:
public:
virtual btCollisionObject *get_object() const;
void pre_step();
void sync_p2b();
void sync_b2p();
protected:
virtual void parents_changed();
virtual void transform_changed();
private:
btPairCachingGhostObject *_ghost;
CPT(TransformState) _sync;
bool _sync_disable;
bool _sync_transform;
btPairCachingGhostObject *_ghost;
////////////////////////////////////////////////////////////////////
public:

View File

@ -21,8 +21,8 @@
INLINE BulletRigidBodyNode::
~BulletRigidBodyNode() {
delete _body;
delete _motion;
delete _rigid->getMotionState();
delete _rigid;
}
////////////////////////////////////////////////////////////////////
@ -33,7 +33,7 @@ INLINE BulletRigidBodyNode::
INLINE void BulletRigidBodyNode::
set_linear_damping(float value) {
_body->setDamping(value, _body->getAngularDamping());
_rigid->setDamping(value, _rigid->getAngularDamping());
}
////////////////////////////////////////////////////////////////////
@ -44,7 +44,7 @@ set_linear_damping(float value) {
INLINE void BulletRigidBodyNode::
set_angular_damping(float value) {
_body->setDamping(_body->getLinearDamping(), value);
_rigid->setDamping(_rigid->getLinearDamping(), value);
}
////////////////////////////////////////////////////////////////////
@ -55,7 +55,7 @@ set_angular_damping(float value) {
INLINE float BulletRigidBodyNode::
get_linear_damping() const {
return _body->getLinearDamping();
return _rigid->getLinearDamping();
}
////////////////////////////////////////////////////////////////////
@ -66,6 +66,6 @@ get_linear_damping() const {
INLINE float BulletRigidBodyNode::
get_angular_damping() const {
return _body->getAngularDamping();
return _rigid->getAngularDamping();
}

View File

@ -25,16 +25,19 @@ TypeHandle BulletRigidBodyNode::_type_handle;
BulletRigidBodyNode::
BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
// Setup motion state
_motion = new MotionState(this);
// Synchronised transform
_sync = TransformState::make_identity();
_sync_disable = false;
// Setup mass properties
// Mass properties
btScalar mass(0.0);
btVector3 inertia(0, 0, 0);
btRigidBody::btRigidBodyConstructionInfo ci(mass, _motion, _shape, inertia);
// Motion state and construction info
btDefaultMotionState *motion = new btDefaultMotionState();
btRigidBody::btRigidBodyConstructionInfo ci(mass, motion, _shape, inertia);
// Enable additional damping
// Additional damping
if (bullet_additional_damping) {
ci.m_additionalDamping = true;
ci.m_additionalDampingFactor = bullet_additional_damping_linear_factor;
@ -43,9 +46,9 @@ BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
ci.m_additionalAngularDampingThresholdSqr = bullet_additional_damping_angular_threshold;
}
// Setup rigid body
_body = new btRigidBody(ci);
_body->setUserPointer(this);
// Rigid body
_rigid = new btRigidBody(ci);
_rigid->setUserPointer(this);
}
////////////////////////////////////////////////////////////////////
@ -69,7 +72,7 @@ output(ostream &out) const {
btCollisionObject *BulletRigidBodyNode::
get_object() const {
return _body;
return _rigid;
}
////////////////////////////////////////////////////////////////////
@ -97,10 +100,10 @@ set_mass(float mass) {
btVector3 inertia(0.0f, 0.0f, 0.0f);
if (mass > 0.0f) {
_body->getCollisionShape()->calculateLocalInertia(mass, inertia);
_rigid->getCollisionShape()->calculateLocalInertia(mass, inertia);
}
_body->setMassProps(mass, inertia);
_rigid->setMassProps(mass, inertia);
}
////////////////////////////////////////////////////////////////////
@ -111,7 +114,7 @@ set_mass(float mass) {
float BulletRigidBodyNode::
get_mass() const {
btScalar invMass = _body->getInvMass();
btScalar invMass = _rigid->getInvMass();
if (invMass == 0.0f) {
return 0.0f;
@ -132,7 +135,7 @@ apply_force(const LVector3f &force, const LPoint3f &pos) {
nassertv_always(!force.is_nan());
nassertv_always(!pos.is_nan());
_body->applyForce(LVecBase3f_to_btVector3(force),
_rigid->applyForce(LVecBase3f_to_btVector3(force),
LVecBase3f_to_btVector3(pos));
}
@ -146,7 +149,7 @@ apply_central_force(const LVector3f &force) {
nassertv_always(!force.is_nan());
_body->applyCentralForce(LVecBase3f_to_btVector3(force));
_rigid->applyCentralForce(LVecBase3f_to_btVector3(force));
}
////////////////////////////////////////////////////////////////////
@ -159,7 +162,7 @@ apply_torque(const LVector3f &torque) {
nassertv_always(!torque.is_nan());
_body->applyTorque(LVecBase3f_to_btVector3(torque));
_rigid->applyTorque(LVecBase3f_to_btVector3(torque));
}
////////////////////////////////////////////////////////////////////
@ -172,7 +175,7 @@ apply_torque_impulse(const LVector3f &torque) {
nassertv_always(!torque.is_nan());
_body->applyTorqueImpulse(LVecBase3f_to_btVector3(torque));
_rigid->applyTorqueImpulse(LVecBase3f_to_btVector3(torque));
}
////////////////////////////////////////////////////////////////////
@ -186,7 +189,7 @@ apply_impulse(const LVector3f &impulse, const LPoint3f &pos) {
nassertv_always(!impulse.is_nan());
nassertv_always(!pos.is_nan());
_body->applyImpulse(LVecBase3f_to_btVector3(impulse),
_rigid->applyImpulse(LVecBase3f_to_btVector3(impulse),
LVecBase3f_to_btVector3(pos));
}
@ -200,18 +203,7 @@ apply_central_impulse(const LVector3f &impulse) {
nassertv_always(!impulse.is_nan());
_body->applyCentralImpulse(LVecBase3f_to_btVector3(impulse));
}
////////////////////////////////////////////////////////////////////
// Function: BulletRigidBodyNode::parents_changed
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void BulletRigidBodyNode::
parents_changed() {
transform_changed();
_rigid->applyCentralImpulse(LVecBase3f_to_btVector3(impulse));
}
////////////////////////////////////////////////////////////////////
@ -222,56 +214,65 @@ parents_changed() {
void BulletRigidBodyNode::
transform_changed() {
if (_disable_transform_changed) return;
if (_sync_disable) return;
btTransform trans = btTransform::getIdentity();
get_node_transform(trans, this);
_body->setWorldTransform(trans);
_body->setInterpolationWorldTransform(trans);
NodePath np = NodePath::any_path((PandaNode *)this);
CPT(TransformState) ts = np.get_net_transform();
BulletBodyNode::transform_changed();
}
LMatrix4f m_sync = _sync->get_mat();
LMatrix4f m_ts = ts->get_mat();
////////////////////////////////////////////////////////////////////
// Function: BulletRigidBodyNode::MotionState::getWorldTransform
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletRigidBodyNode::MotionState::
getWorldTransform(btTransform &trans) const {
if (!m_sync.almost_equal(m_ts)) {
_sync = ts;
get_node_transform(trans, _node);
}
btTransform trans = TransformState_to_btTrans(ts);
_rigid->setWorldTransform(trans);
_rigid->setInterpolationWorldTransform(trans);
////////////////////////////////////////////////////////////////////
// Function: BulletRigidBodyNode::MotionState::setWorldTransform
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletRigidBodyNode::MotionState::
setWorldTransform(const btTransform &trans) {
if (trans.getOrigin().getX() != trans.getOrigin().getX()) {
bullet_cat.error() << "setWorldTransform: trans is NAN!" << endl;
return;
if (ts->has_scale()) {
LVecBase3f scale = ts->get_scale();
for (int i=0; i<get_num_shapes(); i++) {
PT(BulletShape) shape = _shapes[i];
shape->set_local_scale(scale);
}
}
}
}
LVecBase3f scale = _node->get_transform()->get_scale();
////////////////////////////////////////////////////////////////////
// Function: BulletRigidBodyNode::sync_p2b
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletRigidBodyNode::
sync_p2b() {
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: BulletRigidBodyNode::sync_b2p
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletRigidBodyNode::
sync_b2p() {
NodePath np = NodePath::any_path((PandaNode *)this);
LVecBase3f scale = np.get_net_transform()->get_scale();
btTransform trans = _rigid->getWorldTransform();
CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
// Disable transform_changed callback
_node->_disable_transform_changed = true;
LMatrix4f m_sync = _sync->get_mat();
LMatrix4f m_ts = ts->get_mat();
if (_node->get_num_parents() == 0) {
_node->set_transform(ts);
if (!m_sync.almost_equal(m_ts)) {
_sync = ts;
_sync_disable = true;
np.set_transform(NodePath(), ts);
_sync_disable = false;
}
else {
NodePath np = NodePath::any_path(_node);
np.set_transform(np.get_top(), ts);
}
// Re-enable transform_changed callback again
_node->_disable_transform_changed = false;
}
////////////////////////////////////////////////////////////////////
@ -284,11 +285,10 @@ set_center_of_mass_pos(const LPoint3f &pos) {
nassertv_always(!pos.is_nan());
btTransform xform = btTransform::getIdentity();
xform.setIdentity();
xform.setOrigin(LVecBase3f_to_btVector3(pos));
btTransform trans = btTransform::getIdentity();
trans.setOrigin(LVecBase3f_to_btVector3(pos));
_body->setCenterOfMassTransform(xform);
_rigid->setCenterOfMassTransform(trans);
}
////////////////////////////////////////////////////////////////////
@ -299,7 +299,7 @@ set_center_of_mass_pos(const LPoint3f &pos) {
LPoint3f BulletRigidBodyNode::
get_center_of_mass_pos() const {
return btVector3_to_LPoint3f(_body->getCenterOfMassPosition());
return btVector3_to_LPoint3f(_rigid->getCenterOfMassPosition());
}
////////////////////////////////////////////////////////////////////
@ -310,7 +310,7 @@ get_center_of_mass_pos() const {
LVector3f BulletRigidBodyNode::
get_linear_velocity() const {
return btVector3_to_LVector3f(_body->getLinearVelocity());
return btVector3_to_LVector3f(_rigid->getLinearVelocity());
}
////////////////////////////////////////////////////////////////////
@ -321,7 +321,7 @@ get_linear_velocity() const {
LVector3f BulletRigidBodyNode::
get_angular_velocity() const {
return btVector3_to_LVector3f(_body->getAngularVelocity());
return btVector3_to_LVector3f(_rigid->getAngularVelocity());
}
////////////////////////////////////////////////////////////////////
@ -334,7 +334,7 @@ set_linear_velocity(const LVector3f &velocity) {
nassertv_always(!velocity.is_nan());
_body->setLinearVelocity(LVecBase3f_to_btVector3(velocity));
_rigid->setLinearVelocity(LVecBase3f_to_btVector3(velocity));
}
////////////////////////////////////////////////////////////////////
@ -347,7 +347,7 @@ set_angular_velocity(const LVector3f &velocity) {
nassertv_always(!velocity.is_nan());
_body->setAngularVelocity(LVecBase3f_to_btVector3(velocity));
_rigid->setAngularVelocity(LVecBase3f_to_btVector3(velocity));
}
////////////////////////////////////////////////////////////////////
@ -358,7 +358,7 @@ set_angular_velocity(const LVector3f &velocity) {
void BulletRigidBodyNode::
clear_forces() {
_body->clearForces();
_rigid->clearForces();
}
////////////////////////////////////////////////////////////////////
@ -369,7 +369,7 @@ clear_forces() {
float BulletRigidBodyNode::
get_linear_sleep_threshold() const {
return _body->getLinearSleepingThreshold();
return _rigid->getLinearSleepingThreshold();
}
////////////////////////////////////////////////////////////////////
@ -380,7 +380,7 @@ get_linear_sleep_threshold() const {
float BulletRigidBodyNode::
get_angular_sleep_threshold() const {
return _body->getAngularSleepingThreshold();
return _rigid->getAngularSleepingThreshold();
}
////////////////////////////////////////////////////////////////////
@ -391,7 +391,7 @@ get_angular_sleep_threshold() const {
void BulletRigidBodyNode::
set_linear_sleep_threshold(float threshold) {
_body->setSleepingThresholds(_body->getLinearSleepingThreshold(), threshold);
_rigid->setSleepingThresholds(_rigid->getLinearSleepingThreshold(), threshold);
}
////////////////////////////////////////////////////////////////////
@ -402,7 +402,7 @@ set_linear_sleep_threshold(float threshold) {
void BulletRigidBodyNode::
set_angular_sleep_threshold(float threshold) {
_body->setSleepingThresholds(threshold, _body->getAngularSleepingThreshold());
_rigid->setSleepingThresholds(threshold, _rigid->getAngularSleepingThreshold());
}
////////////////////////////////////////////////////////////////////
@ -415,7 +415,7 @@ set_gravity(const LVector3f &gravity) {
nassertv_always(!gravity.is_nan());
_body->setGravity(LVecBase3f_to_btVector3(gravity));
_rigid->setGravity(LVecBase3f_to_btVector3(gravity));
}
////////////////////////////////////////////////////////////////////
@ -426,7 +426,7 @@ set_gravity(const LVector3f &gravity) {
LVector3f BulletRigidBodyNode::
get_gravity() const {
return btVector3_to_LVector3f(_body->getGravity());
return btVector3_to_LVector3f(_rigid->getGravity());
}
////////////////////////////////////////////////////////////////////
@ -437,7 +437,7 @@ get_gravity() const {
void BulletRigidBodyNode::
set_linear_factor(const LVector3f &factor) {
_body->setLinearFactor(LVecBase3f_to_btVector3(factor));
_rigid->setLinearFactor(LVecBase3f_to_btVector3(factor));
}
////////////////////////////////////////////////////////////////////
@ -448,6 +448,6 @@ set_linear_factor(const LVector3f &factor) {
void BulletRigidBodyNode::
set_angular_factor(const LVector3f &factor) {
_body->setAngularFactor(LVecBase3f_to_btVector3(factor));
_rigid->setAngularFactor(LVecBase3f_to_btVector3(factor));
}

View File

@ -82,28 +82,19 @@ public:
virtual void output(ostream &out) const;
void sync_p2b();
void sync_b2p();
protected:
virtual void parents_changed();
virtual void transform_changed();
private:
virtual void shape_changed();
class MotionState : public btMotionState {
CPT(TransformState) _sync;
bool _sync_disable;
public:
MotionState(BulletRigidBodyNode *node) : _node(node) {};
~MotionState() {};
virtual void getWorldTransform(btTransform &trans) const;
virtual void setWorldTransform(const btTransform &trans);
private:
BulletRigidBodyNode *_node;
};
btRigidBody *_body;
MotionState *_motion;
btRigidBody *_rigid;
////////////////////////////////////////////////////////////////////
public:

View File

@ -21,7 +21,7 @@
INLINE BulletSoftBodyNode::
~BulletSoftBodyNode() {
delete _body;
delete _soft;
}
////////////////////////////////////////////////////////////////////

View File

@ -32,12 +32,16 @@ TypeHandle BulletSoftBodyNode::_type_handle;
BulletSoftBodyNode::
BulletSoftBodyNode(btSoftBody *body, const char *name) : BulletBodyNode(name) {
// Setup body
_body = body;
_body->setUserPointer(this);
// Synchronised transform
_sync = TransformState::make_identity();
_sync_disable = false;
// Softbody
_soft = body;
_soft->setUserPointer(this);
// Shape
btCollisionShape *shape_ptr = _body->getCollisionShape();
btCollisionShape *shape_ptr = _soft->getCollisionShape();
nassertv(shape_ptr != NULL);
nassertv(shape_ptr->getShapeType() == SOFTBODY_SHAPE_PROXYTYPE);
@ -58,7 +62,7 @@ BulletSoftBodyNode(btSoftBody *body, const char *name) : BulletBodyNode(name) {
btCollisionObject *BulletSoftBodyNode::
get_object() const {
return _body;
return _soft;
}
////////////////////////////////////////////////////////////////////
@ -69,7 +73,7 @@ get_object() const {
BulletSoftBodyConfig BulletSoftBodyNode::
get_cfg() {
return BulletSoftBodyConfig(_body->m_cfg);
return BulletSoftBodyConfig(_soft->m_cfg);
}
////////////////////////////////////////////////////////////////////
@ -80,7 +84,7 @@ get_cfg() {
BulletSoftBodyWorldInfo BulletSoftBodyNode::
get_world_info() {
return BulletSoftBodyWorldInfo(*(_body->m_worldInfo));
return BulletSoftBodyWorldInfo(*(_soft->m_worldInfo));
}
////////////////////////////////////////////////////////////////////
@ -91,7 +95,7 @@ get_world_info() {
int BulletSoftBodyNode::
get_num_materials() const {
return _body->m_materials.size();
return _soft->m_materials.size();
}
////////////////////////////////////////////////////////////////////
@ -104,7 +108,21 @@ get_material(int idx) const {
nassertr(idx >= 0 && idx < get_num_materials(), BulletSoftBodyMaterial::empty());
btSoftBody::Material *material = _body->m_materials[idx];
btSoftBody::Material *material = _soft->m_materials[idx];
return BulletSoftBodyMaterial(*material);
}
////////////////////////////////////////////////////////////////////
// Function: BulletSoftBodyNode::append_material
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
BulletSoftBodyMaterial BulletSoftBodyNode::
append_material() {
btSoftBody::Material *material = _soft->appendMaterial();
nassertr(material, BulletSoftBodyMaterial::empty());
return BulletSoftBodyMaterial(*material);
}
@ -116,7 +134,7 @@ get_material(int idx) const {
int BulletSoftBodyNode::
get_num_nodes() const {
return _body->m_nodes.size();
return _soft->m_nodes.size();
}
////////////////////////////////////////////////////////////////////
@ -128,21 +146,7 @@ BulletSoftBodyNodeElement BulletSoftBodyNode::
get_node(int idx) const {
nassertr(idx >=0 && idx < get_num_nodes(), BulletSoftBodyNodeElement::empty());
return BulletSoftBodyNodeElement(_body->m_nodes[idx]);
}
////////////////////////////////////////////////////////////////////
// Function: BulletSoftBodyNode::append_material
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
BulletSoftBodyMaterial BulletSoftBodyNode::
append_material() {
btSoftBody::Material *material = _body->appendMaterial();
nassertr(material, BulletSoftBodyMaterial::empty());
return BulletSoftBodyMaterial(*material);
return BulletSoftBodyNodeElement(_soft->m_nodes[idx]);
}
////////////////////////////////////////////////////////////////////
@ -154,10 +158,10 @@ void BulletSoftBodyNode::
generate_bending_constraints(int distance, BulletSoftBodyMaterial *material) {
if (material) {
_body->generateBendingConstraints(distance, &(material->get_material()));
_soft->generateBendingConstraints(distance, &(material->get_material()));
}
else {
_body->generateBendingConstraints(distance);
_soft->generateBendingConstraints(distance);
}
}
@ -169,18 +173,7 @@ generate_bending_constraints(int distance, BulletSoftBodyMaterial *material) {
void BulletSoftBodyNode::
randomize_constraints() {
_body->randomizeConstraints();
}
////////////////////////////////////////////////////////////////////
// Function: BulletSoftBodyNode::parents_changed
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void BulletSoftBodyNode::
parents_changed() {
transform_changed();
_soft->randomizeConstraints();
}
////////////////////////////////////////////////////////////////////
@ -191,24 +184,52 @@ parents_changed() {
void BulletSoftBodyNode::
transform_changed() {
if (_disable_transform_changed) return;
if (_sync_disable) return;
btTransform trans = btTransform::getIdentity();
get_node_transform(trans, this);
trans *= _body->m_initialWorldTransform.inverse();
_body->transform(trans);
NodePath np = NodePath::any_path((PandaNode *)this);
CPT(TransformState) ts = np.get_net_transform();
BulletBodyNode::transform_changed();
LMatrix4f m_sync = _sync->get_mat();
LMatrix4f m_ts = ts->get_mat();
if (!m_sync.almost_equal(m_ts)) {
_sync = ts;
btTransform trans = TransformState_to_btTrans(ts);
trans *= _soft->m_initialWorldTransform.inverse();
_soft->transform(trans);
if (ts->has_scale()) {
LVecBase3f scale = ts->get_scale();
for (int i=0; i<get_num_shapes(); i++) {
PT(BulletShape) shape = _shapes[i];
shape->set_local_scale(scale);
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: BulletSoftBodyNode::post_step
// Function: BulletSoftBodyNode::sync_p2b
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletSoftBodyNode::
post_step() {
sync_p2b() {
transform_changed();
}
////////////////////////////////////////////////////////////////////
// Function: BulletSoftBodyNode::sync_b2p
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletSoftBodyNode::
sync_b2p() {
// Render softbody
if (_geom) {
btTransform trans = btTransform::getIdentity();
get_node_transform(trans, this);
@ -221,7 +242,7 @@ post_step() {
GeomVertexReader flips(vdata, BulletHelper::get_sb_flip());
while (!vertices.is_at_end()) {
btSoftBody::Node node = _body->m_nodes[indices.get_data1i()];
btSoftBody::Node node = _soft->m_nodes[indices.get_data1i()];
btVector3 v = trans.invXform(node.m_x);
btVector3 n = node.m_n;
@ -233,7 +254,7 @@ post_step() {
}
if (_curve) {
btSoftBody::tNodeArray &nodes(_body->m_nodes);
btSoftBody::tNodeArray &nodes(_soft->m_nodes);
for (int i=0; i < nodes.size(); i++) {
btVector3 pos = nodes[i].m_x;
@ -242,7 +263,7 @@ post_step() {
}
if (_surface) {
btSoftBody::tNodeArray &nodes(_body->m_nodes);
btSoftBody::tNodeArray &nodes(_soft->m_nodes);
int num_u = _surface->get_num_u_vertices();
int num_v = _surface->get_num_v_vertices();
@ -260,11 +281,18 @@ post_step() {
// set_bounds does not store the pointer - it makes a copy using
// volume->make_copy().
BoundingBox bb = this->get_aabb();
CPT(TransformState) xform = TransformState::make_pos(bb.get_approx_center());
LVecBase3f pos = bb.get_approx_center();
_disable_transform_changed = true;
this->set_transform(xform);
_disable_transform_changed = false;
NodePath np = NodePath::any_path((PandaNode *)this);
LVecBase3f scale = np.get_net_transform()->get_scale();
CPT(TransformState) ts = TransformState::make_pos(pos);
ts = ts->set_scale(scale);
_sync = ts;
_sync_disable = true;
np.set_transform(NodePath(), ts);
_sync_disable = false;
Thread *current_thread = Thread::get_current_thread();
this->r_mark_geom_bounds_stale(current_thread);
@ -289,7 +317,7 @@ get_closest_node_index(LVecBase3f point, bool local) {
get_node_transform(trans, this);
}
btSoftBody::tNodeArray &nodes(_body->m_nodes);
btSoftBody::tNodeArray &nodes(_soft->m_nodes);
int node_idx = 0;
for (int i=0; i<nodes.size(); ++i) {
@ -317,6 +345,8 @@ link_geom(Geom *geom) {
nassertv(geom->get_vertex_data()->has_column(InternalName::get_vertex()));
nassertv(geom->get_vertex_data()->has_column(InternalName::get_normal()));
sync_p2b();
_geom = geom;
PT(GeomVertexData) vdata = _geom->modify_vertex_data();
@ -362,7 +392,7 @@ unlink_geom() {
void BulletSoftBodyNode::
link_curve(NurbsCurveEvaluator *curve) {
nassertv(curve->get_num_vertices() == _body->m_nodes.size());
nassertv(curve->get_num_vertices() == _soft->m_nodes.size());
_curve = curve;
}
@ -386,7 +416,7 @@ unlink_curve() {
void BulletSoftBodyNode::
link_surface(NurbsSurfaceEvaluator *surface) {
nassertv(surface->get_num_u_vertices() * surface->get_num_v_vertices() == _body->m_nodes.size());
nassertv(surface->get_num_u_vertices() * surface->get_num_v_vertices() == _soft->m_nodes.size());
_surface = surface;
}
@ -413,7 +443,7 @@ get_aabb() const {
btVector3 pMin;
btVector3 pMax;
_body->getAabb(pMin, pMax);
_soft->getAabb(pMin, pMax);
return BoundingBox(
btVector3_to_LPoint3f(pMin),
@ -429,7 +459,7 @@ get_aabb() const {
void BulletSoftBodyNode::
set_volume_mass(float mass) {
_body->setVolumeMass(mass);
_soft->setVolumeMass(mass);
}
////////////////////////////////////////////////////////////////////
@ -440,7 +470,7 @@ set_volume_mass(float mass) {
void BulletSoftBodyNode::
set_total_mass(float mass, bool fromfaces) {
_body->setTotalMass(mass, fromfaces);
_soft->setTotalMass(mass, fromfaces);
}
////////////////////////////////////////////////////////////////////
@ -451,7 +481,7 @@ set_total_mass(float mass, bool fromfaces) {
void BulletSoftBodyNode::
set_volume_density(float density) {
_body->setVolumeDensity(density);
_soft->setVolumeDensity(density);
}
////////////////////////////////////////////////////////////////////
@ -462,7 +492,7 @@ set_volume_density(float density) {
void BulletSoftBodyNode::
set_total_density(float density) {
_body->setTotalDensity(density);
_soft->setTotalDensity(density);
}
////////////////////////////////////////////////////////////////////
@ -473,7 +503,7 @@ set_total_density(float density) {
void BulletSoftBodyNode::
set_mass(int node, float mass) {
_body->setMass(node, mass);
_soft->setMass(node, mass);
}
////////////////////////////////////////////////////////////////////
@ -484,7 +514,7 @@ set_mass(int node, float mass) {
float BulletSoftBodyNode::
get_mass(int node) const {
return _body->getMass(node);
return _soft->getMass(node);
}
////////////////////////////////////////////////////////////////////
@ -495,7 +525,7 @@ get_mass(int node) const {
float BulletSoftBodyNode::
get_total_mass() const {
return _body->getTotalMass();
return _soft->getTotalMass();
}
////////////////////////////////////////////////////////////////////
@ -506,7 +536,7 @@ get_total_mass() const {
float BulletSoftBodyNode::
get_volume() const {
return _body->getVolume();
return _soft->getVolume();
}
////////////////////////////////////////////////////////////////////
@ -518,7 +548,7 @@ void BulletSoftBodyNode::
add_force(const LVector3f &force) {
nassertv(!force.is_nan());
_body->addForce(LVecBase3f_to_btVector3(force));
_soft->addForce(LVecBase3f_to_btVector3(force));
}
////////////////////////////////////////////////////////////////////
@ -530,7 +560,7 @@ void BulletSoftBodyNode::
add_force(const LVector3f &force, int node) {
nassertv(!force.is_nan());
_body->addForce(LVecBase3f_to_btVector3(force), node);
_soft->addForce(LVecBase3f_to_btVector3(force), node);
}
////////////////////////////////////////////////////////////////////
@ -542,7 +572,7 @@ void BulletSoftBodyNode::
set_velocity(const LVector3f &velocity) {
nassertv(!velocity.is_nan());
_body->setVelocity(LVecBase3f_to_btVector3(velocity));
_soft->setVelocity(LVecBase3f_to_btVector3(velocity));
}
////////////////////////////////////////////////////////////////////
@ -554,7 +584,7 @@ void BulletSoftBodyNode::
add_velocity(const LVector3f &velocity) {
nassertv(!velocity.is_nan());
_body->addVelocity(LVecBase3f_to_btVector3(velocity));
_soft->addVelocity(LVecBase3f_to_btVector3(velocity));
}
////////////////////////////////////////////////////////////////////
@ -566,7 +596,7 @@ void BulletSoftBodyNode::
add_velocity(const LVector3f &velocity, int node) {
nassertv(!velocity.is_nan());
_body->addVelocity(LVecBase3f_to_btVector3(velocity), node);
_soft->addVelocity(LVecBase3f_to_btVector3(velocity), node);
}
////////////////////////////////////////////////////////////////////
@ -577,7 +607,7 @@ add_velocity(const LVector3f &velocity, int node) {
void BulletSoftBodyNode::
generate_clusters(int k, int maxiterations) {
_body->generateClusters(k, maxiterations);
_soft->generateClusters(k, maxiterations);
}
////////////////////////////////////////////////////////////////////
@ -588,7 +618,7 @@ generate_clusters(int k, int maxiterations) {
void BulletSoftBodyNode::
release_clusters() {
_body->releaseClusters();
_soft->releaseClusters();
}
////////////////////////////////////////////////////////////////////
@ -599,7 +629,7 @@ release_clusters() {
void BulletSoftBodyNode::
release_cluster(int index) {
_body->releaseCluster(index);
_soft->releaseCluster(index);
}
////////////////////////////////////////////////////////////////////
@ -610,7 +640,7 @@ release_cluster(int index) {
int BulletSoftBodyNode::
get_num_clusters() const {
return _body->clusterCount();
return _soft->clusterCount();
}
////////////////////////////////////////////////////////////////////
@ -621,7 +651,7 @@ get_num_clusters() const {
LVecBase3f BulletSoftBodyNode::
cluster_com(int cluster) const {
return btVector3_to_LVecBase3f(_body->clusterCom(cluster));
return btVector3_to_LVecBase3f(_soft->clusterCom(cluster));
}
////////////////////////////////////////////////////////////////////
@ -632,7 +662,7 @@ cluster_com(int cluster) const {
void BulletSoftBodyNode::
set_pose(bool bvolume, bool bframe) {
_body->setPose(bvolume, bframe);
_soft->setPose(bvolume, bframe);
}
////////////////////////////////////////////////////////////////////
@ -643,11 +673,13 @@ set_pose(bool bvolume, bool bframe) {
void BulletSoftBodyNode::
append_anchor(int node, BulletRigidBodyNode *body, bool disable) {
nassertv(node < _body->m_nodes.size())
nassertv(node < _soft->m_nodes.size())
nassertv(body);
body->sync_p2b();
btRigidBody *ptr =(btRigidBody *)body->get_object();
_body->appendAnchor(node, ptr, disable);
_soft->appendAnchor(node, ptr, disable);
}
////////////////////////////////////////////////////////////////////
@ -658,12 +690,14 @@ append_anchor(int node, BulletRigidBodyNode *body, bool disable) {
void BulletSoftBodyNode::
append_anchor(int node, BulletRigidBodyNode *body, const LVector3f &pivot, bool disable) {
nassertv(node < _body->m_nodes.size())
nassertv(node < _soft->m_nodes.size())
nassertv(body);
nassertv(!pivot.is_nan());
body->sync_p2b();
btRigidBody *ptr =(btRigidBody *)body->get_object();
_body->appendAnchor(node, ptr, LVecBase3f_to_btVector3(pivot), disable);
_soft->appendAnchor(node, ptr, LVecBase3f_to_btVector3(pivot), disable);
}
////////////////////////////////////////////////////////////////////

View File

@ -188,14 +188,17 @@ PUBLISHED:
public:
virtual btCollisionObject *get_object() const;
void post_step();
void sync_p2b();
void sync_b2p();
protected:
virtual void parents_changed();
virtual void transform_changed();
private:
btSoftBody *_body;
btSoftBody *_soft;
CPT(TransformState) _sync;
bool _sync_disable;
PT(Geom) _geom;
PT(NurbsCurveEvaluator) _curve;

View File

@ -218,12 +218,12 @@ get_wheel(int idx) const {
}
////////////////////////////////////////////////////////////////////
// Function: BulletVehicle::post_step
// Function: BulletVehicle::sync_b2p
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void BulletVehicle::
post_step() {
sync_b2p() {
for (int i=0; i < get_num_wheels(); i++) {
btWheelInfo info = _vehicle->getWheelInfo(i);

View File

@ -91,7 +91,7 @@ PUBLISHED:
public:
INLINE btRaycastVehicle *get_vehicle() const;
void post_step();
void sync_b2p();
private:
btRaycastVehicle *_vehicle;

View File

@ -24,7 +24,8 @@ TypeHandle BulletWorld::_type_handle;
PStatCollector BulletWorld::_pstat_physics("App:Bullet:DoPhysics");
PStatCollector BulletWorld::_pstat_simulation("App:Bullet:DoPhysics:Simulation");
PStatCollector BulletWorld::_pstat_debug("App:Bullet:DoPhysics:Debug");
PStatCollector BulletWorld::_pstat_sb("App:Bullet:DoPhysics:SoftBodies");
PStatCollector BulletWorld::_pstat_p2b("App:Bullet:DoPhysics:SyncP2B");
PStatCollector BulletWorld::_pstat_b2p("App:Bullet:DoPhysics:SyncB2P");
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::Constructor
@ -140,49 +141,86 @@ do_physics(float dt, int substeps, float stepsize) {
_pstat_physics.start();
// Preprocess characters
for (int i=0; i < get_num_characters(); i++) {
get_character(i)->pre_step(dt);
}
// Preprocess ghosts (autosync)
for (int i=0; i < get_num_ghosts(); i++) {
get_ghost(i)->pre_step();
}
// Synchronize Panda to Bullet
_pstat_p2b.start();
sync_p2b(dt);
_pstat_p2b.stop();
// Simulation
_pstat_simulation.start();
_world->stepSimulation(dt, substeps, stepsize);
_pstat_simulation.stop();
// Postprocess characters
for (int i=0; i < get_num_characters(); i++) {
get_character(i)->post_step();
}
// Postprocess vehicles
for (int i=0; i < get_num_vehicles(); i++) {
get_vehicle(i)->post_step();
}
// Synchronize Bullet to Panda
_pstat_b2p.start();
sync_b2p();
_info.m_sparsesdf.GarbageCollect(bullet_gc_lifetime);
_pstat_b2p.stop();
// Render debug
_pstat_debug.start();
if (_debug) {
_debug->post_step(_world);
_pstat_debug.start();
_debug->sync_b2p(_world);
_pstat_debug.stop();
}
_pstat_debug.stop();
// Render soft bodies
_pstat_sb.start();
for (int i=0; i < get_num_soft_bodies(); i++) {
get_soft_body(i)->post_step();
}
_info.m_sparsesdf.GarbageCollect(bullet_gc_lifetime);
_pstat_sb.stop();
_pstat_physics.stop();
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::sync_p2b
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void BulletWorld::
sync_p2b(float dt) {
for (int i=0; i < get_num_rigid_bodies(); i++) {
get_rigid_body(i)->sync_p2b();
}
for (int i=0; i < get_num_soft_bodies(); i++) {
get_soft_body(i)->sync_p2b();
}
for (int i=0; i < get_num_ghosts(); i++) {
get_ghost(i)->sync_p2b();
}
for (int i=0; i < get_num_characters(); i++) {
get_character(i)->sync_p2b(dt);
}
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::sync_b2p
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void BulletWorld::
sync_b2p() {
for (int i=0; i < get_num_vehicles(); i++) {
get_vehicle(i)->sync_b2p();
}
for (int i=0; i < get_num_rigid_bodies(); i++) {
get_rigid_body(i)->sync_b2p();
}
for (int i=0; i < get_num_soft_bodies(); i++) {
get_soft_body(i)->sync_b2p();
}
for (int i=0; i < get_num_ghosts(); i++) {
get_ghost(i)->sync_b2p();
}
for (int i=0; i < get_num_characters(); i++) {
get_character(i)->sync_b2p();
}
}
////////////////////////////////////////////////////////////////////
// Function: BulletWorld::set_debug_node
// Access: Published
@ -325,7 +363,7 @@ attach_ghost(BulletGhostNode *node) {
// TODO group/filter settings...
/*
enum CollisionFilterGroups {
enum CollisionFilterGroups {
DefaultFilter = 1,
StaticFilter = 2,
KinematicFilter = 4,

View File

@ -151,6 +151,9 @@ public:
INLINE btDispatcher *get_dispatcher() const;
private:
void sync_p2b(float dt);
void sync_b2p();
typedef PTA(PT(BulletRigidBodyNode)) BulletRigidBodies;
typedef PTA(PT(BulletSoftBodyNode)) BulletSoftBodies;
typedef PTA(PT(BulletGhostNode)) BulletGhosts;
@ -161,7 +164,8 @@ private:
static PStatCollector _pstat_physics;
static PStatCollector _pstat_simulation;
static PStatCollector _pstat_debug;
static PStatCollector _pstat_sb;
static PStatCollector _pstat_p2b;
static PStatCollector _pstat_b2p;
struct btFilterCallback : public btOverlapFilterCallback {
virtual bool needBroadphaseCollision(