Panda3D
bulletGhostNode.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file bulletGhostNode.cxx
10  * @author enn0x
11  * @date 2010-11-19
12  */
13 
14 #include "bulletGhostNode.h"
15 
16 #include "bulletShape.h"
17 #include "bulletWorld.h"
18 
19 TypeHandle BulletGhostNode::_type_handle;
20 
21 /**
22  *
23  */
24 BulletGhostNode::
25 BulletGhostNode(const char *name) : BulletBodyNode(name) {
26 
27  // Synchronised transform
28  _sync = TransformState::make_identity();
29  _sync_disable = false;
30  _sync_local = false;
31 
32  // Initial transform
33  btTransform trans = btTransform::getIdentity();
34 
35  // Ghost object
36  _ghost = new btPairCachingGhostObject();
37  _ghost->setUserPointer(this);
38  _ghost->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
39  _ghost->setWorldTransform(trans);
40  _ghost->setInterpolationWorldTransform(trans);
41  _ghost->setCollisionShape(_shape);
42 }
43 
44 /**
45  *
46  */
47 btCollisionObject *BulletGhostNode::
48 get_object() const {
49 
50  return _ghost;
51 }
52 
53 /**
54  *
55  */
56 void BulletGhostNode::
57 parents_changed() {
58  LightMutexHolder holder(BulletWorld::get_global_lock());
59 
60  Parents parents = get_parents();
61  for (size_t i = 0; i < parents.get_num_parents(); ++i) {
62  PandaNode *parent = parents.get_parent(i);
63  TypeHandle type = parent->get_type();
64 
65  if (BulletRigidBodyNode::get_class_type() == type ||
66  BulletSoftBodyNode::get_class_type() == type ||
67  BulletGhostNode::get_class_type() == type ||
68  type.is_derived_from(BulletBaseCharacterControllerNode::get_class_type())) {
69 
70  _sync_local = true;
71  return;
72  }
73  }
74 
75  _sync_local = false;
76 }
77 
78 /**
79  * Assumes the lock(bullet global lock) is held by the caller
80  */
81 void BulletGhostNode::
82 do_transform_changed() {
83 
84  if (_sync_disable) return;
85 
87  CPT(TransformState) ts = np.get_net_transform();
88 
89  LMatrix4 m_sync = _sync->get_mat();
90  LMatrix4 m_ts = ts->get_mat();
91 
92  if (!m_sync.almost_equal(m_ts)) {
93  _sync = ts;
94 
95  btTransform trans = TransformState_to_btTrans(ts);
96  _ghost->setWorldTransform(trans);
97  _ghost->setInterpolationWorldTransform(trans);
98 
99  if (ts->has_scale()) {
100  LVecBase3 scale = ts->get_scale();
101  if (!scale.almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
102  for (BulletShape *shape : _shapes) {
103  shape->do_set_local_scale(scale);
104  }
105  }
106  }
107  }
108 }
109 
110 void BulletGhostNode::
111 transform_changed() {
112 
113  if (_sync_disable) return;
114 
115  LightMutexHolder holder(BulletWorld::get_global_lock());
116 
117  do_transform_changed();
118 }
119 
120 /**
121  *
122  */
123 int BulletGhostNode::
124 get_num_overlapping_nodes() const {
125  LightMutexHolder holder(BulletWorld::get_global_lock());
126 
127  return _ghost->getNumOverlappingObjects();
128 }
129 
130 /**
131  *
132  */
133 PandaNode *BulletGhostNode::
134 get_overlapping_node(int idx) const {
135  LightMutexHolder holder(BulletWorld::get_global_lock());
136 
137  nassertr(idx >=0 && idx < _ghost->getNumOverlappingObjects(), nullptr);
138 
139  btCollisionObject *object = _ghost->getOverlappingObject(idx);
140  return (object) ? (PandaNode *)object->getUserPointer() : nullptr;
141 }
142 
143 /**
144  * Assumes the lock(bullet global lock) is held by the caller
145  */
148 
149  do_transform_changed();
150 }
151 
152 /**
153  * Assumes the lock(bullet global lock) is held by the caller
154  */
157 
158  NodePath np = NodePath::any_path((PandaNode *)this);
159  LVecBase3 scale = np.get_net_transform()->get_scale();
160 
161  btTransform trans = _ghost->getWorldTransform();
162  CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
163 
164  LMatrix4 m_sync = _sync->get_mat();
165  LMatrix4 m_ts = ts->get_mat();
166 
167  if (!m_sync.almost_equal(m_ts)) {
168  _sync = ts;
169  _sync_disable = true;
170  np.set_transform(NodePath(), ts);
171  _sync_disable = false;
172  }
173 }
void do_sync_p2b()
Assumes the lock(bullet global lock) is held by the caller.
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Indicates a coordinate-system transform on vertices.
void do_sync_b2p()
Assumes the lock(bullet global lock) is held by the caller.
bool is_derived_from(TypeHandle parent, TypedObject *object=nullptr) const
Returns true if this type is derived from the indicated type, false otherwise.
Definition: typeHandle.I:105
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Changes the complete transform object on this node.
Definition: nodePath.I:565
get_parents
Returns an object that can be used to walk through the list of parents of the node,...
Definition: pandaNode.h:786
static NodePath any_path(PandaNode *node, Thread *current_thread=Thread::get_current_thread())
Returns a new NodePath that represents any arbitrary path from the root to the indicated node.
Definition: nodePath.I:62
Similar to MutexHolder, but for a light mutex.
get_parent
Returns the nth parent node of this node.
Definition: pandaNode.h:118
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
LVecBase3 get_scale() const
Retrieves the scale component of the transform.
Definition: nodePath.cxx:1128
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const LMatrix4 & get_mat() const
Returns the transform matrix that has been applied to the referenced node, or the identity matrix if ...
Definition: nodePath.I:776
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161