Branan Purvine-Riley
12 years ago
43 changed files with 1909 additions and 5321 deletions
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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 <hkdynamics/entity/rigidbody.h> |
||||
#include <hkdynamics/world/subspace.h> |
||||
|
||||
#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); |
||||
float angCurrent = 0.f; |
||||
if (fCurrentRegion != nil) |
||||
fCurrentRegion->GetCurrent(fPhysical, linCurrent, angCurrent, (float)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);
|
||||
float 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, float 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 |
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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, float surfaceHeight); |
||||
float GetBuoyancy() { return fBuoyancy; } |
||||
bool IsOnGround() { return fOnGround; } |
||||
bool HadContacts() { return fHadContacts; } |
||||
|
||||
protected: |
||||
void IAdjustBuoyancy(); |
||||
|
||||
bool fOnGround; |
||||
bool fHadContacts; |
||||
float fBuoyancy; |
||||
float fSurfaceHeight; |
||||
plSwimRegionInterface *fCurrentRegion; |
||||
}; |
||||
|
||||
#endif |
||||
|
||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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.
|
||||
static bool LinearVelocity(hsVector3 &outputV, float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat); |
||||
static void AngularVelocity(float &outputV, float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat); |
||||
static 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, bool 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 float 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= new plWalkingStrategy(fController); |
||||
fController->SetMovementSimulationInterface(fWalkingStrategy); |
||||
} |
||||
else |
||||
fWalkingStrategy = nil; |
||||
} |
||||
|
||||
void plWalkingController::RecalcVelocity(double timeNow, double timePrev, bool 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: AchievedLinearVelocity is a Cyanic fix for superjumps. LinearVelocity is
|
||||
// always (0,0,0) outside of the controller update proc
|
||||
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= 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);
|
||||
//
|
||||
// bool isPhysical = !fPhysical->GetProperty(plSimulationInterface::kPinned);
|
||||
// const Havok::Vector3 straightUp(0.0f, 0.0f, 1.0f);
|
||||
// bool 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); |
||||
float 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 float threshold = hsDegreesToRadians(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] = atan2(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]) |
||||
{ |
||||
float 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 * M_PI))) |
||||
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 += (float)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 = (float)(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 += (float)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); |
||||
float 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= 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 = 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 bool 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; |
||||
bool valid = xfabs < maxVel && yfabs < maxVel && zfabs < maxVel; |
||||
|
||||
if (valid) |
||||
{ |
||||
outputV = prev2Now; |
||||
result = true; |
||||
} |
||||
}
|
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
static void AngularVelocity(float &outputV, float elapsed, hsMatrix44 &prevMat, hsMatrix44 &curMat) |
||||
{ |
||||
outputV = 0.f; |
||||
float appliedVelocity = 0.0f; |
||||
hsVector3 prevForward = GetYAxis(prevMat); |
||||
hsVector3 curForward = GetYAxis(curMat); |
||||
|
||||
float angleSincePrev = AngleRad2d(curForward.fX, curForward.fY, prevForward.fX, prevForward.fY); |
||||
bool sincePrevSign = angleSincePrev > 0.0f; |
||||
if (angleSincePrev > M_PI) |
||||
angleSincePrev = angleSincePrev - TWO_PI; |
||||
|
||||
const hsVector3 startForward = hsVector3(0, -1.0, 0); // the Y orientation of a "resting" armature....
|
||||
float angleSinceStart = AngleRad2d(curForward.fX, curForward.fY, startForward.fX, startForward.fY); |
||||
bool sinceStartSign = angleSinceStart > 0.0f; |
||||
if (angleSinceStart > M_PI) |
||||
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; |
||||
} |
||||
} |
||||
} |
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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, float height, float 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, float 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 float 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, bool useAnim = true); |
||||
void SetTurnStrength(float val) { fTurnStr = val; } |
||||
float GetTurnStrength() { return fTurnStr; } |
||||
virtual void ActivateController()=0; |
||||
protected: |
||||
plSceneObject* fRootObject; |
||||
plPhysicalControllerCore* fController; |
||||
plAGApplicator* fRootApp; |
||||
float fAnimAngVel; |
||||
hsVector3 fAnimPosVel; |
||||
float 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, bool 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); |
||||
float GetAirTime() const { return fWalkingStrategy ? fWalkingStrategy->GetAirTime() : 0.f; } |
||||
void ResetAirTime() { if (fWalkingStrategy) fWalkingStrategy->ResetAirTime(); } |
||||
float GetForwardVelocity() const; |
||||
void ActivateController(); |
||||
// Check these after the avatar the avatar hits the ground for his total
|
||||
// hangtime and impact velocity.
|
||||
float 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.
|
||||
float fControlledFlightTime; |
||||
int fControlledFlight; // Count of how many are currently forcing flight
|
||||
plWalkingStrategy* fWalkingStrategy; |
||||
float fImpactTime; |
||||
hsVector3 fImpactVelocity; |
||||
bool fClearImpact; |
||||
bool fGroundLastFrame;//used for a test to pass the event of first getting air during a jump
|
||||
static const float kControlledFlightThreshold; |
||||
}; |
||||
class plSwimmingController: public plAnimatedController
|
||||
{ |
||||
public : |
||||
plSwimmingController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller); |
||||
virtual ~plSwimmingController(); |
||||
void SetSurface(plSwimRegionInterface *region, float surfaceHeight){ |
||||
fSwimmingStrategy->SetSurface(region,surfaceHeight); |
||||
} |
||||
float GetBuoyancy() { return fSwimmingStrategy->GetBuoyancy(); } |
||||
bool IsOnGround() { return fSwimmingStrategy->IsOnGround(); } |
||||
bool 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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,211 +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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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 plPXPhysicalController_h_inc |
||||
#define plPXPhysicalController_h_inc |
||||
|
||||
#include "plAvatar/plAvCallbackAction.h" |
||||
#include "hsQuat.h" |
||||
|
||||
#define PHYSX_ONLY_TRIGGER_FROM_KINEMATIC 1 |
||||
|
||||
class NxController; |
||||
class NxCapsuleController; |
||||
class NxActor; |
||||
class plCoordinateInterface; |
||||
class plPhysicalProxy; |
||||
class plDrawableSpans; |
||||
class hsGMaterial; |
||||
class NxCapsule; |
||||
#ifndef PLASMA_EXTERNAL_RELEASE |
||||
class plDbgCollisionInfo |
||||
{ |
||||
public: |
||||
plSceneObject *fSO; |
||||
hsVector3 fNormal; |
||||
bool fOverlap; |
||||
}; |
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
class plPXPhysicalController : public plPhysicalController |
||||
{ |
||||
public: |
||||
plPXPhysicalController(plKey ownerSO, hsScalar height, hsScalar radius); |
||||
virtual ~plPXPhysicalController(); |
||||
|
||||
virtual void Enable(bool enable); |
||||
virtual bool IsEnabled() const { return fEnable; } |
||||
|
||||
virtual void SetLOSDB(plSimDefs::plLOSDB losDB) { fLOSDB = losDB; } |
||||
plSimDefs::plLOSDB GetLOSDB() const { return fLOSDB; } |
||||
|
||||
virtual void SetVelocities(const hsVector3& linearVel, hsScalar angVel) |
||||
{ |
||||
fLinearVelocity = linearVel; |
||||
fAngularVelocity = angVel; |
||||
} |
||||
|
||||
virtual const hsVector3& GetLinearVelocity() const { return fAchievedLinearVelocity; } |
||||
virtual void ResetAchievedLinearVelocity() { fAchievedLinearVelocity.Set(0.f, 0.f, 0.f); } |
||||
|
||||
virtual plKey GetSubworld() const { return fWorldKey; } |
||||
virtual void SetSubworld(plKey world); |
||||
|
||||
virtual bool IsOnGround() const { return fTimeInAir < kAirTimeThreshold || fFalseGround; } |
||||
virtual bool IsOnFalseGround() const { return fFalseGround && !fGroundHit; } |
||||
virtual void GroundHit() { fGroundHit = true; } |
||||
virtual hsScalar GetAirTime() const { return fTimeInAir; } |
||||
virtual void ResetAirTime() { fTimeInAir = 0.f; } |
||||
virtual void AddSlidingNormal(hsVector3 vec); |
||||
virtual hsTArray<hsVector3>* GetSlidingNormals() { return &fSlidingNormals; } |
||||
|
||||
virtual plPhysical* GetPushingPhysical() const { return fPushingPhysical; } |
||||
virtual bool GetFacingPushingPhysical() const { return fFacingPushingPhysical; } |
||||
|
||||
virtual const plCoordinateInterface* GetSubworldCI() const; |
||||
|
||||
virtual void GetState(hsPoint3& pos, float& zRot); |
||||
virtual void SetState(const hsPoint3& pos, float zRot); |
||||
|
||||
plKey GetOwner() const { return fOwner; } |
||||
|
||||
// Called by the simulation mgr each frame
|
||||
static void Update(bool prestep, hsScalar delSecs); |
||||
// Used by the LOS mgr to find the controller for an actor it hit
|
||||
static plPXPhysicalController* GetController(NxActor& actor, bool* isController); |
||||
// test to see if there are any controllers (i.e. avatars) in this subworld
|
||||
static bool plPXPhysicalController::AnyControllersInThisWorld(plKey world); |
||||
static int plPXPhysicalController::NumControllers(); |
||||
static int plPXPhysicalController::GetControllersInThisSubWorld(plKey world, int maxToReturn,
|
||||
plPXPhysicalController** bufferout); |
||||
static int plPXPhysicalController::GetNumberOfControllersInThisSubWorld(plKey world); |
||||
// Call this if a static physical in the scene has changed (unloaded,
|
||||
// collision enabled/disabled, etc)
|
||||
static void RebuildCache(); |
||||
|
||||
virtual void GetPositionSim(hsPoint3& pos) const { IGetPositionSim(pos); } |
||||
|
||||
virtual void Kinematic(bool state); |
||||
virtual bool IsKinematic(); |
||||
virtual void GetKinematicPosition(hsPoint3& pos); |
||||
|
||||
virtual plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray<uint32_t>& idx, plDrawableSpans* addTo); |
||||
|
||||
virtual const hsMatrix44& GetPrevSubworldW2L() { return fPrevSubworldW2L; } |
||||
|
||||
virtual void SetSeek(bool seek){fSeeking=seek;} |
||||
virtual void GetWorldSpaceCapsule(NxCapsule& cap); |
||||
#ifndef PLASMA_EXTERNAL_RELEASE |
||||
static bool fDebugDisplay; |
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
protected: |
||||
static const hsScalar kAirTimeThreshold; |
||||
|
||||
friend class PXControllerHitReport; |
||||
static plPXPhysicalController* FindController(NxController* controller); |
||||
|
||||
void IApply(hsScalar delSecs); |
||||
void ISendUpdates(hsScalar delSecs); |
||||
void ICheckForFalseGround(); |
||||
void ISetGlobalLoc(const hsMatrix44& l2w); |
||||
void IMatchKinematicToController(); |
||||
void IMoveKinematicToController(hsPoint3& pos); |
||||
void ISetKinematicLoc(const hsMatrix44& l2w); |
||||
void IGetPositionSim(hsPoint3& pos) const; |
||||
|
||||
void ICreateController(); |
||||
void IDeleteController(); |
||||
|
||||
void IInformDetectors(bool entering); |
||||
|
||||
plKey fOwner; |
||||
plKey fWorldKey; |
||||
hsScalar fRadius, fHeight; |
||||
NxCapsuleController* fController; |
||||
|
||||
// this is the kinematic actor for triggering things when the avatar is collision-less during behaviors
|
||||
NxActor* fKinematicActor; |
||||
|
||||
hsVector3 fLinearVelocity; |
||||
hsScalar fAngularVelocity; |
||||
|
||||
hsVector3 fAchievedLinearVelocity; |
||||
|
||||
// The global position and rotation of the avatar last time we set it (so we
|
||||
// can detect if someone else moves him)
|
||||
hsMatrix44 fLastGlobalLoc; |
||||
//
|
||||
hsPoint3 fLocalPosition; |
||||
hsQuat fLocalRotation; |
||||
|
||||
hsMatrix44 fPrevSubworldW2L; |
||||
|
||||
bool fEnable; |
||||
bool fEnableChanged; |
||||
plSimDefs::plLOSDB fLOSDB; |
||||
|
||||
bool fKinematic; |
||||
bool fKinematicChanged; |
||||
bool fKinematicEnableNextUpdate; |
||||
|
||||
bool fGroundHit; |
||||
bool fFalseGround; |
||||
hsScalar fTimeInAir; |
||||
hsTArray<hsVector3> fSlidingNormals; |
||||
hsTArray<hsVector3> fPrevSlidingNormals; |
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE |
||||
hsTArray<plDbgCollisionInfo> fDbgCollisionInfo; |
||||
void IDrawDebugDisplay(); |
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
plPhysical* fPushingPhysical; |
||||
bool fFacingPushingPhysical; |
||||
|
||||
plPhysicalProxy* fProxyGen; // visual proxy for debugging
|
||||
|
||||
bool fHitHead; |
||||
|
||||
bool fSeeking; |
||||
}; |
||||
|
||||
#endif // plPXPhysicalController_h_inc
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue