Panda3D

physicsManager.cxx

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 }
 All Classes Functions Variables Enumerations