Changeset 7673 for code/trunk/src/modules/objects/ForceField.cc
- Timestamp:
- Nov 25, 2010, 11:24:50 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/modules/objects/ForceField.cc
r5781 r7673 27 27 */ 28 28 29 /** 30 @file ForceField.cc 31 @brief Implementation of the ForceField class. 32 */ 33 29 34 #include "ForceField.h" 30 35 … … 36 41 { 37 42 CreateFactory(ForceField); 43 44 /*static*/ const std::string modeStringNormal_s = "tube"; 45 /*static*/ const std::string modeStringSphere_s = "sphere"; 38 46 39 47 ForceField::ForceField(BaseObject* creator) : StaticEntity(creator) … … 43 51 //Standard Values 44 52 this->setDirection(Vector3::ZERO); 45 velocity_ = 100; 46 diameter_ = 500; 47 length_ = 5000; 53 this->velocity_ = 100; 54 this->diameter_ = 500; 55 this->length_ = 5000; 56 this->mode_ = ForceFieldMode::tube; 48 57 } 49 58 50 ForceField::~ForceField() {} 59 ForceField::~ForceField() 60 { 61 } 51 62 52 63 void ForceField::XMLPort(Element& xmlelement, XMLPort::Mode mode) … … 58 69 XMLPortParam(ForceField, "diameter", setDiameter, getDiameter, xmlelement, mode).defaultValues(500); 59 70 XMLPortParam(ForceField, "length" , setLength , getLength , xmlelement, mode).defaultValues(2000); 71 XMLPortParam(ForceField, "mode", setMode, getMode, xmlelement, mode); 60 72 } 61 73 62 74 void ForceField::tick(float dt) 63 75 { 76 // Iterate over all objects that could possibly be affected by the ForceField. 64 77 for (ObjectList<MobileEntity>::iterator it = ObjectList<MobileEntity>::begin(); it != ObjectList<MobileEntity>::end(); ++it) 65 78 { 66 //calculate from 67 Vector3 directionVec = this->getOrientation() * WorldEntity::FRONT; 68 directionVec.normalise(); 79 if(this->mode_ == ForceFieldMode::tube) 80 { 81 // The direction of the orientation of the force field. 82 Vector3 direction = this->getOrientation() * WorldEntity::FRONT; 83 direction.normalise(); 69 84 70 Vector3 distanceVec = it->getWorldPosition() - (this->getWorldPosition() + (this->length_ / 2 * directionVec)); 85 // Vector from the center of the force field to the object its acting on. 86 // TODO: This could probably be simplified. 87 Vector3 distanceVector = it->getWorldPosition() - (this->getWorldPosition() + (this->halfLength_ * direction)); 88 89 // The object is outside of the length of the ForceField. 90 if(distanceVector.length() > this->halfLength_) 91 return; 71 92 72 //distance from centervector of the field ( 73 float distFromCenterVec = ((it->getWorldPosition() - this->getWorldPosition()).crossProduct(directionVec)).length(); 93 // The distance of the object form the orientation vector. (Or rather the smallest distance from the orientation vector) 94 float distanceFromDirectionVector = ((it->getWorldPosition() - this->getWorldPosition()).crossProduct(direction)).length(); 95 96 // If the object in a tube of radius diameter/2 around the direction of orientation. 97 if(distanceFromDirectionVector >= this->radius_) 98 return; 74 99 75 if (distanceVec.length() < this->length_ / 2 && distFromCenterVec < diameter_ / 2) 100 // Apply a force to the object in the direction of the orientation. 101 // The force is highest when the object is directly on the direction vector, with a linear decrease, finally reaching zero, when distanceFromDirectionVector = radius. 102 it->applyCentralForce(((this->radius_ - distanceFromDirectionVector)/(this->radius_)) * this->velocity_ * direction); 103 } 104 else if(this->mode_ == ForceFieldMode::sphere) 76 105 { 77 //normalize distance from center 78 it->applyCentralForce(((diameter_ / 2 - distFromCenterVec) / (diameter_ / 2)) * directionVec * velocity_); 106 Vector3 distanceVector = it->getWorldPosition() - this->getWorldPosition(); 107 float distance = distanceVector.length(); 108 if (distance < this->radius_) 109 { 110 distanceVector.normalise(); 111 it->applyCentralForce((this->radius_ - distance)/this->radius_ * this->velocity_ * distanceVector); 112 } 79 113 } 114 } 115 } 116 117 void ForceField::setMode(const std::string& mode) 118 { 119 if(mode == ForceField::modeStringTube_s) 120 this->mode_ = ForceFieldMode::tube; 121 else if(mode == ForceField::modeStringSphere_s) 122 this->mode_ = ForceFieldMode::sphere; 123 else 124 { 125 COUT(2) << "Wrong mode '" << mode << "' in ForceField. Setting to 'tube'." << std::endl; 126 this->mode_ = ForceFieldMode::tube; 127 } 128 } 129 130 inline const std::string& ForceField::getMode(void) 131 { 132 switch(this->mode_) 133 { 134 case ForceFieldMode::tube: 135 return ForceField::modeStringTube_s; 136 case ForceFieldMode::sphere: 137 return ForceField::modeStringSphere_s; 138 default: 139 return ForceField::modeStringTube_s; 80 140 } 81 141 }
Note: See TracChangeset
for help on using the changeset viewer.