Panda3D
|
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 }