00001 /************************************************************************* 00002 * * 00003 * Open Physics Abstraction Layer * 00004 * Copyright (C) 2004-2005 * 00005 * Alan Fischer alan.fischer@gmail.com * 00006 * Andres Reinot andres@reinot.com * 00007 * Tyler Streeter tylerstreeter@gmail.com * 00008 * Oleksandr Lozitskiy mr.olexander@gmail.com * 00009 * All rights reserved. * 00010 * Web: opal.sourceforge.net * 00011 * * 00012 * This library is free software; you can redistribute it and/or * 00013 * modify it under the terms of EITHER: * 00014 * (1) The GNU Lesser General Public License as published by the Free * 00015 * Software Foundation; either version 2.1 of the License, or (at * 00016 * your option) any later version. The text of the GNU Lesser * 00017 * General Public License is included with this library in the * 00018 * file license-LGPL.txt. * 00019 * (2) The BSD-style license that is included with this library in * 00020 * the file license-BSD.txt. * 00021 * * 00022 * This library is distributed in the hope that it will be useful, * 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 00025 * license-LGPL.txt and license-BSD.txt for more details. * 00026 * * 00027 *************************************************************************/ 00028 00029 // class headers 00030 #include "VelocityMotor.h" 00031 00032 // project headers 00033 #include "Simulator.h" 00034 00035 namespace opal 00036 { 00037 VelocityMotor::VelocityMotor( Simulator * sim ) 00038 { 00039 mSimulator = sim; 00040 } 00041 00042 VelocityMotor::~VelocityMotor() 00043 {} 00044 00045 void VelocityMotor::setVelocity( const Vec3r & velocity ) 00046 { 00047 mData.velocity = velocity; 00048 } 00049 00050 const Vec3r & VelocityMotor::getVelocity() const 00051 { 00052 return mData.velocity; 00053 } 00054 00055 void VelocityMotor::init( const VelocityMotorData & data ) 00056 { 00057 Motor::init(); 00058 mData = data; 00059 if ( mData.solid ) 00060 { 00061 mData.solid->setLinearDamping( 0 ); 00062 } 00063 } 00064 00065 void VelocityMotor::setEnabled( bool e ) 00066 { 00067 mData.enabled = e; 00068 } 00069 00070 bool VelocityMotor::isEnabled() const 00071 { 00072 return mData.enabled; 00073 } 00074 00075 MotorType VelocityMotor::getType() const 00076 { 00077 return VELOCITY_MOTOR; 00078 } 00079 00080 void VelocityMotor::setName( const std::string& name ) 00081 { 00082 mData.name = name; 00083 } 00084 00085 const std::string & VelocityMotor::getName() const 00086 { 00087 return mData.name; 00088 } 00089 00090 bool VelocityMotor::internal_dependsOnSolid( Solid * s ) const 00091 { 00092 if ( mData.solid == s ) 00093 return true; 00094 else 00095 return false; 00096 } 00097 00098 void VelocityMotor::letGravityAffectSolid( bool affect ) 00099 { 00100 mData.letGravityAffectSolid = affect; 00101 } 00102 00103 bool VelocityMotor::doesGravityAffectSolid() const 00104 { 00105 return mData.letGravityAffectSolid; 00106 } 00107 00108 void VelocityMotor::internal_update() 00109 { 00110 // check if we have a solid 00111 if ( mData.solid == NULL || isEnabled() == false ) return ; 00112 00113 Vec3r targetVelocity = mData.velocity; 00114 Solid * solid = mData.solid; 00115 00116 Vec3r currentAchievedVelocity = solid->getGlobalLinearVel(); 00117 00118 if ( doesGravityAffectSolid() ) 00119 { 00120 Vec3r gravity = mSimulator->getGravity(); 00121 if ( gravity.length() > 0 ) 00122 { 00123 Vec3r gravity_velocity = project( gravity, currentAchievedVelocity ); 00124 currentAchievedVelocity -= gravity_velocity; 00125 } 00126 } 00127 00128 Vec3r deltaVelocity = targetVelocity - currentAchievedVelocity; 00129 00130 Vec3r forceVector = deltaVelocity / mSimulator->getStepSize() * solid->getMass(); 00131 if ( !doesGravityAffectSolid() ) 00132 forceVector -= mSimulator->getGravity() * solid->getMass(); 00133 00134 if ( forceVector.length() > getMaximumForce() ) 00135 { 00136 forceVector.normalize(); 00137 forceVector *= getMaximumForce(); 00138 } 00139 00140 Force controllingForce; 00141 controllingForce.duration = 0; 00142 controllingForce.singleStep = true; 00143 controllingForce.type = GLOBAL_FORCE; 00144 controllingForce.vec = forceVector; 00145 00146 solid->addForce( controllingForce ); 00147 } 00148 00149 void VelocityMotor::setMaximumForce( real maxForce ) 00150 { 00151 mData.maxForce = maxForce; 00152 } 00153 00154 real VelocityMotor::getMaximumForce() const 00155 { 00156 return mData.maxForce; 00157 } 00158 }