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 * All rights reserved. * 00009 * Web: opal.sourceforge.net * 00010 * * 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of EITHER: * 00013 * (1) The GNU Lesser General Public License as published by the Free * 00014 * Software Foundation; either version 2.1 of the License, or (at * 00015 * your option) any later version. The text of the GNU Lesser * 00016 * General Public License is included with this library in the * 00017 * file license-LGPL.txt. * 00018 * (2) The BSD-style license that is included with this library in * 00019 * the file license-BSD.txt. * 00020 * * 00021 * This library is distributed in the hope that it will be useful, * 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 00024 * license-LGPL.txt and license-BSD.txt for more details. * 00025 * * 00026 *************************************************************************/ 00027 00028 #include "AttractorMotor.h" 00029 #include "Solid.h" 00030 00031 namespace opal 00032 { 00033 AttractorMotor::AttractorMotor() 00034 : Motor() 00035 { 00036 // "mData" will be initialized in its own constructor. 00037 mSolid0Mass = 0; 00038 mSolid1Mass = 0; 00039 mMassConstant = 0; 00040 } 00041 00042 AttractorMotor::~AttractorMotor() 00043 { 00044 } 00045 00046 //void AttractorMotor::init(Solid* solid0, Solid* solid1) 00047 //{ 00048 // Motor::init(); 00049 // mSolid0 = solid0; 00050 // mSolid1 = solid1; 00051 // mSolid0Mass = solid0->getMass(); 00052 // mSolid1Mass = solid1->getMass(); 00053 00054 // // Update this constant since the masses changed. 00055 // mMassConstant = mStrength * mSolid0Mass * mSolid1Mass; 00056 //} 00057 00058 void AttractorMotor::init(const AttractorMotorData& data) 00059 { 00060 Motor::init(); 00061 mData = data; 00062 00063 if (data.solid0 && data.solid1) 00064 { 00065 mSolid0Mass = data.solid0->getMass(); 00066 mSolid1Mass = data.solid1->getMass(); 00067 00068 // Update this constant since the masses changed. 00069 mMassConstant = data.strength * mSolid0Mass * mSolid1Mass; 00070 } 00071 } 00072 00073 const AttractorMotorData& AttractorMotor::getData()const 00074 { 00075 return mData; 00076 } 00077 00078 MotorType AttractorMotor::getType()const 00079 { 00080 return mData.getType(); 00081 } 00082 00083 void AttractorMotor::setName(const std::string& name) 00084 { 00085 mData.name = name; 00086 } 00087 00088 const std::string& AttractorMotor::getName()const 00089 { 00090 return mData.name; 00091 } 00092 00093 bool AttractorMotor::isEnabled()const 00094 { 00095 return mData.enabled; 00096 } 00097 00098 void AttractorMotor::setEnabled(bool e) 00099 { 00100 //if (!mInitCalled) 00101 //{ 00102 // return; 00103 //} 00104 00105 mData.enabled = e; 00106 } 00107 00108 void AttractorMotor::internal_update() 00109 { 00110 if (mData.enabled && mData.solid0 && mData.solid1) 00111 { 00112 Point3r pos1 = mData.solid0->getPosition(); 00113 Point3r pos2 = mData.solid1->getPosition(); 00114 00115 // Create a unit vector pointing from mSolid1 to mSolid0. 00116 Vec3r direction = pos1 - pos2; 00117 real distanceSquared = direction.lengthSquared(); 00118 if (0 != distanceSquared) 00119 { 00120 direction.normalize(); 00121 } 00122 00123 Force f; 00124 f.singleStep = true; 00125 f.type = GLOBAL_FORCE; 00126 f.vec = direction; 00127 00128 // Use force magnitude = (strength * m0 * m1) / distance^exponent. 00129 if ((real)2.0 == mData.exponent) 00130 { 00131 // If we know the exponent is 2, this can speed things up. 00132 f.vec *= (mMassConstant / distanceSquared); 00133 } 00134 else 00135 { 00136 f.vec *= (mMassConstant / (pow(direction.length(), 00137 mData.exponent))); 00138 } 00139 00140 mData.solid1->addForce(f); 00141 f.vec *= (real)-1.0; 00142 mData.solid0->addForce(f); 00143 } 00144 } 00145 00146 void AttractorMotor::setStrength(real s) 00147 { 00148 mData.strength = s; 00149 00150 // Update this constant since the strength changed. 00151 mMassConstant = mData.strength * mSolid0Mass * mSolid1Mass; 00152 } 00153 00154 real AttractorMotor::getStrength()const 00155 { 00156 return mData.strength; 00157 } 00158 00159 void AttractorMotor::setExponent(real e) 00160 { 00161 mData.exponent = e; 00162 } 00163 00164 real AttractorMotor::getExponent()const 00165 { 00166 return mData.exponent; 00167 } 00168 00169 bool AttractorMotor::internal_dependsOnSolid(Solid* s) 00170 { 00171 if (s == mData.solid0 || s == mData.solid1) 00172 { 00173 return true; 00174 } 00175 else 00176 { 00177 return false; 00178 } 00179 } 00180 }