diff --git a/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/PubUtilLib/plAvatar/plAvatar.vcxproj b/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/PubUtilLib/plAvatar/plAvatar.vcxproj
index 4f719944..bdff6ddc 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/PubUtilLib/plAvatar/plAvatar.vcxproj
+++ b/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/PubUtilLib/plAvatar/plAvatar.vcxproj
@@ -328,7 +328,6 @@
%(PreprocessorDefinitions)
%(PreprocessorDefinitions)
-
Disabled
Disabled
@@ -555,7 +554,6 @@
%(PreprocessorDefinitions)
%(PreprocessorDefinitions)
-
Disabled
Disabled
@@ -807,7 +805,6 @@
-
@@ -825,7 +822,6 @@
-
diff --git a/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/PubUtilLib/plAvatar/plAvatar.vcxproj.filters b/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/PubUtilLib/plAvatar/plAvatar.vcxproj.filters
index 4f4cb2d2..a1d89d7d 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/PubUtilLib/plAvatar/plAvatar.vcxproj.filters
+++ b/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/PubUtilLib/plAvatar/plAvatar.vcxproj.filters
@@ -35,9 +35,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -86,9 +83,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -163,9 +157,6 @@
Header Files
-
- Header Files
-
Header Files
@@ -217,9 +208,6 @@
Header Files
-
- Header Files
-
Header Files
diff --git a/MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/PubUtilLib/plAvatar/plAvatar.vcproj b/MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/PubUtilLib/plAvatar/plAvatar.vcproj
index ae798721..f8d53b38 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/PubUtilLib/plAvatar/plAvatar.vcproj
+++ b/MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/PubUtilLib/plAvatar/plAvatar.vcproj
@@ -282,26 +282,6 @@
PreprocessorDefinitions=""/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -993,9 +950,6 @@
-
-
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfAudio/plListener.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfAudio/plListener.cpp
index 3dd47931..48401135 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfAudio/plListener.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfAudio/plListener.cpp
@@ -57,7 +57,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../plAvatar/plAvatarMgr.h"
#include "../plAvatar/plArmatureMod.h"
-#include "../plAvatar/plAvCallbackAction.h"
+#include "../plAvatar/plPhysicalControllerCore.h"
hsBool plListener::fPrintDbgInfo = false;
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfCamera/plCameraModifier.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfCamera/plCameraModifier.cpp
index 0a40eb29..90397012 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfCamera/plCameraModifier.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfCamera/plCameraModifier.cpp
@@ -63,7 +63,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../pnSceneObject/plSimulationInterface.h"
#include "../plAvatar/plAvatarMgr.h"
#include "../plAvatar/plArmatureMod.h"
-#include "../plAvatar/plAvCallbackAction.h"
+#include "../plAvatar/plPhysicalControllerCore.h"
// new stuff
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/pySceneObject.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/pySceneObject.cpp
index c7bacef2..20e8dcc2 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/pySceneObject.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/FeatureLib/pfPython/pySceneObject.cpp
@@ -545,7 +545,7 @@ hsBool pySceneObject::IsAvatar()
return false;
}
-#include "../plAvatar/plAvCallbackAction.h"
+#include "../plAvatar/plPhysicalControllerCore.h"
PyObject* pySceneObject::GetAvatarVelocity()
{
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAnimStage.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAnimStage.cpp
index 917ff1e0..129c052e 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAnimStage.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAnimStage.cpp
@@ -39,7 +39,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
Mead, WA 99021
*==LICENSE==*/
-#include "plAvCallbackAction.h" // must be first: references havok new
// singular
#include "plAnimStage.h"
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAntiGravAction.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAntiGravAction.cpp
deleted file mode 100644
index e78d319e..00000000
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAntiGravAction.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*==LICENSE==*
-
-CyanWorlds.com Engine - MMOG client, server and tools
-Copyright (C) 2011 Cyan Worlds, Inc.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-Additional permissions under GNU GPL version 3 section 7
-
-If you modify this Program, or any covered work, by linking or
-combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
-NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
-JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
-(or a modified version of those libraries),
-containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
-PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
-JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
-licensors of this Program grant you additional
-permission to convey the resulting work. Corresponding Source for a
-non-source form of such a combination shall include the source code for
-the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
-work.
-
-You can contact Cyan Worlds, Inc. by email legal@cyan.com
- or by snail mail at:
- Cyan Worlds, Inc.
- 14617 N Newport Hwy
- Mead, WA 99021
-
-*==LICENSE==*/
-#if 0
-// havok first
-#include
-#include
-
-#include "plAntiGravAction.h"
-
-#include "../pnSceneObject/plSceneObject.h"
-#include "../plHavok1/plHKPhysical.h"
-#include "../plAvatar/plSwimRegion.h"
-#include "hsTimer.h"
-
-// This is meant to be a specific physicsAction for the swim behavior
-plAntiGravAction::plAntiGravAction(plHKPhysical *physical, plAGApplicator *rootApp) :
- plAnimatedCallbackAction(physical, rootApp),
- fOnGround(false),
- fBuoyancy(1.f),
- fSurfaceHeight(0.f),
- fCurrentRegion(nil),
- fHadContacts(false)
-{
-}
-
-plSimDefs::ActionType plAntiGravAction::GetType()
-{
- return plSimDefs::kAntiGravAction;
-}
-
-void plAntiGravAction::apply(Havok::Subspace &space, Havok::hkTime time)
-{
- double elapsed = time.asDouble() - getRefresh().asDouble();
- setRefresh(time);
-
- IAdjustBuoyancy();
- Havok::RigidBody *body = fPhysical->GetBody();
- float mass = body->getMass();
- Havok::Vector3 gravity = space.getGravity();
- Havok::Vector3 force = -gravity * (mass * fBuoyancy);
- body->applyForce(force);
-
- hsVector3 vel;
- fPhysical->GetLinearVelocitySim(vel);
- fAnimPosVel.fZ = vel.fZ;
-
- hsVector3 linCurrent(0.f, 0.f, 0.f);
- hsScalar angCurrent = 0.f;
- if (fCurrentRegion != nil)
- fCurrentRegion->GetCurrent(fPhysical, linCurrent, angCurrent, (hsScalar)elapsed);
-
- int numContacts = fPhysical->GetNumContacts();
- fHadContacts = (numContacts > 0);
-
- const Havok::Vector3 straightUp(0.0f, 0.0f, 1.0f);
- fOnGround = false;
- int i;
- for (i = 0; i < numContacts; i++)
- {
- const Havok::ContactPoint *contact = fPhysical->GetContactPoint(i);
- hsScalar dotUp = straightUp.dot(contact->m_normal);
- if (dotUp > .5)
- {
- fOnGround = true;
- break;
- }
- }
-
- fPhysical->SetLinearVelocitySim(fAnimPosVel + linCurrent);
- fPhysical->SetAngularVelocitySim(hsVector3(0.f, 0.f, fAnimAngVel + fTurnStr + angCurrent));
-}
-
-void plAntiGravAction::SetSurface(plSwimRegionInterface *region, hsScalar surfaceHeight)
-{
- fCurrentRegion = region;
- if (region != nil)
- fSurfaceHeight = surfaceHeight;
-}
-
-void plAntiGravAction::IAdjustBuoyancy()
-{
- // "surface depth" refers to the depth our handle object should be below
- // the surface for the avatar to be "at the surface"
- static const float surfaceDepth = 4.0f;
- // 1.0 = neutral buoyancy
- // 0 = no buoyancy (normal gravity)
- // 2.0 = opposite of gravity, floating upwards
- static const float buoyancyAtSurface = 1.0f;
-
- if (fCurrentRegion == nil)
- {
- fBuoyancy = 0.f;
- return;
- }
-
- hsMatrix44 l2w, w2l;
- fPhysical->GetTransform(l2w, w2l);
- float depth = fSurfaceHeight - surfaceDepth - l2w.GetTranslate().fZ;
- if (depth < -1)
- fBuoyancy = 0.f; // Same as being above ground. Plain old gravity.
- else if (depth < 0)
- fBuoyancy = 1 + depth;
- else
- {
- hsVector3 vel;
- fPhysical->GetLinearVelocitySim(vel);
- if (vel.fZ > 0)
- {
- if (vel.fZ > fCurrentRegion->fMaxUpwardVel)
- {
- vel.fZ = fCurrentRegion->fMaxUpwardVel;
- fPhysical->SetLinearVelocitySim(vel);
- }
- else
- {
- if (depth > 1)
- fBuoyancy = fCurrentRegion->fUpBuoyancy;
- else
- fBuoyancy = (fCurrentRegion->fUpBuoyancy - 1) * depth + 1;
- }
- }
- else
- {
- if (depth > 1)
- fBuoyancy = fCurrentRegion->fDownBuoyancy;
- else
- fBuoyancy = (fCurrentRegion->fDownBuoyancy - 1) * depth + 1;
- }
- }
-}
-
-#endif
\ No newline at end of file
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAntiGravAction.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAntiGravAction.h
deleted file mode 100644
index f8dd2125..00000000
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAntiGravAction.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*==LICENSE==*
-
-CyanWorlds.com Engine - MMOG client, server and tools
-Copyright (C) 2011 Cyan Worlds, Inc.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-Additional permissions under GNU GPL version 3 section 7
-
-If you modify this Program, or any covered work, by linking or
-combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
-NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
-JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
-(or a modified version of those libraries),
-containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
-PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
-JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
-licensors of this Program grant you additional
-permission to convey the resulting work. Corresponding Source for a
-non-source form of such a combination shall include the source code for
-the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
-work.
-
-You can contact Cyan Worlds, Inc. by email legal@cyan.com
- or by snail mail at:
- Cyan Worlds, Inc.
- 14617 N Newport Hwy
- Mead, WA 99021
-
-*==LICENSE==*/
-#if 0//ndef PL_ANTI_GRAV_ACTION_H
-#define PL_ANTI_GRAV_ACTION_H
-
-#include "plAvCallbackAction.h"
-
-class plSwimRegionInterface;
-
-class plAntiGravAction : public plAnimatedCallbackAction
-{
-public:
- plAntiGravAction(plHKPhysical *physical, plAGApplicator *rootApp);
-
- /** Return the type of the action as defined in the enum plSimDefs::ActionType.
- Used to retrieve actions by entity/type indexing, and to
- reuse actions that can be shared between entities. */
- virtual plSimDefs::ActionType GetType();
-
- /** Called by Havok at substep frequency. */
- void apply(Havok::Subspace &s, Havok::hkTime time);
-
- void SetSurface(plSwimRegionInterface *region, hsScalar surfaceHeight);
- hsScalar GetBuoyancy() { return fBuoyancy; }
- hsBool IsOnGround() { return fOnGround; }
- hsBool HadContacts() { return fHadContacts; }
-
-protected:
- void IAdjustBuoyancy();
-
- hsBool fOnGround;
- hsBool fHadContacts;
- hsScalar fBuoyancy;
- hsScalar fSurfaceHeight;
- plSwimRegionInterface *fCurrentRegion;
-};
-
-#endif
-
-
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureEffects.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureEffects.cpp
index 2f6907f6..16835813 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureEffects.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureEffects.cpp
@@ -39,7 +39,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
Mead, WA 99021
*==LICENSE==*/
-#include "plAvCallbackAction.h"
#include "../plStatusLog/plStatusLog.h"
#include "plArmatureEffects.h"
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp
index 8f879739..051219c7 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.cpp
@@ -54,7 +54,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plAvBrainHuman.h"
#include "plMatrixChannel.h"
#include "plAvatarTasks.h"
-#include "plAvCallbackAction.h"
+#include "plPhysicalControllerCore.h"
#include "plAvBrainCritter.h"
// global
@@ -534,8 +534,7 @@ void plArmatureModBase::EnablePhysics(hsBool status, UInt16 reason /* = kDisable
// i.e. normal enabled physical
void plArmatureModBase::EnablePhysicsKinematic(hsBool status)
{
- if (fController)
- fController->Kinematic(status);
+ EnablePhysics(!status, kDisableReasonKinematic);
}
void plArmatureModBase::EnableDrawing(hsBool status, UInt16 reason /* = kDisableReasonUnknown */)
@@ -2684,19 +2683,7 @@ void plArmatureMod::DumpToDebugDisplay(int &x, int &y, int lineHeight, char *str
debugTxt.DrawString(x, y, strBuf);
y += lineHeight;
- hsPoint3 kPos;
- char *kinematic = "n.a.";
const char* frozen = "n.a.";
- if (fController)
- {
- fController->GetKinematicPosition(kPos);
- kinematic = fController->IsKinematic() ? "on" : "off";
- }
- sprintf(strBuf, "kinematc(world): %.2f, %.2f, %.2f Kinematic: %3s",
- kPos.fX, kPos.fY, kPos.fZ,kinematic);
- debugTxt.DrawString(x, y, strBuf);
- y += lineHeight;
-
if (fController)
frozen = fController->IsEnabled() ? "no" : "yes";
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h
index afc1cddf..8353125e 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plArmatureMod.h
@@ -145,6 +145,7 @@ public:
kDisableReasonCCR = 0x0008,
kDisableReasonVehicle = 0x0010,
kDisableReasonGenericBrain = 0x0020,
+ kDisableReasonKinematic = 0x0040
};
void EnablePhysics(hsBool status, UInt16 reason = kDisableReasonUnknown);
void EnablePhysicsKinematic(hsBool status);
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainCritter.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainCritter.cpp
index 7a6ad23f..b86912cf 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainCritter.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainCritter.cpp
@@ -42,7 +42,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsConfig.h"
#include "hsWindows.h"
-#include "plAvCallbackAction.h"
+#include "plPhysicalControllerCore.h"
#include "plAvBrainCritter.h"
#include "plAvBrainHuman.h"
#include "plArmatureMod.h"
@@ -127,7 +127,7 @@ protected:
///////////////////////////////////////////////////////////////////////////////
-plAvBrainCritter::plAvBrainCritter(): fCallbackAction(nil), fCurMode(kIdle), fNextMode(kIdle), fFadingNextBehavior(true),
+plAvBrainCritter::plAvBrainCritter(): fWalkingStrategy(nil), fCurMode(kIdle), fNextMode(kIdle), fFadingNextBehavior(true),
fLocallyControlled(false), fAvoidingAvatars(false), fFinalGoalPos(0, 0, 0), fImmediateGoalPos(0, 0, 0), fDotGoal(0),
fAngRight(0)
{
@@ -145,8 +145,8 @@ plAvBrainCritter::~plAvBrainCritter()
fBehaviors[i] = nil;
}
- delete fCallbackAction;
- fCallbackAction = nil;
+ delete fWalkingStrategy;
+ fWalkingStrategy = nil;
fUserBehaviors.clear();
fReceivers.clear();
@@ -169,8 +169,8 @@ hsBool plAvBrainCritter::Apply(double time, hsScalar elapsed)
IProcessBehavior(time, elapsed); // just continue with the currently running one
// update our controller to keep us turned and moving to where we want to go
- fCallbackAction->RecalcVelocity(time, time - elapsed);
- fCallbackAction->SetTurnStrength(IGetTurnStrength(time));
+ fWalkingStrategy->SetTurnStrength(IGetTurnStrength(time));
+ fWalkingStrategy->RecalcVelocity(time, elapsed);
return plArmatureBrain::Apply(time, elapsed);
}
@@ -190,13 +190,13 @@ void plAvBrainCritter::Activate(plArmatureModBase* avMod)
IInitBaseAnimations();
// create the controller if we haven't done so already
- if (!fCallbackAction)
+ if (!fWalkingStrategy)
{
plSceneObject* avObj = fArmature->GetTarget(0);
plAGModifier* agMod = const_cast(plAGModifier::ConvertNoRef(FindModifierByClass(avObj, plAGModifier::Index())));
plPhysicalControllerCore* controller = avMod->GetController();
- fCallbackAction = TRACKED_NEW plWalkingController(avObj, agMod->GetApplicator(kAGPinTransform), controller);
- fCallbackAction->ActivateController();
+ fWalkingStrategy = TRACKED_NEW plWalkingStrategy(agMod->GetApplicator(kAGPinTransform), controller);
+ controller->SetMovementStrategy(fWalkingStrategy);
}
// tell people that care that we are good to go
@@ -226,7 +226,7 @@ void plAvBrainCritter::Resume()
// fade in the idle
fNextMode = kIdle;
- fCallbackAction->Reset(false);
+ fWalkingStrategy->Reset(false);
plArmatureBrain::Resume();
}
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainCritter.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainCritter.h
index ab44245b..7b6359d7 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainCritter.h
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainCritter.h
@@ -47,7 +47,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../pnKeyedObject/plKey.h"
class plArmatureMod;
-class plWalkingController;
+class plWalkingStrategy;
class plAIMsg;
class plAvBrainCritter : public plArmatureBrain
@@ -127,8 +127,6 @@ public:
virtual void DumpToDebugDisplay(int& x, int& y, int lineHeight, char* strBuf, plDebugText& debugTxt);
- plWalkingController* GetCallbackAction() {return fCallbackAction;}
-
// For the console
static bool fDrawDebug;
@@ -152,7 +150,7 @@ protected:
std::vector IAvatarsICanSee() const;
std::vector IAvatarsICanHear() const;
- plWalkingController* fCallbackAction;
+ plWalkingStrategy* fWalkingStrategy;
int fCurMode; // current behavior we are running
int fNextMode; // the next behavior to run (-1 if we aren't switching on next eval)
bool fFadingNextBehavior; // is the next behavior supposed to blend?
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainDrive.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainDrive.cpp
index 9521cf95..1a5b6cb5 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainDrive.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainDrive.cpp
@@ -42,7 +42,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
// local includes
#include "plAvBrainDrive.h"
#include "plArmatureMod.h"
-#include "plAvCallbackAction.h"
// global includes
#include "hsTimer.h"
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainGeneric.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainGeneric.cpp
index d20862b9..32655893 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainGeneric.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainGeneric.cpp
@@ -39,7 +39,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
Mead, WA 99021
*==LICENSE==*/
-#include "plAvCallbackAction.h" // havok-contaminated file: must go first
// singular
#include "plAvBrainGeneric.h"
@@ -94,7 +93,6 @@ plAvBrainGeneric::plAvBrainGeneric()
fFadeIn(0.0f),
fFadeOut(0.0f),
fMoveMode(kMoveRelative),
- fCallbackAction(nil),
fBodyUsage(plAGAnim::kBodyUnknown)
{
}
@@ -122,7 +120,6 @@ plAvBrainGeneric::plAvBrainGeneric(plAnimStageVec *stages,
fFadeIn(fadeIn),
fFadeOut(fadeOut),
fMoveMode(moveMode),
- fCallbackAction(nil),
fBodyUsage(plAGAnim::kBodyUnknown)
{
}
@@ -141,7 +138,6 @@ plAvBrainGeneric::plAvBrainGeneric(UInt32 exitFlags, float fadeIn, float fadeOut
fFadeIn(fadeIn),
fFadeOut(fadeOut),
fMoveMode(moveMode),
- fCallbackAction(nil),
fBodyUsage(plAGAnim::kBodyUnknown)
{
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainGeneric.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainGeneric.h
index 79be24fc..fc3c16c2 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainGeneric.h
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainGeneric.h
@@ -49,7 +49,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
class plAnimStage;
class plAnimStageVec;
class plAvBrainGenericMsg;
-class plHorizontalFreezeAction;
class plNotifyMsg;
/** \class plAvBrainGeneric
@@ -300,7 +299,6 @@ protected:
int fCurStage; // which stage are we playing? (zero-based)
BrainType fType; // what type of brain are we?
UInt32 fExitFlags; // what will cause us to exit?
- plHorizontalFreezeAction *fCallbackAction;
bool fForward; // are we currently moving forward or backward through the stages?
// this is used by the "auto-" movement types in the stages
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp
index b6acd180..62ac40e5 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.cpp
@@ -42,9 +42,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsConfig.h"
#include "hsWindows.h"
-#include "plAvCallbackAction.h" // subclasses a havok object; must be in first include section
-
-
+#include "plPhysicalControllerCore.h"
#include "plAvBrainHuman.h"
#include "plAvBrainClimb.h"
#include "plAvBrainDrive.h"
@@ -142,7 +140,7 @@ plAvBrainHuman::TurnCurve plAvBrainHuman::GetTurnCurve(hsBool walk)
plAvBrainHuman::plAvBrainHuman(bool isActor /* = false */) :
fHandleAGMod(nil),
fStartedTurning(-1.0f),
- fCallbackAction(nil),
+ fWalkingStrategy(nil),
fPreconditions(0),
fIsActor(isActor)
{
@@ -156,9 +154,9 @@ hsBool plAvBrainHuman::Apply(double timeNow, hsScalar elapsed)
#endif
// SetTurnStrength runs first to make sure it's set to a sane value
// (or cleared). RunStandardBehaviors may overwrite it.
- fCallbackAction->SetTurnStrength(IGetTurnStrength(timeNow));
+ fWalkingStrategy->SetTurnStrength(IGetTurnStrength(timeNow));
RunStandardBehaviors(timeNow, elapsed);
- fCallbackAction->RecalcVelocity(timeNow, timeNow - elapsed, (fPreconditions & plHBehavior::kBehaviorTypeNeedsRecalcMask));
+ fWalkingStrategy->RecalcVelocity(timeNow, elapsed, (fPreconditions & plHBehavior::kBehaviorTypeNeedsRecalcMask));
plArmatureBrain::Apply(timeNow, elapsed);
#ifndef _DEBUG
@@ -179,13 +177,13 @@ void plAvBrainHuman::Activate(plArmatureModBase *avMod)
IInitBoneMap();
IInitAnimations();
- if (!fCallbackAction)
+ if (!fWalkingStrategy)
{
plSceneObject* avObj = fArmature->GetTarget(0);
plAGModifier* agMod = const_cast(plAGModifier::ConvertNoRef(FindModifierByClass(avObj, plAGModifier::Index())));
plPhysicalControllerCore* controller = avMod->GetController();
- fCallbackAction = TRACKED_NEW plWalkingController(avObj, agMod->GetApplicator(kAGPinTransform), controller);
- fCallbackAction->ActivateController();
+ fWalkingStrategy = TRACKED_NEW plWalkingStrategy(agMod->GetApplicator(kAGPinTransform), controller);
+ controller->SetMovementStrategy(fWalkingStrategy);
}
@@ -330,8 +328,8 @@ plAvBrainHuman::~plAvBrainHuman()
delete fBehaviors[i];
fBehaviors.Reset();
- delete fCallbackAction;
- fCallbackAction = nil;
+ delete fWalkingStrategy;
+ fWalkingStrategy = nil;
}
void plAvBrainHuman::Deactivate()
@@ -364,7 +362,7 @@ void plAvBrainHuman::Resume()
if (fAvMod->GetInputFlag(S_PUSH_TO_TALK))
IChatOn();
- fCallbackAction->Reset(false);
+ fWalkingStrategy->Reset(false);
plArmatureBrain::Resume();
}
@@ -468,25 +466,23 @@ hsBool plAvBrainHuman::MsgReceive(plMessage * msg)
{
if(ride->Entering())
{
- //plAvBrainRideAnimatedPhysical *rideBrain = TRACKED_NEW plAvBrainRideAnimatedPhysical();
- //fAvMod->PushBrain(rideBrain);
- delete fCallbackAction;
+ // Switch to dynamic walking strategy
+ delete fWalkingStrategy;
plSceneObject* avObj = fArmature->GetTarget(0);
plAGModifier* agMod = const_cast(plAGModifier::ConvertNoRef(FindModifierByClass(avObj, plAGModifier::Index())));
plPhysicalControllerCore* controller = fAvMod->GetController();
- fCallbackAction= TRACKED_NEW plRidingAnimatedPhysicalController(avObj, agMod->GetApplicator(kAGPinTransform), controller);
- fCallbackAction->ActivateController();
-
+ fWalkingStrategy = TRACKED_NEW plDynamicWalkingStrategy(agMod->GetApplicator(kAGPinTransform), controller);
+ controller->SetMovementStrategy(fWalkingStrategy);
}
else
{
- delete fCallbackAction;
+ // Restore default walking strategy
+ delete fWalkingStrategy;
plSceneObject* avObj = fArmature->GetTarget(0);
plAGModifier* agMod = const_cast(plAGModifier::ConvertNoRef(FindModifierByClass(avObj, plAGModifier::Index())));
plPhysicalControllerCore* controller = fAvMod->GetController();
- fCallbackAction= TRACKED_NEW plWalkingController(avObj, agMod->GetApplicator(kAGPinTransform), controller);
- fCallbackAction->ActivateController();
- //hsStatusMessage("Got an exiting ride animated physical message");
+ fWalkingStrategy = TRACKED_NEW plWalkingStrategy(agMod->GetApplicator(kAGPinTransform), controller);
+ controller->SetMovementStrategy(fWalkingStrategy);
}
}
@@ -560,8 +556,8 @@ hsScalar plAvBrainHuman::IGetTurnStrength(double timeNow)
// Turning based on keypress
if ((turnLeftStrength > 0.f)
|| (turnRightStrength > 0.f)
- || (!fCallbackAction->IsOnGround()
- && !fCallbackAction->IsControlledFlight())
+ || (!fWalkingStrategy->IsOnGround()
+ && !fWalkingStrategy->IsControlledFlight())
) {
float t = (float)(timeNow - fStartedTurning);
float turnSpeed;
@@ -593,7 +589,7 @@ hsScalar plAvBrainHuman::IGetTurnStrength(double timeNow)
result += fAvMod->GetKeyTurnStrength() * turnSpeed;
}
- if (!fCallbackAction->IsControlledFlight())
+ if (!fWalkingStrategy->IsControlledFlight())
result += fAvMod->GetAnalogTurnStrength() * maxTurnSpeed;
return result;
@@ -650,7 +646,7 @@ void plAvBrainHuman::ResetIdle()
void plAvBrainHuman::IdleOnly(bool instantOff)
{
- if (!fCallbackAction)
+ if (!fWalkingStrategy)
return;
hsScalar rate = instantOff ? 0.f : 1.f;
@@ -676,7 +672,7 @@ bool plAvBrainHuman::IsMovementZeroBlend()
void plAvBrainHuman::TurnToPoint(hsPoint3 point)
{
- if (!fCallbackAction->IsOnGround() || IsRunningTask() || fAvMod->GetCurrentBrain() != this || !IsMovementZeroBlend())
+ if (!fWalkingStrategy->IsOnGround() || IsRunningTask() || fAvMod->GetCurrentBrain() != this || !IsMovementZeroBlend())
return;
hsPoint3 avPos;
@@ -875,23 +871,23 @@ void plAvBrainHuman::Spawn(double timeNow)
hsBool plAvBrainHuman::LeaveAge()
{
plPhysicalControllerCore* controller = fAvMod->GetController();
- if(!controller->BehavingLikeAnAnimatedPhysical())
+
+ // If our current walking strategy is dynamic, restore the default kinematic strategy.
+ if (!fWalkingStrategy->IsKinematic())
{
- controller->BehaveLikeAnimatedPhysical(true);
- delete fCallbackAction;
+ delete fWalkingStrategy;
plSceneObject* avObj = fArmature->GetTarget(0);
plAGModifier* agMod = const_cast(plAGModifier::ConvertNoRef(FindModifierByClass(avObj, plAGModifier::Index())));
- fCallbackAction= TRACKED_NEW plWalkingController(avObj, agMod->GetApplicator(kAGPinTransform), controller);
- fCallbackAction->ActivateController();
+ fWalkingStrategy = TRACKED_NEW plWalkingStrategy(agMod->GetApplicator(kAGPinTransform), controller);
}
- plArmatureBrain::LeaveAge();
-
+ fWalkingStrategy->Reset(true);
+
+ plArmatureBrain::LeaveAge();
// pin the physical so it doesn't fall when the world is deleted
fAvMod->EnablePhysics(false);
- // this will get set to true when we hit ground
- fCallbackAction->Reset(true);
+
return false;
}
@@ -901,11 +897,10 @@ void plAvBrainHuman::DumpToDebugDisplay(int &x, int &y, int lineHeight, char *st
debugTxt.DrawString(x, y, strBuf);
y += lineHeight;
- const char *grounded = fCallbackAction->IsOnGround() ? "yes" : "no";
- const char *falseGrounded = fCallbackAction->IsOnFalseGround() ? "yes" : "no";
- const char *pushing = (fCallbackAction->GetPushingPhysical() ? (fCallbackAction->GetFacingPushingPhysical() ? "facing" : "behind") : "none");
- sprintf(strBuf, "Ground: %3s, FalseGround: %3s, AirTime: %5.2f (Peak: %5.2f), PushingPhys: %6s",
- grounded, falseGrounded, fCallbackAction->GetAirTime(), fCallbackAction->GetImpactTime(), pushing);
+ const char *grounded = fWalkingStrategy->IsOnGround() ? "yes" : "no";
+ const char *pushing = (fWalkingStrategy->GetPushingPhysical() ? (fWalkingStrategy->GetFacingPushingPhysical() ? "facing" : "behind") : "none");
+ sprintf(strBuf, "Ground: %3s, AirTime: %5.2f (Peak: %5.2f), PushingPhys: %6s",
+ grounded, fWalkingStrategy->GetAirTime(), fWalkingStrategy->GetImpactTime(), pushing);
debugTxt.DrawString(x, y, strBuf);
y += lineHeight;
@@ -1018,8 +1013,8 @@ hsBool Run::PreCondition(double time, float elapsed)
{
if (fAnim)
{
- if (fAvMod->ForwardKeyDown() && fAvMod->FastKeyDown() && fHuBrain->fCallbackAction->IsOnGround() &&
- (!fHuBrain->fCallbackAction->GetPushingPhysical() || !fHuBrain->fCallbackAction->GetFacingPushingPhysical()))
+ if (fAvMod->ForwardKeyDown() && fAvMod->FastKeyDown() && fHuBrain->fWalkingStrategy->IsOnGround() &&
+ (!fHuBrain->fWalkingStrategy->GetPushingPhysical() || !fHuBrain->fWalkingStrategy->GetFacingPushingPhysical()))
return true;
}
return false;
@@ -1029,8 +1024,8 @@ hsBool Walk::PreCondition(double time, float elapsed)
{
if (fAnim)
{
- if (fAvMod->ForwardKeyDown() && !fAvMod->FastKeyDown() && fHuBrain->fCallbackAction->IsOnGround() &&
- (!fHuBrain->fCallbackAction->GetPushingPhysical() || !fHuBrain->fCallbackAction->GetFacingPushingPhysical()))
+ if (fAvMod->ForwardKeyDown() && !fAvMod->FastKeyDown() && fHuBrain->fWalkingStrategy->IsOnGround() &&
+ (!fHuBrain->fWalkingStrategy->GetPushingPhysical() || !fHuBrain->fWalkingStrategy->GetFacingPushingPhysical()))
return true;
}
return false;
@@ -1040,8 +1035,8 @@ hsBool WalkBack::PreCondition(double time, float elapsed)
{
if (fAnim)
{
- if (fAvMod->BackwardKeyDown() && !fAvMod->ForwardKeyDown() && fHuBrain->fCallbackAction->IsOnGround() &&
- (!fHuBrain->fCallbackAction->GetPushingPhysical() || fHuBrain->fCallbackAction->GetFacingPushingPhysical()))
+ if (fAvMod->BackwardKeyDown() && !fAvMod->ForwardKeyDown() && fHuBrain->fWalkingStrategy->IsOnGround() &&
+ (!fHuBrain->fWalkingStrategy->GetPushingPhysical() || fHuBrain->fWalkingStrategy->GetFacingPushingPhysical()))
return true;
}
return false;
@@ -1054,7 +1049,7 @@ hsBool StepLeft::PreCondition(double time, float elapsed)
return ((fAvMod->StrafeLeftKeyDown() || (fAvMod->StrafeKeyDown() && fAvMod->TurnLeftKeyDown())) &&
!(fAvMod->StrafeRightKeyDown() || (fAvMod->StrafeKeyDown() && fAvMod->TurnRightKeyDown())) &&
!(fAvMod->ForwardKeyDown() || fAvMod->BackwardKeyDown()) &&
- fHuBrain->fCallbackAction->IsOnGround());
+ fHuBrain->fWalkingStrategy->IsOnGround());
}
return false;
}
@@ -1066,7 +1061,7 @@ hsBool StepRight::PreCondition(double time, float elapsed)
return ((fAvMod->StrafeRightKeyDown() || (fAvMod->StrafeKeyDown() && fAvMod->TurnRightKeyDown())) &&
!(fAvMod->StrafeLeftKeyDown() || (fAvMod->StrafeKeyDown() && fAvMod->TurnLeftKeyDown())) &&
!(fAvMod->ForwardKeyDown() || fAvMod->BackwardKeyDown()) &&
- fHuBrain->fCallbackAction->IsOnGround());
+ fHuBrain->fWalkingStrategy->IsOnGround());
}
return false;
}
@@ -1107,8 +1102,8 @@ hsBool MovingTurnLeft::PreCondition(double time, float elapsed)
{
if (fAvMod->GetTurnStrength() > 0)
{
- if (fHuBrain->fCallbackAction->IsOnGround() && (fAvMod->ForwardKeyDown() || fAvMod->BackwardKeyDown()) &&
- (!fHuBrain->fCallbackAction->GetPushingPhysical() || !fHuBrain->fCallbackAction->GetFacingPushingPhysical()))
+ if (fHuBrain->fWalkingStrategy->IsOnGround() && (fAvMod->ForwardKeyDown() || fAvMod->BackwardKeyDown()) &&
+ (!fHuBrain->fWalkingStrategy->GetPushingPhysical() || !fHuBrain->fWalkingStrategy->GetFacingPushingPhysical()))
return true;
}
return false;
@@ -1118,8 +1113,8 @@ hsBool MovingTurnRight::PreCondition(double time, float elapsed)
{
if (fAvMod->GetTurnStrength() < 0)
{
- if (fHuBrain->fCallbackAction->IsOnGround() && (fAvMod->ForwardKeyDown() || fAvMod->BackwardKeyDown()) &&
- (!fHuBrain->fCallbackAction->GetPushingPhysical() || !fHuBrain->fCallbackAction->GetFacingPushingPhysical()))
+ if (fHuBrain->fWalkingStrategy->IsOnGround() && (fAvMod->ForwardKeyDown() || fAvMod->BackwardKeyDown()) &&
+ (!fHuBrain->fWalkingStrategy->GetPushingPhysical() || !fHuBrain->fWalkingStrategy->GetFacingPushingPhysical()))
return true;
}
@@ -1128,14 +1123,14 @@ hsBool MovingTurnRight::PreCondition(double time, float elapsed)
void Jump::IStart()
{
- fHuBrain->fCallbackAction->EnableControlledFlight(true);
+ fHuBrain->fWalkingStrategy->EnableControlledFlight(true);
plHBehavior::IStart();
}
void Jump::IStop()
{
- fHuBrain->fCallbackAction->EnableControlledFlight(false);
+ fHuBrain->fWalkingStrategy->EnableControlledFlight(false);
plHBehavior::IStop();
}
@@ -1146,7 +1141,7 @@ hsBool StandingJump::PreCondition(double time, float elapsed)
{
if (GetStrength() > 0.f)
{
- if (!fHuBrain->fCallbackAction->IsControlledFlight() ||
+ if (!fHuBrain->fWalkingStrategy->IsControlledFlight() ||
fAnim->GetTimeConvert()->WorldToAnimTimeNoUpdate(time) >= fAnim->GetTimeConvert()->GetEnd())
{
return false;
@@ -1158,7 +1153,7 @@ hsBool StandingJump::PreCondition(double time, float elapsed)
if (fAvMod->JumpKeyDown() &&
!fAvMod->ForwardKeyDown() &&
fAnim->GetBlend() == 0.0f &&
- fHuBrain->fCallbackAction->IsOnGround())
+ fHuBrain->fWalkingStrategy->IsOnGround())
{
if (fAvMod->ConsumeJump())
return true;
@@ -1174,7 +1169,7 @@ hsBool WalkingJump::PreCondition(double time, float elapsed)
{
if (GetStrength() > 0.f)
{
- if (!fHuBrain->fCallbackAction->IsControlledFlight() ||
+ if (!fHuBrain->fWalkingStrategy->IsControlledFlight() ||
fAnim->GetTimeConvert()->WorldToAnimTimeNoUpdate(time) >= fAnim->GetTimeConvert()->GetEnd())
{
return false;
@@ -1187,8 +1182,8 @@ hsBool WalkingJump::PreCondition(double time, float elapsed)
!fAvMod->FastKeyDown() &&
fAvMod->ForwardKeyDown() &&
fAnim->GetBlend() == 0.0f &&
- fHuBrain->fCallbackAction->IsOnGround() &&
- (!fHuBrain->fCallbackAction->GetPushingPhysical() || !fHuBrain->fCallbackAction->GetFacingPushingPhysical()))
+ fHuBrain->fWalkingStrategy->IsOnGround() &&
+ (!fHuBrain->fWalkingStrategy->GetPushingPhysical() || !fHuBrain->fWalkingStrategy->GetFacingPushingPhysical()))
{
if (fAvMod->ConsumeJump())
return true;
@@ -1204,7 +1199,7 @@ hsBool RunningJump::PreCondition(double time, float elapsed)
{
if (GetStrength() > 0.f)
{
- if (!fHuBrain->fCallbackAction->IsControlledFlight() ||
+ if (!fHuBrain->fWalkingStrategy->IsControlledFlight() ||
fAnim->GetTimeConvert()->WorldToAnimTimeNoUpdate(time) >= fAnim->GetTimeConvert()->GetEnd())
{
return false;
@@ -1217,8 +1212,8 @@ hsBool RunningJump::PreCondition(double time, float elapsed)
fAvMod->ForwardKeyDown() &&
fAvMod->FastKeyDown() &&
fAnim->GetBlend() == 0.0f &&
- fHuBrain->fCallbackAction->IsOnGround() &&
- (!fHuBrain->fCallbackAction->GetPushingPhysical() || !fHuBrain->fCallbackAction->GetFacingPushingPhysical()))
+ fHuBrain->fWalkingStrategy->IsOnGround() &&
+ (!fHuBrain->fWalkingStrategy->GetPushingPhysical() || !fHuBrain->fWalkingStrategy->GetFacingPushingPhysical()))
{
if (fAvMod->ConsumeJump())
return true;
@@ -1243,13 +1238,13 @@ hsBool RunningImpact::PreCondition(double time, float elapsed)
{
if (fDuration > 0.0f)
fDuration = fDuration - elapsed;
- else if (fHuBrain->fCallbackAction->IsOnGround() && fHuBrain->fCallbackAction->GetImpactTime() > kMinAirTime)
+ else if (fHuBrain->fWalkingStrategy->IsOnGround() && fHuBrain->fWalkingStrategy->GetImpactTime() > kMinAirTime)
{
- if (fHuBrain->fCallbackAction->GetImpactVelocity().fZ < -kMinImpactVel)
+ if (fHuBrain->fWalkingStrategy->GetImpactVelocity().fZ < -kMinImpactVel)
{
- if (fHuBrain->fCallbackAction->GetImpactVelocity().fY < kRunningImpactThresh)
+ if (fHuBrain->fWalkingStrategy->GetImpactVelocity().fY < kRunningImpactThresh)
{
- fMaxBlend = 0.5f + (0.5f * (-fHuBrain->fCallbackAction->GetImpactVelocity().fZ / (kFullImpactVel - kMinImpactVel)));
+ fMaxBlend = 0.5f + (0.5f * (-fHuBrain->fWalkingStrategy->GetImpactVelocity().fZ / (kFullImpactVel - kMinImpactVel)));
if (fMaxBlend > 1)
fMaxBlend = 1;
fDuration = 1.0f / fFadeIn;
@@ -1273,13 +1268,13 @@ hsBool GroundImpact::PreCondition(double time, float elapsed)
bool result = false;
if (fDuration > 0.0f)
fDuration = fDuration - elapsed;
- else if (fHuBrain->fCallbackAction->IsOnGround() && fHuBrain->fCallbackAction->GetImpactTime() > kMinAirTime)
+ else if (fHuBrain->fWalkingStrategy->IsOnGround() && fHuBrain->fWalkingStrategy->GetImpactTime() > kMinAirTime)
{
- if (fHuBrain->fCallbackAction->GetImpactVelocity().fZ < -kMinImpactVel)
+ if (fHuBrain->fWalkingStrategy->GetImpactVelocity().fZ < -kMinImpactVel)
{
- if (fHuBrain->fCallbackAction->GetImpactVelocity().fY >= kRunningImpactThresh)
+ if (fHuBrain->fWalkingStrategy->GetImpactVelocity().fY >= kRunningImpactThresh)
{
- fMaxBlend = 0.5f + (0.5f * (-fHuBrain->fCallbackAction->GetImpactVelocity().fZ / (kFullImpactVel - kMinImpactVel)));
+ fMaxBlend = 0.5f + (0.5f * (-fHuBrain->fWalkingStrategy->GetImpactVelocity().fZ / (kFullImpactVel - kMinImpactVel)));
if (fMaxBlend > 1)
fMaxBlend = 1;
fDuration = 1.0f / fFadeIn;
@@ -1298,7 +1293,7 @@ void GroundImpact::IStop()
hsBool Fall::PreCondition(double time, float elapsed)
{
- return !fHuBrain->fCallbackAction->IsOnGround() && fHuBrain->fCallbackAction->HitGroundInThisAge();
+ return !fHuBrain->fWalkingStrategy->IsOnGround() && fHuBrain->fWalkingStrategy->HitGroundInThisAge();
}
void Fall::Process(double time, float elapsed)
@@ -1310,7 +1305,7 @@ void Fall::Process(double time, float elapsed)
if (fAnim && fAnim->GetBlend() > 0.8)
{
float panicThresh = plAvBrainHuman::kAirTimePanicThreshold;
- if (panicThresh > 0.0f && fHuBrain->fCallbackAction->GetAirTime() > panicThresh)
+ if (panicThresh > 0.0f && fHuBrain->fWalkingStrategy->GetAirTime() > panicThresh)
{
fHuBrain->IdleOnly(); // clear the fall state; we're going somewhere new
fAvMod->PanicLink();
@@ -1327,7 +1322,7 @@ void Push::Process(double time, float elapsed)
fAvMod->GetPositionAndRotationSim(&pos, &rot);
hsPoint3 lookAt;
- fHuBrain->fCallbackAction->GetPushingPhysical()->GetPositionSim(lookAt);
+ fHuBrain->fWalkingStrategy->GetPushingPhysical()->GetPositionSim(lookAt);
hsVector3 up(0.f, 0.f, 1.f);
hsScalar angle = hsATan2(lookAt.fY - pos.fY, lookAt.fX - pos.fX) + hsScalarPI / 2;
hsQuat targRot(angle, &up);
@@ -1341,23 +1336,23 @@ void Push::Process(double time, float elapsed)
globFwd = rot.Rotate(&globFwd);
if (globFwd.fX < 0)
- fHuBrain->fCallbackAction->SetTurnStrength(-turnSpeed);
+ fHuBrain->fWalkingStrategy->SetTurnStrength(-turnSpeed);
else
- fHuBrain->fCallbackAction->SetTurnStrength(turnSpeed);
+ fHuBrain->fWalkingStrategy->SetTurnStrength(turnSpeed);
}
//hsBool PushIdle::PreCondition(double time, float elapsed)
//{
-// return (fHuBrain->fCallbackAction->GetPushingPhysical() &&
-// fHuBrain->fCallbackAction->IsOnGround() &&
+// return (fHuBrain->fWalkingStrategy->GetPushingPhysical() &&
+// fHuBrain->fWalkingStrategy->IsOnGround() &&
// !fAvMod->TurnLeftKeyDown() && !fAvMod->TurnRightKeyDown()
// && fAvMod->GetTurnStrength() == 0);
//}
hsBool PushWalk::PreCondition(double time, float elapsed)
{
- return (fHuBrain->fCallbackAction->GetPushingPhysical() && fHuBrain->fCallbackAction->GetFacingPushingPhysical() &&
- fHuBrain->fCallbackAction->IsOnGround() &&
+ return (fHuBrain->fWalkingStrategy->GetPushingPhysical() && fHuBrain->fWalkingStrategy->GetFacingPushingPhysical() &&
+ fHuBrain->fWalkingStrategy->IsOnGround() &&
fAvMod->ForwardKeyDown());
}
@@ -1372,7 +1367,7 @@ bool PushSimpleMultiStage(plArmatureMod *avatar, const char *enterAnim, const ch
{
plAvBrainHuman *huBrain = plAvBrainHuman::ConvertNoRef(avatar->FindBrainByClass(plAvBrainHuman::Index()));
const char *names[3] = {enterAnim, idleAnim, exitAnim};
- if (!huBrain || !huBrain->fCallbackAction->IsOnGround() || !huBrain->fCallbackAction->HitGroundInThisAge() || huBrain->IsRunningTask() ||
+ if (!huBrain || !huBrain->fWalkingStrategy->IsOnGround() || !huBrain->fWalkingStrategy->HitGroundInThisAge() || huBrain->IsRunningTask() ||
!avatar->IsPhysicsEnabled() || avatar->FindMatchingGenericBrain(names, 3))
return false;
@@ -1436,7 +1431,7 @@ bool AvatarEmote(plArmatureMod *avatar, const char *emoteName)
if (swimBrain && swimBrain->IsSwimming())
return false;
- if (huBrain && huBrain->fCallbackAction->IsOnGround() && huBrain->fCallbackAction->HitGroundInThisAge() && !huBrain->IsRunningTask() &&
+ if (huBrain && huBrain->fWalkingStrategy->IsOnGround() && huBrain->fWalkingStrategy->HitGroundInThisAge() && !huBrain->IsRunningTask() &&
emote && !alreadyActive && avatar->IsPhysicsEnabled())
{
plKey avKey = avatar->GetKey();
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h
index 008c0324..1544d151 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainHuman.h
@@ -58,7 +58,7 @@ class plAGAnimInstance;
class plAvTask;
class plAvTaskMsg;
class plAvBrainHuman;
-class plWalkingController;
+class plWalkingStrategy;
class plArmatureUpdateMsg;
class plClimbMsg;
class plControlEventMsg;
@@ -164,7 +164,7 @@ public:
static const hsScalar kControlledFlightThreshold;
static const hsScalar kAirTimeThreshold;
static const hsScalar kAirTimePanicThreshold;
- plWalkingController* fCallbackAction;
+ plWalkingStrategy* fWalkingStrategy;
protected:
plAGAnim *FindCustomAnim(const char *baseName);
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainRideAnimatedPhysical.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainRideAnimatedPhysical.cpp
index 85a1d975..8c71b456 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainRideAnimatedPhysical.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainRideAnimatedPhysical.cpp
@@ -44,7 +44,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plAvBrainHuman.h"
#include "plAvBrain.h"
-#include "plAvCallbackAction.h"
+#include "plPhysicalControllerCore.h"
#include "../plMessage/plRideAnimatedPhysMsg.h"
@@ -52,20 +52,19 @@ void plAvBrainRideAnimatedPhysical::Activate(plArmatureModBase *avMod)
{
plArmatureBrain::Activate(avMod);
IInitAnimations();
- if (!fCallbackAction)
+ if (!fWalkingStrategy)
{
plSceneObject* avObj = fArmature->GetTarget(0);
plAGModifier* agMod = const_cast(plAGModifier::ConvertNoRef(FindModifierByClass(avObj, plAGModifier::Index())));
plPhysicalControllerCore* controller = avMod->GetController();
- fCallbackAction = TRACKED_NEW plRidingAnimatedPhysicalController(avObj, agMod->GetApplicator(kAGPinTransform), controller);
- fCallbackAction->ActivateController();
+ fWalkingStrategy = TRACKED_NEW plDynamicWalkingStrategy(agMod->GetApplicator(kAGPinTransform), controller);
+ controller->SetMovementStrategy(fWalkingStrategy);
}
}
plAvBrainRideAnimatedPhysical::~plAvBrainRideAnimatedPhysical()
{
- delete fCallbackAction;
- fCallbackAction=nil;
-
+ delete fWalkingStrategy;
+ fWalkingStrategy = nil;
}
void plAvBrainRideAnimatedPhysical::Deactivate()
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainRideAnimatedPhysical.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainRideAnimatedPhysical.h
index 6e02bbe2..520dfb96 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainRideAnimatedPhysical.h
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainRideAnimatedPhysical.h
@@ -41,8 +41,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
*==LICENSE==*/
#include "plAvBrainHuman.h"
-class plRidingAnimatedPhysicalController;
-
class plAvBrainRideAnimatedPhysical : public plAvBrainHuman
{
public:
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainSwim.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainSwim.cpp
index 3f0bd8ca..1499b36f 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainSwim.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainSwim.cpp
@@ -46,10 +46,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
//
/////////////////////////////////////////////////////////////////////////////////////////
-//#include
-//#include
-#include "plAntiGravAction.h" // descends from Havok class, so must be included first, like havok objects
-
// singular
#include "plAvBrainSwim.h"
@@ -69,7 +65,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsTimer.h"
#include "plPhysical.h"
#include "plPhysicalControllerCore.h"
-#include "plAvCallbackAction.h"
// other
#include "../plPhysical/plCollisionDetector.h"
#include "../plPipeline/plDebugText.h"
@@ -180,18 +175,16 @@ public:
static const float timeToMaxTurn = 0.5f;
static const float incPerSec = maxTurnSpeed / timeToMaxTurn;
-// hsAssert(0, "fixme physx");
- float oldSpeed = fabs(fSwimBrain->fCallbackAction->GetTurnStrength());
+ float oldSpeed = fabs(fSwimBrain->fSwimStrategy->GetTurnStrength());
float thisInc = elapsed * incPerSec;
float newSpeed = __min(oldSpeed + thisInc, maxTurnSpeed);
- fSwimBrain->fCallbackAction->SetTurnStrength(newSpeed * fAvMod->GetKeyTurnStrength() + fAvMod->GetAnalogTurnStrength());
+ fSwimBrain->fSwimStrategy->SetTurnStrength(newSpeed * fAvMod->GetKeyTurnStrength() + fAvMod->GetAnalogTurnStrength());
// the turn is actually applied during PhysicsUpdate
}
virtual void IStop()
{
-// hsAssert(0, "fixme physx");
- if (fSwimBrain->fCallbackAction)
- fSwimBrain->fCallbackAction->SetTurnStrength(0.0f);
+ if (fSwimBrain->fSwimStrategy)
+ fSwimBrain->fSwimStrategy->SetTurnStrength(0.0f);
plSwimBehavior::IStop();
}
};
@@ -237,7 +230,7 @@ public:
const hsScalar plAvBrainSwim::kMinSwimDepth = 4.0f;
plAvBrainSwim::plAvBrainSwim() :
- fCallbackAction(nil),
+ fSwimStrategy(nil),
fMode(kWalking),
fSurfaceDistance(0.f)
{
@@ -250,12 +243,9 @@ plAvBrainSwim::plAvBrainSwim() :
plAvBrainSwim::~plAvBrainSwim()
{
- if(fCallbackAction)
- {
- IDetachAction();
- delete fCallbackAction;
- fCallbackAction=nil;
- }
+ delete fSwimStrategy;
+ fSwimStrategy = nil;
+
fSurfaceProbeMsg->UnRef();
int i;
@@ -273,8 +263,7 @@ hsBool plAvBrainSwim::Apply(double time, hsScalar elapsed)
fMode = kWading;
plAvBrainHuman *huBrain = plAvBrainHuman::ConvertNoRef(fAvMod->GetNextBrain(this));
-// hsAssert(0, "fixme physx");
- if (huBrain && !huBrain->fCallbackAction->IsOnGround())
+ if (huBrain && !huBrain->fWalkingStrategy->IsOnGround())
{
// We're jumping in! Trigger splash effect (sound)
plArmatureEffectMsg *msg = TRACKED_NEW plArmatureEffectMsg(fAvMod->GetArmatureEffects()->GetKey(), kTime);
@@ -318,8 +307,7 @@ hsBool plAvBrainSwim::Apply(double time, hsScalar elapsed)
// The contact check is so that if buoyancy bobs us a little too high, we don't
// switch to wading only to fall again.
-// hsAssert(0, "fixme physx");
- if (fSurfaceDistance < kMinSwimDepth-.5 && fCallbackAction->HadContacts())
+ if (fSurfaceDistance < kMinSwimDepth-.5 && fSwimStrategy->HadContacts())
IStartWading();
}
else if (fMode == kSwimming3D)
@@ -346,13 +334,12 @@ hsBool plAvBrainSwim::MsgReceive(plMessage *msg)
else
fSurfaceDistance = -100.f;
-// hsAssert(0, "fixme physx");
- if (fCallbackAction)
+ if (fSwimStrategy)
{
if (region)
- fCallbackAction->SetSurface(region, fArmature->GetTarget(0)->GetLocalToWorld().GetTranslate().fZ + fSurfaceDistance);
+ fSwimStrategy->SetSurface(region, fArmature->GetTarget(0)->GetLocalToWorld().GetTranslate().fZ + fSurfaceDistance);
else
- fCallbackAction->SetSurface(nil, 0.f);
+ fSwimStrategy->SetSurface(nil, 0.f);
}
return true;
}
@@ -419,20 +406,16 @@ void plAvBrainSwim::Activate(plArmatureModBase* avMod)
void plAvBrainSwim::Deactivate()
{
plArmatureBrain::Deactivate();
-
- IDetachAction();
}
void plAvBrainSwim::Suspend()
{
- if (fMode == kSwimming2D)
- IDetachAction();
}
void plAvBrainSwim::Resume()
{
if (fMode == kSwimming2D)
- IAttachAction();
+ fSwimStrategy->Reset(false);
}
bool plAvBrainSwim::IsWalking()
@@ -460,8 +443,6 @@ void plAvBrainSwim::IStartWading()
for (i = 0; i < fBehaviors.GetCount(); i++)
fBehaviors[i]->SetStrength(0.f, 2.f);
- IDetachAction();
-
if (fAvMod->IsLocalAvatar())
{
plCameraMsg* pMsg = TRACKED_NEW plCameraMsg;
@@ -479,7 +460,16 @@ void plAvBrainSwim::IStartSwimming(bool is2D)
plArmatureBrain *nextBrain = fAvMod->GetNextBrain(this);
nextBrain->Suspend();
- IAttachAction();
+ if (!fSwimStrategy)
+ {
+ plSceneObject * avObj = fArmature->GetTarget(0);
+ plAGModifier *agMod = const_cast(plAGModifier::ConvertNoRef(FindModifierByClass(avObj, plAGModifier::Index())));
+ plPhysicalControllerCore *controller = fAvMod->GetController();
+ fSwimStrategy = new plSwimStrategy(agMod->GetApplicator(kAGPinTransform), controller);
+ }
+
+ fSwimStrategy->Reset(false);
+
if (is2D)
fMode = kSwimming2D;
else
@@ -509,8 +499,8 @@ hsBool plAvBrainSwim::IProcessSwimming2D(double time, float elapsed)
else
behavior->SetStrength(0.f, 2.f);
}
-// hsAssert(0, "fixme physx");
- fCallbackAction->RecalcVelocity(time, time - elapsed);
+
+ fSwimStrategy->RecalcVelocity(time, elapsed);
return true;
}
@@ -568,59 +558,6 @@ hsBool plAvBrainSwim::IInitAnimations()
return true;
}
-bool plAvBrainSwim::IAttachAction()
-{
- bool result = false;
- if(fAvMod)
- {
-// hsAssert(0, "fixme physx");
- plPhysicalControllerCore *physical = fAvMod->GetController();
-
- if (physical)
- {
- if (!fCallbackAction)
- {
- plSceneObject * avObj = fArmature->GetTarget(0);
- plAGModifier *agMod = const_cast(plAGModifier::ConvertNoRef(FindModifierByClass(avObj, plAGModifier::Index())));
- fCallbackAction = new plSwimmingController(avObj, agMod->GetApplicator(kAGPinTransform),physical);
-// physical->AttachAction(fCallbackAction, true, false);
- result = true;
- }
- else
- {
- fCallbackAction->ActivateController();
- }
-
- }
- }
- return result;
-}
-
-bool plAvBrainSwim::IDetachAction()
-{
- bool result = false;
-
- if (fCallbackAction)
- {
-// hsAssert(0, "fixme physx");
-// plPhysical *physical = fAvMod->GetPhysical();
-//
-// if(physical)
-// {
-// physical->RemoveAction(fCallbackAction);
-// result = true; // there was an action and we removed it
-// }
-
- // TODO: We get a compiler warning about deleting a pointer to an
- // undefined class. So, who knows what the code is actually doing.
- // Seems bad. Just putting a note in here for whoever fixes the
- // physx issue.
- //delete fCallbackAction;
- //fCallbackAction = nil;
- }
- return result;
-}
-
void plAvBrainSwim::IProbeSurface()
{
hsPoint3 ourPos = fAvMod->GetTarget(0)->GetLocalToWorld().GetTranslate();
@@ -676,21 +613,15 @@ void plAvBrainSwim::DumpToDebugDisplay(int &x, int &y, int lineHeight, char *str
debugTxt.DrawString(x, y, strBuf);
y += lineHeight;
+ float buoy = fSwimStrategy ? fSwimStrategy->GetBuoyancy() : 0.0f;
+ sprintf(strBuf, "Distance to surface: %f Buoyancy: %f", fSurfaceDistance, buoy);
+ debugTxt.DrawString(x, y, strBuf);
+ y += lineHeight;
-// hsAssert(0, "fixme physx");
-// float buoy = fCallbackAction? fCallbackAction->GetBuoyancy() : 0.0f;
-// sprintf(strBuf, "Distance to surface: %f Buoyancy: %f", fSurfaceDistance, buoy);
-// debugTxt.DrawString(x, y, strBuf);
-// y += lineHeight;
-//
-// hsVector3 linV;
-// fAvMod->GetPhysical()->GetLinearVelocitySim(linV);
-// hsVector3 angV;
-// fAvMod->GetPhysical()->GetAngularVelocitySim(angV);
-// hsScalar angle = angV.fZ > 0 ? angV.Magnitude() : -angV.Magnitude();
-// sprintf(strBuf, "Velocity: Linear (%5.2f, %5.2f, %5.2f), Angular %5.2f", linV.fX, linV.fY, linV.fZ, angle);
-// debugTxt.DrawString(x, y, strBuf);
-// y += lineHeight;
+ hsVector3 linV = fAvMod->GetController()->GetAchievedLinearVelocity();
+ sprintf(strBuf, "Linear Velocity: (%5.2f, %5.2f, %5.2f)", linV.fX, linV.fY, linV.fZ);
+ debugTxt.DrawString(x, y, strBuf);
+ y += lineHeight;
int i;
for (i = 0; i < fBehaviors.GetCount(); i++)
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainSwim.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainSwim.h
index b75651ef..d3e9f83b 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainSwim.h
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvBrainSwim.h
@@ -47,11 +47,10 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../pnKeyedObject/plKey.h"
class plArmatureMod;
-class plAntiGravAction;
class plControlEventMsg;
class plLOSRequestMsg;
class plSwimRegionInterface;
-class plSwimmingController;
+class plSwimStrategy;
class plAvBrainSwim : public plArmatureBrain
{
public:
@@ -73,7 +72,7 @@ public:
bool IsSwimming();
hsScalar GetSurfaceDistance() { return fSurfaceDistance; }
- plSwimmingController *fCallbackAction;
+ plSwimStrategy *fSwimStrategy;
static const hsScalar kMinSwimDepth;
protected:
@@ -86,8 +85,6 @@ protected:
hsBool IProcessBehaviors(double time, float elapsed);
virtual hsBool IInitAnimations();
- bool IAttachAction();
- bool IDetachAction();
void IProbeSurface();
hsBool IHandleControlMsg(plControlEventMsg* msg);
float IGetTargetZ();
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvCallbackAction.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvCallbackAction.cpp
deleted file mode 100644
index c192f3b9..00000000
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvCallbackAction.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-/*==LICENSE==*
-
-CyanWorlds.com Engine - MMOG client, server and tools
-Copyright (C) 2011 Cyan Worlds, Inc.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-Additional permissions under GNU GPL version 3 section 7
-
-If you modify this Program, or any covered work, by linking or
-combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
-NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
-JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
-(or a modified version of those libraries),
-containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
-PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
-JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
-licensors of this Program grant you additional
-permission to convey the resulting work. Corresponding Source for a
-non-source form of such a combination shall include the source code for
-the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
-work.
-
-You can contact Cyan Worlds, Inc. by email legal@cyan.com
- or by snail mail at:
- Cyan Worlds, Inc.
- 14617 N Newport Hwy
- Mead, WA 99021
-
-*==LICENSE==*/
-#include "plAvCallbackAction.h"
-#include "../plMessage/plLOSHitMsg.h"
-
-#include "plArmatureMod.h" // for LOS enum type
-#include "plMatrixChannel.h"
-#include "hsTimer.h"
-#include "plPhysicalControllerCore.h"
-
-// Generic geom utils.
-hsBool LinearVelocity(hsVector3 &outputV, float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat);
-void AngularVelocity(hsScalar &outputV, float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat);
-float AngleRad2d (float x1, float y1, float x3, float y3);
-inline hsVector3 GetYAxis(hsMatrix44 &mat)
-{
- return hsVector3(mat.fMap[1][0], mat.fMap[1][1], mat.fMap[1][2]);
-}
-
-plAnimatedController::plAnimatedController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller)
- : fRootObject(rootObject)
- , fRootApp(rootApp)
- , fController(controller)
- , fTurnStr(0.f)
- , fAnimAngVel(0.f)
- , fAnimPosVel(0.f, 0.f, 0.f)
-{
-}
-
-void plAnimatedController::RecalcVelocity(double timeNow, double timePrev, hsBool useAnim /* = true */)
-{
- if (useAnim)
- {
- // while you may think it would be correct to cache this,
- // what we're actually asking is "what would the animation's
- // position be at the previous time given its *current*
- // parameters (particularly blends)"
- hsMatrix44 prevMat = ((plMatrixChannel *)fRootApp->GetChannel())->Value(timePrev, true);
- hsMatrix44 curMat = ((plMatrixChannel *)fRootApp->GetChannel())->Value(timeNow, true);
-
- // If we get a valid linear velocity (ie, we didn't wrap around in the anim),
- // use it. Otherwise just reuse the previous frames velocity.
- hsVector3 linearVel;
- if (LinearVelocity(linearVel, (float)(timeNow - timePrev), prevMat, curMat))
- fAnimPosVel = linearVel;
-
- // Automatically sets fAnimAngVel
- AngularVelocity(fAnimAngVel, (float)(timeNow - timePrev), prevMat, curMat);
- }
- else
- {
- fAnimPosVel.Set(0.f, 0.f, 0.f);
- fAnimAngVel = 0.f;
- }
-
- if (fController)
- fController->SetVelocities(fAnimPosVel, fAnimAngVel + fTurnStr);
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-const hsScalar plWalkingController::kControlledFlightThreshold = 1.f; // seconds
-
-plWalkingController::plWalkingController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller)
- : plAnimatedController(rootObject, rootApp, controller)
- , fHitGroundInThisAge(false)
- , fWaitingForGround(false)
- , fControlledFlightTime(0)
- , fControlledFlight(0)
- , fImpactTime(0.f)
- , fImpactVelocity(0.f, 0.f, 0.f)
- , fClearImpact(false)
- , fGroundLastFrame(false)
-{
- if (fController)
- {
- fWalkingStrategy= TRACKED_NEW plWalkingStrategy(fController);
- fController->SetMovementSimulationInterface(fWalkingStrategy);
- }
- else
- fWalkingStrategy = nil;
-}
-
-void plWalkingController::RecalcVelocity(double timeNow, double timePrev, hsBool useAnim)
-{
- if (!fHitGroundInThisAge && fController && fController->IsEnabled() && fWalkingStrategy->IsOnGround())
- fHitGroundInThisAge = true; // if we're not pinned and we're not in an age yet, we are now.
-
- if (fClearImpact)
- {
- fImpactTime = 0.f;
- fImpactVelocity.Set(0.f, 0.f, 0.f);
- }
-
- if (fController && !fWalkingStrategy->IsOnGround())
- {
- // PhysX Hack
- // LinearVelocity is always (0,0,0) outside the PhysController
- fImpactTime = fWalkingStrategy->GetAirTime();
- fImpactVelocity = fController->GetAchievedLinearVelocity();
- // convert orientation from subworld to avatar-local coordinates
- fImpactVelocity = (hsVector3)fController->GetLocalRotation().Rotate(&fImpactVelocity);
- fClearImpact = false;
- }
- else
- fClearImpact = true;
-
- if (IsControlledFlight())
- {
- if (fWalkingStrategy && fWalkingStrategy->IsOnGround())
- fControlledFlightTime = fWalkingStrategy->GetAirTime();
- if(fGroundLastFrame&&(fWalkingStrategy && !fWalkingStrategy->IsOnGround()))
- {
- //we have started to leave the ground tell the movement strategy in case it cares
- fWalkingStrategy->StartJump();
- }
- if (fControlledFlightTime > kControlledFlightThreshold)
- EnableControlledFlight(false);
- }
- if (fWalkingStrategy)
- fGroundLastFrame = fWalkingStrategy->IsOnGround();
- else
- fGroundLastFrame=false;
- plAnimatedController::RecalcVelocity(timeNow, timePrev, useAnim);
-}
-
-void plWalkingController::Reset(bool newAge)
-{
-
- ActivateController();
- if (newAge)
- {
- if (fWalkingStrategy)
- fWalkingStrategy->ResetAirTime();
- fHitGroundInThisAge = false;
- }
-}
- void plWalkingController::ActivateController()
-{
- if (fWalkingStrategy)
- {
- fWalkingStrategy->RefreshConnectionToControllerCore();
- }
- else
- {
- fWalkingStrategy= TRACKED_NEW plWalkingStrategy(fController);
- fWalkingStrategy->RefreshConnectionToControllerCore();
-
- }
-}
-
-bool plWalkingController::EnableControlledFlight(bool status)
-{
- if (status)
- {
- if (fControlledFlight == 0)
- fControlledFlightTime = 0.f;
-
- ++fControlledFlight;
- fWaitingForGround = true;
- }
- else
- fControlledFlight = __max(--fControlledFlight, 0);
-
- return status;
-}
-plWalkingController::~plWalkingController()
-{
- delete fWalkingStrategy;
- if (fController)
- fController->SetMovementSimulationInterface(nil);
-}
-#if 0
-void plWalkingController::Update()
-{
-// double elapsed = time.asDouble() - getRefresh().asDouble();
-// setRefresh(time);
-//
-// hsBool isPhysical = !fPhysical->GetProperty(plSimulationInterface::kPinned);
-// const Havok::Vector3 straightUp(0.0f, 0.0f, 1.0f);
-// hsBool alreadyInAge = fHitGroundInThisAge;
-//
-// int numContacts = fPhysical->GetNumContacts();
-// bool ground = false;
-// fPushingPhysical = nil;
-// int i, j;
-
-/* for(i = 0; i < numContacts; i++)
- {
- plHKPhysical *contactPhys = fPhysical->GetContactPhysical(i);
- if (!contactPhys)
- continue; // Physical no longer exists. Skip it.
-
- const Havok::ContactPoint *contact = fPhysical->GetContactPoint(i);
- hsScalar dotUp = straightUp.dot(contact->m_normal);
- if (dotUp > .5)
- ground = true;
- else if (contactPhys->GetProperty(plSimulationInterface::kAvAnimPushable))
- {
- hsPoint3 position;
- hsQuat rotation;
- fPhysical->GetPositionAndRotationSim(&position, &rotation);
-
- hsQuat inverseRotation = rotation.Inverse();
- hsVector3 normal(contact->m_normal.x, contact->m_normal.y, contact->m_normal.z);
- fFacingPushingPhysical = (inverseRotation.Rotate(&kAvatarForward).InnerProduct(normal) < 0 ? true : false);
-
- fPushingPhysical = contactPhys;
- }
- }
-
- // We need to check for the case where the avatar hasn't collided with "ground", but is colliding
- // with a few other objects so that he's not actually falling (wedged in between some slopes).
- // We do this by answering the following question (in 2d top-down space): "If you sort the contact
- // normals by angle, is there a large enough gap between normals?"
- //
- // If you think in terms of geometry, this means a collection of surfaces are all pushing on you.
- // If they're pushing from all sides, you have nowhere to go, and you won't fall. There needs to be
- // a gap, so that you're pushed out and have somewhere to fall. This is the same as finding a gap
- // larger than 180 degrees between sorted normals.
- //
- // The problem is that on top of that, the avatar needs enough force to shove him out that gap (he
- // has to overcome friction). I deal with that by making the threshold (360 - (180 - 60) = 240). I've
- // seen up to 220 reached in actual gameplay in a situation where we'd want this to take effect.
- // This is the same running into 2 walls where the angle between them is 60.
- const hsScalar threshold = hsScalarDegToRad(240);
- if (!ground && numContacts >= 2)
- {
- // Can probably do a special case for exactly 2 contacts. Not sure if it's worth it...
-
- fCollisionAngles.SetCount(numContacts);
- for (i = 0; i < numContacts; i++)
- {
- const Havok::ContactPoint *contact = fPhysical->GetContactPoint(i);
- fCollisionAngles[i] = hsATan2(contact->m_normal.y, contact->m_normal.x);
- }
-
- // numContacts is rarely larger than 6, so let's do a simple bubble sort.
- for (i = 0; i < numContacts; i++)
- {
- for (j = i + 1; j < numContacts; j++)
- {
- if (fCollisionAngles[i] > fCollisionAngles[j])
- {
- hsScalar tempAngle = fCollisionAngles[i];
- fCollisionAngles[i] = fCollisionAngles[j];
- fCollisionAngles[j] = tempAngle;
- }
- }
- }
-
- // sorted, now we check.
- for (i = 1; i < numContacts; i++)
- {
- if (fCollisionAngles[i] - fCollisionAngles[i - 1] >= threshold)
- break;
- }
-
- if (i == numContacts)
- {
- // We got to the end. Check the last with the first and make your decision.
- if (!(fCollisionAngles[0] - fCollisionAngles[numContacts - 1] >= (threshold - 2 * hsScalarPI)))
- ground = true;
- }
- }
-*/
-
- bool ground = fController ? fController->GotGroundHit() : true;
- bool isPhysical = true;
-
- if (!fHitGroundInThisAge && isPhysical)
- fHitGroundInThisAge = true; // if we're not pinned and we're not in an age yet, we are now.
-
- if (IsControlledFlight())
- fControlledFlightTime += (hsScalar)elapsed;
- if (fControlledFlightTime > kControlledFlightThreshold && numContacts > 0)
- EnableControlledFlight(false);
-
- if (ground || !isPhysical)
- {
- if (!IsControlledFlight() && !IsOnGround())
- {
- // The first ground contact in an age doesn't count.
-// if (alreadyInAge)
-// {
-// hsVector3 vel;
-// fPhysical->GetLinearVelocitySim(vel);
-// fImpactVel = vel.fZ;
-// fTimeInAirPeak = (hsScalar)(fTimeInAir + elapsed);
-// }
-
- fWaitingForGround = false;
- }
- fTimeInAir = 0;
- }
- else if (elapsed < plSimulationMgr::GetInstance()->GetMaxDelta())
- {
- // If the simultation skipped a huge chunk of time, we didn't process the
- // collisions, which could trick us into thinking we've just gone a long
- // time without hitting ground. So we only count the time if this wasn't
- // the case.
- fTimeInAir += (hsScalar)elapsed;
- }
-
-
- // Tweakage so that we still fall under the right conditions.
- // If we're in controlled flight, or standing still with ground solidly under us (probe hit). We only use anim velocity.
-// if (!IsControlledFlight() && !(ground && fProbeHitGround && fAnimPosVel.fX == 0 && fAnimPosVel.fY == 0))
-// {
-// hsVector3 curV;
-// fPhysical->GetLinearVelocitySim(curV);
-// fAnimPosVel.fZ = curV.fZ;
-//
-// // Prevents us from going airborn from running up bumps/inclines.
-// if (IsOnGround() && fAnimPosVel.fZ > 0.f)
-// fAnimPosVel.fZ = 0.f;
-//
-// // Unless we're on the ground and moving, or standing still with a probe hit, we use the sim's other axes too.
-// if (!(IsOnGround() && (fProbeHitGround || fAnimPosVel.fX != 0 || fAnimPosVel.fY != 0)))
-// {
-// fAnimPosVel.fX = curV.fX;
-// fAnimPosVel.fY = curV.fY;
-// }
-// }
-//
-// fPhysical->SetLinearVelocitySim(fAnimPosVel);
-// fPhysical->SetSpin(fAnimAngVel + fTurnStr, hsVector3(0.0f, 0.0f, 1.0f));
-}
-#endif
-
-
-#if 0
-
-/////////////////////////////////////////////////////////////////////////
-
-plSimDefs::ActionType plHorizontalFreezeAction::GetType()
-{
- return plSimDefs::kHorizontalFreeze;
-}
-
-void plHorizontalFreezeAction::apply(Havok::Subspace &s, Havok::hkTime time)
-{
- double elapsed = time.asDouble() - getRefresh().asDouble();
- setRefresh(time);
-
- int numContacts = fPhysical->GetNumContacts();
- bool ground = false;
- const Havok::Vector3 straightUp(0.0f, 0.0f, 1.0f);
- int i;
- for(i = 0; i < numContacts; i++)
- {
- const Havok::ContactPoint *contact = fPhysical->GetContactPoint(i);
- hsScalar dotUp = straightUp.dot(contact->m_normal);
- if (dotUp > .5)
- ground = true;
- }
-
- hsVector3 vel;
- fPhysical->GetLinearVelocitySim(vel);
- vel.fX = 0.0;
- vel.fY = 0.0;
- if (ground)
- vel.fZ = 0;
- fPhysical->SetLinearVelocitySim(vel);
- fPhysical->ClearContacts();
-}
-#endif
-plSwimmingController::plSwimmingController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller)
-:plAnimatedController(rootObject,rootApp,controller)
-{
- if (controller)
- fSwimmingStrategy= TRACKED_NEW plSwimStrategy(controller);
- else
- fSwimmingStrategy = nil;
-}
-plSwimmingController::~plSwimmingController()
-{
- delete fSwimmingStrategy;
-}
-
-plRidingAnimatedPhysicalController::plRidingAnimatedPhysicalController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller)
-: plWalkingController(rootObject, rootApp, controller)
-{
- if(controller)
- fWalkingStrategy = TRACKED_NEW plRidingAnimatedPhysicalStrategy(controller);
- else
- fWalkingStrategy = nil;
-}
-plRidingAnimatedPhysicalController::~plRidingAnimatedPhysicalController()
-{
- delete fWalkingStrategy;
- fWalkingStrategy=nil;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-
-
-/*
-Purpose:
-
-ANGLE_RAD_2D returns the angle in radians swept out between two rays in 2D.
-
-Discussion:
-
-Except for the zero angle case, it should be true that
-
-ANGLE_RAD_2D(X1,Y1,X2,Y2,X3,Y3)
-+ ANGLE_RAD_2D(X3,Y3,X2,Y2,X1,Y1) = 2 * PI
-
-Modified:
-
-19 April 1999
-
-Author:
-
-John Burkardt
-
-Parameters:
-
-Input, float X1, Y1, X2, Y2, X3, Y3, define the rays
-( X1-X2, Y1-Y2 ) and ( X3-X2, Y3-Y2 ) which in turn define the
-angle, counterclockwise from ( X1-X2, Y1-Y2 ).
-
-Output, float ANGLE_RAD_2D, the angle swept out by the rays, measured
-in radians. 0 <= ANGLE_DEG_2D < 2 PI. If either ray has zero length,
-then ANGLE_RAD_2D is set to 0.
-*/
-
-static float AngleRad2d ( float x1, float y1, float x3, float y3 )
-{
- float value;
- float x;
- float y;
-
- x = ( x1 ) * ( x3 ) + ( y1 ) * ( y3 );
- y = ( x1 ) * ( y3 ) - ( y1 ) * ( x3 );
-
- if ( x == 0.0 && y == 0.0 ) {
- value = 0.0;
- }
- else
- {
- value = atan2 ( y, x );
-
- if ( value < 0.0 )
- {
- value = (float)(value + TWO_PI);
- }
- }
- return value;
-}
-
-static hsBool LinearVelocity(hsVector3 &outputV, float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat)
-{
- bool result = false;
-
- hsPoint3 startPos(0.0f, 0.0f, 0.0f); // default position (at start of anim)
- hsPoint3 prevPos = prevMat.GetTranslate(); // position previous frame
- hsPoint3 nowPos = curMat.GetTranslate(); // position current frame
-
- hsVector3 prev2Now = (hsVector3)(nowPos - prevPos); // frame-to-frame delta
-
- if (fabs(prev2Now.fX) < 0.0001f && fabs(prev2Now.fY) < 0.0001f && fabs(prev2Now.fZ) < 0.0001f)
- {
- outputV.Set(0.f, 0.f, 0.f);
- result = true;
- }
- else
- {
- hsVector3 start2Now = (hsVector3)(nowPos - startPos); // start-to-frame delta
-
- float prev2NowMagSqr = prev2Now.MagnitudeSquared();
- float start2NowMagSqr = start2Now.MagnitudeSquared();
-
- float dot = prev2Now.InnerProduct(start2Now);
-
- // HANDLING ANIMATION WRAPPING:
- // the vector from the animation origin to the current frame should point in roughly
- // the same direction as the vector from the previous animation position to the
- // current animation position.
- //
- // If they don't agree (dot < 0,) then we probably mpst wrapped around.
- // The right answer would be to compare the current frame to the start of
- // the anim loop, but it's cheaper to cheat and return false,
- // telling the caller to use the previous frame's velocity.
- if (dot > 0.0f)
- {
- prev2Now /= elapsed;
-
- float xfabs = fabs(prev2Now.fX);
- float yfabs = fabs(prev2Now.fY);
- float zfabs = fabs(prev2Now.fZ);
- static const float maxVel = 20.0f;
- hsBool valid = xfabs < maxVel && yfabs < maxVel && zfabs < maxVel;
-
- if (valid)
- {
- outputV = prev2Now;
- result = true;
- }
- }
- }
-
- return result;
-}
-
-static void AngularVelocity(hsScalar &outputV, float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat)
-{
- outputV = 0.f;
- hsScalar appliedVelocity = 0.0f;
- hsVector3 prevForward = GetYAxis(prevMat);
- hsVector3 curForward = GetYAxis(curMat);
-
- hsScalar angleSincePrev = AngleRad2d(curForward.fX, curForward.fY, prevForward.fX, prevForward.fY);
- hsBool sincePrevSign = angleSincePrev > 0.0f;
- if (angleSincePrev > hsScalarPI)
- angleSincePrev = angleSincePrev - TWO_PI;
-
- const hsVector3 startForward = hsVector3(0, -1.0, 0); // the Y orientation of a "resting" armature....
- hsScalar angleSinceStart = AngleRad2d(curForward.fX, curForward.fY, startForward.fX, startForward.fY);
- hsBool sinceStartSign = angleSinceStart > 0.0f;
- if (angleSinceStart > hsScalarPI)
- angleSinceStart = angleSinceStart - TWO_PI;
-
- // HANDLING ANIMATION WRAPPING:
- // under normal conditions, the angle from rest to the current frame will have the same
- // sign as the angle from the previous frame to the current frame.
- // if it does not, we have (most likely) wrapped the motivating animation from frame n back
- // to frame zero, creating a large angle from the previous frame to the current one
- if (sincePrevSign == sinceStartSign)
- {
- // signs are the same; didn't wrap; use the frame-to-frame angle difference
- appliedVelocity = angleSincePrev / elapsed; // rotation / time
- if (fabs(appliedVelocity) < 3)
- {
- outputV = appliedVelocity;
- }
- }
-}
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvCallbackAction.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvCallbackAction.h
deleted file mode 100644
index c4e374ba..00000000
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvCallbackAction.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*==LICENSE==*
-
-CyanWorlds.com Engine - MMOG client, server and tools
-Copyright (C) 2011 Cyan Worlds, Inc.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-Additional permissions under GNU GPL version 3 section 7
-
-If you modify this Program, or any covered work, by linking or
-combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
-NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
-JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
-(or a modified version of those libraries),
-containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
-PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
-JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
-licensors of this Program grant you additional
-permission to convey the resulting work. Corresponding Source for a
-non-source form of such a combination shall include the source code for
-the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
-work.
-
-You can contact Cyan Worlds, Inc. by email legal@cyan.com
- or by snail mail at:
- Cyan Worlds, Inc.
- 14617 N Newport Hwy
- Mead, WA 99021
-
-*==LICENSE==*/
-#ifndef PL_HK_CALLBACK_ACTION_H
-#define PL_HK_CALLBACK_ACTION_H
-
-#include "hsGeometry3.h"
-#include "hsMatrix44.h"
-#include "hsTemplates.h"
-#include "../pnKeyedObject/plKey.h"
-#include "../plPhysical/plSimDefs.h"
-#include "../pnMessage/plMessage.h"
-#include "plPhysicalControllerCore.h"
-class plLOSHitMsg;
-class plAGApplicator;
-class plSceneObject;
-class plPhysical;
-class plAvatarController;
-class plCoordinateInterface;
-class plPhysicalControllerCore;
-// Used by the other controllers to actually move the avatar. The actual
-// implementation is in the physics system.
-/*class plPhysicalController
-{
-public:
- // Implemented in the physics system. If you're linking this without that for
- // some reason, just stub this function out.
- //
- // Pass in the key to the root sceneobject for the avatar
- static plPhysicalController* Create(plKey ownerSO, hsScalar height, hsScalar width);
-
- virtual ~plPhysicalController() {}
-
- // A disabled avatar doesn't move or accumulate air time if he's off the ground.
- virtual void Enable(bool enable) = 0;
- virtual bool IsEnabled() const = 0;
-
- // Set the LOS DB this avatar will be in (only one)
- virtual void SetLOSDB(plSimDefs::plLOSDB losDB) = 0;
-
- // Call this once per frame with the velocities of the avatar in avatar space.
- virtual void SetVelocities(const hsVector3& linearVel, hsScalar angVel) = 0;
-
- // Gets the actual velocity we achieved in the last step (relative to our subworld)
- virtual const hsVector3& GetLinearVelocity() const = 0;
- virtual void ResetAchievedLinearVelocity() = 0;
-
- // Get and set the current subworld for the avatar. Use nil for the main world.
- virtual plKey GetSubworld() const = 0;
- virtual void SetSubworld(plKey world) = 0;
-
- // If IsOnGround returns false, GetAirTime will tell you how long the avatar
- // has been airborne. Use ResetAirTime to reset the air time to zero, for
- // cases like when the avatar spawns into a new age.
- virtual bool IsOnGround() const = 0;
- virtual bool IsOnFalseGround() const = 0;
- virtual hsScalar GetAirTime() const = 0;
- virtual void ResetAirTime() = 0;
-
- virtual plPhysical* GetPushingPhysical() const = 0;
- virtual bool GetFacingPushingPhysical() const = 0;
-
- // A helper function to get the coordinate interface for the avatars current
- // world. Handy if you need to convert points to and from that. This will
- // return nil if the avatar is in the main world (ie, you don't need to do
- // any translation).
- virtual const plCoordinateInterface* GetSubworldCI() const = 0;
-
- // For the avatar SDL only
- virtual void GetState(hsPoint3& pos, float& zRot) = 0;
- virtual void SetState(const hsPoint3& pos, float zRot) = 0;
-
- // kinematic stuff .... should be just for when playing a behavior...
- virtual void Kinematic(bool state) = 0;
- virtual bool IsKinematic() = 0;
- virtual void GetKinematicPosition(hsPoint3& pos) = 0;
-
- virtual const hsMatrix44& GetPrevSubworldW2L() = 0;
-
- //when seeking no longer want to interact with exclusion regions
- virtual void SetSeek(bool seek)=0;
-
-
-};
-*/
-class plAvatarController
-{
-public:
- virtual ~plAvatarController() {}
-};
-
-class plAnimatedController : public plAvatarController
-{
-public:
- plAnimatedController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller);
-
- virtual void RecalcVelocity(double timeNow, double timePrev, hsBool useAnim = true);
- void SetTurnStrength(hsScalar val) { fTurnStr = val; }
- hsScalar GetTurnStrength() { return fTurnStr; }
- virtual void ActivateController()=0;
-protected:
- plSceneObject* fRootObject;
- plPhysicalControllerCore* fController;
- plAGApplicator* fRootApp;
- hsScalar fAnimAngVel;
- hsVector3 fAnimPosVel;
- hsScalar fTurnStr; // Explicit turning, separate from animations
-};
-
-class plWalkingController : public plAnimatedController
-{
-public:
- plWalkingController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller);
- virtual ~plWalkingController();
- virtual void RecalcVelocity(double timeNow, double timePrev, hsBool useAnim = true);
-
- void Reset(bool newAge);
- bool IsControlledFlight() const { return fControlledFlight != 0; }
- bool IsOnGround() const { return fWalkingStrategy ? fWalkingStrategy->IsOnGround() : true; }
- bool IsOnFalseGround() const { return fWalkingStrategy ? fWalkingStrategy->IsOnFalseGround() : true; }
- bool HitGroundInThisAge() const { return fHitGroundInThisAge; }
- bool EnableControlledFlight(bool status);
- hsScalar GetAirTime() const { return fWalkingStrategy ? fWalkingStrategy->GetAirTime() : 0.f; }
- void ResetAirTime() { if (fWalkingStrategy) fWalkingStrategy->ResetAirTime(); }
- hsScalar GetForwardVelocity() const;
- void ActivateController();
- // Check these after the avatar the avatar hits the ground for his total
- // hangtime and impact velocity.
- hsScalar GetImpactTime() const { return fImpactTime; }
- const hsVector3& GetImpactVelocity() const { return fImpactVelocity; }
-
- plPhysical* GetPushingPhysical() const
- {
- if(fController)return fController->GetPushingPhysical();
- else return nil;
- }
- bool GetFacingPushingPhysical() const
- { if(fController)return fController->GetFacingPushingPhysical();
- else return false;
- }
-
-
-protected:
- bool fHitGroundInThisAge;
- bool fWaitingForGround; // We've gone airborne. IsOnGround() returns false until we hit ground again.
- hsScalar fControlledFlightTime;
- int fControlledFlight; // Count of how many are currently forcing flight
- plWalkingStrategy* fWalkingStrategy;
- hsScalar fImpactTime;
- hsVector3 fImpactVelocity;
- bool fClearImpact;
- bool fGroundLastFrame;//used for a test to pass the event of first getting air during a jump
- static const hsScalar kControlledFlightThreshold;
-};
-class plSwimmingController: public plAnimatedController
-{
-public :
- plSwimmingController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller);
- virtual ~plSwimmingController();
- void SetSurface(plSwimRegionInterface *region, hsScalar surfaceHeight){
- fSwimmingStrategy->SetSurface(region,surfaceHeight);
- }
- hsScalar GetBuoyancy() { return fSwimmingStrategy->GetBuoyancy(); }
- hsBool IsOnGround() { return fSwimmingStrategy->IsOnGround(); }
- hsBool HadContacts() { return fSwimmingStrategy->HadContacts();}
- void Enable(bool en){if (fController) fController->Enable(en);}
- plPhysicalControllerCore* GetController(){return fController;}
- virtual void ActivateController(){fSwimmingStrategy->RefreshConnectionToControllerCore();}
-protected:
- plSwimStrategy* fSwimmingStrategy;
-
-};
-class plRidingAnimatedPhysicalController: public plWalkingController
-{
-public:
- plRidingAnimatedPhysicalController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller);
- virtual ~plRidingAnimatedPhysicalController();
-};
-#endif // PL_HK_CALLBACK_ACTION_H
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvLadderModifier.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvLadderModifier.cpp
index f303c47f..2c214e92 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvLadderModifier.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvLadderModifier.cpp
@@ -39,7 +39,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
Mead, WA 99021
*==LICENSE==*/
-#include "../plAvatar/plAvCallbackAction.h"
+#include "plPhysicalControllerCore.h"
#include "hsTypes.h"
@@ -129,7 +129,7 @@ bool plAvLadderMod::IIsReadyToClimb()
if (armMod)
{
plAvBrainHuman* brain = plAvBrainHuman::ConvertNoRef(armMod->GetCurrentBrain());
- if (brain && brain->IsMovingForward() && brain->fCallbackAction->IsOnGround())
+ if (brain && brain->IsMovingForward() && brain->fWalkingStrategy->IsOnGround())
movingForward = true;
}
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvTaskSeek.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvTaskSeek.cpp
index 3b70bca4..84b80cfe 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvTaskSeek.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvTaskSeek.cpp
@@ -54,7 +54,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plAGAnim.h"
#include "plArmatureMod.h"
#include "plAvatarMgr.h"
-#include "plAvCallbackAction.h"
+#include "plPhysicalControllerCore.h"
// other
#include "../plMessage/plAvatarMsg.h"
@@ -462,10 +462,10 @@ hsBool plAvTaskSeek::IFinishPosition(hsPoint3 &newPosition,
{
// While warping, we might be hovering just above the ground. Don't want that to
// trigger any falling behavior.
- if(brain&&brain->fCallbackAction)
+ if(brain&&brain->fWalkingStrategy)
{
- brain->fCallbackAction->ResetAirTime();
+ brain->fWalkingStrategy->ResetAirTime();
}
// how far will we translate this frame?
float thisDist = kFloatSpeed * elapsed;
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvatarSDLModifier.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvatarSDLModifier.cpp
index d728b8fd..9f132f2a 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvatarSDLModifier.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvatarSDLModifier.cpp
@@ -47,7 +47,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../plAvatar/plAvBrainClimb.h"
#include "../plAvatar/plAvBrainDrive.h"
#include "../plAvatar/plAnimStage.h"
-#include "../plAvatar/plAvCallbackAction.h"
+#include "../plAvatar/plPhysicalControllerCore.h"
#include "../pnSceneObject/plSceneObject.h"
#include "../pnMessage/plSDLModifierMsg.h"
#include "../plSDL/plSDL.h"
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvatarTasks.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvatarTasks.cpp
index b3ed9ea6..cf67d229 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvatarTasks.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plAvatarTasks.cpp
@@ -53,7 +53,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plAGAnimInstance.h"
#include "plAGModifier.h"
#include "plMatrixChannel.h"
-#include "plAvCallbackAction.h"
+#include "plPhysicalControllerCore.h"
#include "plAvatarMgr.h"
// global
@@ -689,7 +689,7 @@ hsBool plAvOneShotTask::Process(plArmatureMod *avatar, plArmatureBrain *brain, d
if(fEnablePhysicsAtEnd)
{
#if 0//ndef PLASMA_EXTERNAL_RELEASE
- if (!humanBrain || humanBrain->fCallbackAction->HitGroundInThisAge())
+ if (!humanBrain || humanBrain->fWalkingStrategy->HitGroundInThisAge())
{
// For some reason, calling CheckValidPosition at the beginning of
// an age can cause detectors to incorrectly report collisions. So
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plPhysicalControllerCore.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plPhysicalControllerCore.cpp
index 9dff5e3d..710645ff 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plPhysicalControllerCore.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plPhysicalControllerCore.cpp
@@ -40,548 +40,601 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
*==LICENSE==*/
#include "plPhysicalControllerCore.h"
-#include "../plMessage/plLOSHitMsg.h"
+
+#include "plArmatureMod.h"
+#include "plSwimRegion.h"
+#include "plMatrixChannel.h"
#include "../pnSceneObject/plCoordinateInterface.h"
#include "../../NucleusLib/inc/plPhysical.h"
#include "../../NucleusLib/pnMessage/plCorrectionMsg.h"
-#include "plSwimRegion.h"
-#include "plArmatureMod.h" // for LOS enum type
-#include "plMatrixChannel.h"
-#include "hsTimer.h"
-#include "../plPhysx/plSimulationMgr.h"
-#include "../plPhysx/plPXPhysical.h"
-#include "../pnMessage/plSetNetGroupIDMsg.h"
-#define kSWIMRADIUS 1.1f
-#define kSWIMHEIGHT 2.8f
-#define kGENERICCONTROLLERRADIUS 1.1f
-#define kGENERICCONTROLLERHEIGHT 2.8f
-
-//#define kSWIMMINGCONTACTSLOPELIMIT (cosf(hsScalarDegToRad(80.f)))
-const hsScalar plMovementStrategy::kAirTimeThreshold = .1f; // seconds
+
+// Gravity constants
+#define kGravity -32.174f
+#define kTerminalVelocity kGravity
+
+static inline hsVector3 GetYAxis(hsMatrix44 &mat) { return hsVector3(mat.fMap[1][0], mat.fMap[1][1], mat.fMap[1][2]); }
+static float AngleRad2d(float x1, float y1, float x3, float y3);
+
bool CompareMatrices(const hsMatrix44 &matA, const hsMatrix44 &matB, float tolerance);
-bool operator<(const plControllerSweepRecord left, const plControllerSweepRecord right)
+
+
+// plPhysicalControllerCore
+plPhysicalControllerCore::plPhysicalControllerCore(plKey OwnerSceneObject, hsScalar height, hsScalar radius)
+ : fOwner(OwnerSceneObject),
+ fWorldKey(nil),
+ fHeight(height),
+ fRadius(radius),
+ fLOSDB(plSimDefs::kLOSDBNone),
+ fMovementStrategy(nil),
+ fSimLength(0.0f),
+ fLocalRotation(0.0f, 0.0f, 0.0f, 1.0f),
+ fLocalPosition(0.0f, 0.0f, 0.0f),
+ fLastLocalPosition(0.0f, 0.0f, 0.0f),
+ fLinearVelocity(0.0f, 0.0f, 0.0f),
+ fAchievedLinearVelocity(0.0f, 0.0f, 0.0f),
+ fPushingPhysical(nil),
+ fFacingPushingPhysical(false),
+ fSeeking(false),
+ fEnabled(false),
+ fEnableChanged(false)
+{
+ fLastGlobalLoc.Reset();
+ fPrevSubworldW2L.Reset();
+}
+
+const plCoordinateInterface* plPhysicalControllerCore::GetSubworldCI()
{
- if(left.TimeHit < right.TimeHit) return true;
- else return false;
+ if (fWorldKey)
+ {
+ plSceneObject* so = plSceneObject::ConvertNoRef(fWorldKey->ObjectIsLoaded());
+ if (so)
+ return so->GetCoordinateInterface();
+ }
+
+ return nil;
}
-plMovementStrategy::plMovementStrategy(plPhysicalControllerCore* core)
+
+void plPhysicalControllerCore::IncrementAngle(hsScalar deltaAngle)
{
- this->fTimeInAir=0.0f;
- fCore=core;
- fOwner=core->GetOwner();
- this->fPreferedControllerHeight=kGENERICCONTROLLERHEIGHT;
- this->fPreferedControllerWidth=kGENERICCONTROLLERRADIUS;
+ hsVector3 axis;
+ hsScalar angle;
+
+ fLocalRotation.NormalizeIfNeeded();
+ fLocalRotation.GetAngleAxis(&angle, &axis);
+ if (axis.fZ < 0)
+ angle = (2.0f * hsScalarPI) - angle; // axis is backwards, so reverse the angle too
+
+ angle += deltaAngle;
+
+ // make sure we wrap around
+ if (angle < 0.0f)
+ angle = (2.0f * hsScalarPI) + angle; // angle is -, so this works like a subtract
+ if (angle >= (2.0f * hsScalarPI))
+ angle = angle - (2.0f * hsScalarPI);
+
+ // set the new angle
+ axis.Set(0.0f, 0.0f, 1.0f);
+ fLocalRotation.SetAngleAxis(angle, axis);
}
-void plMovementStrategy::IApplyKinematic()
+
+void plPhysicalControllerCore::IApply(hsScalar delSecs)
{
- // first apply sceneobject update to the kinematic
+ fSimLength = delSecs;
+
+ // Match controller to owner if transform has changed since the last frame
plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- if (so)
+ const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld();
+ if (!CompareMatrices(fLastGlobalLoc, l2w, 0.0001f))
+ SetGlobalLoc(l2w);
+
+ if (fEnabled)
{
- // If we've been moved since the last physics update (somebody warped us),
- // update the physics before we apply velocity.
- const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld();
- if (!CompareMatrices(l2w, fCore->GetLastGlobalLoc(), .0001f))
+ // Convert velocity from avatar to world space
+ if (!fLinearVelocity.IsEmpty())
{
- fCore->SetKinematicLoc(l2w);
- //fCore->SetGlobalLoc(l2w);
+ fLinearVelocity = l2w * fLinearVelocity;
+
+ const plCoordinateInterface* subworldCI = GetSubworldCI();
+ if (subworldCI)
+ fLinearVelocity = subworldCI->GetWorldToLocal() * fLinearVelocity;
}
+
+ fMovementStrategy->Apply(delSecs);
}
}
-plPhysicalControllerCore::~plPhysicalControllerCore()
+void plPhysicalControllerCore::IUpdate(int numSubSteps, hsScalar alpha)
{
+ if (fEnabled)
+ {
+ // Update local position and acheived velocity
+ fLastLocalPosition = fLocalPosition;
+ GetPositionSim(fLocalPosition);
+ hsVector3 displacement = (hsVector3)(fLocalPosition - fLastLocalPosition);
+ fAchievedLinearVelocity = displacement / fSimLength;
+
+ displacement /= (hsScalar)numSubSteps;
+ fLastLocalPosition = fLocalPosition - displacement;
+ hsPoint3 interpLocalPos = fLastLocalPosition + (displacement * alpha);
+
+ // Update global location
+ fLocalRotation.MakeMatrix(&fLastGlobalLoc);
+ fLastGlobalLoc.SetTranslate(&interpLocalPos);
+ const plCoordinateInterface* subworldCI = GetSubworldCI();
+ if (subworldCI)
+ {
+ const hsMatrix44& subL2W = subworldCI->GetLocalToWorld();
+ fLastGlobalLoc = subL2W * fLastGlobalLoc;
+ fPrevSubworldW2L = subworldCI->GetWorldToLocal();
+ }
+
+ fMovementStrategy->Update(fSimLength);
+ ISendCorrectionMessages(true);
+ }
+ else
+ {
+ // Update global location if in a subworld
+ const plCoordinateInterface* subworldCI = GetSubworldCI();
+ if (subworldCI)
+ {
+ hsMatrix44 l2s = fPrevSubworldW2L * fLastGlobalLoc;
+ const hsMatrix44& subL2W = subworldCI->GetLocalToWorld();
+ fLastGlobalLoc = subL2W * l2s;
+ fPrevSubworldW2L = subworldCI->GetWorldToLocal();
+
+ ISendCorrectionMessages();
+ }
+ }
+
+ if (fEnableChanged)
+ IHandleEnableChanged();
}
-void plPhysicalControllerCore::Apply(hsScalar delSecs)
-{
- fSimLength=delSecs;
- hsAssert(fMovementInterface, "plPhysicalControllerCore::Apply() missing a movement interface");
- if(fMovementInterface)fMovementInterface->Apply(delSecs);
-}
-void plPhysicalControllerCore::PostStep(hsScalar delSecs)
-{
- hsAssert(fMovementInterface, "plPhysicalControllerCore::PostStep() missing a movement interface");
- if(fMovementInterface)fMovementInterface->PostStep(delSecs);
-}
-void plPhysicalControllerCore::Update(hsScalar delSecs)
+void plPhysicalControllerCore::IUpdateNonPhysical(hsScalar alpha)
{
- hsAssert(fMovementInterface, "plPhysicalControllerCore::Update() missing a movement interface");
- if(fMovementInterface)fMovementInterface->Update(delSecs);
-
+ // Update global location if owner transform hasn't changed.
+ plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
+ const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld();
+ if (CompareMatrices(fLastGlobalLoc, l2w, 0.0001f))
+ {
+ hsVector3 displacement = (hsVector3)(fLocalPosition - fLastLocalPosition);
+ hsPoint3 interpLocalPos = fLastLocalPosition + (displacement * alpha);
+
+ fLocalRotation.MakeMatrix(&fLastGlobalLoc);
+ fLastGlobalLoc.SetTranslate(&interpLocalPos);
+ const plCoordinateInterface* subworldCI = GetSubworldCI();
+ if (subworldCI)
+ {
+ const hsMatrix44& subL2W = subworldCI->GetLocalToWorld();
+ fLastGlobalLoc = subL2W * fLastGlobalLoc;
+ fPrevSubworldW2L = subworldCI->GetWorldToLocal();
+ }
+
+ ISendCorrectionMessages();
+ }
}
-void plPhysicalControllerCore::SendCorrectionMessages()
+
+void plPhysicalControllerCore::ISendCorrectionMessages(bool dirtySynch)
{
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- plCorrectionMsg* corrMsg = TRACKED_NEW plCorrectionMsg;
+ plCorrectionMsg* corrMsg = TRACKED_NEW plCorrectionMsg();
corrMsg->fLocalToWorld = fLastGlobalLoc;
corrMsg->fLocalToWorld.GetInverse(&corrMsg->fWorldToLocal);
- corrMsg->fDirtySynch = true;
- // Send the new position to the plArmatureMod and the scene object
- const plArmatureMod* armMod = plArmatureMod::ConvertNoRef(so->GetModifierByType(plArmatureMod::Index()));
- if (armMod)
- corrMsg->AddReceiver(armMod->GetKey());
+ corrMsg->fDirtySynch = dirtySynch;
corrMsg->AddReceiver(fOwner);
corrMsg->Send();
}
-plPhysicalControllerCore::plPhysicalControllerCore(plKey OwnerSceneObject, hsScalar height, hsScalar radius)
-:fMovementInterface(nil)
-,fOwner(OwnerSceneObject)
-,fHeight(height)
-,fRadius(radius)
-,fWorldKey(nil)
-,fLinearVelocity(0.f,0.f,0.f)
-,fAngularVelocity(0.f)
-,fAchievedLinearVelocity(0.0f,0.0f,0.0f)
-,fLocalPosition(0.0f,0.0f,0.0f)
-,fLocalRotation(0.0f,0.0f,0.0f,1.0f)
-,fSeeking(false)
-,fEnabled(true)
-,fEnableChanged(false)
-,fLOSDB(plSimDefs::kLOSDBNone)
-,fDisplacementThisStep(0.f,0.f,0.f)
-,fSimLength(0.f)
-,fKinematic(false)
-,fKinematicEnableNextUpdate(false)
-,fNeedsResize(false)
-,fPushingPhysical(nil)
+
+
+// Movement Strategy
+plMovementStrategy::plMovementStrategy(plPhysicalControllerCore* controller)
+ : fController(controller)
{
}
-void plPhysicalControllerCore::UpdateSubstepNonPhysical()
-{
- // When we're in non-phys or a behavior we can't go through the rest of the function
- // so we need to get out early, but we need to update the current position if we're
- // in a subworld.
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- const plCoordinateInterface* ci = GetSubworldCI();
- if (ci && so)
- {
- const hsMatrix44& soL2W = so->GetCoordinateInterface()->GetLocalToWorld();
- const hsMatrix44& ciL2W = ci->GetLocalToWorld();
- hsMatrix44 l2w =GetPrevSubworldW2L()* soL2W;
- l2w = ciL2W * l2w;
- hsMatrix44 w2l;
- l2w.GetInverse(&w2l);
- ((plCoordinateInterface*)so->GetCoordinateInterface())->SetTransform(l2w, w2l);
- ((plCoordinateInterface*)so->GetCoordinateInterface())->FlushTransform();
- SetGlobalLoc(l2w);
- }
+void plMovementStrategy::Reset(bool newAge) { fController->SetMovementStrategy(this); }
-}
-void plPhysicalControllerCore::CheckAndHandleAnyStateChanges()
-{
- if (IsEnabledChanged())HandleEnableChanged();
- if (IsKinematicChanged())HandleKinematicChanged();
- if (IsKinematicEnableNextUpdate())HandleKinematicEnableNextUpdate();
-}
-void plPhysicalControllerCore::MoveActorToSim()
+// Animated Movement Strategy
+plAnimatedMovementStrategy::plAnimatedMovementStrategy(plAGApplicator* rootApp, plPhysicalControllerCore* controller)
+ : plMovementStrategy(controller),
+ fRootApp(rootApp),
+ fAnimLinearVel(0.0f, 0.0f, 0.0f),
+ fAnimAngularVel(0.0f),
+ fTurnStr(0.0f)
{
- // Get the current position of the physical
- hsPoint3 curLocalPos;
- hsPoint3 lastLocalPos;
- GetPositionSim(curLocalPos);
- MoveKinematicToController(curLocalPos);
- lastLocalPos=GetLocalPosition();
- fDisplacementThisStep= hsVector3(curLocalPos - lastLocalPos);
- fLocalPosition = curLocalPos;
- if(fSimLength>0.0f)
- fAchievedLinearVelocity=fDisplacementThisStep/fSimLength;
- else fAchievedLinearVelocity.Set(0.0f,0.0f,0.0f);
-}
-void plPhysicalControllerCore::IncrementAngle(hsScalar deltaAngle)
-{
- hsScalar angle;
- hsVector3 axis;
- fLocalRotation.NormalizeIfNeeded();
- fLocalRotation.GetAngleAxis(&angle, &axis);
- // adjust it (quaternions are weird...)
- if (axis.fZ < 0)
- angle = (2*hsScalarPI) - angle; // axis is backwards, so reverse the angle too
- angle += deltaAngle;
- // make sure we wrap around
- if (angle < 0)
- angle = (2*hsScalarPI) + angle; // angle is -, so this works like a subtract
- if (angle >= (2*hsScalarPI))
- angle = angle - (2*hsScalarPI);
- // and set the new angle
- fLocalRotation.SetAngleAxis(angle, hsVector3(0,0,1));
}
-void plPhysicalControllerCore::UpdateWorldRelativePos()
+void plAnimatedMovementStrategy::RecalcVelocity(double timeNow, hsScalar elapsed, hsBool useAnim)
{
+ if (useAnim)
+ {
+ // while you may think it would be correct to cache this, what we're actually asking is "what would the animation's
+ // position be at the previous time given its *current* parameters (particularly blends)"
+ hsMatrix44 prevMat = ((plMatrixChannel *)fRootApp->GetChannel())->Value(timeNow - elapsed, true);
+ hsMatrix44 curMat = ((plMatrixChannel *)fRootApp->GetChannel())->Value(timeNow, true);
- // Apply rotation and translation
- fLocalRotation.MakeMatrix(&fLastGlobalLoc);
- fLastGlobalLoc.SetTranslate(&fLocalPosition);
- // Localize to global coords if in a subworld
- const plCoordinateInterface* ci = GetSubworldCI();
- if (ci)
+ IRecalcLinearVelocity(elapsed, prevMat, curMat);
+ IRecalcAngularVelocity(elapsed, prevMat, curMat);
+
+ // Update controller rotation
+ hsScalar zRot = fAnimAngularVel + fTurnStr;
+ if (hsABS(zRot) > 0.0001f)
+ fController->IncrementAngle(zRot * elapsed);
+ }
+ else
{
- const hsMatrix44& l2w = ci->GetLocalToWorld();
- fLastGlobalLoc = l2w * fLastGlobalLoc;
+ fAnimLinearVel.Set(0.0f, 0.0f, 0.0f);
+ fAnimAngularVel = 0.0f;
}
+
+ // Update controller velocity
+ fController->SetLinearVelocity(fAnimLinearVel);
}
-plPhysical* plPhysicalControllerCore::GetPushingPhysical()
+
+void plAnimatedMovementStrategy::IRecalcLinearVelocity(float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat)
{
- return fPushingPhysical;
+ hsPoint3 startPos(0.0f, 0.0f, 0.0f); // default position (at start of anim)
+ hsPoint3 prevPos = prevMat.GetTranslate(); // position previous frame
+ hsPoint3 nowPos = curMat.GetTranslate(); // position current frame
+
+ hsVector3 prev2Now = (hsVector3)(nowPos - prevPos); // frame-to-frame delta
+
+ if (fabs(prev2Now.fX) < 0.0001f && fabs(prev2Now.fY) < 0.0001f && fabs(prev2Now.fZ) < 0.0001f)
+ {
+ fAnimLinearVel.Set(0.f, 0.f, 0.f);
+ }
+ else
+ {
+ hsVector3 start2Now = (hsVector3)(nowPos - startPos); // start-to-frame delta
+
+ float prev2NowMagSqr = prev2Now.MagnitudeSquared();
+ float start2NowMagSqr = start2Now.MagnitudeSquared();
+
+ float dot = prev2Now.InnerProduct(start2Now);
+
+ // HANDLING ANIMATION WRAPPING:
+ // the vector from the animation origin to the current frame should point in roughly
+ // the same direction as the vector from the previous animation position to the
+ // current animation position.
+ //
+ // If they don't agree (dot < 0,) then we probably mpst wrapped around.
+ // The right answer would be to compare the current frame to the start of
+ // the anim loop, but it's cheaper to cheat and use the previous frame's velocity.
+ if (dot > 0.0f)
+ {
+ prev2Now /= elapsed;
+
+ float xfabs = fabs(prev2Now.fX);
+ float yfabs = fabs(prev2Now.fY);
+ float zfabs = fabs(prev2Now.fZ);
+ static const float maxVel = 20.0f;
+ hsBool valid = xfabs < maxVel && yfabs < maxVel && zfabs < maxVel;
+
+ if (valid)
+ {
+ fAnimLinearVel = prev2Now;
+ }
+ }
+ }
}
-const hsVector3& plPhysicalControllerCore::GetLinearVelocity()
+
+void plAnimatedMovementStrategy::IRecalcAngularVelocity(float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat)
{
- return fLinearVelocity;
+ fAnimAngularVel = 0.0f;
+ hsScalar appliedVelocity = 0.0f;
+ hsVector3 prevForward = GetYAxis(prevMat);
+ hsVector3 curForward = GetYAxis(curMat);
+
+ hsScalar angleSincePrev = AngleRad2d(curForward.fX, curForward.fY, prevForward.fX, prevForward.fY);
+ hsBool sincePrevSign = angleSincePrev > 0.0f;
+ if (angleSincePrev > hsScalarPI)
+ angleSincePrev = angleSincePrev - TWO_PI;
+
+ const hsVector3 startForward = hsVector3(0.0f, -1.0f, 0.0f); // the Y orientation of a "resting" armature....
+ hsScalar angleSinceStart = AngleRad2d(curForward.fX, curForward.fY, startForward.fX, startForward.fY);
+ hsBool sinceStartSign = angleSinceStart > 0.0f;
+ if (angleSinceStart > hsScalarPI)
+ angleSinceStart = angleSinceStart - TWO_PI;
+
+ // HANDLING ANIMATION WRAPPING:
+ // under normal conditions, the angle from rest to the current frame will have the same
+ // sign as the angle from the previous frame to the current frame.
+ // if it does not, we have (most likely) wrapped the motivating animation from frame n back
+ // to frame zero, creating a large angle from the previous frame to the current one
+ if (sincePrevSign == sinceStartSign)
+ {
+ // signs are the same; didn't wrap; use the frame-to-frame angle difference
+ appliedVelocity = angleSincePrev / elapsed; // rotation / time
+ if (fabs(appliedVelocity) < 3)
+ {
+ fAnimAngularVel = appliedVelocity;
+ }
+ }
}
-bool plPhysicalControllerCore::GetFacingPushingPhysical()
+
+
+// Walking Strategy
+plWalkingStrategy::plWalkingStrategy(plAGApplicator* rootApp, plPhysicalControllerCore* controller)
+ : plAnimatedMovementStrategy(rootApp, controller),
+ fSlidingNormals(),
+ fImpactVelocity(0.0f, 0.0f, 0.0f),
+ fImpactTime(0.0f),
+ fTimeInAir(0.0f),
+ fControlledFlightTime(0.0f),
+ fControlledFlight(0),
+ fGroundHit(false),
+ fFalseGround(false),
+ fHeadHit(false),
+ fClearImpact(false),
+ fHitGroundInThisAge(false)
{
- return fFacingPushingPhysical;
}
-///////////////////////////
-//Walking Strategy
+
void plWalkingStrategy::Apply(hsScalar delSecs)
{
- //Apply Should Only be Called from a PhysicalControllerCore
- hsAssert(fCore,"No Core shouldn't be Applying");
- UInt32 collideFlags =
- 1<IsSeeking())
+ hsVector3 velocity = fController->GetLinearVelocity();
+ hsVector3 achievedVelocity = fController->GetAchievedLinearVelocity();
+
+ // Add in gravity if the avatar's z velocity isn't being set explicitly
+ if (hsABS(velocity.fZ) < 0.001f)
{
- collideFlags|=(1<GetLinearVelocity();
- hsVector3 AchievedLinearVelocity=fCore->GetAchievedLinearVelocity();
- hsPoint3 positionBegin;
- fCore->GetPositionSim(positionBegin);
- bool recovered=false;
- if (fCore->IsKinematic())
+
+ // If we're airborne and the velocity isn't set, use the velocity from
+ // the last frame so we maintain momentum.
+ if (!IsOnGround() && velocity.fX == 0.0f && velocity.fY == 0.0f)
{
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- if (so)
- {
- // If we've been moved since the last physics update (somebody warped us),
- // update the physics before we apply velocity.
- const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld();
- if (!CompareMatrices(l2w, fCore->GetLastGlobalLoc(), .0001f))
- {
- fCore->SetKinematicLoc(l2w);
- fCore->SetGlobalLoc(l2w);
- }
- }
- return;
+ velocity.fX = achievedVelocity.fX;
+ velocity.fY = achievedVelocity.fY;
}
- if (!fCore->IsEnabled())
- return;
-
- bool gotGroundHit = fGroundHit;
- fGroundHit = false;
-
- fCore->SetPushingPhysical(nil);
- fCore->SetFacingPushingPhysical( false);
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- if (so)
+ if (!fGroundHit && fSlidingNormals.Count())
{
- static const float kGravity = -32.f;
- // If we've been moved since the last physics update (somebody warped us),
- // update the physics before we apply velocity.
- const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld();
- if (!CompareMatrices(l2w, fCore->GetLastGlobalLoc(), .0001f))
- fCore->SetGlobalLoc(l2w);
-
- // Convert our avatar relative velocity to subworld relative
- if (!LinearVelocity.IsEmpty())
+ // We're not on solid ground, so we should be sliding against whatever
+ // we're hitting (like a rock cliff). Each vector in fSlidingNormals is
+ // the surface normal of a collision that's too steep to be ground, so
+ // we project our current velocity onto that plane and slide along the
+ // wall.
+ //
+ // Also, sometimes PhysX reports a bunch of collisions from the wall,
+ // but nothing from underneath (when there should be). So if we're not
+ // touching ground, we offset the avatar in the direction of the
+ // surface normal(s). This doesn't fix the issue 100%, but it's a hell
+ // of a lot better than nothing, and suitable duct tape until a future
+ // PhysX revision fixes the issue.
+ //
+ // Yes, there's room for optimization here if we care.
+ hsVector3 offset(0.0f, 0.0f, 0.0f);
+ for (int i = 0; i < fSlidingNormals.GetCount(); i++)
{
- LinearVelocity = l2w * LinearVelocity;
- const plCoordinateInterface* subworldCI = fCore->GetSubworldCI();
- if (subworldCI)
- LinearVelocity = subworldCI->GetWorldToLocal() * LinearVelocity;
- }
+ offset += fSlidingNormals[i];
+ hsVector3 velNorm = velocity;
- // Add in gravity if the avatar's z velocity isn't being set explicitly
- // (Add in a little fudge factor, since the animations usually add a
- // tiny bit of z.)
- if (hsABS(LinearVelocity.fZ) < 0.001f)
- {
- // Get our previous z velocity. If we're on the ground, clamp it to zero at
- // the largest, so we won't launch into the air if we're running uphill.
- hsScalar prevZVel = AchievedLinearVelocity.fZ;
- if (IsOnGround())
- prevZVel = hsMinimum(prevZVel, 0.f);
- hsScalar grav = kGravity * delSecs;
- // If our gravity contribution isn't high enough this frame, we won't
- // report a collision even when standing on solid ground.
- hsScalar maxGrav = -.001f / delSecs;
- if (grav > maxGrav)
- grav = maxGrav;
- LinearVelocity.fZ = prevZVel + grav;
- }
+ if (velNorm.MagnitudeSquared() > 0.0f)
+ velNorm.Normalize();
- // If we're airborne and the velocity isn't set, use the velocity from
- // the last frame so we maintain momentum.
- if (!IsOnGround() && LinearVelocity.fX == 0.f && LinearVelocity.fY == 0.f)
- {
- LinearVelocity.fX = AchievedLinearVelocity.fX;
- LinearVelocity.fY = AchievedLinearVelocity.fY;
- }
- if (!IsOnGround() || IsOnFalseGround())
- {
- // We're not on solid ground, so we should be sliding against whatever
- // we're hitting (like a rock cliff). Each vector in fSlidingNormals is
- // the surface normal of a collision that's too steep to be ground, so
- // we project our current velocity onto that plane and slide along the
- // wall.
- //
- // Also, sometimes PhysX reports a bunch of collisions from the wall,
- // but nothing from underneath (when there should be). So if we're not
- // touching ground, we offset the avatar in the direction of the
- // surface normal(s). This doesn't fix the issue 100%, but it's a hell
- // of a lot better than nothing, and suitable duct tape until a future
- // PhysX revision fixes the issue.
- //
- // Yes, there's room for optimization here if we care.
- hsVector3 offset(0.f, 0.f, 0.f);
- for (int i = 0; i < fContactNormals.GetCount(); i++)
+ if (velNorm * fSlidingNormals[i] < 0.0f)
{
- offset += fContactNormals[i];
- hsVector3 velNorm = LinearVelocity;
-
- if (velNorm.MagnitudeSquared() > 0)
- velNorm.Normalize();
-
- if (velNorm * fContactNormals[i] < 0)
- {
- hsVector3 proj = (velNorm % fContactNormals[i]) % fContactNormals[i];
- if (velNorm * proj < 0)
- proj *= -1.f;
- LinearVelocity = LinearVelocity.Magnitude() * proj;
- }
- }
- if (offset.MagnitudeSquared() > 0)
- {
- // 5 ft/sec is roughly the speed we walk backwards.
- // The higher the value, the less likely you'll trip
- // the bug, and this seems reasonable.
- offset.Normalize();
- LinearVelocity += offset * 5.0f;
- }
- }
- //make terminal velocity equal to k. it is wrong but has been this way and
- //don't want to break any puzzles. on top of that it will reduce tunneling behavior
- if(LinearVelocity.fZSetLinearVelocity(LinearVelocity);
- // Scale the velocity to our actual step size (by default it's feet/sec)
- hsVector3 vel(LinearVelocity.fX * delSecs, LinearVelocity.fY * delSecs, LinearVelocity.fZ * delSecs);
- unsigned int colFlags = 0;
- fGroundHit = false;
- fFalseGround = false;
- fContactNormals.Swap(fPrevSlidingNormals);
- fContactNormals.SetCount(0);
- fCore->Move(vel, collideFlags, colFlags);
- ICheckForFalseGround();
- //if(fReqMove2) fCore->Move2(vel);
- /*If the Physx controller thinks we have a collision from below, need to make sure we
- have at least have false ground, otherwise Autostepping can send us into the air, and we will some times
- float/panic link. For some reason the NxControllerHitReport does not always send messages
- regarding Controller contact with ground plane, but will (almost) always return NXCC_COLLISION_DOWN
- with the move method.
- */
- if((colFlags&kBottom ) &&(fGroundHit==false))
- {
- fFalseGround=true;
+ velocity = velocity.Magnitude() * proj;
+ }
}
-
- if(colFlags&kTop)
+ if (offset.MagnitudeSquared() > 0.0f)
{
- fHitHead=true;
- //Did you hit your head on a dynamic?
- //with Physx's wonderful controller hit report vs flags issues we need to actually sweep to see
- std::multiset< plControllerSweepRecord > HitsDynamic;
- UInt32 testFlag=1<GetPositionSim(startPos);
- endPos= startPos + vel;
- int NumObjsHit=fCore->SweepControllerPath(startPos, endPos, true, false, testFlag, HitsDynamic);
- if(NumObjsHit>0)
- {
- for(std::multiset< plControllerSweepRecord >::iterator curObj= HitsDynamic.begin();
- curObj!=HitsDynamic.end(); curObj++)
- {
-
- hsAssert(curObj->ObjHit,"We allegedly hit something, but there is no plasma physical associated with it");
- if(curObj->ObjHit)
- {//really we shouldn't have to check hitObj should be nil only if we miss, or the physX object
- //doesn't have a user data associated with this either way this just shouldn't happen
- hsVector3 hitObjVel;
- curObj->ObjHit->GetLinearVelocitySim(hitObjVel);
- hsVector3 relativevel=LinearVelocity-hitObjVel;
- curObj->ObjHit->SetHitForce(relativevel * 10.0f * (*curObj).ObjHit->GetMass(), (*curObj).locHit);
- }
- }
- HitsDynamic.clear();
- }
+ // 5 ft/sec is roughly the speed we walk backwards.
+ // The higher the value, the less likely you'll trip
+ // the bug, and this seems reasonable.
+ offset.Normalize();
+ velocity += offset * 5.0f;
}
}
+
+ if (velocity.fZ < kTerminalVelocity)
+ velocity.fZ = kTerminalVelocity;
+
+ // Convert to a displacement vector
+ hsVector3 displacement = velocity * delSecs;
+
+ // Reset vars and move the controller
+ fController->SetPushingPhysical(nil);
+ fController->SetFacingPushingPhysical(false);
+ fGroundHit = fFalseGround = fHeadHit = false;
+ fSlidingNormals.SetCount(0);
+
+ unsigned int collideResults = 0;
+ unsigned int collideFlags = 1<IsSeeking())
+ collideFlags |= (1<Move(displacement, collideFlags, collideResults);
+
+ if ((!fGroundHit) && (collideResults & kBottom))
+ fFalseGround = true;
+
+ if (collideResults & kTop)
+ fHeadHit = true;
}
-void plWalkingStrategy::ICheckForFalseGround()
+void plWalkingStrategy::Update(hsScalar delSecs)
{
- if (fGroundHit)
- return; // Already collided with "real" ground.
-
- // We need to check for the case where the avatar hasn't collided with "ground", but is colliding
- // with a few other objects so that he's not actually falling (wedged in between some slopes).
- // We do this by answering the following question (in 2d top-down space): "If you sort the contact
- // normals by angle, is there a large enough gap between normals?"
- //
- // If you think in terms of geometry, this means a collection of surfaces are all pushing on you.
- // If they're pushing from all sides, you have nowhere to go, and you won't fall. There needs to be
- // a gap, so that you're pushed out and have somewhere to fall. This is the same as finding a gap
- // larger than 180 degrees between sorted normals.
- //
- // The problem is that on top of that, the avatar needs enough force to shove him out that gap (he
- // has to overcome friction). I deal with that by making the threshold (360 - (180 - 60) = 240). I've
- // seen up to 220 reached in actual gameplay in a situation where we'd want this to take effect.
- // This is the same running into 2 walls where the angle between them is 60.
- int i, j;
- const hsScalar threshold = hsScalarDegToRad(240.f);
- int numContacts = fContactNormals.GetCount() + fPrevSlidingNormals.GetCount();
- if (numContacts >= 2)
+ if (fGroundHit || fFalseGround)
+ fTimeInAir = 0.0f;
+ else
{
- // For extra fun... PhysX will actually report some collisions every other frame, as though
- // we're bouncing back and forth between the two (or more) objects blocking us. So it's not
- // enough to look at this frame's collisions, we have to check previous frames too.
- hsTArray fCollisionAngles;
- fCollisionAngles.SetCount(numContacts);
- int angleIdx = 0;
- for (i = 0; i < fContactNormals.GetCount(); i++, angleIdx++)
- {
- fCollisionAngles[angleIdx] = hsATan2(fContactNormals[i].fY, fContactNormals[i].fX);
- }
- for (i = 0; i < fPrevSlidingNormals.GetCount(); i++, angleIdx++)
- {
- fCollisionAngles[angleIdx] = hsATan2(fPrevSlidingNormals[i].fY, fPrevSlidingNormals[i].fX);
- }
- // numContacts is rarely larger than 6, so let's do a simple bubble sort.
- for (i = 0; i < numContacts; i++)
- {
- for (j = i + 1; j < numContacts; j++)
- {
- if (fCollisionAngles[i] > fCollisionAngles[j])
- {
- hsScalar tempAngle = fCollisionAngles[i];
- fCollisionAngles[i] = fCollisionAngles[j];
- fCollisionAngles[j] = tempAngle;
- }
- }
- }
- // sorted, now we check.
- for (i = 1; i < numContacts; i++)
- {
- if (fCollisionAngles[i] - fCollisionAngles[i - 1] >= threshold)
- break;
- }
- if (i == numContacts)
- {
- // We got to the end. Check the last with the first and make your decision.
- if (!(fCollisionAngles[0] - fCollisionAngles[numContacts - 1] >= (threshold - 2 * hsScalarPI)))
- fFalseGround = true;
+ fTimeInAir += delSecs;
+ if (fHeadHit)
+ {
+ // If we're airborne and hit our head, override achieved velocity to avoid being shoved sideways
+ hsVector3 velocity = fController->GetLinearVelocity();
+ hsVector3 achievedVelocity = fController->GetAchievedLinearVelocity();
+
+ achievedVelocity.fX = velocity.fX;
+ achievedVelocity.fY = velocity.fY;
+ if (achievedVelocity.fZ > 0.0f)
+ achievedVelocity.fZ = 0.0f;
+
+ fController->OverrideAchievedLinearVelocity(achievedVelocity);
}
}
+
+ if (!fHitGroundInThisAge && IsOnGround())
+ fHitGroundInThisAge = true;
+
+ if (fClearImpact)
+ {
+ fImpactTime = 0.0f;
+ fImpactVelocity.Set(0.0f, 0.0f, 0.0f);
+ }
+
+ if (IsOnGround())
+ fClearImpact = true;
+ else
+ {
+ fImpactTime = fTimeInAir;
+ fImpactVelocity = fController->GetAchievedLinearVelocity();
+ // convert orientation from subworld to avatar-local coordinates
+ fImpactVelocity = (hsVector3)fController->GetLocalRotation().Rotate(&fImpactVelocity);
+ fClearImpact = false;
+ }
+
+ if (fControlledFlight != 0)
+ {
+ if (IsOnGround())
+ fControlledFlightTime = fTimeInAir;
+
+ if (fControlledFlightTime > kControlledFlightThreshold)
+ EnableControlledFlight(false);
+ }
}
-void plWalkingStrategy::Update(hsScalar delSecs)
+
+void plWalkingStrategy::AddContactNormals(hsVector3& vec)
{
- //Update Should Only be Called from a PhysicalControllerCore
- hsAssert(fCore,"Running Update: but have no Core");
- hsScalar AngularVelocity=fCore->GetAngularVelocity();
- hsVector3 LinearVelocity=fCore->GetLinearVelocity();
+ hsScalar dot = vec * kAvatarUp;
+ if (dot >= 0.5f)
+ fGroundHit = true;
+ else
+ fSlidingNormals.Append(vec);
+}
- if (!fCore->IsEnabled() || fCore->IsKinematic())
+void plWalkingStrategy::Reset(bool newAge)
+{
+ plMovementStrategy::Reset(newAge);
+ if (newAge)
{
- fCore->UpdateSubstepNonPhysical();
- return;
+ fTimeInAir = 0.0f;
+ fClearImpact = true;
+ fHitGroundInThisAge = false;
+ fSlidingNormals.SetCount(0);
}
- fCore->CheckAndHandleAnyStateChanges();
- if (!fGroundHit && !fFalseGround)
- fTimeInAir += delSecs;
- else
- fTimeInAir = 0.f;
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- if (so)
+}
+
+bool plWalkingStrategy::EnableControlledFlight(bool status)
+{
+ if (status)
{
- fCore->MoveActorToSim();
- if (AngularVelocity != 0.f)
- {
- hsScalar deltaAngle=AngularVelocity*delSecs;
- fCore->IncrementAngle( deltaAngle);
- }
- // We can't only send updates when the physical position changes because the
- // world relative position may be changing all the time if we're in a subworld.
- fCore->UpdateWorldRelativePos();
- fCore->SendCorrectionMessages();
- bool headhit=fHitHead;
- fHitHead=false;
- hsVector3 AchievedLinearVelocity;
- AchievedLinearVelocity = fCore->DisplacementLastStep();
- AchievedLinearVelocity=AchievedLinearVelocity/delSecs;
-
- /*if we hit our head the sweep api might try to
- move us laterally to go as high as we requested kind of like autostep, to top it off the
- way the NxCharacter and the sweep api work as a whole NxControllerHitReport::OnShapeHit
- wont be called regarding the head blow.
- if we are airborne: with out this we will gain large amounts of velocity in the x y plane
- and on account of fAchievedLinearVelocity being used in the next step we will fly sideways
- */
- if(headhit&&!(fGroundHit||fFalseGround))
- {
- //we have hit our head and we don't have anything beneath our feet
- //not really friction just a way to make it seem more realistic keep between 0 and 1
- hsScalar headFriction=0.0f;
- AchievedLinearVelocity.fX=(1.0f-headFriction)*LinearVelocity.fX;
- AchievedLinearVelocity.fY=(1.0f-headFriction)*LinearVelocity.fY;
- //only clamping when hitting head and going upwards, if going down leave it be
- // this should only occur when going down stairwells with low ceilings like in cleft
- //kitchen area
- if(AchievedLinearVelocity.fZ>0.0f)
- {
- AchievedLinearVelocity.fZ=0.0f;
- }
- fCore->OverrideAchievedVelocity(AchievedLinearVelocity);
- }
- fCore->OverrideAchievedVelocity(AchievedLinearVelocity);
- // Apply angular velocity
+ if (fControlledFlight == 0)
+ fControlledFlightTime = 0.0f;
+
+ ++fControlledFlight;
}
+ else
+ fControlledFlight = __max(--fControlledFlight, 0);
+
+ return status;
+}
+
+plPhysical* plWalkingStrategy::GetPushingPhysical() const { return fController->GetPushingPhysical(); }
+bool plWalkingStrategy::GetFacingPushingPhysical() const { return fController->GetFacingPushingPhysical(); }
+
+const hsScalar plWalkingStrategy::kAirTimeThreshold = 0.1f;
+const hsScalar plWalkingStrategy::kControlledFlightThreshold = 1.0f;
- LinearVelocity.Set(0.f, 0.f, 0.f);
- AngularVelocity = 0.f;
- fCore->SetVelocities(LinearVelocity,AngularVelocity);
+// Swim Strategy
+plSwimStrategy::plSwimStrategy(plAGApplicator* rootApp, plPhysicalControllerCore* controller)
+ : plAnimatedMovementStrategy(rootApp, controller),
+ fBuoyancy(0.0f),
+ fSurfaceHeight(0.0f),
+ fCurrentRegion(nil),
+ fOnGround(false),
+ fHadContacts(false)
+{
}
+void plSwimStrategy::Apply(hsScalar delSecs)
+{
+ hsVector3 velocity = fController->GetLinearVelocity();
+ hsVector3 achievedVelocity = fController->GetAchievedLinearVelocity();
+
+ IAdjustBuoyancy();
+
+ //trying to dampen the oscillations
+ hsScalar retardent = 0.0f;
+ static hsScalar finalBobSpeed = 0.5f;
+ if ((achievedVelocity.fZ > finalBobSpeed) || (achievedVelocity.fZ < -finalBobSpeed))
+ retardent = achievedVelocity.fZ * -0.90f;
+
+ hsScalar zacc = (1.0f - fBuoyancy) * kGravity + retardent;
+ velocity.fZ += (zacc * delSecs);
+
+ velocity.fZ += achievedVelocity.fZ;
+
+ // Water Current
+ if (fCurrentRegion != nil)
+ {
+ hsScalar angCurrent = 0.0f;
+ hsVector3 linCurrent(0.0f, 0.0f, 0.0f);
+ fCurrentRegion->GetCurrent(fController, linCurrent, angCurrent, delSecs);
+
+ if (hsABS(angCurrent) > 0.0001f)
+ fController->IncrementAngle(angCurrent * delSecs);
+
+ velocity += linCurrent;
-void plWalkingStrategy::IAddContactNormals(hsVector3& vec)
-{
- //TODO: ADD in functionality to Adjust walkable slope for controller, also apply that in here
+ if (velocity.fZ > fCurrentRegion->fMaxUpwardVel)
+ velocity.fZ = fCurrentRegion->fMaxUpwardVel;
+ }
+
+ if (velocity.fZ < kTerminalVelocity)
+ velocity.fZ = kTerminalVelocity;
+
+ // Convert to displacement vector
+ hsVector3 displacement = velocity * delSecs;
+
+ // Reset vars and move controller //
+ fController->SetPushingPhysical(nil);
+ fController->SetFacingPushingPhysical(false);
+ fHadContacts = fOnGround = false;
+
+ unsigned int collideResults = 0;
+ unsigned int collideFlags = 1<IsSeeking())
+ collideFlags |= (1<Move(displacement, collideFlags, collideResults);
+
+ if ((collideResults & kBottom) || (collideResults & kSides))
+ fHadContacts = true;
+}
+
+void plSwimStrategy::AddContactNormals(hsVector3& vec)
+{
hsScalar dot = vec * kAvatarUp;
- if ( dot >= kSLOPELIMIT ) fGroundHit=true;
- else plMovementStrategySimulationInterface::IAddContactNormals(vec);
+ if (dot >= kSlopeLimit)
+ fOnGround = true;
}
-//swimming strategy
-plSwimStrategy::plSwimStrategy(plPhysicalControllerCore* core)
- :plMovementStrategy(core)
- ,fOnGround(false)
- ,fHadContacts(false)
- ,fBuoyancy(0.f)
- ,fSurfaceHeight(0.0f)
- ,fCurrentRegion(nil)
+void plSwimStrategy::SetSurface(plSwimRegionInterface *region, hsScalar surfaceHeight)
{
- fPreferedControllerHeight=kSWIMHEIGHT;
- fPreferedControllerWidth=kSWIMRADIUS;
- fCore->SetMovementSimulationInterface(this);
+ fCurrentRegion = region;
+ fSurfaceHeight = surfaceHeight;
}
void plSwimStrategy::IAdjustBuoyancy()
{
@@ -599,383 +652,148 @@ void plSwimStrategy::IAdjustBuoyancy()
return;
}
- hsMatrix44 l2w, w2l;
hsPoint3 posSim;
- fCore->GetPositionSim(posSim);
- float depth = fSurfaceHeight - posSim.fZ;
- //this isn't a smooth transition but hopefully it won't be too obvious
- if(depth<=0.0)//all the away above water
+ fController->GetPositionSim(posSim);
+ float depth = fSurfaceHeight - posSim.fZ;
+
+ // this isn't a smooth transition but hopefully it won't be too obvious
+ if (depth <= 0.0) //all the away above water
fBuoyancy = 0.f; // Same as being above ground. Plain old gravity.
- else if(depth >= 5.0f) fBuoyancy=3.0f;//completely Submereged
- else fBuoyancy =(depth/surfaceDepth );
-
+ else if (depth >= 5.0f)
+ fBuoyancy = 3.0f; //completely Submereged
+ else
+ fBuoyancy = depth / surfaceDepth;
}
-void plSwimStrategy::Apply(hsScalar delSecs)
-{
- hsAssert(fCore,"PlSwimStrategy::Apply No Core shouldn't be Applying");
- UInt32 collideFlags =
- 1<IsSeeking())
- {
- collideFlags|=(1<GetLinearVelocity();
- hsVector3 AchievedLinearVelocity=fCore->GetAchievedLinearVelocity();
- if (fCore->IsKinematic())
- {
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- if (so)
- {
- // If we've been moved since the last physics update (somebody warped us),
- // update the physics before we apply velocity.
- const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld();
- if (!CompareMatrices(l2w, fCore->GetLastGlobalLoc(), .0001f))
- {
- fCore->SetKinematicLoc(l2w);
- fCore->SetGlobalLoc(l2w);
- }
- }
- return;
-
- }
- if (!fCore->IsEnabled())
- return;
-
- fCore->SetPushingPhysical(nil);
- fCore->SetFacingPushingPhysical( false);
- fHadContacts=false;
- fOnGround=false;
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- if (so)
- {
- // If we've been moved since the last physics update (somebody warped us),
- // update the physics before we apply velocity.
- const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld();
- if (!CompareMatrices(l2w, fCore->GetLastGlobalLoc(), .0001f))
- fCore->SetGlobalLoc(l2w);
-
- // Convert our avatar relative velocity to subworld relative
- if (!LinearVelocity.IsEmpty())
- {
- LinearVelocity = l2w * LinearVelocity;
- const plCoordinateInterface* subworldCI = fCore->GetSubworldCI();
- if (subworldCI)
- LinearVelocity = subworldCI->GetWorldToLocal() * LinearVelocity;
- }
- IAdjustBuoyancy();
- hsScalar zacc;
- hsScalar retardent=0.0f;
- static hsScalar FinalBobSpeed=0.5f;
- //trying to dampen the oscillations
- if((AchievedLinearVelocity.fZ>FinalBobSpeed)||(AchievedLinearVelocity.fZ<-FinalBobSpeed))
- retardent=AchievedLinearVelocity.fZ *-.90f;
- zacc=(1-fBuoyancy)*-32.f + retardent;
-
- hsVector3 linCurrent(0.0f,0.0f,0.0f);
- hsScalar angCurrent = 0.f;
- if (fCurrentRegion != nil)
- {
-
- fCurrentRegion->GetCurrent(fCore, linCurrent, angCurrent, delSecs);
- //fAngularVelocity+= angCurrent;
- }
- hsVector3 vel(LinearVelocity.fX , LinearVelocity.fY , AchievedLinearVelocity.fZ+ LinearVelocity.fZ );
- vel.fZ= vel.fZ + zacc*delSecs;
- if(fCurrentRegion!=nil){
- if (vel.fZ > fCurrentRegion->fMaxUpwardVel)
- {
- vel.fZ = fCurrentRegion->fMaxUpwardVel;
- }
- vel+= linCurrent;
- }
- static const float kGravity = -32.f;
- if(vel.fZMove(displacement,collideFlags,colFlags);
- if((colFlags&kBottom)||(colFlags&kSides))fHadContacts=true;
- hsScalar angvel=fCore->GetAngularVelocity();
- fCore->SetAngularVelocity(angvel +angCurrent);
- }
+
+// Dynamic Walking Strategy
+plDynamicWalkingStrategy::plDynamicWalkingStrategy(plAGApplicator* rootApp, plPhysicalControllerCore* controller)
+ : plWalkingStrategy(rootApp, controller)
+{
}
-void plSwimStrategy::Update(hsScalar delSecs)
+
+void plDynamicWalkingStrategy::Apply(hsScalar delSecs)
{
- hsAssert(fCore,"Running Update: but have no Core");
- hsScalar AngularVelocity=fCore->GetAngularVelocity();
- hsVector3 LinearVelocity=fCore->GetLinearVelocity();
- if (!fCore->IsEnabled() || fCore->IsKinematic())
- {
- fCore->UpdateSubstepNonPhysical();
- return;
- }
- fCore->CheckAndHandleAnyStateChanges();
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- if (so)
- {
- fCore->MoveActorToSim();
+ hsVector3 velocity = fController->GetLinearVelocity();
+ hsVector3 achievedVelocity = fController->GetAchievedLinearVelocity();
- if (AngularVelocity != 0.f)
- {
- hsScalar deltaAngle=AngularVelocity*delSecs;
- fCore->IncrementAngle( deltaAngle);
- }
- fCore->UpdateWorldRelativePos();
- fCore->SendCorrectionMessages();
- }
- LinearVelocity.Set(0.f, 0.f, 0.f);
- AngularVelocity = 0.f;
- fCore->SetVelocities(LinearVelocity,AngularVelocity);
-}
-void plSwimStrategy::IAddContactNormals(hsVector3& vec)
-{
- //TODO: ADD in functionality to Adjust walkable slope for controller, also apply that in here
- hsScalar dot = vec * kAvatarUp;
- if ( dot >= kSLOPELIMIT )
+ // Add in gravity if the avatar's z velocity isn't being set explicitly
+ if (hsABS(velocity.fZ) < 0.001f)
{
- fOnGround=true;
- // fHadContacts=true;
+ // Get our previous z velocity. If we're on the ground, clamp it to zero at
+ // the largest, so we won't launch into the air if we're running uphill.
+ hsScalar prevZVel = achievedVelocity.fZ;
+ if (IsOnGround())
+ prevZVel = hsMinimum(prevZVel, 0.f);
+
+ velocity.fZ = prevZVel + (kGravity * delSecs);
}
- else plMovementStrategySimulationInterface::IAddContactNormals(vec);
-}
-void plSwimStrategy::SetSurface(plSwimRegionInterface *region, hsScalar surfaceHeight)
-{
- fCurrentRegion=region;
- fSurfaceHeight=surfaceHeight;
+
+ if (velocity.fZ < kTerminalVelocity)
+ velocity.fZ = kTerminalVelocity;
+
+ fController->SetPushingPhysical(nil);
+ fController->SetFacingPushingPhysical(false);
+ fGroundHit = fFalseGround = false;
+
+ hsScalar groundZVelocity;
+ if (ICheckForGround(groundZVelocity))
+ velocity.fZ += groundZVelocity;
+
+ fController->SetLinearVelocitySim(velocity);
}
-void plRidingAnimatedPhysicalStrategy::Apply(hsScalar delSecs)
+
+bool plDynamicWalkingStrategy::ICheckForGround(hsScalar& zVelocity)
{
- hsVector3 LinearVelocity=fCore->GetLinearVelocity();
- hsVector3 AchievedLinearVelocity=fCore->GetAchievedLinearVelocity();
- if (fCore->IsKinematic())
- {
- //want to make sure nothing funky happens in the sim
- IApplyKinematic();
- return;
- }
- if (!fCore->IsEnabled())
- return;
+ std::vector groundHits;
+ UInt32 collideFlags = 1<GetPositionSim(startPos);
+ hsPoint3 endPos = startPos;
-
- fCore->SetPushingPhysical(nil);
- fCore->SetFacingPushingPhysical( false);
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- hsPoint3 startPos, desiredDestination, endPos;
- fCore->GetPositionSim(startPos);
- UInt32 collideFlags =
- 1< GroundHitRecords;
- int possiblePlatformCount =fCore->SweepControllerPath(startPos, startPos + hsPoint3(0.f,0.f, -0.002f), true, true, collideFlags, GroundHitRecords);
- float maxPlatformVel = - FLT_MAX;
- int platformCount=0;
- fGroundHit = false;
- if(possiblePlatformCount)
+ // Set sweep length
+ startPos.fZ += 0.05f;
+ endPos.fZ -= 0.05f;
+
+ int possiblePlatformCount = fController->SweepControllerPath(startPos, endPos, true, true, collideFlags, groundHits);
+ if (possiblePlatformCount)
{
-
- std::multiset::iterator curRecord;
+ zVelocity = -FLT_MAX;
- for(curRecord = GroundHitRecords.begin(); curRecord != GroundHitRecords.end(); curRecord++)
+ std::vector::iterator curRecord;
+ for (curRecord = groundHits.begin(); curRecord != groundHits.end(); ++curRecord)
{
- hsBool groundlike=false;
- if((curRecord->locHit.fZ - startPos.fZ)<= .2) groundlike= true;
- if(groundlike)
+ if (curRecord->ObjHit != nil)
{
- if(curRecord->ObjHit !=nil)
- {
- hsVector3 vel;
- curRecord->ObjHit->GetLinearVelocitySim(vel);
- if(vel.fZ > maxPlatformVel)
- {
- maxPlatformVel= vel.fZ;
- }
- }
- platformCount ++;
+ hsVector3 objVelocity;
+ curRecord->ObjHit->GetLinearVelocitySim(objVelocity);
+ if (objVelocity.fZ > zVelocity)
+ zVelocity = objVelocity.fZ;
+
fGroundHit = true;
}
}
}
-
-
-
- bool gotGroundHit = fGroundHit;
- if (so)
- {
-
- // If we've been moved since the last physics update (somebody warped us),
- // update the physics before we apply velocity.
- const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld();
- if (!CompareMatrices(l2w, fCore->GetLastGlobalLoc(), .0001f))
- fCore->SetGlobalLoc(l2w);
-
- // Convert our avatar relative velocity to subworld relative
- if (!LinearVelocity.IsEmpty())
- {
- LinearVelocity = l2w * LinearVelocity;
- const plCoordinateInterface* subworldCI = fCore->GetSubworldCI();
- if (subworldCI)
- LinearVelocity = subworldCI->GetWorldToLocal() * LinearVelocity;
- }
-
- if(!IsOnGround())
- {
- if(!fNeedVelocityOverride)
- {
- LinearVelocity.fZ= AchievedLinearVelocity.fZ;
- }
- else
- {
- LinearVelocity = fOverrideVelocity;
- }
- }
- if(fStartJump)
- {
- LinearVelocity.fZ =12.0f;
- }
- if(platformCount)
- {
- LinearVelocity.fZ = LinearVelocity.fZ + maxPlatformVel;
- }
-
- //probably neeed to do something with contact normals in here
- //for false ground stuff
-
- fFalseGround = false;
- hsVector3 testLength = LinearVelocity * delSecs + hsVector3(0.0, 0.0, -0.00f);
- //
- hsPoint3 desiredDestination= startPos + testLength;
- if(!IsOnGround())
- {
- if(ICheckMove(startPos, desiredDestination))
- {//we can get there soley by the LinearVelocity
-
- fNeedVelocityOverride =false;
- }
- else
- {
-
- fNeedVelocityOverride =true;
- fOverrideVelocity = LinearVelocity;
- fOverrideVelocity.fZ -= delSecs * 32.f;
- }
- }
- else
- {
- fNeedVelocityOverride =false;
- }
- fCore->SetLinearVelocity(LinearVelocity);
-
- }
+ return fGroundHit;
}
-bool plRidingAnimatedPhysicalStrategy::ICheckMove(const hsPoint3& startPos, const hsPoint3& desiredPos)
+
+
+//////////////////////////////////////////////////////////////////////////
+
+/*
+Purpose:
+
+ANGLE_RAD_2D returns the angle in radians swept out between two rays in 2D.
+
+Discussion:
+
+Except for the zero angle case, it should be true that
+
+ANGLE_RAD_2D(X1,Y1,X2,Y2,X3,Y3)
++ ANGLE_RAD_2D(X3,Y3,X2,Y2,X1,Y1) = 2 * PI
+
+Modified:
+
+19 April 1999
+
+Author:
+
+John Burkardt
+
+Parameters:
+
+Input, float X1, Y1, X2, Y2, X3, Y3, define the rays
+( X1-X2, Y1-Y2 ) and ( X3-X2, Y3-Y2 ) which in turn define the
+angle, counterclockwise from ( X1-X2, Y1-Y2 ).
+
+Output, float ANGLE_RAD_2D, the angle swept out by the rays, measured
+in radians. 0 <= ANGLE_DEG_2D < 2 PI. If either ray has zero length,
+then ANGLE_RAD_2D is set to 0.
+*/
+
+static float AngleRad2d( float x1, float y1, float x3, float y3 )
{
- //returns false if it believes the end result can't be obtained by pure application of velocity (collides into somthing that it can't climb up)
- //used as a way to check if it needs to hack getting there like in jumping
-
- UInt32 collideFlags =
- 1<IsSeeking())
- {
- collideFlags|=(1< DynamicHits;
- int NumberOfHits=fCore->SweepControllerPath(startPos, desiredPos, true, true, collideFlags, DynamicHits);
-
- hsPoint3 stepFromPoint;
- hsVector3 movementdir(&startPos, &desiredPos);
- movementdir.Normalize();
- if(NumberOfHits)
- {
- hsPoint3 initBottomPos;
- fCore->GetPositionSim(initBottomPos);
- std::multiset< plControllerSweepRecord >::iterator cur;
- hsVector3 testLength(desiredPos - startPos);
- bool freeMove=true;
- for(cur = DynamicHits.begin(); cur != DynamicHits.end(); cur++)
- {
- if(movementdir.InnerProduct(cur->Norm)>0.01f)
- {
- hsVector3 topOfBottomHemAtTimeT=hsVector3(initBottomPos + testLength * cur->TimeHit );
- topOfBottomHemAtTimeT.fZ = topOfBottomHemAtTimeT.fZ + fCore->GetControllerWidth();
- if(cur->locHit.fZ <= (topOfBottomHemAtTimeT.fZ -.5f))
- {
- hitBottomOfCapsule=true;
- hsVector3 norm= hsVector3(-1*(cur->locHit-topOfBottomHemAtTimeT));
- norm.Normalize();
- IAddContactNormals(norm);
- }
- else
- {
- return false;
- }
- }
+ float value;
+ float x;
+ float y;
- }
- return true;
+ x = ( x1 ) * ( x3 ) + ( y1 ) * ( y3 );
+ y = ( x1 ) * ( y3 ) - ( y1 ) * ( x3 );
+
+ if ( x == 0.0 && y == 0.0 ) {
+ value = 0.0;
}
- else
+ else
{
- return true;
- }
-
-}
-void plRidingAnimatedPhysicalStrategy::Update(hsScalar delSecs)
-{
- if (!fCore->IsEnabled() || fCore->IsKinematic())
- {
- fCore->UpdateSubstepNonPhysical();
- return;
- }
- fCore->CheckAndHandleAnyStateChanges();
-}
-void plRidingAnimatedPhysicalStrategy::PostStep(hsScalar delSecs)
-{
- if(!(!fCore->IsEnabled() || fCore->IsKinematic()))
- {
- if (!fGroundHit && !fFalseGround)
- fTimeInAir += delSecs;
- else
- fTimeInAir = 0.f;
- hsVector3 AchievedLinearVelocity, LinearVelocity;
- AchievedLinearVelocity = fCore->GetLinearVelocity();
- hsScalar AngularVelocity=fCore->GetAngularVelocity();
- fCore->OverrideAchievedVelocity(AchievedLinearVelocity);
- plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded());
- if (so)
+ value = atan2 ( y, x );
+
+ if ( value < 0.0 )
{
- fCore->UpdateControllerAndPhysicalRep();
- if (AngularVelocity != 0.f)
- {
- hsScalar deltaAngle=AngularVelocity*delSecs;
- fCore->IncrementAngle( deltaAngle);
- }
- fCore->UpdateWorldRelativePos();
- fCore->SendCorrectionMessages();
+ value = (float)(value + TWO_PI);
}
- LinearVelocity.Set(0.f, 0.f, 0.f);
- AngularVelocity = 0.f;
- fCore->SetVelocities(LinearVelocity, AngularVelocity);
}
- fStartJump = false;
+ return value;
}
+
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plPhysicalControllerCore.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plPhysicalControllerCore.h
index bc96f697..8f56ddc2 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plPhysicalControllerCore.h
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plAvatar/plPhysicalControllerCore.h
@@ -41,310 +41,284 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
*==LICENSE==*/
#ifndef PLPHYSICALCONTROLLERCORE_H
#define PLPHYSICALCONTROLLERCORE_H
+
#include "hsGeometry3.h"
#include "hsMatrix44.h"
+#include "hsQuat.h"
#include "hsTemplates.h"
#include "../pnKeyedObject/plKey.h"
#include "../plPhysical/plSimDefs.h"
-#include "../pnMessage/plMessage.h"
-
-#include "hsQuat.h"
-#define PHYSX_ONLY_TRIGGER_FROM_KINEMATIC 1
-#define kSLOPELIMIT (cosf(hsScalarDegToRad(55.f)))
+#include
class plCoordinateInterface;
class plPhysical;
-class plPXPhysical;
+class plMovementStrategy;
+class plAGApplicator;
class plSwimRegionInterface;
-//Replacement for for plPhysicalController stripped out some walk specific code
-//plPhysicalControllerCore needs to have movement strategies registered to it these will then
-//be called by the controller during the simulation steps. The Strategies need to at least have an
-// Apply and Update definition. Everything else should be movement specific. I hope to come back and
-//and refactor when I have time this in the future.
-enum plControllerCollisionFlags
-{
- kSides=1,
- kTop= (1<<1),
- kBottom=(1<<2),
-};
-class plMovementStrategySimulationInterface
-{
-public:
+#define kSlopeLimit (cosf(hsScalarDegToRad(55.f)))
- virtual void Apply(hsScalar delSecs)=0;
- virtual void Update(hsScalar delSecs)=0;
- //most strategies don't require this. Only the ones that require behavior like a physical or need
- //something after the sim step. this used to be taken care of by Update, but this was moved to take care of
- //some of the frame lag
- virtual void PostStep(hsScalar delSecs){};
- virtual void IAddContactNormals(hsVector3& vec){fContactNormals.Append(vec);}
- virtual void AddOnTopOfObject(plPhysical* phys){ fOnTopOf.Append(phys);}
- virtual void LeaveAge()
- {
- fContactNormals.SetCount(0);
- fOnTopOf.SetCount(0);
- }
-protected:
- hsTArray fContactNormals;
- hsTArray fOnTopOf;
+enum plControllerCollisionFlags
+{
+ kSides = 1,
+ kTop = (1 << 1),
+ kBottom = (1 << 2)
};
-class plControllerSweepRecord
+struct plControllerSweepRecord
{
-public:
plPhysical *ObjHit;
- hsPoint3 locHit;//World space
- hsScalar TimeHit;//Normalized between 0 and 1
- hsVector3 Norm;
+ hsPoint3 Point;
+ hsVector3 Normal;
};
-bool operator<(const plControllerSweepRecord left, const plControllerSweepRecord right);
+
class plPhysicalControllerCore
{
public:
- virtual ~plPhysicalControllerCore();
- virtual void Move(hsVector3 displacement, unsigned int collideWith, unsigned int &collisionResults)=0;
- virtual void SetMovementSimulationInterface(plMovementStrategySimulationInterface* strat){fMovementInterface=strat;}
- virtual void Apply(hsScalar delSecs);
- virtual void Update(hsScalar delSecs);
- virtual void PostStep(hsScalar delSecs);
- // A disabled avatar doesn't move or accumulate air time if he's off the ground.
+ plPhysicalControllerCore(plKey ownerSceneObject, hsScalar height, hsScalar radius);
+ virtual ~plPhysicalControllerCore() { }
+
+ // An ArmatureMod has its own idea about when physics should be enabled/disabled.
+ // Use plArmatureModBase::EnablePhysics() instead.
virtual void Enable(bool enable) = 0;
- virtual bool IsEnabled() {return fEnabled;}
- virtual plKey GetSubworld() {return fWorldKey;}
+ virtual bool IsEnabled() { return fEnabled; }
+
+ // Subworld
+ virtual plKey GetSubworld() { return fWorldKey; }
virtual void SetSubworld(plKey world) = 0;
- virtual const plCoordinateInterface* GetSubworldCI() const = 0;
+ virtual const plCoordinateInterface* GetSubworldCI();
+
// For the avatar SDL only
virtual void GetState(hsPoint3& pos, float& zRot) = 0;
virtual void SetState(const hsPoint3& pos, float zRot) = 0;
- // kinematic stuff .... should be just for when playing a behavior...
- virtual void Kinematic(bool state) = 0;
- virtual bool IsKinematic() = 0;
- virtual void GetKinematicPosition(hsPoint3& pos) = 0;
- virtual const hsMatrix44& GetPrevSubworldW2L() = 0;
- //when seeking no longer want to interact with exclusion regions
- virtual void SetSeek(bool seek){fSeeking=seek;}
- virtual bool IsSeeking(){return fSeeking;}
- static plPhysicalControllerCore* Create(plKey ownerSO, hsScalar height, hsScalar radius);
- virtual plMovementStrategySimulationInterface* GetMovementInterface(){return fMovementInterface;}
- plPhysicalControllerCore(plKey ownerSceneObject, hsScalar height, hsScalar radius);
- virtual plKey GetOwner(){return fOwner;};
- // Set the LOS DB this avatar will be in (only one)
- virtual void SetLOSDB(plSimDefs::plLOSDB losDB) { fLOSDB = losDB; } ;
- virtual plSimDefs::plLOSDB GetLOSDB() {return fLOSDB ; }
- virtual const hsMatrix44& GetLastGlobalLoc()=0;
- virtual void SetKinematicLoc(const hsMatrix44& l2w)=0;
- virtual void SetGlobalLoc(const hsMatrix44& l2w)=0;
- virtual bool IsEnabledChanged(){return fEnableChanged;}
- virtual void HandleEnableChanged()=0;
- virtual bool IsKinematicChanged(){return fKinematicChanged;}
- virtual void GetPositionSim(hsPoint3& pos)=0;
- virtual void HandleKinematicChanged()=0;
- virtual bool IsKinematicEnableNextUpdate(){return fKinematicEnableNextUpdate;}
- virtual void HandleKinematicEnableNextUpdate()=0;
- virtual void MoveKinematicToController(hsPoint3& pos)=0;
- virtual void UpdateControllerAndPhysicalRep()=0;
- virtual void CheckAndHandleAnyStateChanges();
- virtual void UpdateSubstepNonPhysical();
- virtual const hsPoint3& GetLocalPosition()=0;
- const hsQuat& GetLocalRotation() { return fLocalRotation; }
- virtual void MoveActorToSim();
-
- virtual void OverrideAchievedVelocity(hsVector3 newAchievedVel)
- {//because of things like superjumps this is needed I'd rather not, but can't help it
- fAchievedLinearVelocity=newAchievedVel;
- }
- //any clean up for the controller should go here
- virtual void LeaveAge()=0;
- hsVector3 DisplacementLastStep(){return fDisplacementThisStep;}
- hsVector3 MeanVelocityForLastStep()
- {
- hsVector3 vel=fDisplacementThisStep;
- return vel/fSimLength;
- }
- void SendCorrectionMessages();
+
+ // The LOS DB this avatar is in (only one)
+ virtual plSimDefs::plLOSDB GetLOSDB() { return fLOSDB; }
+ virtual void SetLOSDB(plSimDefs::plLOSDB losDB) { fLOSDB = losDB; }
+
+ // Movement strategy
+ virtual void SetMovementStrategy(plMovementStrategy* strategy) = 0;
+
+ // Global location
+ virtual const hsMatrix44& GetLastGlobalLoc() { return fLastGlobalLoc; }
+ virtual void SetGlobalLoc(const hsMatrix44& l2w) = 0;
+
+ // Local sim position
+ virtual void GetPositionSim(hsPoint3& pos) = 0;
+
+ // Move kinematic controller
+ virtual void Move(hsVector3 displacement, unsigned int collideWith, unsigned int &collisionResults) = 0;
+
+ // Set linear velocity on dynamic controller
+ virtual void SetLinearVelocitySim(const hsVector3& linearVel) = 0;
+
+ // Sweep the controller path from startPos through endPos
+ virtual int SweepControllerPath(const hsPoint3& startPos,const hsPoint3& endPos, hsBool vsDynamics, hsBool vsStatics,
+ UInt32& vsSimGroups, std::vector& hits) = 0;
+
+ // any clean up for the controller should go here
+ virtual void LeaveAge() = 0;
+
+ // Local rotation
+ const hsQuat& GetLocalRotation() const { return fLocalRotation; }
void IncrementAngle(hsScalar deltaAngle);
- void UpdateWorldRelativePos();
- virtual void SetLinearVelocity(const hsVector3& linearVel){fLinearVelocity=linearVel;}
- //should actually be a 3 vector but everywhere else it is assumed to be just around Z
- virtual void SetAngularVelocity(const hsScalar angvel){ fAngularVelocity=angvel;}
- virtual void SetVelocities(const hsVector3& linearVel, hsScalar angVel)
- {
- fLinearVelocity=linearVel;
- fAngularVelocity=angVel;
- }
- virtual const hsVector3& GetLinearVelocity() ;
- virtual hsScalar GetAngularVelocity(){return fAngularVelocity;}
- virtual const hsVector3& GetAchievedLinearVelocity()const {return fAchievedLinearVelocity;}
- plPhysical* GetPushingPhysical();
- bool GetFacingPushingPhysical();
- virtual void SetPushingPhysical(plPhysical* pl){fPushingPhysical=pl;}
- virtual void SetFacingPushingPhysical(bool ans){fFacingPushingPhysical=ans;}
- //To be Used during runtime conversions, say to switch a tall controller to a ball for swimming
- virtual void SetControllerDimensions(hsScalar radius, hsScalar height)=0;
- virtual hsScalar GetControllerWidth(){return fRadius;}
- virtual hsScalar GetControllerHeight(){return fHeight;}
- virtual void ResetAchievedLinearVelocity()
- {
- fAchievedLinearVelocity.Set(0.f,0.f,0.f);
- }
- virtual int SweepControllerPath(const hsPoint3& startPos,const hsPoint3& endPos, hsBool vsDynamics, hsBool vsStatics, UInt32& vsSimGroups, std::multiset< plControllerSweepRecord >& WhatWasHitOut)=0;
- //this should only be used to force a move it could place your head into a wall and that would be good
- virtual hsScalar GetHeight() {return fHeight;}
- virtual hsScalar GetRadius() {return fRadius;}
- //Wether the avatar thing has mass and forces things down or not, and changes the way things move
- //This is an attempt fix things like riding on an animated physical
- virtual void BehaveLikeAnimatedPhysical(hsBool actLikeAnAnimatedPhys)=0;
- virtual hsBool BehavingLikeAnAnimatedPhysical()=0;
-protected:
+ // Linear velocity
+ void SetLinearVelocity(const hsVector3& linearVel) { fLinearVelocity = linearVel; }
+ const hsVector3& GetLinearVelocity() const { return fLinearVelocity; }
+
+ // Acheived linear velocity
+ const hsVector3& GetAchievedLinearVelocity() const { return fAchievedLinearVelocity; }
+ void OverrideAchievedLinearVelocity(const hsVector3& linearVel) { fAchievedLinearVelocity = linearVel; }
+ void ResetAchievedLinearVelocity() { fAchievedLinearVelocity.Set(0.f, 0.f, 0.f); }
+
+ // SceneObject
+ plKey GetOwner() { return fOwner; }
+
+ // When seeking no longer want to interact with exclude regions
+ void SetSeek(bool seek) { fSeeking = seek; }
+ bool IsSeeking() const { return fSeeking; }
+
+ // Pushing physical
+ plPhysical* GetPushingPhysical() const { return fPushingPhysical; }
+ void SetPushingPhysical(plPhysical* phys) { fPushingPhysical = phys; }
+ bool GetFacingPushingPhysical() const { return fFacingPushingPhysical; }
+ void SetFacingPushingPhysical(bool facing) { fFacingPushingPhysical = facing; }
+ // Controller dimensions
+ hsScalar GetRadius() const { return fRadius; }
+ hsScalar GetHeight() const { return fHeight; }
+
+ // Create a new controller instance - Implemented in the physics system
+ static plPhysicalControllerCore* Create(plKey ownerSO, hsScalar height, hsScalar radius);
+
+protected:
+ virtual void IHandleEnableChanged() = 0;
+
+ void IApply(hsScalar delSecs);
+ void IUpdate(int numSubSteps, hsScalar alpha);
+ void IUpdateNonPhysical(hsScalar alpha);
+
+ void ISendCorrectionMessages(bool dirtySynch = false);
+
plKey fOwner;
+ plKey fWorldKey;
+
hsScalar fHeight;
hsScalar fRadius;
- plKey fWorldKey;
+
plSimDefs::plLOSDB fLOSDB;
- bool fSeeking;
- bool fEnabled;
- bool fEnableChanged;
- bool fKinematic;
- bool fKinematicEnableNextUpdate;
- bool fKinematicChanged;
- plMovementStrategySimulationInterface* fMovementInterface;
- hsMatrix44 fLastGlobalLoc;
- hsPoint3 fLocalPosition;
+
+ plMovementStrategy* fMovementStrategy;
+
+ hsScalar fSimLength;
+
hsQuat fLocalRotation;
+ hsPoint3 fLocalPosition;
+ hsPoint3 fLastLocalPosition;
+
+ hsMatrix44 fLastGlobalLoc;
hsMatrix44 fPrevSubworldW2L;
- hsVector3 fDisplacementThisStep;
- hsScalar fSimLength;
- //physical properties
hsVector3 fLinearVelocity;
- hsScalar fAngularVelocity;
hsVector3 fAchievedLinearVelocity;
+
plPhysical* fPushingPhysical;
bool fFacingPushingPhysical;
- bool fNeedsResize;
+
+ bool fSeeking;
+ bool fEnabled;
+ bool fEnableChanged;
};
-class plMovementStrategy: public plMovementStrategySimulationInterface
+class plMovementStrategy
{
public:
- virtual void SetControllerCore(plPhysicalControllerCore* core)
- {
- fCore=core;
- fCore->SetMovementSimulationInterface(this);
- }
- virtual void RefreshConnectionToControllerCore()
- {
- fCore->SetMovementSimulationInterface(this);
- //fCore->SetControllerDimensions(fPreferedControllerWidth,fPreferedControllerHeight);
- fCore->BehaveLikeAnimatedPhysical(this->IRequireBehaviourLikeAnAnimatedPhysical());
- }
- plMovementStrategy(plPhysicalControllerCore* core);
- //should actually be a 3 vector but everywhere else it is assumed to be just around Z
- virtual void SetLinearAcceleration(const hsVector3& accel){fLinearAcceleration=accel;}
- virtual const hsVector3& GetLinearAcceleration()const{return fLinearAcceleration;}
- //should actually be a 3 vector but everywhere else it is assumed to be just around Z
- virtual void ResetAchievedLinearVelocity()
- {
- hsVector3 AchievedLinearVelocity(0.f,0.f,0.f);
- if(fCore)fCore->OverrideAchievedVelocity(AchievedLinearVelocity);
- }
-//proxy functions for Controller Core
- virtual hsScalar GetAirTime() const { return fTimeInAir; }
- virtual void ResetAirTime() { fTimeInAir = 0.f; }
-
+ plMovementStrategy(plPhysicalControllerCore* controller);
+ virtual ~plMovementStrategy() { }
+
+ virtual void Apply(hsScalar delSecs) = 0;
+ virtual void Update(hsScalar delSecs) { }
+
+ virtual void AddContactNormals(hsVector3& vec) { }
+ virtual void Reset(bool newAge);
+ virtual bool IsKinematic() { return true; }
+
protected:
- virtual hsBool IRequireBehaviourLikeAnAnimatedPhysical()=0;
- virtual void IApplyKinematic();
- plPhysicalControllerCore* fCore;
- hsVector3 fLinearAcceleration;
- hsScalar fAngularAcceleration;
- plKey fOwner;
- static const hsScalar kAirTimeThreshold;
- hsScalar fTimeInAir;
- hsScalar fPreferedControllerWidth;
- hsScalar fPreferedControllerHeight;
-
+ plPhysicalControllerCore* fController;
+};
+
+class plAnimatedMovementStrategy : public plMovementStrategy
+{
+public:
+ plAnimatedMovementStrategy(plAGApplicator* rootApp, plPhysicalControllerCore* controller);
+ virtual ~plAnimatedMovementStrategy() { }
+
+ void RecalcVelocity(double timeNow, hsScalar elapsed, hsBool useAnim = true);
+ void SetTurnStrength(hsScalar val) { fTurnStr = val; }
+ hsScalar GetTurnStrength() const { return fTurnStr; }
+private:
+ void IRecalcLinearVelocity(float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat);
+ void IRecalcAngularVelocity(float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat);
+
+ plAGApplicator* fRootApp;
+ hsVector3 fAnimLinearVel;
+ hsScalar fAnimAngularVel;
+ hsScalar fTurnStr;
};
-class plWalkingStrategy: public plMovementStrategy
+class plWalkingStrategy : public plAnimatedMovementStrategy
{
public:
- plWalkingStrategy(plPhysicalControllerCore* core):plMovementStrategy(core)
- {
- fGroundHit=false;
- fFalseGround=false;
- fHitHead=false;
- fCore->SetMovementSimulationInterface(this);
- fPreferedControllerWidth=core->GetControllerWidth();
- fPreferedControllerHeight=core->GetControllerHeight();
- fOnTopOfAnimatedPhysLastFrame=false;
- }
- virtual ~plWalkingStrategy(){};
+ plWalkingStrategy(plAGApplicator* rootApp, plPhysicalControllerCore* controller);
+ virtual ~plWalkingStrategy() { }
+
virtual void Apply(hsScalar delSecs);
- virtual void Update(hsScalar delSecs);
+ virtual void Update(hsScalar delSecs);
+
+ virtual void AddContactNormals(hsVector3& vec);
+ virtual void Reset(bool newAge);
+ bool HitGroundInThisAge() const { return fHitGroundInThisAge; }
bool IsOnGround() const { return fTimeInAir < kAirTimeThreshold || fFalseGround; }
- bool IsOnFalseGround() const { return fFalseGround && !fGroundHit; }
- void GroundHit() { fGroundHit = true; }
- virtual void IAddContactNormals(hsVector3& vec);
- virtual void StartJump(){};
-
+
+ hsScalar GetAirTime() const { return fTimeInAir; }
+ void ResetAirTime() { fTimeInAir = 0.0f; }
+
+ hsScalar GetImpactTime() const { return fImpactTime; }
+ const hsVector3& GetImpactVelocity() const { return fImpactVelocity; }
+
+ bool EnableControlledFlight(bool status);
+ bool IsControlledFlight() const { return fControlledFlight != 0; }
+
+ plPhysical* GetPushingPhysical() const;
+ bool GetFacingPushingPhysical() const;
protected:
+ static const hsScalar kAirTimeThreshold;
+ static const hsScalar kControlledFlightThreshold;
+
+ hsTArray fSlidingNormals;
+
+ hsVector3 fImpactVelocity;
+ hsScalar fImpactTime;
+
+ hsScalar fTimeInAir;
- void ICheckForFalseGround();
+ hsScalar fControlledFlightTime;
+ int fControlledFlight;
+
bool fGroundHit;
bool fFalseGround;
- bool fHitHead;
- bool fOnTopOfAnimatedPhysLastFrame;
- hsTArray fPrevSlidingNormals;
- virtual hsBool IRequireBehaviourLikeAnAnimatedPhysical(){return true;}
+ bool fHeadHit;
+ bool fSliding;
+ bool fClearImpact;
+ bool fHitGroundInThisAge;
};
-class plSwimStrategy: public plMovementStrategy
+
+class plSwimStrategy : public plAnimatedMovementStrategy
{
public:
- plSwimStrategy(plPhysicalControllerCore *core);
- virtual ~plSwimStrategy(){};
- void SetSurface(plSwimRegionInterface *region, hsScalar surfaceHeight);
+ plSwimStrategy(plAGApplicator* rootApp, plPhysicalControllerCore* controller);
+ virtual ~plSwimStrategy() { }
+
virtual void Apply(hsScalar delSecs);
- virtual void Update(hsScalar delSecs);
- hsScalar GetBuoyancy() { return fBuoyancy; }
- hsBool IsOnGround() { return fOnGround; }
- hsBool HadContacts() { return fHadContacts; }
- virtual void IAddContactNormals(hsVector3& vec);
+
+ virtual void AddContactNormals(hsVector3& vec);
+
+ void SetSurface(plSwimRegionInterface* region, hsScalar surfaceHeight);
+
+ hsScalar GetBuoyancy() const { return fBuoyancy; }
+ bool IsOnGround() const { return fOnGround; }
+ bool HadContacts() const { return fHadContacts; }
+
protected:
- virtual hsBool IRequireBehaviourLikeAnAnimatedPhysical(){return true;}
-private:
void IAdjustBuoyancy();
+
hsScalar fBuoyancy;
- hsBool fOnGround;
- hsBool fHadContacts;
hsScalar fSurfaceHeight;
+
plSwimRegionInterface *fCurrentRegion;
+
+ bool fOnGround;
+ bool fHadContacts;
};
-class plRidingAnimatedPhysicalStrategy : public plWalkingStrategy
+
+class plDynamicWalkingStrategy : public plWalkingStrategy
{
public:
- plRidingAnimatedPhysicalStrategy(plPhysicalControllerCore *core ) :
- fNeedVelocityOverride(false),fStartJump(false),plWalkingStrategy(core){};
- virtual ~plRidingAnimatedPhysicalStrategy(){};
+ plDynamicWalkingStrategy(plAGApplicator* rootApp, plPhysicalControllerCore* controller);
+ virtual ~plDynamicWalkingStrategy() { }
+
virtual void Apply(hsScalar delSecs);
- virtual void Update(hsScalar delSecs);
- virtual void PostStep(hsScalar delSecs);
- bool IsOnGround() const { return fTimeInAir < kAirTimeThreshold || fFalseGround; }
- bool IsOnFalseGround() const { return fFalseGround && !fGroundHit; }
- void GroundHit() { fGroundHit = true; }
- virtual void StartJump(){fStartJump = true;}
+
+ virtual bool IsKinematic() { return false; }
+
protected:
- virtual hsBool IRequireBehaviourLikeAnAnimatedPhysical(){return false;}
- bool ICheckMove(const hsPoint3& startPos, const hsPoint3& desiredPos);
- hsBool fNeedVelocityOverride;
- hsVector3 fOverrideVelocity;
- bool fStartJump;
+ bool ICheckForGround(hsScalar& zVelocity);
};
+
#endif// PLPHYSICALCONTROLLERCORE_H
+
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plInputCore/plSceneInputInterface.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plInputCore/plSceneInputInterface.cpp
index 4d40e538..57d9ee7c 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plInputCore/plSceneInputInterface.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plInputCore/plSceneInputInterface.cpp
@@ -73,7 +73,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../plAvatar/plArmatureMod.h"
#include "../plAvatar/plAvBrain.h"
#include "../plAvatar/plAvatarMgr.h"
-#include "../plAvatar/plAvCallbackAction.h"
+#include "../plAvatar/plPhysicalControllerCore.h"
#include "../plModifier/plInterfaceInfoModifier.h"
#include "../pnModifier/plLogicModBase.h"
#include "../plVault/plVault.h"
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plModifier/plExcludeRegionModifier.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plModifier/plExcludeRegionModifier.cpp
index c1f0d5f2..5872072a 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plModifier/plExcludeRegionModifier.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plModifier/plExcludeRegionModifier.cpp
@@ -54,7 +54,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../plMessage/plAvatarMsg.h"
#include "plPhysical.h"
#include "../plPhysical/plSimDefs.h"
-#include "../plAvatar/plAvCallbackAction.h"
#include "../plAvatar/plAvBrainGeneric.h"
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp
index a2ea1df0..5b8f23a8 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp
@@ -39,7 +39,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
Mead, WA 99021
*==LICENSE==*/
-#include "../plAvatar/plAvCallbackAction.h"
#include "hsTypes.h"
#include "plCollisionDetector.h"
@@ -65,6 +64,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../plAvatar/plAvatarMgr.h"
#include "../plAvatar/plAvBrainHuman.h"
#include "../plAvatar/plAvBrainDrive.h"
+#include "../plAvatar/plPhysicalControllerCore.h"
#include "../plModifier/plDetectorLog.h"
@@ -770,7 +770,7 @@ void plObjectInVolumeAndFacingDetector::ICheckForTrigger()
// And are we walking towards it?
plArmatureBrain* abrain = armMod->FindBrainByClass(plAvBrainHuman::Index()); //armMod->GetCurrentBrain();
plAvBrainHuman* brain = plAvBrainHuman::ConvertNoRef(abrain);
- if (brain && brain->IsMovingForward() && brain->fCallbackAction->IsOnGround())
+ if (brain && brain->IsMovingForward() && brain->fWalkingStrategy->IsOnGround())
movingForward = true;
}
else
@@ -940,11 +940,11 @@ hsBool plPanicLinkRegion::MsgReceive(plMessage* msg)
plArmatureMod* avMod = IGetAvatarModifier(pCollMsg->fOtherKey);
if (avMod)
{
- hsPoint3 kinPos;
+ hsPoint3 pos;
if (avMod->GetController())
{
- avMod->GetController()->GetKinematicPosition(kinPos);
- DetectorLogSpecial("Avatar is panic linking. KinPos at %f,%f,%f and is %s",kinPos.fX,kinPos.fY,kinPos.fZ,avMod->GetController()->IsEnabled() ? "enabled" : "disabled");
+ avMod->GetController()->GetPositionSim(pos);
+ DetectorLogSpecial("Avatar is panic linking. Position %f,%f,%f and is %s", pos.fX, pos.fY, pos.fZ, avMod->GetController()->IsEnabled() ? "enabled" : "disabled");
}
avMod->PanicLink(fPlayLinkOutAnim);
}
@@ -1168,4 +1168,4 @@ hsBool plRidingAnimatedPhysicalDetector::MsgReceive(plMessage *msg)
return true;
}
return plSimpleRegionSensor::MsgReceive(msg);
-}
+}
diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plSimDefs.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plSimDefs.h
index 24b4583e..b98d6f97 100644
--- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plSimDefs.h
+++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plSimDefs.h
@@ -72,25 +72,6 @@ namespace plSimDefs
kGroupMax,
};
- /** A taxonomy of action types. Crucial for doing things like making sure you don't
- do things like attach duplicate actions. */
- enum ActionType
- {
- kUnknownAction = 0x01, // don't know the type (probably forgot to override GetType())
- kUnknownZAction = 0x02, // unknown type of z-order action
- kAntiGravityAction = 0x03, // an action that counters gravity exactly
- kUprightAction = 0x04, // an action that keeps an object upright by apply force
- kPhysAnimAction = 0x05, // an action that parses keyframed animation into physical information
- kConstraint = 0x06, // a general constraint.
- kCallbackAction = 0x07, // an action that just hands us the physics "tick"
- kPseudoPhysAction = 0x08, // replacement for the physAnim
- kAntiGravAction = 0x09, // makes things float in the air
- kBasicGroundAction = 0x0a, // for your basic walkAroundOnGround corrections
- kHorizontalFreeze = 0x0b, // Let's you fall vertically, but otherwise keeps you in place (generic brains)
-
- kMaxAction = 0xffff // force 16-bit
- };
-
/** Different types of line-of-sight requests. */
enum LOSReqType
{