Panda3D
physicsManager.cxx
1 // Filename: physicsManager.cxx
2 // Created by: charles (14Jun00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "physicsManager.h"
16 #include "actorNode.h"
17 
18 #include <algorithm>
19 #include "pvector.h"
20 
21 ConfigVariableInt PhysicsManager::_random_seed
22 ("physics_manager_random_seed", 139);
23 
24 ////////////////////////////////////////////////////////////////////
25 // Function : PhysicsManager
26 // Access : Public
27 // Description : Default Constructor. NOTE: EulerIntegrator is
28 // the standard default.
29 ////////////////////////////////////////////////////////////////////
32  _linear_integrator.clear();
33  _angular_integrator.clear();
34  _viscosity=0.0;
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function : ~PhysicsManager
39 // Access : Public
40 // Description : Simple Destructor
41 ////////////////////////////////////////////////////////////////////
44  PhysicalsVector::iterator pi;
45  for (pi = _physicals.begin(); pi != _physicals.end(); ++pi) {
46  nassertv((*pi)->_physics_manager == this);
47  (*pi)->_physics_manager = NULL;
48  }
49 }
50 
51 ////////////////////////////////////////////////////////////////////
52 // Function : InitRandomSeed
53 // Access : Public
54 // Description : One-time config function, sets up the random seed
55 // used by the physics and particle systems.
56 // For synchronizing across distributed computers
57 ////////////////////////////////////////////////////////////////////
60  // Use the random seed specified by the physics_manager_random_seed
61  // Config Variable
62  srand(_random_seed);
63 }
64 
65 ////////////////////////////////////////////////////////////////////
66 // Function : remove_linear_force
67 // Access : Public
68 // Description : takes a linear force out of the physics list
69 ////////////////////////////////////////////////////////////////////
72  nassertv(f);
73  LinearForceVector::iterator found;
74 
75  PT(LinearForce) ptbf = f;
76  found = find(_linear_forces.begin(), _linear_forces.end(), ptbf);
77 
78  if (found == _linear_forces.end()) {
79  return;
80  }
81  _linear_forces.erase(found);
82 }
83 
84 ////////////////////////////////////////////////////////////////////
85 // Function : remove_angular_force
86 // Access : Public
87 // Description : takes an angular force out of the physics list
88 ////////////////////////////////////////////////////////////////////
91  nassertv(f);
92  AngularForceVector::iterator found;
93 
94  PT(BaseForce) ptbf = f;
95  found = find(_angular_forces.begin(), _angular_forces.end(), ptbf);
96 
97  if (found == _angular_forces.end()) {
98  return;
99  }
100  _angular_forces.erase(found);
101 }
102 
103 ////////////////////////////////////////////////////////////////////
104 // Function : remove_physical
105 // Access : Public
106 // Description : takes a physical out of the object list
107 ////////////////////////////////////////////////////////////////////
108 void PhysicsManager::
110  nassertv(p);
112 
113  found = find(_physicals.begin(), _physicals.end(), p);
114  if (found == _physicals.end()) {
115  return;
116  }
117  nassertv(p->_physics_manager == this);
118  p->_physics_manager = (PhysicsManager *) NULL;
119  _physicals.erase(found);
120 }
121 
122 ////////////////////////////////////////////////////////////////////
123 // Function : remove_physical_node
124 // Access : Public
125 // Description : Removes a physicalnode from the manager
126 ////////////////////////////////////////////////////////////////////
127 void PhysicsManager::
129  nassertv(p);
130  for (int i = 0; i < p->get_num_physicals(); ++i) {
131  remove_physical(p->get_physical(i));
132  }
133 }
134 
135 ////////////////////////////////////////////////////////////////////
136 // Function : DoPhysics
137 // Access : Public
138 // Description : This is the main high-level API call. Performs
139 // integration on every attached Physical.
140 ////////////////////////////////////////////////////////////////////
141 void PhysicsManager::
142 do_physics(PN_stdfloat dt) {
143  // now, run through each physics object in the set.
144  PhysicalsVector::iterator p_cur = _physicals.begin();
145  for (; p_cur != _physicals.end(); ++p_cur) {
146  Physical *physical = *p_cur;
147  nassertv(physical);
148 
149  // do linear
150  //if (_linear_integrator.is_null() == false) {
151  if (_linear_integrator) {
152  _linear_integrator->integrate(physical, _linear_forces, dt);
153  }
154 
155  // do angular
156  //if (_angular_integrator.is_null() == false) {
157  if (_angular_integrator) {
158  _angular_integrator->integrate(physical, _angular_forces, dt);
159  }
160 
161  // if it's an actor node, tell it to update itself.
162  PhysicalNode *pn = physical->get_physical_node();
163  if (pn && pn->is_of_type(ActorNode::get_class_type())) {
164  ActorNode *an = (ActorNode *) pn;
165  an->update_transform();
166  }
167  }
168 }
169 
170 ////////////////////////////////////////////////////////////////////
171 // Function : DoPhysics
172 // Access : Public
173 // Description : This is the main high-level API call. Performs
174 // integration on a single physical. Make sure its
175 // associated forces are active.
176 ////////////////////////////////////////////////////////////////////
177 void PhysicsManager::
178 do_physics(PN_stdfloat dt, Physical *physical) {
179  nassertv(physical);
180 
181  // do linear
182  //if (_linear_integrator.is_null() == false) {
183  if (_linear_integrator) {
184  _linear_integrator->integrate(physical, _linear_forces, dt);
185  }
186 
187  // do angular
188  //if (_angular_integrator.is_null() == false) {
189  if (_angular_integrator) {
190  _angular_integrator->integrate(physical, _angular_forces, dt);
191  }
192 
193  // if it's an actor node, tell it to update itself.
194  PhysicalNode *pn = physical->get_physical_node();
195  if (pn && pn->is_of_type(ActorNode::get_class_type())) {
196  ActorNode *an = (ActorNode *) pn;
197  an->update_transform();
198  }
199 }
200 
201 ////////////////////////////////////////////////////////////////////
202 // Function : output
203 // Access : Public
204 // Description : Write a string representation of this instance to
205 // <out>.
206 ////////////////////////////////////////////////////////////////////
207 void PhysicsManager::
208 output(ostream &out) const {
209  #ifndef NDEBUG //[
210  out<<""<<"PhysicsManager";
211  #endif //] NDEBUG
212 }
213 
214 ////////////////////////////////////////////////////////////////////
215 // Function : write_physicals
216 // Access : Public
217 // Description : Write a string representation of this instance to
218 // <out>.
219 ////////////////////////////////////////////////////////////////////
220 void PhysicsManager::
221 write_physicals(ostream &out, unsigned int indent) const {
222  #ifndef NDEBUG //[
223  if (indent>10) {
224  return;
225  }
226  out.width(indent);
227  out<<""<<"_physicals ("<<_physicals.size()<<" physicals)\n";
228  //out<<ios::width(indent)<<" "<<"[physicals \n";
229  for (pvector< Physical * >::const_iterator i=_physicals.begin();
230  i != _physicals.end();
231  ++i) {
232  (*i)->write(out, indent+2);
233  }
234  #endif //] NDEBUG
235 }
236 
237 ////////////////////////////////////////////////////////////////////
238 // Function : write_forces
239 // Access : Public
240 // Description : Write a string representation of this instance to
241 // <out>.
242 ////////////////////////////////////////////////////////////////////
243 void PhysicsManager::
244 write_linear_forces(ostream &out, unsigned int indent) const {
245  #ifndef NDEBUG //[
246  out.width(indent);
247  out<<""<<"_linear_forces ("<<_linear_forces.size()<<" forces)\n";
248  for (LinearForceVector::const_iterator i=_linear_forces.begin();
249  i != _linear_forces.end();
250  ++i) {
251  (*i)->write(out, indent+2);
252  }
253  #endif //] NDEBUG
254 }
255 
256 ////////////////////////////////////////////////////////////////////
257 // Function : write_angular_forces
258 // Access : Public
259 // Description : Write a string representation of this instance to
260 // <out>.
261 ////////////////////////////////////////////////////////////////////
262 void PhysicsManager::
263 write_angular_forces(ostream &out, unsigned int indent) const {
264  #ifndef NDEBUG //[
265  out.width(indent);
266  out<<""<<"_angular_forces ("<<_angular_forces.size()<<" forces)\n";
267  for (AngularForceVector::const_iterator i=_angular_forces.begin();
268  i != _angular_forces.end();
269  ++i) {
270  (*i)->write(out, indent+2);
271  }
272  #endif //] NDEBUG
273 }
274 
275 ////////////////////////////////////////////////////////////////////
276 // Function : write
277 // Access : Public
278 // Description : Write a string representation of this instance to
279 // <out>.
280 ////////////////////////////////////////////////////////////////////
281 void PhysicsManager::
282 write(ostream &out, unsigned int indent) const {
283  #ifndef NDEBUG //[
284  out.width(indent); out<<""<<"PhysicsManager:\n";
285  if (indent>20) {
286  // ...indent limit is arbitrary, it limits recursion.
287  out.width(indent+2); out<<""<<"...\n";
288  return;
289  }
290  write_physicals(out, indent+2);
291  write_linear_forces(out, indent+2);
292  write_angular_forces(out, indent+2);
293  out.width(indent+2); out<<""<<"_linear_integrator:\n";
294  if (_linear_integrator) {
295  _linear_integrator->write(out, indent+4);
296  } else {
297  out.width(indent+4); out<<""<<"null\n";
298  }
299  out.width(indent+2); out<<""<<"_angular_integrator:\n";
300  if (_angular_integrator) {
301  _angular_integrator->write(out, indent+4);
302  } else {
303  out.width(indent+4); out<<""<<"null\n";
304  }
305  #endif //] NDEBUG
306 }
307 
308 ////////////////////////////////////////////////////////////////////
309 // Function : write
310 // Access : Public
311 // Description : Write a string representation of this instance to
312 // <out>.
313 ////////////////////////////////////////////////////////////////////
314 void PhysicsManager::
315 debug_output(ostream &out, unsigned int indent) const {
316  #ifndef NDEBUG //[
317  out.width(indent); out<<""<<"PhysicsManager li"<<(_linear_integrator?1:0)<<" ai"<<(_angular_integrator?1:0)<<"\n";
318  out<<" _physicals "<<_physicals.size()<<"\n";
319  //_physicals._phys_body.write(out, indent+2);
320 
321 
322  out.width(indent+2);
323  out<<""<<"_linear_forces ("<<_linear_forces.size()<<" forces)\n";
324  LinearForceVector::const_iterator li;
325  for (li=_linear_forces.begin();
326  li != _linear_forces.end();
327  ++li) {
328  (*li)->write(out, indent+2);
329  }
330 
331  out.width(indent+2);
332  out<<""<<" _angular_forces "<<_angular_forces.size()<<"\n";
333  AngularForceVector::const_iterator ai;
334  for (ai=_angular_forces.begin();
335  ai != _angular_forces.end();
336  ++ai) {
337  (*ai)->write(out, indent+2);
338  }
339  #endif //] NDEBUG
340 }
PhysicsManager()
Default Constructor.
void init_random_seed()
One-time config function, sets up the random seed used by the physics and particle systems...
void remove_physical(Physical *p)
takes a physical out of the object list
virtual void write_angular_forces(ostream &out, unsigned int indent=0) const
Write a string representation of this instance to <out>.
void update_transform()
this sets the transform generated by the contained Physical, moving the node and subsequent geometry...
Definition: actorNode.cxx:73
A force that acts on a PhysicsObject by way of an Integrator.
Definition: linearForce.h:25
pure virtual base class for all forces that could POSSIBLY exist.
Definition: baseForce.h:32
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
Graph node that encapsulated a series of physical objects.
Definition: physicalNode.h:31
Physics don&#39;t get much higher-level than this.
virtual void write_physicals(ostream &out, unsigned int indent=0) const
Write a string representation of this instance to <out>.
void remove_linear_force(LinearForce *f)
takes a linear force out of the physics list
Defines a set of physically modeled attributes.
Definition: physical.h:40
virtual ~PhysicsManager()
Simple Destructor.
pure virtual parent of all quat-based forces.
Definition: angularForce.h:24
void do_physics(PN_stdfloat dt)
This is the main high-level API call.
This is a convenience class to specialize ConfigVariable as an integer type.
void remove_angular_force(AngularForce *f)
takes an angular force out of the physics list
virtual void write_linear_forces(ostream &out, unsigned int indent=0) const
Write a string representation of this instance to <out>.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:63
virtual void write(ostream &out, unsigned int indent=0) const
Write a string representation of this instance to <out>.
Like a physical node, but with a little more.
Definition: actorNode.h:30
void remove_physical_node(PhysicalNode *p)
Removes a physicalnode from the manager.
virtual void output(ostream &out) const
Write a string representation of this instance to <out>.
virtual void debug_output(ostream &out, unsigned int indent=0) const
Write a string representation of this instance to <out>.