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

panda/src/physics/angularEulerIntegrator.cxx

Go to the documentation of this file.
00001 // Filename: angularEulerIntegrator.cxx
00002 // Created by:  charles (09Aug00)
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 "angularEulerIntegrator.h"
00020 #include "forceNode.h"
00021 #include "physicalNode.h"
00022 #include "config_physics.h"
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function : AngularEulerIntegrator
00026 //       Access : Public
00027 //  Description : constructor
00028 ////////////////////////////////////////////////////////////////////
00029 AngularEulerIntegrator::
00030 AngularEulerIntegrator(void) {
00031 }
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //     Function : AngularEulerIntegrator
00035 //       Access : Public
00036 //  Description : destructor
00037 ////////////////////////////////////////////////////////////////////
00038 AngularEulerIntegrator::
00039 ~AngularEulerIntegrator(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 AngularEulerIntegrator::
00050 child_integrate(Physical *physical,
00051                 pvector< PT(AngularForce) >& forces,
00052                 float dt) {
00053   // perform the precomputation.  Note that the vector returned by
00054   // get_precomputed_matrices() has the matrices loaded in order of force
00055   // type: first global, then local.  If you're using this as a guide to write
00056   // another integrator, be sure to process your forces global, then local.
00057   // otherwise your transforms will be VERY bad.  No good.
00058   precompute_angular_matrices(physical, forces);
00059   const pvector< LMatrix4f > &matrices = get_precomputed_angular_matrices();
00060 
00061   // Loop through each object in the set.  This processing occurs in O(pf) time,
00062   // where p is the number of physical objects and f is the number of
00063   // forces.  Unfortunately, no precomputation of forces can occur, as
00064   // each force is possibly contingent on such things as the position and
00065   // velocity of each physicsobject in the set.  Accordingly, we have
00066   // to grunt our way through each one.  wrt caching of the xform matrix
00067   // should help.
00068   pvector< PT(PhysicsObject) >::const_iterator current_object_iter;
00069   current_object_iter = physical->get_object_vector().begin();
00070 
00071   for (; current_object_iter != physical->get_object_vector().end();
00072        current_object_iter++) {
00073 
00074     PhysicsObject *current_object = *current_object_iter;
00075 
00076     // bail out if this object doesn't exist or doesn't want to be
00077     // processed.
00078     if (current_object == (PhysicsObject *) NULL)
00079       continue;
00080 
00081     if (current_object->get_active() == false)
00082       continue;
00083 
00084     LVector3f accum_vec(0, 0, 0);
00085 
00086     // set up the traversal stuff.
00087     ForceNode *force_node;
00088     pvector< PT(AngularForce) >::const_iterator f_cur;
00089 
00090     LVector3f f;
00091 
00092     // global forces
00093     f_cur = forces.begin();
00094     int index = 0;
00095     for (; f_cur != forces.end(); f_cur++) {
00096       AngularForce *cur_force = *f_cur;
00097 
00098       // make sure the force is turned on.
00099       if (cur_force->get_active() == false)
00100         continue;
00101 
00102       force_node = cur_force->get_force_node();
00103 
00104       // now we go from force space to our object's space.
00105       f = cur_force->get_vector(current_object) * matrices[index++];
00106 
00107       // tally it into the accum vector, applying the inertial tensor.
00108       accum_vec += f;
00109     }
00110 
00111     // local forces
00112     f_cur = physical->get_angular_forces().begin();
00113     for (; f_cur != physical->get_angular_forces().end(); f_cur++) {
00114       AngularForce *cur_force = *f_cur;
00115 
00116       // make sure the force is turned on.
00117       if (cur_force->get_active() == false)
00118         continue;
00119 
00120       force_node = cur_force->get_force_node();
00121 
00122       // go from force space to object space
00123       f = cur_force->get_vector(current_object) * matrices[index++];
00124 
00125       // tally it into the accum vectors
00126       accum_vec += f;
00127     }
00128 
00129     // apply the accumulated torque vector to the object's inertial tensor.
00130     // this matrix represents how much force the object 'wants' applied to it
00131     // in any direction, among other things.
00132     accum_vec =  accum_vec * current_object->get_inertial_tensor();
00133 
00134     // derive this into the angular velocity vector.
00135     LVector3f rot_vec = current_object->get_rotation();
00136     rot_vec += accum_vec * dt;
00137 
00138     // here's the trick.  we've been accumulating these forces as vectors
00139     // and treating them as vectors, but now we're going to treat them as pure
00140     // imaginary quaternions where r = 0.  This vector NOW represents the
00141     // imaginary vector formed by (i, j, k).
00142 
00143     LVector3f normalized_rot_vec = rot_vec;
00144     float len = rot_vec.length();
00145 
00146     normalized_rot_vec *= 1.0f / len;
00147     LRotationf rot_quat = LRotationf(normalized_rot_vec, len);
00148 
00149     LOrientationf old_orientation = current_object->get_orientation();
00150     LOrientationf new_orientation = old_orientation * rot_quat;
00151     new_orientation.normalize();
00152 
00153     // and write the results back.
00154     current_object->set_orientation(new_orientation);
00155     current_object->set_rotation(rot_vec);
00156   }
00157 }

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