Panda3D
physicsManager.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 physicsManager.cxx
10  * @author charles
11  * @date 2000-06-14
12  */
13 
14 #include "physicsManager.h"
15 #include "actorNode.h"
16 
17 #include <algorithm>
18 #include "pvector.h"
19 
20 using std::ostream;
21 
22 ConfigVariableInt PhysicsManager::_random_seed
23 ("physics_manager_random_seed", 139);
24 
25 /**
26  * Default Constructor. NOTE: EulerIntegrator is the standard default.
27  */
30  _linear_integrator.clear();
31  _angular_integrator.clear();
32  _viscosity=0.0;
33 }
34 
35 /**
36  * Simple Destructor
37  */
40  PhysicalsVector::iterator pi;
41  for (pi = _physicals.begin(); pi != _physicals.end(); ++pi) {
42  nassertv((*pi)->_physics_manager == this);
43  (*pi)->_physics_manager = nullptr;
44  }
45 }
46 
47 /**
48  * One-time config function, sets up the random seed used by the physics and
49  * particle systems. For synchronizing across distributed computers
50  */
53  // Use the random seed specified by the physics_manager_random_seed Config
54  // Variable
55  srand(_random_seed);
56 }
57 
58 /**
59  * takes a linear force out of the physics list
60  */
63  nassertv(f);
64  LinearForceVector::iterator found;
65 
66  PT(LinearForce) ptbf = f;
67  found = find(_linear_forces.begin(), _linear_forces.end(), ptbf);
68 
69  if (found == _linear_forces.end()) {
70  return;
71  }
72  _linear_forces.erase(found);
73 }
74 
75 /**
76  * takes an angular force out of the physics list
77  */
80  nassertv(f);
81  AngularForceVector::iterator found;
82 
83  PT(BaseForce) ptbf = f;
84  found = find(_angular_forces.begin(), _angular_forces.end(), ptbf);
85 
86  if (found == _angular_forces.end()) {
87  return;
88  }
89  _angular_forces.erase(found);
90 }
91 
92 /**
93  * takes a physical out of the object list
94  */
97  nassertv(p);
99 
100  found = find(_physicals.begin(), _physicals.end(), p);
101  if (found == _physicals.end()) {
102  return;
103  }
104  nassertv(p->_physics_manager == this);
105  p->_physics_manager = nullptr;
106  _physicals.erase(found);
107 }
108 
109 /**
110  * Removes a physicalnode from the manager
111  */
112 void PhysicsManager::
114  nassertv(p);
115  for (size_t i = 0; i < p->get_num_physicals(); ++i) {
116  remove_physical(p->get_physical(i));
117  }
118 }
119 
120 /**
121  * This is the main high-level API call. Performs integration on every
122  * attached Physical.
123  */
124 void PhysicsManager::
125 do_physics(PN_stdfloat dt) {
126  // now, run through each physics object in the set.
127  PhysicalsVector::iterator p_cur = _physicals.begin();
128  for (; p_cur != _physicals.end(); ++p_cur) {
129  Physical *physical = *p_cur;
130  nassertv(physical);
131 
132  // do linear if (_linear_integrator.is_null() == false) {
133  if (_linear_integrator) {
134  _linear_integrator->integrate(physical, _linear_forces, dt);
135  }
136 
137  // do angular if (_angular_integrator.is_null() == false) {
138  if (_angular_integrator) {
139  _angular_integrator->integrate(physical, _angular_forces, dt);
140  }
141 
142  // if it's an actor node, tell it to update itself.
143  PhysicalNode *pn = physical->get_physical_node();
144  if (pn && pn->is_of_type(ActorNode::get_class_type())) {
145  ActorNode *an = (ActorNode *) pn;
146  an->update_transform();
147  }
148  }
149 }
150 
151 /**
152  * This is the main high-level API call. Performs integration on a single
153  * physical. Make sure its associated forces are active.
154  */
155 void PhysicsManager::
156 do_physics(PN_stdfloat dt, Physical *physical) {
157  nassertv(physical);
158 
159  // do linear if (_linear_integrator.is_null() == false) {
160  if (_linear_integrator) {
161  _linear_integrator->integrate(physical, _linear_forces, dt);
162  }
163 
164  // do angular if (_angular_integrator.is_null() == false) {
165  if (_angular_integrator) {
166  _angular_integrator->integrate(physical, _angular_forces, dt);
167  }
168 
169  // if it's an actor node, tell it to update itself.
170  PhysicalNode *pn = physical->get_physical_node();
171  if (pn && pn->is_of_type(ActorNode::get_class_type())) {
172  ActorNode *an = (ActorNode *) pn;
173  an->update_transform();
174  }
175 }
176 
177 /**
178  * Write a string representation of this instance to <out>.
179  */
180 void PhysicsManager::
181 output(ostream &out) const {
182  #ifndef NDEBUG //[
183  out<<""<<"PhysicsManager";
184  #endif //] NDEBUG
185 }
186 
187 /**
188  * Write a string representation of this instance to <out>.
189  */
190 void PhysicsManager::
191 write_physicals(ostream &out, int indent) const {
192  #ifndef NDEBUG //[
193  if (indent>10) {
194  return;
195  }
196  out.width(indent);
197  out<<""<<"_physicals ("<<_physicals.size()<<" physicals)\n";
198  // out<<ios::width(indent)<<" "<<"[physicals \n";
199  for (pvector< Physical * >::const_iterator i=_physicals.begin();
200  i != _physicals.end();
201  ++i) {
202  (*i)->write(out, indent+2);
203  }
204  #endif //] NDEBUG
205 }
206 
207 /**
208  * Write a string representation of this instance to <out>.
209  */
210 void PhysicsManager::
211 write_linear_forces(ostream &out, int indent) const {
212  #ifndef NDEBUG //[
213  out.width(indent);
214  out<<""<<"_linear_forces ("<<_linear_forces.size()<<" forces)\n";
215  for (LinearForceVector::const_iterator i=_linear_forces.begin();
216  i != _linear_forces.end();
217  ++i) {
218  (*i)->write(out, indent+2);
219  }
220  #endif //] NDEBUG
221 }
222 
223 /**
224  * Write a string representation of this instance to <out>.
225  */
226 void PhysicsManager::
227 write_angular_forces(ostream &out, int indent) const {
228  #ifndef NDEBUG //[
229  out.width(indent);
230  out<<""<<"_angular_forces ("<<_angular_forces.size()<<" forces)\n";
231  for (AngularForceVector::const_iterator i=_angular_forces.begin();
232  i != _angular_forces.end();
233  ++i) {
234  (*i)->write(out, indent+2);
235  }
236  #endif //] NDEBUG
237 }
238 
239 /**
240  * Write a string representation of this instance to <out>.
241  */
242 void PhysicsManager::
243 write(ostream &out, int indent) const {
244  #ifndef NDEBUG //[
245  out.width(indent); out<<""<<"PhysicsManager:\n";
246  if (indent>20) {
247  // ...indent limit is arbitrary, it limits recursion.
248  out.width(indent+2); out<<""<<"...\n";
249  return;
250  }
251  write_physicals(out, indent+2);
252  write_linear_forces(out, indent+2);
254  out.width(indent+2); out<<""<<"_linear_integrator:\n";
255  if (_linear_integrator) {
256  _linear_integrator->write(out, indent+4);
257  } else {
258  out.width(indent+4); out<<""<<"null\n";
259  }
260  out.width(indent+2); out<<""<<"_angular_integrator:\n";
261  if (_angular_integrator) {
262  _angular_integrator->write(out, indent+4);
263  } else {
264  out.width(indent+4); out<<""<<"null\n";
265  }
266  #endif //] NDEBUG
267 }
268 
269 /**
270  * Write a string representation of this instance to <out>.
271  */
272 void PhysicsManager::
273 debug_output(ostream &out, int indent) const {
274  #ifndef NDEBUG //[
275  out.width(indent); out<<""<<"PhysicsManager li"<<(_linear_integrator?1:0)<<" ai"<<(_angular_integrator?1:0)<<"\n";
276  out<<" _physicals "<<_physicals.size()<<"\n";
277  // _physicals._phys_body.write(out, indent+2);
278 
279 
280  out.width(indent+2);
281  out<<""<<"_linear_forces ("<<_linear_forces.size()<<" forces)\n";
282  LinearForceVector::const_iterator li;
283  for (li=_linear_forces.begin();
284  li != _linear_forces.end();
285  ++li) {
286  (*li)->write(out, indent+2);
287  }
288 
289  out.width(indent+2);
290  out<<""<<" _angular_forces "<<_angular_forces.size()<<"\n";
291  AngularForceVector::const_iterator ai;
292  for (ai=_angular_forces.begin();
293  ai != _angular_forces.end();
294  ++ai) {
295  (*ai)->write(out, indent+2);
296  }
297  #endif //] NDEBUG
298 }
virtual void write_angular_forces(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
virtual void write_physicals(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
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
void update_transform()
this sets the transform generated by the contained Physical, moving the node and subsequent geometry.
Definition: actorNode.cxx:63
A force that acts on a PhysicsObject by way of an Integrator.
Definition: linearForce.h:23
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pure virtual base class for all forces that could POSSIBLY exist.
Definition: baseForce.h:29
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
Graph node that encapsulated a series of physical objects.
Definition: physicalNode.h:28
virtual void write_linear_forces(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
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:37
virtual void debug_output(std::ostream &out, int indent=0) const
Write a string representation of this instance to <out>.
virtual void output(std::ostream &out) const
Write a string representation of this instance to <out>.
virtual ~PhysicsManager()
Simple Destructor.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pure virtual parent of all quat-based forces.
Definition: angularForce.h:22
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
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
virtual void write(std::ostream &out, 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:26
void remove_physical_node(PhysicalNode *p)
Removes a physicalnode from the manager.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.