Panda3D
 All Classes Functions Variables Enumerations
physical.cxx
00001 // Filename: physical.cxx
00002 // Created by:  charles (16Jun00)
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 "pointerTo.h"
00016 
00017 #include "physical.h"
00018 #include "physicsManager.h"
00019 
00020 TypeHandle Physical::_type_handle;
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function : Physical
00024 //       Access : Public
00025 //  Description : Default Constructor
00026 //
00027 //                The idea here is that most physicals will NOT 
00028 //                be collections of sets (i.e. particle systems 
00029 //                and whatever else).  Because of this, the default 
00030 //                constructor, unless otherwise specified, will 
00031 //                automatically allocate and initialize one 
00032 //                PhysicalObject.  This makes it easier for 
00033 //                high-level work.
00034 //
00035 //                pre-alloc is ONLY for multiple-object physicals, 
00036 //                and if true, fills the physics_object vector 
00037 //                with dead nodes, pre-allocating for the speed
00038 //                end of the speed-vs-overhead deal.
00039 ////////////////////////////////////////////////////////////////////
00040 Physical::
00041 Physical(int total_objects, bool pre_alloc) {
00042   _viscosity=0.0;
00043   _physical_node = (PhysicalNode *) NULL;
00044   _physics_manager = (PhysicsManager *) NULL;
00045 
00046   if (total_objects == 1) {
00047     _phys_body = new PhysicsObject;
00048     add_physics_object(_phys_body);
00049   } else {
00050     _phys_body = (PhysicsObject *) NULL;
00051     // allocate each object.
00052     if (pre_alloc == true) {
00053       for (int i = 0; i < total_objects; ++i) {
00054         PhysicsObject *po = new PhysicsObject;
00055         add_physics_object(po);
00056       }
00057     }
00058   }
00059 }
00060 
00061 ////////////////////////////////////////////////////////////////////
00062 //     Function : Physical
00063 //       Access : Public
00064 //  Description : copy constructor (note- does deep copy of pn's)
00065 //                but does NOT attach itself to its template's
00066 //                physicsmanager.
00067 ////////////////////////////////////////////////////////////////////
00068 Physical::
00069 Physical(const Physical& copy) {
00070   _physics_manager = (PhysicsManager *) NULL;
00071 
00072   // copy the forces.
00073   LinearForceVector::const_iterator lf_cur;
00074   LinearForceVector::const_iterator lf_end = copy._linear_forces.end();
00075 
00076   for (lf_cur = copy._linear_forces.begin(); lf_cur != lf_end; lf_cur++) {
00077     _linear_forces.push_back((*lf_cur)->make_copy());
00078   }
00079 
00080   AngularForceVector::const_iterator af_cur;
00081   AngularForceVector::const_iterator af_end = copy._angular_forces.end();
00082 
00083   for (af_cur = copy._angular_forces.begin(); af_cur != af_end; af_cur++) {
00084     _angular_forces.push_back((*af_cur)->make_copy());
00085   }
00086 
00087   // copy the physics objects
00088   PhysicsObject::Vector::const_iterator p_cur;
00089   PhysicsObject::Vector::const_iterator p_end = copy._physics_objects.end();
00090 
00091   for (p_cur = copy._physics_objects.begin(); p_cur != p_end; p_cur++) {
00092     // oooh so polymorphic.
00093     _physics_objects.push_back((*p_cur)->make_copy());
00094   }
00095 
00096   // now set the one-element-quick-access pointer
00097   if (_physics_objects.size() == 1)
00098     _phys_body = _physics_objects[0];
00099   else
00100     _phys_body = (PhysicsObject *) NULL;
00101 }
00102 
00103 ////////////////////////////////////////////////////////////////////
00104 //     Function : ~Physical
00105 //       Access : Public
00106 //  Description : destructor
00107 ////////////////////////////////////////////////////////////////////
00108 Physical::
00109 ~Physical() {
00110   // note that this removes a physical from a physics manager.
00111   // this is safe because the physics manager doesn't keep PT's to
00112   // physicals, simply *'s, and also means that we don't have to tell
00113   // the physics manager ourselves when one of our physicals is dead.
00114   if (_physics_manager != (PhysicsManager *) NULL) {
00115     _physics_manager->remove_physical(this);
00116   }
00117 }
00118 
00119 ////////////////////////////////////////////////////////////////////
00120 //    Function : get_objects
00121 //      Access : Public
00122 ////////////////////////////////////////////////////////////////////
00123 const PhysicsObjectCollection Physical::
00124 get_objects() const{
00125   PhysicsObjectCollection poc;
00126 
00127   for (PhysicsObject::Vector::const_iterator i=_physics_objects.begin();
00128        i != _physics_objects.end();
00129        ++i) {
00130     poc.add_physics_object((PhysicsObject*)(*i));
00131   }
00132 
00133   return poc;
00134 }
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function : output
00138 //       Access : Public
00139 //  Description : Write a string representation of this instance to
00140 //                <out>.
00141 ////////////////////////////////////////////////////////////////////
00142 void Physical::
00143 output(ostream &out) const {
00144   #ifndef NDEBUG //[
00145   out<<"Physical";
00146   #endif //] NDEBUG
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function : write_physics_objects
00151 //       Access : Public
00152 //  Description : Write a string representation of this instance to
00153 //                <out>.
00154 ////////////////////////////////////////////////////////////////////
00155 void Physical::
00156 write_physics_objects(ostream &out, unsigned int indent) const {
00157   #ifndef NDEBUG //[
00158   out.width(indent);
00159   out<<""<<"_physics_objects ("<<_physics_objects.size()<<" objects)\n";
00160   for (PhysicsObject::Vector::const_iterator i=_physics_objects.begin();
00161        i != _physics_objects.end();
00162        ++i) {
00163     (*i)->write(out, indent+2);
00164   }
00165   #endif //] NDEBUG
00166 }
00167 
00168 ////////////////////////////////////////////////////////////////////
00169 //     Function : write_linear_forces
00170 //       Access : Public
00171 //  Description : Write a string representation of this instance to
00172 //                <out>.
00173 ////////////////////////////////////////////////////////////////////
00174 void Physical::
00175 write_linear_forces(ostream &out, unsigned int indent) const {
00176   #ifndef NDEBUG //[
00177   out.width(indent);
00178   out<<""<<"_linear_forces ("<<_linear_forces.size()<<" forces)\n";
00179   for (LinearForceVector::const_iterator i=_linear_forces.begin();
00180        i != _linear_forces.end();
00181        ++i) {
00182     (*i)->write(out, indent+2);
00183   }
00184   #endif //] NDEBUG
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function : write_angular_forces
00189 //       Access : Public
00190 //  Description : Write a string representation of this instance to
00191 //                <out>.
00192 ////////////////////////////////////////////////////////////////////
00193 void Physical::
00194 write_angular_forces(ostream &out, unsigned int indent) const {
00195   #ifndef NDEBUG //[
00196   out.width(indent);
00197   out<<""<<"_angular_forces ("<<_angular_forces.size()<<" forces)\n";
00198   for (AngularForceVector::const_iterator i=_angular_forces.begin();
00199        i != _angular_forces.end();
00200        ++i) {
00201     (*i)->write(out, indent+2);
00202   }
00203   #endif //] NDEBUG
00204 }
00205 
00206 ////////////////////////////////////////////////////////////////////
00207 //     Function : write
00208 //       Access : Public
00209 //  Description : Write a string representation of this instance to
00210 //                <out>.
00211 ////////////////////////////////////////////////////////////////////
00212 void Physical::
00213 write(ostream &out, unsigned int indent) const {
00214   #ifndef NDEBUG //[
00215   out.width(indent); out<<""<<"Physical\n";
00216   write_physics_objects(out, indent+2);
00217   write_linear_forces(out, indent+2);
00218   write_angular_forces(out, indent+2);
00219   if (_phys_body) {
00220     out.width(indent+2); out<<""<<"_phys_body\n";
00221     _phys_body->write(out, indent+4);
00222   } else {
00223     out.width(indent+2); out<<""<<"_phys_body is null\n";
00224   }
00225   #endif //] NDEBUG
00226 }
 All Classes Functions Variables Enumerations