Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

PhysSystem.cpp

Go to the documentation of this file.
00001 #include "PhysSystem.h"
00002 
00003 PhysSystem::PhysSystem()
00004 {
00005     gravity.SetVector(glVector(0,-9.8,0));
00006     wind.SetVector(glVector(0,0,0));
00007 }
00008         
00009 bool PhysSystem::AddObjects(vector<Object3d*> &new_obj_list)
00010 {
00011     Object3d *new_obj;
00012     for(int i = 0; i < new_obj_list.size(); i++)
00013     {
00014         new_obj = new_obj_list[i];
00015         obj_list.push_back(new_obj);
00016         obj_list.back().qrot_velocity = Quaternion(0, 0, 0);
00017     }
00018 }
00019 
00020 void PhysSystem::UpdateAll()
00021 {
00022     physics_timer.GetElapsedSeconds();
00023     for(int a = 0; a < obj_list.size(); a++)
00024     {
00025         WorldEffect(obj_list[a]);
00026         for(int b = a+1; b < obj_list.size(); b++)
00027         {
00028             float center_distance = ((obj_list[a].bsphere_list[0].offset + *obj_list[a].center) - 
00029                                      (obj_list[b].bsphere_list[0].offset + *obj_list[b].center)).length();
00030             float radius_total = obj_list[a].bsphere_list[0].radius + obj_list[b].bsphere_list[0].radius;
00031                 
00032             if(center_distance - radius_total < 0)
00033                 CollideObjects(obj_list[a], obj_list[b]);
00034         }
00035         Update(obj_list[a]);
00036     }
00037 }
00038 
00039 void PhysSystem::CollideObjects(PhysObject &Object1, PhysObject &Object2)
00040 {
00041     glVector p1_offset;
00042     glVector p2_offset;
00043     
00044     for(int c = 1; c < Object1.bsphere_list.size(); c++)
00045     {
00046         for(int d = 1; d < Object2.bsphere_list.size(); d++)
00047         {
00048             Quaternion q1(Object1.center->rot);
00049             Quaternion q2(Object2.center->rot);
00050             p1_offset = q1.RotateV(Object1.bsphere_list[c].offset);
00051             p2_offset = q2.RotateV(Object2.bsphere_list[d].offset);
00052             
00053             float center_distance = ((p1_offset + *Object1.center) - (p2_offset + *Object2.center)).length();
00054             float radius_total = Object1.bsphere_list[c].radius + Object2.bsphere_list[d].radius;
00055             if(center_distance - radius_total < 0)
00056             {
00057                 float radius1 = p1_offset.length();
00058                 float radius2 = p2_offset.length();
00059                 glVector v1;
00060                 glVector v2;
00061                 glVector v1_lin;
00062                 glVector v2_lin;
00063                 glVector v1_ang;
00064                 glVector v2_ang;
00065 
00066                 v1 = Object1.velocity;
00067                 v2 = Object2.velocity;
00068                 
00069                 Quaternion qin_1(Object1.qrot_velocity);
00070                 Quaternion qin_2(Object2.qrot_velocity);
00071                 
00072                 float angspeed_1 = qin_1.GetAngle();
00073                 float angspeed_2 = qin_2.GetAngle();
00074                 
00075                 glVector angvector_1 = !((q1 * qin_1 * ~q1).v % p1_offset);
00076                 glVector angvector_2 = !((q2 * qin_2 * ~q2).v % p2_offset);
00077                 
00078                 v1 += (angvector_1 * radius1 * angspeed_1);
00079                 v2 += (angvector_2 * radius2 * angspeed_2);
00080                 
00081                 float m1 = Object1.mass + Object1.inertial_moment;
00082                 float m2 = Object2.mass + Object2.inertial_moment;
00083 
00084                 if(!CollidePoints(p1_offset + *Object1.center, v1, m1, Object1.elasticity,
00085                                   p2_offset + *Object2.center, v2, m2, Object2.elasticity))
00086                     return;
00087                     
00088                 if(radius1 != 0) v1_lin = v1.ProjectOnto(p1_offset);
00089                     else v1_lin = v1;
00090                 if(radius2 != 0) v2_lin = v2.ProjectOnto(p2_offset);
00091                     else v2_lin = v2;
00092                 
00093                 v1_ang = v1 - v1_lin;
00094                 v2_ang = v2 - v2_lin;
00095             
00096                 if(radius1 != 0)
00097                 {
00098                     Quaternion qout_1(v1_ang.length() / radius1, !(p1_offset % v1_ang));
00099                     Object1.qrot_velocity = Object1.qrot_velocity * (~q1 * qout_1 * q1);
00100                 }
00101                 if(radius2 != 0)
00102                 {
00103                     Quaternion qout_2(v2_ang.length() / radius2, !(p2_offset % v2_ang));
00104                     Object2.qrot_velocity = Object2.qrot_velocity * (~q2 * qout_2 * q2);
00105                 }
00106                 
00107                 Object1.velocity  += (v1_lin);
00108                 Object2.velocity  += (v2_lin);
00109             }
00110         }
00111     }
00112 }
00113 
00114 bool PhysSystem::CollidePoints(glVector point1, glVector &momentum1, float m1, float cor1,
00115                                glVector point2, glVector &momentum2, float m2, float cor2)
00116 {
00117     glVector col_vector = !(point2 - point1);
00118     glVector rel_momentum = momentum1 - momentum2;
00119     glVector proj_momentum = rel_momentum.ProjectOnto(col_vector);
00120     
00121     if((proj_momentum * col_vector) > 0)
00122     {
00123          momentum1 = proj_momentum * -(m2/(m1+m2))*(1+cor1);
00124          momentum2 = proj_momentum *  (m1/(m1+m2))*(1+cor2);
00125          return true;
00126     }
00127     return false;
00128 }
00129 
00130 void PhysSystem::WorldEffect(PhysObject &cur_obj)
00131 {
00132     cur_obj.velocity = cur_obj.velocity + (!(glVector(*cur_obj.center) - glVector(*obj_list[0].center)) * -98.0/2.0 * cur_obj.gravity_effect) * physics_timer.difference_time;
00133 //    cur_obj.velocity = cur_obj.velocity + (wind * cur_obj.wind_effect) * physics_timer.difference_time;
00134 }
00135 
00136 void PhysSystem::Update(PhysObject &cur_obj)
00137 {
00138     cur_obj.center->Move(cur_obj.velocity * physics_timer.difference_time);
00139     
00140     Quaternion rot_step(cur_obj.qrot_velocity.GetAngle() * physics_timer.difference_time, cur_obj.qrot_velocity.GetAxis());
00141     cur_obj.center->rot = cur_obj.center->rot * rot_step;
00142 }

Generated on Thu Apr 21 18:06:30 2005 for Basic Rendering Engine by  doxygen 1.4.1