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  * Do not call the copy constructor directly; instead, use make_copy() or
46  * copy_subgraph() to make a copy of a node.
47  */
48 BulletGhostNode::
49 BulletGhostNode(const BulletGhostNode &copy) :
50  BulletBodyNode(copy),
51  _sync(TransformState::make_identity()),
52  _sync_disable(false),
53  _sync_local(false)
54 {
55  // Initial transform - the node has no parent yet, so this is the local one
56  btTransform trans = TransformState_to_btTrans(get_transform());
57 
58  // Ghost object
59  _ghost = new btPairCachingGhostObject();
60  _ghost->setUserPointer(this);
61  _ghost->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
62  _ghost->setWorldTransform(trans);
63  _ghost->setInterpolationWorldTransform(trans);
64  _ghost->setCollisionShape(_shape);
65 }
66 
67 /**
68  * Returns a newly-allocated PandaNode that is a shallow copy of this one. It
69  * will be a different pointer, but its internal data may or may not be shared
70  * with that of the original PandaNode. No children will be copied.
71  */
73 make_copy() const {
74  return new BulletGhostNode(*this);
75 }
76 
77 /**
78  *
79  */
80 btCollisionObject *BulletGhostNode::
81 get_object() const {
82 
83  return _ghost;
84 }
85 
86 /**
87  *
88  */
89 void BulletGhostNode::
90 parents_changed() {
91  LightMutexHolder holder(BulletWorld::get_global_lock());
92 
93  Parents parents = get_parents();
94  for (size_t i = 0; i < parents.get_num_parents(); ++i) {
95  PandaNode *parent = parents.get_parent(i);
96  TypeHandle type = parent->get_type();
97 
98  if (BulletRigidBodyNode::get_class_type() == type ||
99  BulletSoftBodyNode::get_class_type() == type ||
100  BulletGhostNode::get_class_type() == type ||
101  type.is_derived_from(BulletBaseCharacterControllerNode::get_class_type())) {
102 
103  _sync_local = true;
104  return;
105  }
106  }
107 
108  _sync_local = false;
109 }
110 
111 /**
112  * Assumes the lock(bullet global lock) is held by the caller
113  */
114 void BulletGhostNode::
115 do_transform_changed() {
116 
117  if (_sync_disable) return;
118 
119  NodePath np = NodePath::any_path((PandaNode *)this);
120  CPT(TransformState) ts = np.get_net_transform();
121 
122  LMatrix4 m_sync = _sync->get_mat();
123  LMatrix4 m_ts = ts->get_mat();
124 
125  if (!m_sync.almost_equal(m_ts)) {
126  _sync = ts;
127 
128  btTransform trans = TransformState_to_btTrans(ts);
129  _ghost->setWorldTransform(trans);
130  _ghost->setInterpolationWorldTransform(trans);
131 
132  if (ts->has_scale()) {
133  LVecBase3 scale = ts->get_scale();
134  if (!scale.almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
135  for (BulletShape *shape : _shapes) {
136  shape->do_set_local_scale(scale);
137  }
138  }
139  }
140  }
141 }
142 
143 void BulletGhostNode::
144 transform_changed() {
145 
146  if (_sync_disable) return;
147 
148  LightMutexHolder holder(BulletWorld::get_global_lock());
149 
150  do_transform_changed();
151 }
152 
153 /**
154  *
155  */
156 int BulletGhostNode::
157 get_num_overlapping_nodes() const {
158  LightMutexHolder holder(BulletWorld::get_global_lock());
159 
160  return _ghost->getNumOverlappingObjects();
161 }
162 
163 /**
164  *
165  */
166 PandaNode *BulletGhostNode::
167 get_overlapping_node(int idx) const {
168  LightMutexHolder holder(BulletWorld::get_global_lock());
169 
170  nassertr(idx >=0 && idx < _ghost->getNumOverlappingObjects(), nullptr);
171 
172  btCollisionObject *object = _ghost->getOverlappingObject(idx);
173  return (object) ? (PandaNode *)object->getUserPointer() : nullptr;
174 }
175 
176 /**
177  * Assumes the lock(bullet global lock) is held by the caller
178  */
180 do_sync_p2b() {
181 
182  do_transform_changed();
183 }
184 
185 /**
186  * Assumes the lock(bullet global lock) is held by the caller
187  */
189 do_sync_b2p() {
190 
191  NodePath np = NodePath::any_path((PandaNode *)this);
192  LVecBase3 scale = np.get_net_transform()->get_scale();
193 
194  btTransform trans = _ghost->getWorldTransform();
195  CPT(TransformState) ts = btTrans_to_TransformState(trans, scale);
196 
197  LMatrix4 m_sync = _sync->get_mat();
198  LMatrix4 m_ts = ts->get_mat();
199 
200  if (!m_sync.almost_equal(m_ts)) {
201  _sync = ts;
202  _sync_disable = true;
203  np.set_transform(NodePath(), ts);
204  _sync_disable = false;
205  }
206 }
207 
208 /**
209  * Tells the BamReader how to create objects of type BulletGhostNode.
210  */
213  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
214 }
215 
216 /**
217  * This function is called by the BamReader's factory when a new object of
218  * this type is encountered in the Bam file. It should create the ghost node.
219  */
220 TypedWritable *BulletGhostNode::
221 make_from_bam(const FactoryParams &params) {
222  BulletGhostNode *param = new BulletGhostNode;
223  DatagramIterator scan;
224  BamReader *manager;
225 
226  parse_params(params, scan, manager);
227  param->fillin(scan, manager);
228 
229  return param;
230 }
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
void do_sync_p2b()
Assumes the lock(bullet global lock) is held by the caller.
virtual PandaNode * make_copy() const
Returns a newly-allocated PandaNode that is a shallow copy of this one.
void do_sync_b2p()
Assumes the lock(bullet global lock) is held by the caller.
static void register_with_read_factory()
Tells the BamReader how to create objects of type BulletGhostNode.
A class to retrieve the individual data elements previously stored in a Datagram.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
Similar to MutexHolder, but for a light mutex.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
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
LVecBase3 get_scale() const
Retrieves the scale component of the transform.
Definition: nodePath.cxx:1195
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
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
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
get_parents
Returns an object that can be used to walk through the list of parents of the node,...
Definition: pandaNode.h:784
get_parent
Returns the nth parent node of this node.
Definition: pandaNode.h:118
Indicates a coordinate-system transform on vertices.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
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
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35