00001 /*************************************************************************** 00002 * This file is part of OpenCAL: Open Computer Animation Library * 00003 * I created OpenCAL as my master's thesis Computer Science (multimedia) * 00004 * at the tUL university in Diepenbeek, Belgium * 00005 * * 00006 * Copyright (C) 2003-2004 by Jeroen Dierckx * 00007 * jeroen.dierckx@student.luc.ac.be * 00008 * * 00009 ***************************************************************************/ 00010 00011 // Includes 00012 #include "FloorConstraint.h" 00013 #include <OpenCAL/Plane.h> 00014 #include <OpenCAL/PhysicsSystem.h> 00015 #include <OpenCAL/PhysicalObject.h> 00016 #include <OpenCAL/ObjectIterator.h> 00017 using namespace OpenCAL; 00018 00019 #include <OpenCAL/Vector3.h> 00020 using namespace Utils; 00021 00022 using namespace std; 00023 00024 00025 /****************************** 00026 * Constructors and destructor * 00027 ******************************/ 00028 00029 FloorConstraint::FloorConstraint(PhysicsSystem *parent) 00030 : Constraint(parent), m_height(0.0f), m_plane(new Plane(parent)), 00031 //m_repulsion(10.0f), m_friction(0.6f), m_absorption(0.5f) 00032 m_restitution(0.0f), m_friction(0.3f) 00033 { 00034 } 00035 00036 FloorConstraint::FloorConstraint(PhysicsSystem *parent, Plane *floorPlane) 00037 : Constraint(parent), m_height(0.0f), m_plane(floorPlane), 00038 //m_repulsion(10.0f), m_friction(0.6f), m_absorption(0.5f) 00039 m_restitution(0.0f), m_friction(0.3f) 00040 { 00041 } 00042 00043 FloorConstraint::~FloorConstraint() 00044 { 00045 } 00046 00047 00048 /****************** 00049 * Other functions * 00050 ******************/ 00051 00052 void OpenCAL::FloorConstraint::satisfy( ) 00053 { 00054 //if(!m_enabled) return; 00055 Constraint::satisfy(); 00056 00058 Vector3 point = m_plane->getPosition(); 00059 Vector3 normal = m_plane->getNormal(); 00060 00061 ObjectIterator it(m_parent); 00062 while(*it) 00063 // for(unsigned int i = 0; i < m_parent->numObjects(); ++i) 00064 { 00065 PhysicalObject *object = (PhysicalObject *) *it; 00066 // PhysicalObject *object = (PhysicalObject *) m_parent->getObject(i); 00067 00068 /* 00069 float test = (object->getPosition() - point).dotProduct(normal); 00070 Vector3 vn = normal.dotProduct(object->getVelocity()) * object->getVelocity(); 00071 Vector3 vt = object->getVelocity() - vn; 00072 00073 if(test <= EPSILON && test >= -EPSILON) // Contact 00074 { 00075 float force = normal.dotProduct(object->getForce()); 00076 if(force < 0.0f) 00077 object->addForce(-force * object->getForce()); 00078 00079 object->addForce(-m_friction * (-object->getForce()).dotProduct(normal) * object->getVelocity()); 00080 } 00081 else if(test < 0.0f) // Collision 00082 { 00083 vn *= -m_restitution; 00084 object->setVelocity(vn + vt); 00085 } 00086 */ 00087 00088 float y = object->getPosition().getY(); 00089 Vector3 vel; 00090 00091 if(y <= (m_height + Math::verySmall) && y >= (m_height -Math::verySmall)) // Contact 00092 { 00093 Vector3 vel = object->getVelocity(); 00094 00095 /* 00096 if(object->getForce().getY() < 0.0f) 00097 object->getForceP()->setY(-object->getForce().getY()); 00098 */ 00099 vel.setY(0.0f); 00100 object->addForce(-m_friction * vel); 00101 } 00102 else if(y < m_height) // Collision 00103 { 00104 object->getVelocityP()->setY(-object->getVelocityP()->getY() * m_restitution); 00105 object->getPositionP()->setY(m_height); 00106 00107 /* 00108 // Apply ground friction 00109 vel = object->getVelocity(); 00110 vel.setY(0.0f); // No vertical velocity in friction 00111 object->addForce(-vel * m_friction); 00112 00113 // Apply ground absorption 00114 vel = object->getVelocity(); 00115 vel.setX(0.0f); 00116 vel.setZ(0.0f); // Only vertical velocity in absorption 00117 if(vel.getY() < 0.0f) // Only if moving towards ground 00118 object->addForce(-vel * m_absorption); 00119 00120 // Apply ground repulsion 00121 object->addForce(Vector3(0, m_repulsion, 0) * (m_height - y)); 00122 00123 object->getPositionP()->setY(m_height); 00124 */ 00125 } 00126 00127 ++it; 00128 } 00129 }