00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "bulletGhostNode.h"
00016 #include "bulletShape.h"
00017
00018 TypeHandle BulletGhostNode::_type_handle;
00019
00020
00021
00022
00023
00024
00025 BulletGhostNode::
00026 BulletGhostNode(const char *name) : BulletBodyNode(name) {
00027
00028
00029 _sync = TransformState::make_identity();
00030 _sync_disable = false;
00031 _sync_local = false;
00032
00033
00034 btTransform trans = btTransform::getIdentity();
00035
00036
00037 _ghost = new btPairCachingGhostObject();
00038 _ghost->setUserPointer(this);
00039 _ghost->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
00040 _ghost->setWorldTransform(trans);
00041 _ghost->setInterpolationWorldTransform(trans);
00042 _ghost->setCollisionShape(_shape);
00043 }
00044
00045
00046
00047
00048
00049
00050 btCollisionObject *BulletGhostNode::
00051 get_object() const {
00052
00053 return _ghost;
00054 }
00055
00056
00057
00058
00059
00060
00061 void BulletGhostNode::
00062 parents_changed() {
00063
00064 Parents parents = get_parents();
00065 for (int i=0; i < parents.get_num_parents(); ++i) {
00066 PandaNode *parent = parents.get_parent(i);
00067 TypeHandle type = parent->get_type();
00068
00069 if (BulletRigidBodyNode::get_class_type() == type ||
00070 BulletSoftBodyNode::get_class_type() == type ||
00071 BulletGhostNode::get_class_type() == type ||
00072 type.is_derived_from(BulletBaseCharacterControllerNode::get_class_type())) {
00073
00074 _sync_local = true;
00075 return;
00076 }
00077 }
00078
00079 _sync_local = false;
00080 }
00081
00082
00083
00084
00085
00086
00087 void BulletGhostNode::
00088 transform_changed() {
00089
00090 if (_sync_disable) return;
00091
00092 NodePath np = NodePath::any_path((PandaNode *)this);
00093 CPT(TransformState) ts = np.get_net_transform();
00094
00095 LMatrix4 m_sync = _sync->get_mat();
00096 LMatrix4 m_ts = ts->get_mat();
00097
00098 if (!m_sync.almost_equal(m_ts)) {
00099 _sync = ts;
00100
00101 btTransform trans = TransformState_to_btTrans(ts);
00102 _ghost->setWorldTransform(trans);
00103 _ghost->setInterpolationWorldTransform(trans);
00104
00105 if (ts->has_scale()) {
00106 LVecBase3 scale = ts->get_scale();
00107 if (!scale.almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
00108 for (int i=0; i<get_num_shapes(); i++) {
00109 PT(BulletShape) shape = _shapes[i];
00110 shape->set_local_scale(scale);
00111 }
00112 }
00113 }
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122 void BulletGhostNode::
00123 sync_p2b() {
00124
00125 transform_changed();
00126 }
00127
00128
00129
00130
00131
00132
00133 void BulletGhostNode::
00134 sync_b2p() {
00135
00136 NodePath np = NodePath::any_path((PandaNode *)this);
00137 LVecBase3 scale = np.get_net_transform()->get_scale();
00138
00139 btTransform trans = _ghost->getWorldTransform();
00140 CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
00141
00142 LMatrix4 m_sync = _sync->get_mat();
00143 LMatrix4 m_ts = ts->get_mat();
00144
00145 if (!m_sync.almost_equal(m_ts)) {
00146 _sync = ts;
00147 _sync_disable = true;
00148 np.set_transform(NodePath(), ts);
00149 _sync_disable = false;
00150 }
00151 }
00152