00001 // Filename: linearCylinderVortexForce.cxx 00002 // Created by: charles (24Jul00) 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 "config_physics.h" 00020 #include "linearCylinderVortexForce.h" 00021 #include <nearly_zero.h> 00022 00023 TypeHandle LinearCylinderVortexForce::_type_handle; 00024 00025 //////////////////////////////////////////////////////////////////// 00026 // Function : LinearCylinderVortexForce 00027 // Access : public 00028 // Description : Simple Constructor 00029 //////////////////////////////////////////////////////////////////// 00030 LinearCylinderVortexForce:: 00031 LinearCylinderVortexForce(float radius, float length, float coef, 00032 float a, bool md) : 00033 LinearForce(a, md), 00034 _radius(radius), _length(length), _coef(coef) 00035 { 00036 } 00037 00038 //////////////////////////////////////////////////////////////////// 00039 // Function : LinearCylinderVortexForce 00040 // Access : public 00041 // Description : copy Constructor 00042 //////////////////////////////////////////////////////////////////// 00043 LinearCylinderVortexForce:: 00044 LinearCylinderVortexForce(const LinearCylinderVortexForce ©) : 00045 LinearForce(copy) { 00046 _radius = copy._radius; 00047 _length = copy._length; 00048 _coef = copy._coef; 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function : ~LinearCylinderVortexForce 00053 // Access : public 00054 // Description : Destructor 00055 //////////////////////////////////////////////////////////////////// 00056 LinearCylinderVortexForce:: 00057 ~LinearCylinderVortexForce(void) { 00058 } 00059 00060 //////////////////////////////////////////////////////////////////// 00061 // Function : make_copy 00062 // Access : public, virtual 00063 // Description : child copier 00064 //////////////////////////////////////////////////////////////////// 00065 LinearForce *LinearCylinderVortexForce:: 00066 make_copy(void) { 00067 return new LinearCylinderVortexForce(*this); 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function : get_child_vector 00072 // Access : private, virtual 00073 // Description : returns the centripetal force vector for the 00074 // passed-in object 00075 //////////////////////////////////////////////////////////////////// 00076 LVector3f LinearCylinderVortexForce:: 00077 get_child_vector(const PhysicsObject *po) { 00078 // get the force-space transform- this MUST be the relative matrix 00079 // from the point's local coordinate system to the attached node's 00080 // local system. 00081 // LMatrix4f force_space_xform = LMatrix4f::ident_mat(); 00082 LVector3f force_vec(0.0f, 0.0f, 0.0f); 00083 00084 // project the point into force_space 00085 LPoint3f point = po->get_position(); 00086 00087 // clip along length 00088 if (point[2] < 0.0f || point[2] > _length) 00089 return force_vec; 00090 00091 // clip to radius 00092 float x_squared = point[0] * point[0]; 00093 float y_squared = point[1] * point[1]; 00094 float dist_squared = x_squared + y_squared; 00095 float radius_squared = _radius * _radius; 00096 00097 // squared space increases monotonically wrt linear space, 00098 // so there's no need to sqrt to check inside/outside this disc. 00099 if (dist_squared > radius_squared) 00100 return force_vec; 00101 00102 if IS_NEARLY_ZERO(dist_squared) 00103 return force_vec; 00104 00105 float r = sqrtf(dist_squared); 00106 00107 if IS_NEARLY_ZERO(r) 00108 return force_vec; 00109 00110 LVector3f tangential = point; 00111 tangential[2] = 0.0f; 00112 tangential.normalize(); 00113 tangential = tangential.cross(LVector3f(0,0,1)); 00114 00115 LVector3f centripetal = -point; 00116 centripetal[2] = 0.0f; 00117 centripetal.normalize(); 00118 00119 LVector3f combined = tangential + centripetal; 00120 combined.normalize(); 00121 00122 // a = v^2 / r 00123 //centripetal = centripetal * _coef * (tangential.length_squared() / 00124 // (r + get_nearly_zero_value(r))); 00125 00126 centripetal = combined * _coef * po->get_velocity().length(); 00127 00128 //centripetal = combined * _coef * (po->get_velocity().length() / 00129 // (r + get_nearly_zero_value(r))); 00130 00131 return centripetal; 00132 }