Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/physics/linearEulerIntegrator.cxx

Go to the documentation of this file.
00001 // Filename: linearEulerIntegrator.cxx
00002 // Created by:  charles (13Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "linearEulerIntegrator.h"
00020 #include "forceNode.h"
00021 #include "physicalNode.h"
00022 #include "config_physics.h"
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function : LinearEulerIntegrator
00026 //       Access : Public
00027 //  Description : constructor
00028 ////////////////////////////////////////////////////////////////////
00029 LinearEulerIntegrator::
00030 LinearEulerIntegrator(void) {
00031 }
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //     Function : LinearEulerIntegrator
00035 //       Access : Public
00036 //  Description : destructor
00037 ////////////////////////////////////////////////////////////////////
00038 LinearEulerIntegrator::
00039 ~LinearEulerIntegrator(void) {
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function : Integrate
00044 //       Access : Public
00045 //  Description : Integrate a step of motion (based on dt) by
00046 //                applying every force in force_vec to every object
00047 //                in obj_vec.
00048 ////////////////////////////////////////////////////////////////////
00049 void LinearEulerIntegrator::
00050 child_integrate(Physical *physical,
00051                 pvector< PT(LinearForce) >& forces,
00052                 float dt) {
00053   pvector< PT(PhysicsObject) >::const_iterator current_object_iter;
00054 
00055   // perform the precomputation.  Note that the vector returned by
00056   // get_precomputed_matrices() has the matrices loaded in order of force
00057   // type: first global, then local.  If you're using this as a guide to write
00058   // another integrator, be sure to process your forces global, then local.
00059   // otherwise your transforms will be VERY bad.
00060   precompute_linear_matrices(physical, forces);
00061   const pvector< LMatrix4f > &matrices = get_precomputed_linear_matrices();
00062 
00063   // Loop through each object in the set.  This processing occurs in O(pf) time,
00064   // where p is the number of physical objects and f is the number of
00065   // forces.  Unfortunately, no precomputation of forces can occur, as
00066   // each force is possibly contingent on such things as the position and
00067   // velocity of each physicsobject in the set.  Accordingly, we have
00068   // to grunt our way through each one.  wrt caching of the xform matrix
00069   // should help.
00070 
00071   current_object_iter = physical->get_object_vector().begin();
00072   for (; current_object_iter != physical->get_object_vector().end();
00073        current_object_iter++) {
00074     LVector3f md_accum_vec, non_md_accum_vec, accel_vec, vel_vec;
00075     LPoint3f pos;
00076     float mass;
00077 
00078     PhysicsObject *current_object = *current_object_iter;
00079 
00080     // bail out if this object doesn't exist or doesn't want to be
00081     // processed.
00082     if (current_object == (PhysicsObject *) NULL)
00083       continue;
00084 
00085     if (current_object->get_active() == false)
00086       continue;
00087 
00088     // reset the accumulation vectors for this object
00089     md_accum_vec.set(0.0f, 0.0f, 0.0f);
00090     non_md_accum_vec.set(0.0f, 0.0f, 0.0f);
00091 
00092     // run through each acting force and sum it
00093     LVector3f f;
00094     //    LMatrix4f force_to_object_xform;
00095 
00096     ForceNode *force_node;
00097     pvector< PT(LinearForce) >::const_iterator f_cur;
00098 
00099     // global forces
00100     f_cur = forces.begin();
00101     int index = 0;
00102     for (; f_cur != forces.end(); f_cur++) {
00103       LinearForce *cur_force = *f_cur;
00104 
00105       // make sure the force is turned on.
00106       if (cur_force->get_active() == false)
00107         continue;
00108 
00109       force_node = cur_force->get_force_node();
00110 
00111       // now we go from force space to our object's space.
00112       f = cur_force->get_vector(current_object) * matrices[index++];
00113 
00114       // tally it into the accum vectors.
00115       if (cur_force->get_mass_dependent() == true)
00116         md_accum_vec += f;
00117       else
00118         non_md_accum_vec += f;
00119     }
00120 
00121     // local forces
00122     f_cur = physical->get_linear_forces().begin();
00123     for (; f_cur != physical->get_linear_forces().end(); f_cur++) {
00124       LinearForce *cur_force = *f_cur;
00125 
00126       // make sure the force is turned on.
00127       if (cur_force->get_active() == false)
00128         continue;
00129 
00130       force_node = cur_force->get_force_node();
00131 
00132       // go from force space to object space
00133       f = cur_force->get_vector(current_object) * matrices[index++];
00134 
00135       // tally it into the accum vectors
00136       if (cur_force->get_mass_dependent() == true)
00137         md_accum_vec += f;
00138       else
00139         non_md_accum_vec += f;
00140     }
00141 
00142     // get this object's physical info
00143     pos = current_object->get_position();
00144     vel_vec = current_object->get_velocity();
00145     mass = current_object->get_mass();
00146 
00147     // we want 'a' in F = ma
00148     // get it by computing F / m
00149     nassertv(mass != 0.0f);
00150 
00151     accel_vec = md_accum_vec / mass;
00152     accel_vec += non_md_accum_vec;
00153 
00154     // step the position and velocity
00155     vel_vec += accel_vec * dt;
00156 
00157     // cap terminal velocity
00158     float len = vel_vec.length();
00159 
00160     if (len > current_object->get_terminal_velocity()) {
00161       //cout << "Capping terminal velocity at: " << current_object->get_terminal_velocity() << endl;
00162       vel_vec *= current_object->get_terminal_velocity() / len;
00163     }
00164 
00165     pos += vel_vec * dt;
00166 
00167     // and store them back.
00168     current_object->set_position(pos);
00169     current_object->set_velocity(vel_vec);
00170   }
00171 }
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 

Generated on Fri May 2 00:42:54 2003 for Panda by doxygen1.3