Panda3D
|
00001 // Filename: physicsManager.cxx 00002 // Created by: charles (14Jun00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "physicsManager.h" 00016 #include "actorNode.h" 00017 00018 #include <algorithm> 00019 #include "pvector.h" 00020 00021 ConfigVariableInt PhysicsManager::_random_seed 00022 ("physics_manager_random_seed", 139); 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function : PhysicsManager 00026 // Access : Public 00027 // Description : Default Constructor. NOTE: EulerIntegrator is 00028 // the standard default. 00029 //////////////////////////////////////////////////////////////////// 00030 PhysicsManager:: 00031 PhysicsManager() { 00032 _linear_integrator.clear(); 00033 _angular_integrator.clear(); 00034 _viscosity=0.0; 00035 } 00036 00037 //////////////////////////////////////////////////////////////////// 00038 // Function : ~PhysicsManager 00039 // Access : Public 00040 // Description : Simple Destructor 00041 //////////////////////////////////////////////////////////////////// 00042 PhysicsManager:: 00043 ~PhysicsManager() { 00044 PhysicalsVector::iterator pi; 00045 for (pi = _physicals.begin(); pi != _physicals.end(); ++pi) { 00046 nassertv((*pi)->_physics_manager == this); 00047 (*pi)->_physics_manager = NULL; 00048 } 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function : InitRandomSeed 00053 // Access : Public 00054 // Description : One-time config function, sets up the random seed 00055 // used by the physics and particle systems. 00056 // For synchronizing across distributed computers 00057 //////////////////////////////////////////////////////////////////// 00058 void PhysicsManager:: 00059 init_random_seed() { 00060 // Use the random seed specified by the physics_manager_random_seed 00061 // Config Variable 00062 srand(_random_seed); 00063 } 00064 00065 //////////////////////////////////////////////////////////////////// 00066 // Function : remove_linear_force 00067 // Access : Public 00068 // Description : takes a linear force out of the physics list 00069 //////////////////////////////////////////////////////////////////// 00070 void PhysicsManager:: 00071 remove_linear_force(LinearForce *f) { 00072 nassertv(f); 00073 LinearForceVector::iterator found; 00074 00075 PT(LinearForce) ptbf = f; 00076 found = find(_linear_forces.begin(), _linear_forces.end(), ptbf); 00077 00078 if (found == _linear_forces.end()) { 00079 return; 00080 } 00081 _linear_forces.erase(found); 00082 } 00083 00084 //////////////////////////////////////////////////////////////////// 00085 // Function : remove_angular_force 00086 // Access : Public 00087 // Description : takes an angular force out of the physics list 00088 //////////////////////////////////////////////////////////////////// 00089 void PhysicsManager:: 00090 remove_angular_force(AngularForce *f) { 00091 nassertv(f); 00092 AngularForceVector::iterator found; 00093 00094 PT(BaseForce) ptbf = f; 00095 found = find(_angular_forces.begin(), _angular_forces.end(), ptbf); 00096 00097 if (found == _angular_forces.end()) { 00098 return; 00099 } 00100 _angular_forces.erase(found); 00101 } 00102 00103 //////////////////////////////////////////////////////////////////// 00104 // Function : remove_physical 00105 // Access : Public 00106 // Description : takes a physical out of the object list 00107 //////////////////////////////////////////////////////////////////// 00108 void PhysicsManager:: 00109 remove_physical(Physical *p) { 00110 nassertv(p); 00111 pvector< Physical * >::iterator found; 00112 00113 found = find(_physicals.begin(), _physicals.end(), p); 00114 if (found == _physicals.end()) { 00115 return; 00116 } 00117 nassertv(p->_physics_manager == this); 00118 p->_physics_manager = (PhysicsManager *) NULL; 00119 _physicals.erase(found); 00120 } 00121 00122 //////////////////////////////////////////////////////////////////// 00123 // Function : remove_physical_node 00124 // Access : Public 00125 // Description : Removes a physicalnode from the manager 00126 //////////////////////////////////////////////////////////////////// 00127 void PhysicsManager:: 00128 remove_physical_node(PhysicalNode *p) { 00129 nassertv(p); 00130 for (int i = 0; i < p->get_num_physicals(); ++i) { 00131 remove_physical(p->get_physical(i)); 00132 } 00133 } 00134 00135 //////////////////////////////////////////////////////////////////// 00136 // Function : DoPhysics 00137 // Access : Public 00138 // Description : This is the main high-level API call. Performs 00139 // integration on every attached Physical. 00140 //////////////////////////////////////////////////////////////////// 00141 void PhysicsManager:: 00142 do_physics(PN_stdfloat dt) { 00143 // now, run through each physics object in the set. 00144 PhysicalsVector::iterator p_cur = _physicals.begin(); 00145 for (; p_cur != _physicals.end(); ++p_cur) { 00146 Physical *physical = *p_cur; 00147 nassertv(physical); 00148 00149 // do linear 00150 //if (_linear_integrator.is_null() == false) { 00151 if (_linear_integrator) { 00152 _linear_integrator->integrate(physical, _linear_forces, dt); 00153 } 00154 00155 // do angular 00156 //if (_angular_integrator.is_null() == false) { 00157 if (_angular_integrator) { 00158 _angular_integrator->integrate(physical, _angular_forces, dt); 00159 } 00160 00161 // if it's an actor node, tell it to update itself. 00162 PhysicalNode *pn = physical->get_physical_node(); 00163 if (pn && pn->is_of_type(ActorNode::get_class_type())) { 00164 ActorNode *an = (ActorNode *) pn; 00165 an->update_transform(); 00166 } 00167 } 00168 } 00169 00170 //////////////////////////////////////////////////////////////////// 00171 // Function : DoPhysics 00172 // Access : Public 00173 // Description : This is the main high-level API call. Performs 00174 // integration on a single physical. Make sure its 00175 // associated forces are active. 00176 //////////////////////////////////////////////////////////////////// 00177 void PhysicsManager:: 00178 do_physics(PN_stdfloat dt, Physical *physical) { 00179 nassertv(physical); 00180 00181 // do linear 00182 //if (_linear_integrator.is_null() == false) { 00183 if (_linear_integrator) { 00184 _linear_integrator->integrate(physical, _linear_forces, dt); 00185 } 00186 00187 // do angular 00188 //if (_angular_integrator.is_null() == false) { 00189 if (_angular_integrator) { 00190 _angular_integrator->integrate(physical, _angular_forces, dt); 00191 } 00192 00193 // if it's an actor node, tell it to update itself. 00194 PhysicalNode *pn = physical->get_physical_node(); 00195 if (pn && pn->is_of_type(ActorNode::get_class_type())) { 00196 ActorNode *an = (ActorNode *) pn; 00197 an->update_transform(); 00198 } 00199 } 00200 00201 //////////////////////////////////////////////////////////////////// 00202 // Function : output 00203 // Access : Public 00204 // Description : Write a string representation of this instance to 00205 // <out>. 00206 //////////////////////////////////////////////////////////////////// 00207 void PhysicsManager:: 00208 output(ostream &out) const { 00209 #ifndef NDEBUG //[ 00210 out<<""<<"PhysicsManager"; 00211 #endif //] NDEBUG 00212 } 00213 00214 //////////////////////////////////////////////////////////////////// 00215 // Function : write_physicals 00216 // Access : Public 00217 // Description : Write a string representation of this instance to 00218 // <out>. 00219 //////////////////////////////////////////////////////////////////// 00220 void PhysicsManager:: 00221 write_physicals(ostream &out, unsigned int indent) const { 00222 #ifndef NDEBUG //[ 00223 if (indent>10) { 00224 return; 00225 } 00226 out.width(indent); 00227 out<<""<<"_physicals ("<<_physicals.size()<<" physicals)\n"; 00228 //out<<ios::width(indent)<<" "<<"[physicals \n"; 00229 for (pvector< Physical * >::const_iterator i=_physicals.begin(); 00230 i != _physicals.end(); 00231 ++i) { 00232 (*i)->write(out, indent+2); 00233 } 00234 #endif //] NDEBUG 00235 } 00236 00237 //////////////////////////////////////////////////////////////////// 00238 // Function : write_forces 00239 // Access : Public 00240 // Description : Write a string representation of this instance to 00241 // <out>. 00242 //////////////////////////////////////////////////////////////////// 00243 void PhysicsManager:: 00244 write_linear_forces(ostream &out, unsigned int indent) const { 00245 #ifndef NDEBUG //[ 00246 out.width(indent); 00247 out<<""<<"_linear_forces ("<<_linear_forces.size()<<" forces)\n"; 00248 for (LinearForceVector::const_iterator i=_linear_forces.begin(); 00249 i != _linear_forces.end(); 00250 ++i) { 00251 (*i)->write(out, indent+2); 00252 } 00253 #endif //] NDEBUG 00254 } 00255 00256 //////////////////////////////////////////////////////////////////// 00257 // Function : write_angular_forces 00258 // Access : Public 00259 // Description : Write a string representation of this instance to 00260 // <out>. 00261 //////////////////////////////////////////////////////////////////// 00262 void PhysicsManager:: 00263 write_angular_forces(ostream &out, unsigned int indent) const { 00264 #ifndef NDEBUG //[ 00265 out.width(indent); 00266 out<<""<<"_angular_forces ("<<_angular_forces.size()<<" forces)\n"; 00267 for (AngularForceVector::const_iterator i=_angular_forces.begin(); 00268 i != _angular_forces.end(); 00269 ++i) { 00270 (*i)->write(out, indent+2); 00271 } 00272 #endif //] NDEBUG 00273 } 00274 00275 //////////////////////////////////////////////////////////////////// 00276 // Function : write 00277 // Access : Public 00278 // Description : Write a string representation of this instance to 00279 // <out>. 00280 //////////////////////////////////////////////////////////////////// 00281 void PhysicsManager:: 00282 write(ostream &out, unsigned int indent) const { 00283 #ifndef NDEBUG //[ 00284 out.width(indent); out<<""<<"PhysicsManager:\n"; 00285 if (indent>20) { 00286 // ...indent limit is arbitrary, it limits recursion. 00287 out.width(indent+2); out<<""<<"...\n"; 00288 return; 00289 } 00290 write_physicals(out, indent+2); 00291 write_linear_forces(out, indent+2); 00292 write_angular_forces(out, indent+2); 00293 out.width(indent+2); out<<""<<"_linear_integrator:\n"; 00294 if (_linear_integrator) { 00295 _linear_integrator->write(out, indent+4); 00296 } else { 00297 out.width(indent+4); out<<""<<"null\n"; 00298 } 00299 out.width(indent+2); out<<""<<"_angular_integrator:\n"; 00300 if (_angular_integrator) { 00301 _angular_integrator->write(out, indent+4); 00302 } else { 00303 out.width(indent+4); out<<""<<"null\n"; 00304 } 00305 #endif //] NDEBUG 00306 } 00307 00308 //////////////////////////////////////////////////////////////////// 00309 // Function : write 00310 // Access : Public 00311 // Description : Write a string representation of this instance to 00312 // <out>. 00313 //////////////////////////////////////////////////////////////////// 00314 void PhysicsManager:: 00315 debug_output(ostream &out, unsigned int indent) const { 00316 #ifndef NDEBUG //[ 00317 out.width(indent); out<<""<<"PhysicsManager li"<<(_linear_integrator?1:0)<<" ai"<<(_angular_integrator?1:0)<<"\n"; 00318 out<<" _physicals "<<_physicals.size()<<"\n"; 00319 //_physicals._phys_body.write(out, indent+2); 00320 00321 00322 out.width(indent+2); 00323 out<<""<<"_linear_forces ("<<_linear_forces.size()<<" forces)\n"; 00324 LinearForceVector::const_iterator li; 00325 for (li=_linear_forces.begin(); 00326 li != _linear_forces.end(); 00327 ++li) { 00328 (*li)->write(out, indent+2); 00329 } 00330 00331 out.width(indent+2); 00332 out<<""<<" _angular_forces "<<_angular_forces.size()<<"\n"; 00333 AngularForceVector::const_iterator ai; 00334 for (ai=_angular_forces.begin(); 00335 ai != _angular_forces.end(); 00336 ++ai) { 00337 (*ai)->write(out, indent+2); 00338 } 00339 #endif //] NDEBUG 00340 }