00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef _areaeffect_cpp
00041 #define _areaeffect_cpp
00042
00043 #include "areaeffect.h"
00044 #include "actorrigid.h"
00045 #include "physicsmanager.h"
00046 #include "collisionshape.h"
00047 #include "collisionshapemanager.h"
00048 #include "mesh.h"
00049 #include "meshmanager.h"
00050 #include "objectreference.h"
00051 #include "internalmeshtools.h.cpp"
00052 #include "world.h"
00053
00054 #include <BulletCollision/CollisionDispatch/btGhostObject.h>
00055 #include <BulletCollision/Gimpact/btGImpactShape.h>
00056 #include <BulletSoftBody/btSoftRigidDynamicsWorld.h>
00057
00058 #ifdef GetObject
00059 #undef GetObject
00060 #endif
00061
00062 namespace Mezzanine
00063 {
00064 AreaEffect::AreaEffect(const String &name, const Vector3& Location)
00065 {
00066 Name = name;
00067 this->GraphicsNode = SceneManager::GetSingletonPtr()->GetGraphicsWorldPointer()->getRootSceneNode()->createChildSceneNode();
00068 CreateGhostObject(Location);
00069
00070 short CollisionGroup = btBroadphaseProxy::SensorTrigger;
00071 short CollisionMask = GetPhysicsSettings()->IsStatic() ? btBroadphaseProxy::AllFilter ^ (btBroadphaseProxy::SensorTrigger|btBroadphaseProxy::StaticFilter) : btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::SensorTrigger;
00072 PhysicsSettings->SetCollisionGroupAndMask(CollisionGroup,CollisionMask);
00073 }
00074
00075 AreaEffect::~AreaEffect()
00076 {
00077 delete (ObjectReference*)Ghost->getUserPointer();
00078 delete Ghost;
00079 delete GraphicsSettings;
00080 delete PhysicsSettings;
00081
00082 Ogre::SceneManager* OgreManager = SceneManager::GetSingletonPtr()->GetGraphicsWorldPointer();
00083 if(GraphicsObject)
00084 OgreManager->destroyEntity(GraphicsObject);
00085 OgreManager->destroySceneNode(GraphicsNode);
00086 }
00087
00088 void AreaEffect::CreateGhostObject(const Vector3& Location)
00089 {
00090 Ghost = new btPairCachingGhostObject();
00091 Ghost->setCollisionFlags(Ghost->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
00092 Ghost->getWorldTransform().setOrigin(Location.GetBulletVector3());
00093 ObjectReference* AERef = new ObjectReference(this->GetType(),this);
00094 Ghost->setUserPointer(AERef);
00095
00096 PhysicsObject = Ghost;
00097 this->GraphicsSettings = new WorldObjectGraphicsSettings(this,GraphicsObject);
00098 this->PhysicsSettings = new WorldObjectPhysicsSettings(this,PhysicsObject);
00099 }
00100
00101 void AreaEffect::AddActorToList(ActorBase* Actor)
00102 {
00103 AddedActors.push_back(Actor);
00104 OverlappingActors.push_back(Actor);
00105 }
00106
00107 void AreaEffect::RemoveActorFromList(ActorBase* Actor)
00108 {
00109 RemovedActors.push_back(Actor);
00110 for( std::list<ActorBase*>::iterator c=OverlappingActors.begin(); c!=OverlappingActors.end(); c++)
00111 {
00112 if ( Actor == (*c) )
00113 {
00114 OverlappingActors.erase(c);
00115 }
00116 }
00117 }
00118
00119 Whole AreaEffect::GetNumOverlappingActors()
00120 {
00121 return OverlappingActors.size();
00122 }
00123
00124 Whole AreaEffect::GetNumAddedActors()
00125 {
00126 return AddedActors.size();
00127 }
00128
00129 Whole AreaEffect::GetNumRemovedActors()
00130 {
00131 return RemovedActors.size();
00132 }
00133
00134 std::list<ActorBase*>& AreaEffect::GetOverlappingActors()
00135 {
00136 return OverlappingActors;
00137 }
00138
00139 std::vector<ActorBase*>& AreaEffect::GetAddedActors()
00140 {
00141 return AddedActors;
00142 }
00143
00144 std::vector<ActorBase*>& AreaEffect::GetRemovedActors()
00145 {
00146 return RemovedActors;
00147 }
00148
00149 ConstString& AreaEffect::GetName() const
00150 {
00151 return WorldObject::GetName();
00152 }
00153
00154 void AreaEffect::SetLocation(const Vector3& Location)
00155 {
00156 WorldObject::SetLocation(Location);
00157 LocalTransformDirty = !(GetUpdating(Parent));
00158
00159 _RecalculateLocalTransform();
00160 _RecalculateAllChildTransforms();
00161 }
00162
00163 Vector3 AreaEffect::GetLocation() const
00164 {
00165 return WorldObject::GetLocation();
00166 }
00167
00168 void AreaEffect::SetOrientation(const Quaternion& Rotation)
00169 {
00170 NonStaticWorldObject::InternalSetOrientation(Rotation);
00171 LocalTransformDirty = !(GetUpdating(Parent));
00172
00173 _RecalculateLocalTransform();
00174 _RecalculateAllChildTransforms();
00175 }
00176
00177 Quaternion AreaEffect::GetOrientation() const
00178 {
00179 return NonStaticWorldObject::GetOrientation();
00180 }
00181
00182 void AreaEffect::SetScaling(const Vector3& Scale)
00183 {
00184 WorldObject::SetScaling(Scale);
00185 LocalTransformDirty = true;
00186
00187 _RecalculateLocalTransform();
00188 _RecalculateAllChildTransforms();
00189 }
00190
00191 Vector3 AreaEffect::GetScaling() const
00192 {
00193 return WorldObject::GetScaling();
00194 }
00195
00196 void AreaEffect::SetLocalLocation(const Vector3& Location)
00197 {
00198 LocalXform.Location = Location;
00199 GlobalTransformDirty = true;
00200
00201 _RecalculateGlobalTransform();
00202 _RecalculateAllChildTransforms();
00203 }
00204
00205 void AreaEffect::SetLocalOrientation(const Quaternion& Orientation)
00206 {
00207 LocalXform.Rotation = Orientation;
00208 GlobalTransformDirty = true;
00209
00210 _RecalculateGlobalTransform();
00211 _RecalculateAllChildTransforms();
00212 }
00213
00214 WorldAndSceneObjectType AreaEffect::GetType() const
00215 {
00216 return Mezzanine::WSO_AEUnknown;
00217 }
00218
00219 void AreaEffect::AddToWorld()
00220 {
00221 PhysicsManager::GetSingletonPtr()->GetPhysicsWorldPointer()->addCollisionObject(this->PhysicsObject,GetPhysicsSettings()->GetCollisionGroup(),GetPhysicsSettings()->GetCollisionMask());
00222 this->AttachToGraphics();
00223 }
00224
00225 void AreaEffect::RemoveFromWorld()
00226 {
00227 PhysicsManager* PhysMan = PhysicsManager::GetSingletonPtr();
00228 btSoftRigidDynamicsWorld* BWorld = PhysMan->GetPhysicsWorldPointer();
00229
00230
00231
00232
00233
00234 BWorld->removeCollisionObject(this->PhysicsObject);
00235 this->DetachFromGraphics();
00236 }
00237
00238 void AreaEffect::_Update()
00239 {
00240 if ( !AddedActors.empty() )
00241 AddedActors.clear();
00242 if ( !RemovedActors.empty() )
00243 RemovedActors.clear();
00244 btSoftRigidDynamicsWorld* PhysWorld = PhysicsManager::GetSingletonPtr()->GetPhysicsWorldPointer();
00245
00246 std::list<ActorBase*>::iterator it = OverlappingActors.begin();
00247
00248 std::vector<bool> Tracker;
00249 Tracker.resize(OverlappingActors.size());
00250 std::vector<bool>::iterator bit;
00251 for ( bit = Tracker.begin() ; bit != Tracker.end() ; bit++ )
00252 {
00253 (*bit) = false;
00254 }
00255
00256 btManifoldArray manifoldArray;
00257 btBroadphasePairArray& pairArray = Ghost->getOverlappingPairCache()->getOverlappingPairArray();
00258 int numPairs = pairArray.size();
00259 for (int i=0;i<numPairs;i++)
00260 {
00261 manifoldArray.clear();
00262 const btBroadphasePair& pair = pairArray[i];
00263 btBroadphasePair* collisionPair = PhysWorld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1);
00264 if (!collisionPair)
00265 continue;
00266 if (collisionPair->m_algorithm)
00267 collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
00268
00269 for (int j=0;j<manifoldArray.size();j++)
00270 {
00271 btPersistentManifold* manifold = manifoldArray[j];
00272 for (int p=0;p<manifold->getNumContacts();p++)
00273 {
00274 const btManifoldPoint& pt = manifold->getContactPoint(p);
00275
00276
00277 btCollisionObject* ColObj = manifold->getBody0() != Ghost ? (btCollisionObject*)(manifold->getBody0()) : (btCollisionObject*)(manifold->getBody1());
00278
00279 ObjectReference* ActorRef = (ObjectReference*)(ColObj->getUserPointer());
00280 ActorBase* Actor = NULL;
00281 if(Mezzanine::WSO_TerrainFirst > ActorRef->GetType())
00282 Actor = (ActorBase*)ActorRef->GetObject();
00283 else
00284 continue;
00285
00286 for( it = OverlappingActors.begin(), bit = Tracker.begin() ; it != OverlappingActors.end() ; it++, bit++ )
00287 {
00288 if ( Actor == (*it) )
00289 {
00290 (*bit) = true;
00291 break;
00292 }
00293 }
00294 if ( it == OverlappingActors.end() )
00295 {
00296 AddActorToList(Actor);
00297 Tracker.push_back(true);
00298 }
00299 }
00300 }
00301 }
00302
00303
00304 if ( OverlappingActors.size() == Tracker.size() )
00305 {
00306 std::list<ActorBase*>::iterator sit = OverlappingActors.begin();
00307 for ( bit = Tracker.begin() ; bit != Tracker.end() ; )
00308 {
00309 if ( (*bit) == false )
00310 {
00311 bit = Tracker.erase(bit);
00312 ActorBase* Act = (*sit);
00313 RemovedActors.push_back(Act);
00314 sit = OverlappingActors.erase(sit);
00315 }else{
00316 sit++;
00317 bit++;
00318 }
00319 }
00320 }
00321 }
00322
00323 #ifdef MEZZXML
00324 void AreaEffect::ThrowSerialError(const String& Fail) const
00325 { SerializeError(Fail, SerializableName()); }
00326
00327 String AreaEffect::GraphicsSettingsSerializableName() const
00328 { return String("WorldObjectGraphicsSettings"); }
00329
00330 String AreaEffect::PhysicsSettingsSerializableName() const
00331 { return String("WorldObjectBasePhysicsSettings"); }
00332
00333 void AreaEffect::ProtoSerialize(xml::Node& CurrentRoot) const
00334 {
00335 xml::Node AreaEffectNode = CurrentRoot.AppendChild("AreaEffect");
00336 if (!AreaEffectNode) { ThrowSerialError("create AreaEffectNode");}
00337
00338 xml::Attribute AreaEffectVersion = AreaEffectNode.AppendAttribute("Version");
00339 AreaEffectVersion.SetValue(1);
00340
00341 NonStaticWorldObject::ProtoSerialize(AreaEffectNode);
00342 }
00343
00344 void AreaEffect::ProtoDeSerialize(const xml::Node& OneNode)
00345 {
00346 if ( Mezzanine::String(OneNode.Name())==this->AreaEffect::SerializableName() )
00347 {
00348 if(OneNode.GetAttribute("Version").AsInt() == 1)
00349 {
00350 NonStaticWorldObject::ProtoDeSerialize(OneNode.GetChild(this->NonStaticWorldObject::SerializableName()));
00351 }
00352 }
00353 }
00354
00355 String AreaEffect::SerializableName()
00356 { return "AreaEffect"; }
00357 #endif
00358
00359
00360
00361
00362 TestAE::TestAE(const String& name, const Vector3& Location) : AreaEffect(name, Location)
00363 {
00364 }
00365
00366 TestAE::~TestAE()
00367 {
00368 }
00369
00370 void TestAE::ApplyEffect()
00371 {
00372 World* TheWorld = World::GetWorldPointer();
00373 std::vector<ActorBase*>::iterator AaRIt;
00374 std::list<ActorBase*>::iterator CurrIt;
00375 ActorBase* Act = NULL;
00376
00377 if ( !AddedActors.empty() )
00378 {
00379 TheWorld->Log("Actors Added to field this frame:");
00380 for ( AaRIt = AddedActors.begin() ; AaRIt != AddedActors.end() ; AaRIt++ )
00381 {
00382 Act = (*AaRIt);
00383 TheWorld->Log(Act);
00384 }
00385 }
00386 if ( !RemovedActors.empty() )
00387 {
00388 TheWorld->Log("Actors Removed from field this frame:");
00389 for ( AaRIt = RemovedActors.begin() ; AaRIt != RemovedActors.end() ; AaRIt++ )
00390 {
00391 Act = (*AaRIt);
00392 TheWorld->Log(Act);
00393 }
00394 }
00395 if ( !OverlappingActors.empty() )
00396 {
00397 TheWorld->Log("Actors Currently in field this frame:");
00398 for ( CurrIt = OverlappingActors.begin() ; CurrIt != OverlappingActors.end() ; CurrIt++ )
00399 {
00400 Act = (*CurrIt);
00401 TheWorld->Log(Act);
00402 }
00403 }
00404 }
00405
00406
00407
00408
00409 GravityField::GravityField(const String &name, const Vector3& Location) : AreaEffect(name, Location)
00410 {
00411 }
00412
00413 GravityField::~GravityField()
00414 {
00415 }
00416
00417 void GravityField::ApplyEffect()
00418 {
00419 std::vector<ActorBase*>::iterator It;
00420 PhysicsManager* Physics = PhysicsManager::GetSingletonPtr();
00421 ActorBase* Act = NULL;
00422
00423 if ( !AddedActors.empty() )
00424 {
00425 for ( It = AddedActors.begin() ; It != AddedActors.end() ; It++ )
00426 {
00427 Act = (*It);
00428 Physics->SetIndividualGravity(Act, Grav);
00429 }
00430 }
00431 if ( !RemovedActors.empty() )
00432 {
00433 for ( It = RemovedActors.begin() ; It != RemovedActors.end() ; It++ )
00434 {
00435 Act = (*It);
00436 Physics->SetIndividualGravity(Act, Physics->GetGravity());
00437 }
00438 }
00439 }
00440
00441 void GravityField::SetFieldGravity(const Vector3& Gravity)
00442 {
00443 Grav = Gravity;
00444 }
00445
00446 Vector3 GravityField::GetFieldGravity() const
00447 {
00448 return Grav;
00449 }
00450
00451 WorldAndSceneObjectType GravityField::GetType() const
00452 {
00453 return Mezzanine::WSO_AEGravityField;
00454 }
00455
00456
00457
00458
00459 GravityWell::GravityWell(const String &name, const Vector3& Location)
00460 : AreaEffect(name, Location),
00461 AllowWorldGrav(true),
00462 Strength(0),
00463 AttenAmount(0),
00464 AttenStyle(Mezzanine::Att_None)
00465 {
00466 }
00467
00468 GravityWell::~GravityWell()
00469 {
00470 }
00471
00472 void GravityWell::ApplyEffect()
00473 {
00474 if(0 == Strength)
00475 return;
00476 ActorBase* Act = NULL;
00477 ActorRigid* ActRig = NULL;
00478 if(!AllowWorldGrav && !AddedActors.empty())
00479 {
00480 for ( std::vector<ActorBase*>::iterator AA = AddedActors.begin() ; AA != AddedActors.end() ; AA++ )
00481 {
00482 if(Mezzanine::WSO_ActorRigid != (*AA)->GetType())
00483 continue;
00484 ActRig = dynamic_cast<ActorRigid*>(*AA);
00485 ActRig->GetPhysicsSettings()->SetIndividualGravity(Vector3());
00486 }
00487 }
00488 if(!OverlappingActors.empty())
00489 {
00490 Vector3 ActorLoc, Direction;
00491 Real Distance, AppliedStrength, InvMass;
00492 Vector3 GhostLoc = this->GetLocation();
00493 for ( std::list<ActorBase*>::iterator OA = OverlappingActors.begin() ; OA != OverlappingActors.end() ; OA++ )
00494 {
00495 if(Mezzanine::WSO_ActorRigid != (*OA)->GetType())
00496 continue;
00497
00498 ActorLoc = (*OA)->GetLocation();
00499 Distance = ActorLoc.Distance(GhostLoc);
00500 Direction = (GhostLoc - ActorLoc) / Distance;
00501 switch(AttenStyle)
00502 {
00503 case Mezzanine::Att_Linear:
00504 AppliedStrength = Strength - (AttenAmount * Distance);
00505 break;
00506 case Mezzanine::Att_Quadratic:
00507 AppliedStrength = Strength - (AttenAmount * (Distance * Distance));
00508 break;
00509 default:
00510 AppliedStrength = Strength;
00511 break;
00512 }
00513 ActRig = static_cast<ActorRigid*>(*OA);
00514 InvMass = ActRig->GetBulletObject()->getInvMass();
00515 if(0 != InvMass)
00516 AppliedStrength *= (1 / ActRig->GetBulletObject()->getInvMass());
00517 else
00518 AppliedStrength = 0;
00519 if(0 > AppliedStrength)
00520 AppliedStrength = 0;
00521
00522 ActRig->GetBulletObject()->applyCentralForce((Direction * AppliedStrength).GetBulletVector3());
00523 }
00524 }
00525 if(!AllowWorldGrav && !RemovedActors.empty())
00526 {
00527 Vector3 WorldGrav = PhysicsManager::GetSingletonPtr()->GetGravity();
00528 for ( std::vector<ActorBase*>::iterator RA = RemovedActors.begin() ; RA != RemovedActors.end() ; RA++ )
00529 {
00530 if(Mezzanine::WSO_ActorRigid != (*RA)->GetType())
00531 continue;
00532 ActRig = dynamic_cast<ActorRigid*>(*RA);
00533 ActRig->GetPhysicsSettings()->SetIndividualGravity(WorldGrav);
00534 }
00535 }
00536 }
00537
00538 void GravityWell::SetFieldStrength(const Real& FieldStrength)
00539 {
00540 Strength = FieldStrength;
00541 }
00542
00543 Real GravityWell::GetFieldStrength() const
00544 {
00545 return Strength;
00546 }
00547
00548 void GravityWell::SetAllowWorldGravity(bool WorldGravity)
00549 {
00550 AllowWorldGrav = WorldGravity;
00551 }
00552
00553 bool GravityWell::GetAllowWorldGravity() const
00554 {
00555 return AllowWorldGrav;
00556 }
00557
00558 void GravityWell::SetAttenuation(const Real& Amount, const Mezzanine::AttenuationStyle& Style)
00559 {
00560 AttenAmount = Amount;
00561 AttenStyle = Style;
00562 }
00563
00564 Mezzanine::AttenuationStyle GravityWell::GetAttenuationStyle() const
00565 {
00566 return AttenStyle;
00567 }
00568
00569 Real GravityWell::GetAttenuationAmount() const
00570 {
00571 return AttenAmount;
00572 }
00573
00574 WorldAndSceneObjectType GravityWell::GetType() const
00575 {
00576 return Mezzanine::WSO_AEGravityWell;
00577 }
00578
00579
00580
00581
00582 FieldOfForce::FieldOfForce(const String &name, const Vector3& Location)
00583 : AreaEffect(name, Location),
00584 Strength(0),
00585 AttenAmount(0),
00586 AttenStyle(Mezzanine::Att_None),
00587 AttenSource(Vector3(0,0,0)),
00588 Direction(Vector3(0,1,0))
00589 {
00590 }
00591
00592 FieldOfForce::~FieldOfForce()
00593 {
00594 }
00595
00596 void FieldOfForce::ApplyEffect()
00597 {
00598 if(0 == Strength)
00599 return;
00600 ActorBase* Act = NULL;
00601 ActorRigid* ActRig = NULL;
00602 if(!OverlappingActors.empty())
00603 {
00604 Vector3 ActorLoc;
00605 Real Distance, AppliedStrength, InvMass;
00606 for ( std::list<ActorBase*>::iterator OA = OverlappingActors.begin() ; OA != OverlappingActors.end() ; OA++ )
00607 {
00608 if(Mezzanine::WSO_ActorRigid != (*OA)->GetType())
00609 continue;
00610 ActorLoc = (*OA)->GetLocation();
00611 switch(AttenStyle)
00612 {
00613 case Mezzanine::Att_Linear:
00614 {
00615 Distance = ActorLoc.Distance(AttenSource);
00616 AppliedStrength = Strength - (AttenAmount * Distance);
00617 break;
00618 }
00619 case Mezzanine::Att_Quadratic:
00620 {
00621 Distance = ActorLoc.Distance(AttenSource);
00622 AppliedStrength = Strength - (AttenAmount * (Distance * Distance));
00623 break;
00624 }
00625 case Mezzanine::Att_None:
00626 {
00627 AppliedStrength = Strength;
00628 break;
00629 }
00630 }
00631
00632 ActRig = static_cast<ActorRigid*>(*OA);
00633
00634
00635
00636
00637
00638 if(0 > AppliedStrength)
00639 AppliedStrength = 0;
00640
00641 ActRig->GetBulletObject()->applyCentralForce((Direction * AppliedStrength).GetBulletVector3());
00642
00643 }
00644 }
00645 }
00646
00647 void FieldOfForce::SetFieldStrength(const Real& FieldStrength)
00648 {
00649 Strength = FieldStrength;
00650 }
00651
00652 Real FieldOfForce::GetFieldStrength() const
00653 {
00654 return Strength;
00655 }
00656
00657 void FieldOfForce::SetDirectionOfForce(const Vector3& ForceDirection)
00658 {
00659 Direction = ForceDirection;
00660 }
00661
00662 Vector3 FieldOfForce::GetDirectionOfForce()
00663 {
00664 return Direction;
00665 }
00666
00667 void FieldOfForce::SetAttenuation(const Real& Amount, const Mezzanine::AttenuationStyle& Style, const Vector3& Source)
00668 {
00669 AttenAmount = Amount;
00670 AttenStyle = Style;
00671 AttenSource = Source;
00672 }
00673
00674 Mezzanine::AttenuationStyle FieldOfForce::GetAttenuationStyle() const
00675 {
00676 return AttenStyle;
00677 }
00678
00679 Real FieldOfForce::GetAttenuationAmount() const
00680 {
00681 return AttenAmount;
00682 }
00683
00684 Vector3 FieldOfForce::GetAttenuationSource() const
00685 {
00686 return AttenSource;
00687 }
00688
00689 WorldAndSceneObjectType FieldOfForce::GetType() const
00690 {
00691 return Mezzanine::WSO_AEFieldOfForce;
00692 }
00693 }
00694
00695 #endif