416 lines
10 KiB
C++
416 lines
10 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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/>.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2006-2010 - Frictional Games
|
|
*
|
|
* This file is part of HPL1 Engine.
|
|
*/
|
|
|
|
#ifndef HPL_CHARACTER_BODY_H
|
|
#define HPL_CHARACTER_BODY_H
|
|
|
|
#include "hpl1/engine/math/MathTypes.h"
|
|
#include "hpl1/engine/physics/PhysicsWorld.h"
|
|
|
|
namespace hpl {
|
|
|
|
class iPhysicsWorld;
|
|
class iCollideShape;
|
|
class iPhysicsBody;
|
|
class cCamera3D;
|
|
class iCharacterBody;
|
|
class iEntity3D;
|
|
|
|
enum eCharDir {
|
|
eCharDir_Forward = 0,
|
|
eCharDir_Right = 1,
|
|
eCharDir_LastEnum = 2
|
|
};
|
|
|
|
class iCharacterBodyCallback {
|
|
public:
|
|
virtual ~iCharacterBodyCallback() = default;
|
|
virtual void OnHitGround(iCharacterBody *apCharBody, const cVector3f &avVel) = 0;
|
|
virtual void OnGravityCollide(iCharacterBody *apCharBody, iPhysicsBody *apCollideBody,
|
|
cCollideData *apCollideData) = 0;
|
|
};
|
|
|
|
//------------------------------------------------
|
|
|
|
class cCharacterBodyRay : public iPhysicsRayCallback {
|
|
public:
|
|
cCharacterBodyRay();
|
|
|
|
void Clear();
|
|
bool OnIntersect(iPhysicsBody *pBody, cPhysicsRayParams *apParams);
|
|
|
|
float mfMinDist;
|
|
bool mbCollide;
|
|
};
|
|
|
|
//------------------------------------------------
|
|
|
|
class cCharacterBodyCollideGravity : public iPhysicsWorldCollisionCallback {
|
|
public:
|
|
cCharacterBodyCollideGravity();
|
|
|
|
void OnCollision(iPhysicsBody *apBody, cCollideData *apCollideData);
|
|
|
|
iCharacterBody *mpCharBody;
|
|
};
|
|
|
|
//------------------------------------------------
|
|
|
|
class cCharacterBodyCollidePush : public iPhysicsWorldCollisionCallback {
|
|
public:
|
|
cCharacterBodyCollidePush();
|
|
|
|
void OnCollision(iPhysicsBody *apBody, cCollideData *apCollideData);
|
|
|
|
iCharacterBody *mpCharBody;
|
|
};
|
|
|
|
//-----------------------------------
|
|
|
|
kSaveData_BaseClass(iCharacterBody) {
|
|
kSaveData_ClassInit(iCharacterBody) public : tString msName;
|
|
|
|
float mfMass;
|
|
bool mbGravityActive;
|
|
float mfMaxGravitySpeed;
|
|
|
|
bool mbActive;
|
|
|
|
bool mbCollideCharacter;
|
|
|
|
cVector3f mvPosition;
|
|
cVector3f mvLastPosition;
|
|
float mfMaxPosMoveSpeed[2];
|
|
float mfMaxNegMoveSpeed[2];
|
|
float mfMoveSpeed[2];
|
|
float mfMoveAcc[2];
|
|
float mfMoveDeacc[2];
|
|
bool mbMoving[2];
|
|
|
|
float mfPitch;
|
|
float mfYaw;
|
|
|
|
bool mbOnGround;
|
|
|
|
float mfMaxPushMass;
|
|
float mfPushForce;
|
|
bool mbPushIn2D;
|
|
|
|
cVector3f mvForce;
|
|
cVector3f mvVelolcity;
|
|
|
|
cVector3f mvSize;
|
|
|
|
cMatrixf m_mtxMove;
|
|
|
|
int mlEntityId;
|
|
cMatrixf m_mtxEntityOffset;
|
|
int mlEntitySmoothPosNum;
|
|
|
|
float mfMaxStepHeight;
|
|
float mfStepClimbSpeed;
|
|
float mfClimbForwardMul;
|
|
float mfClimbHeightAdd;
|
|
bool mbClimbing;
|
|
|
|
float mfGroundFriction;
|
|
float mfAirFriction;
|
|
|
|
int mlBodyId;
|
|
|
|
cContainerList<int> mvExtraBodyIds;
|
|
|
|
virtual iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame);
|
|
virtual int GetSaveCreatePrio();
|
|
};
|
|
|
|
//------------------------------------------------
|
|
|
|
class iCharacterBody : public iSaveObject {
|
|
typedef iSaveObject super;
|
|
friend class cSaveData_iCharacterBody;
|
|
friend class cCharacterBodyCollideGravity;
|
|
|
|
public:
|
|
iCharacterBody(const tString &asName, iPhysicsWorld *apWorld, const cVector3f avSize);
|
|
virtual ~iCharacterBody();
|
|
|
|
const tString &GetName() { return msName; }
|
|
|
|
///////////////////////////////////////
|
|
// Properties
|
|
|
|
float GetMass();
|
|
void SetMass(float afMass);
|
|
|
|
void SetActive(bool abX);
|
|
bool IsActive() { return mbActive; }
|
|
|
|
cVector3f GetSize();
|
|
|
|
void SetCollideCharacter(bool abX);
|
|
bool GetCollideCharacter() { return mbCollideCharacter; }
|
|
|
|
void SetTestCollision(bool abX) { mbTestCollision = abX; }
|
|
bool GetTestCollision() { return mbTestCollision; }
|
|
|
|
void SetMaxPositiveMoveSpeed(eCharDir aDir, float afX);
|
|
float GetMaxPositiveMoveSpeed(eCharDir aDir);
|
|
void SetMaxNegativeMoveSpeed(eCharDir aDir, float afX);
|
|
float GetMaxNegativeMoveSpeed(eCharDir aDir);
|
|
|
|
void SetMoveSpeed(eCharDir aDir, float afX);
|
|
float GetMoveSpeed(eCharDir aDir);
|
|
void SetMoveAcc(eCharDir aDir, float afX);
|
|
float GetMoveAcc(eCharDir aDir);
|
|
void SetMoveDeacc(eCharDir aDir, float afX);
|
|
float GetMoveDeacc(eCharDir aDir);
|
|
|
|
cVector3f GetVelocity(float afFrameTime);
|
|
|
|
void SetPosition(const cVector3f &avPos, bool abSmooth = false);
|
|
const cVector3f &GetPosition();
|
|
const cVector3f &GetLastPosition();
|
|
void SetFeetPosition(const cVector3f &avPos, bool abSmooth = false);
|
|
cVector3f GetFeetPosition();
|
|
|
|
void SetYaw(float afX);
|
|
void AddYaw(float afX);
|
|
float GetYaw();
|
|
void SetPitch(float afX);
|
|
void AddPitch(float afX);
|
|
float GetPitch();
|
|
|
|
cVector3f GetForward();
|
|
cVector3f GetRight();
|
|
cVector3f GetUp();
|
|
|
|
cMatrixf &GetMoveMatrix();
|
|
|
|
void SetGravityActive(bool abX);
|
|
bool GravityIsActive();
|
|
void SetMaxGravitySpeed(float afX);
|
|
float GetMaxGravitySpeed();
|
|
|
|
bool GetCustomGravityActive();
|
|
void SetCustomGravityActive(bool abX);
|
|
void SetCustomGravity(const cVector3f &avCustomGravity);
|
|
cVector3f GetCustomGravity();
|
|
|
|
void SetMaxPushMass(float afX) { mfMaxPushMass = afX; }
|
|
void SetPushForce(float afX) { mfPushForce = afX; }
|
|
float GetMaxPushMass() { return mfMaxPushMass; }
|
|
float GetPushForce() { return mfPushForce; }
|
|
|
|
bool GetPushIn2D() { return mbPushIn2D; }
|
|
void SetPushIn2D(bool abX) { mbPushIn2D = abX; }
|
|
|
|
void AddForceVelocity(const cVector3f &avVel) { mvVelolcity += avVel; }
|
|
void SetForceVelocity(const cVector3f &avVel) { mvVelolcity = avVel; }
|
|
cVector3f GetForceVelocity() { return mvVelolcity; }
|
|
|
|
int AddExtraSize(const cVector3f &avSize);
|
|
void SetActiveSize(int alNum);
|
|
|
|
///////////////////////////////////////
|
|
// Actions
|
|
void SetForce(const cVector3f &avForce);
|
|
void AddForce(const cVector3f &avForce);
|
|
cVector3f GetForce();
|
|
|
|
void Move(eCharDir aDir, float afMul, float afTimeStep);
|
|
|
|
void Update(float afTimeStep);
|
|
|
|
///////////////////////////////////////
|
|
// Other
|
|
void SetCamera(cCamera3D *apCam);
|
|
cCamera3D *GetCamera();
|
|
void SetCameraPosAdd(const cVector3f &avAdd);
|
|
cVector3f GetCameraPosAdd();
|
|
void SetCameraSmoothPosNum(int alNum) { mlCameraSmoothPosNum = alNum; }
|
|
int GetCameraSmoothPosNum() { return mlCameraSmoothPosNum; }
|
|
|
|
void SetEntity(iEntity3D *apEntity);
|
|
iEntity3D *GetEntity();
|
|
|
|
void SetEntityOffset(const cMatrixf &a_mtxOffset);
|
|
const cMatrixf &GetEntityOffset();
|
|
|
|
void SetEntityPostOffset(const cMatrixf &a_mtxOffset);
|
|
const cMatrixf &GetEntityPostOffset();
|
|
|
|
void SetEntitySmoothPosNum(int alNum) { mlEntitySmoothPosNum = alNum; }
|
|
int GetEntitySmoothPosNum() { return mlEntitySmoothPosNum; }
|
|
|
|
void SetUserData(void *apUserData) { mpUserData = apUserData; }
|
|
void *GetUserData() { return mpUserData; }
|
|
|
|
void SetCallback(iCharacterBodyCallback *apCallback) { mpCallback = apCallback; }
|
|
|
|
void SetEnableNearbyBodies(bool abX) { mbEnableNearbyBodies = abX; }
|
|
bool GetEnableNearbyBodies() { return mbEnableNearbyBodies; }
|
|
|
|
iPhysicsBody *GetBody() { return mpBody; }
|
|
iCollideShape *GetShape();
|
|
|
|
iPhysicsBody *GetExtraBody(size_t alIdx) { return mvExtraBodies[alIdx]; }
|
|
|
|
bool IsOnGround();
|
|
|
|
float GetMaxStepSize() { return mfMaxStepHeight; }
|
|
void SetMaxStepSize(float afSize) { mfMaxStepHeight = afSize; }
|
|
|
|
void SetStepClimbSpeed(float afX) { mfStepClimbSpeed = afX; }
|
|
float GetStepClimbSpeed() { return mfStepClimbSpeed; }
|
|
|
|
void SetAccurateClimbing(bool abX) { mbAccurateClimbing = abX; }
|
|
bool GetAccurateClimbing() { return mbAccurateClimbing; }
|
|
|
|
void SetClimbForwardMul(float afX) { mfClimbForwardMul = afX; }
|
|
float GetClimbForwardMul() { return mfClimbForwardMul; }
|
|
|
|
void SetClimbHeightAdd(float afX) { mfClimbHeightAdd = afX; }
|
|
float GetClimbHeightAdd() { return mfClimbHeightAdd; }
|
|
|
|
void SetGroundFriction(float afX) { mfGroundFriction = afX; }
|
|
float GetGroundFriction() { return mfGroundFriction; }
|
|
|
|
void SetAirFriction(float afX) { mfAirFriction = afX; }
|
|
float GetAirFriction() { return mfAirFriction; }
|
|
|
|
bool IsClimbing() { return mbClimbing; }
|
|
|
|
void SetAttachedBody(iPhysicsBody *apBody);
|
|
iPhysicsBody *GetAttachedBody() { return mpAttachedBody; }
|
|
|
|
// O=nly sue when you know what you are doing, Update calls these
|
|
void UpdateMoveMarix();
|
|
|
|
void UpdateCamera();
|
|
void UpdateEntity();
|
|
|
|
void UpdateAttachment();
|
|
|
|
// SaveObject implementation
|
|
virtual iSaveData *CreateSaveData();
|
|
virtual void SaveToSaveData(iSaveData *apSaveData);
|
|
virtual void LoadFromSaveData(iSaveData *apSaveData);
|
|
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
|
|
|
|
protected:
|
|
tString msName;
|
|
|
|
float mfMass;
|
|
|
|
bool mbActive;
|
|
|
|
bool mbCollideCharacter;
|
|
|
|
bool mbTestCollision;
|
|
|
|
bool mbGravityActive;
|
|
float mfMaxGravitySpeed;
|
|
bool mbCustomGravity;
|
|
cVector3f mvCustomGravity;
|
|
|
|
cVector3f mvPosition;
|
|
cVector3f mvLastPosition;
|
|
|
|
float mfMaxPosMoveSpeed[2];
|
|
float mfMaxNegMoveSpeed[2];
|
|
|
|
float mfMoveSpeed[2];
|
|
float mfMoveAcc[2];
|
|
float mfMoveDeacc[2];
|
|
bool mbMoving[2];
|
|
|
|
float mfPitch;
|
|
float mfYaw;
|
|
|
|
bool mbOnGround;
|
|
|
|
float mfMaxPushMass;
|
|
float mfPushForce;
|
|
bool mbPushIn2D;
|
|
|
|
float mfCheckStepClimbCount;
|
|
float mfCheckStepClimbInterval;
|
|
|
|
cVector3f mvForce;
|
|
cVector3f mvVelolcity;
|
|
|
|
cVector3f mvSize;
|
|
|
|
cMatrixf m_mtxMove;
|
|
|
|
cCamera3D *mpCamera;
|
|
cVector3f mvCameraPosAdd;
|
|
int mlCameraSmoothPosNum;
|
|
tVector3fList mlstCameraPos;
|
|
|
|
iEntity3D *mpEntity;
|
|
cMatrixf m_mtxEntityOffset;
|
|
cMatrixf m_mtxEntityPostOffset;
|
|
int mlEntitySmoothPosNum;
|
|
tVector3fList mlstEntityPos;
|
|
|
|
float mfGroundFriction;
|
|
float mfAirFriction;
|
|
|
|
void *mpUserData;
|
|
|
|
iPhysicsBody *mpAttachedBody;
|
|
cMatrixf m_mtxAttachedPrevMatrix;
|
|
bool mbAttachmentJustAdded;
|
|
|
|
iCharacterBodyCallback *mpCallback;
|
|
|
|
cCharacterBodyRay *mpRayCallback;
|
|
|
|
cCharacterBodyCollideGravity *mpCollideCallbackGravity;
|
|
cCharacterBodyCollidePush *mpCollideCallbackPush;
|
|
|
|
float mfMaxStepHeight;
|
|
float mfStepClimbSpeed;
|
|
float mfClimbForwardMul;
|
|
float mfClimbHeightAdd;
|
|
bool mbClimbing;
|
|
bool mbAccurateClimbing;
|
|
|
|
bool mbEnableNearbyBodies;
|
|
|
|
iPhysicsBody *mpBody;
|
|
iPhysicsWorld *mpWorld;
|
|
|
|
Common::Array<iPhysicsBody *> mvExtraBodies;
|
|
};
|
|
|
|
} // namespace hpl
|
|
|
|
#endif // HPL_CHARACTER_BODY_H
|