Files
scummvm-cursorfix/engines/hpl1/engine/scene/MeshEntity.h
2026-02-02 04:50:13 +01:00

288 lines
8.1 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_MESH_ENTITY_H
#define HPL_MESH_ENTITY_H
#include "hpl1/engine/graphics/GraphicsTypes.h"
#include "hpl1/engine/graphics/Renderable.h"
#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/math/MeshTypes.h"
#include "hpl1/engine/scene/Entity3D.h"
#include "hpl1/engine/system/SystemTypes.h"
#include "hpl1/engine/scene/SubMeshEntity.h"
#include "common/array.h"
#include "hpl1/engine/scene/AnimationState.h"
#include "common/stablemap.h"
namespace hpl {
class cMaterialManager;
class cMeshManager;
class cAnimationManager;
class cMesh;
class cSubMesh;
class cMeshEntity;
class cAnimation;
class cAnimationState;
class cNodeState;
class cBone;
class cNode3D;
class iCollideShape;
class iPhysicsBody;
class iPhysicsWorld;
class cWorld3D;
//-----------------------------------------------------------------------
class cMeshEntityRootNodeUpdate : public iEntityCallback {
public:
void OnTransformUpdate(iEntity3D *apEntity);
};
//------------------------------------------
class cMeshEntityCallback {
public:
virtual ~cMeshEntityCallback() = default;
virtual void AfterAnimationUpdate(cMeshEntity *apMeshEntity, float afTimeStep) = 0;
};
//------------------------------------------
kSaveData_ChildClass(iRenderable, cMeshEntity) {
kSaveData_ClassInit(cMeshEntity) public : tString msMeshName;
bool mbCastShadows;
int mlBodyId;
cContainerVec<cSaveData_cSubMeshEntity> mvSubEntities;
cContainerVec<cSaveData_cAnimationState> mvAnimStates;
virtual iSaveObject *CreateSaveObject(cSaveObjectHandler * apSaveObjectHandler, cGame * apGame);
virtual int GetSaveCreatePrio();
};
//------------------------------------------
class cMeshEntity : public iRenderable {
typedef iRenderable super;
friend class cSubMeshEntity;
friend class cMeshEntityRootNodeUpdate;
friend class cMesh;
public:
cMeshEntity(const tString asName, cMesh *apMesh, cMaterialManager *apMaterialManager,
cMeshManager *apMeshManager, cAnimationManager *apAnimationManager);
~cMeshEntity();
void SetWorld(cWorld3D *apWorld) { mpWorld = apWorld; }
cWorld3D *GetWorld() { return mpWorld; }
void SetCastsShadows(bool abX);
cNode3D *GetRootNode() { return mpRootNode; }
void SetCallback(cMeshEntityCallback *apCallback) { mpCallback = apCallback; }
// Sub mesh entities
cSubMeshEntity *GetSubMeshEntity(unsigned int alIdx);
cSubMeshEntity *GetSubMeshEntityName(const tString &asName);
int GetSubMeshEntityNum();
// Animation states
cAnimationState *AddAnimation(cAnimation *apAnimation, const tString &asName, float afBaseSpeed);
void ClearAnimations();
cAnimationState *GetAnimationState(int alIndex);
int GetAnimationStateIndex(const tString &asName);
cAnimationState *GetAnimationStateFromName(const tString &asName);
int GetAnimationStateNum();
// Animation controller
void Play(int alIndex, bool abLoop, bool bStopPrev);
void PlayName(const tString &asName, bool abLoop, bool bStopPrev);
void Stop();
// Bone states
cBoneState *GetBoneState(int alIndex);
int GetBoneStateIndex(const tString &asName);
cBoneState *GetBoneStateFromName(const tString &asName);
int GetBoneStateNum();
void SetSkeletonPhysicsActive(bool abX);
bool GetSkeletonPhysicsActive();
void SetSkeletonPhysicsCanSleep(bool abX) { mbSkeletonPhysicsCanSleep = abX; }
bool GetSkeletonPhysicsCanSleep() { return mbSkeletonPhysicsCanSleep; }
float GetSkeletonPhysicsWeight();
void SetSkeletonPhysicsWeight(float afX);
void FadeSkeletonPhysicsWeight(float afTime);
void SetSkeletonCollidersActive(bool abX);
bool GetSkeletonCollidersActive();
void AlignBodiesToSkeleton(bool abCalculateSpeed);
cMesh *GetMesh() { return mpMesh; }
/**
* Calculates the transform (and angles and position if wanted) of a mesh based on the position of the root bone.
* This is useful when going from rag doll to mesh.
* \param *apPostion Can be NULL, the position
* \param *apAngles Can be NULL, the angles.
*/
cMatrixf CalculateTransformFromSkeleton(cVector3f *apPostion, cVector3f *apAngles);
/**
* Checks collision with the skeletons collider boides
* \param *apWorld Physics world
* \param *apShape The shape
* \param &a_mtxShape The shapes matrix
* \param *apPosList A list of positions that all contact points are stored in. can be NULL.
* \param *apNumList A list of ints of number of the bone state body hit. can be NULL.
*/
bool CheckColliderShapeCollision(iPhysicsWorld *apWorld,
iCollideShape *apShape, const cMatrixf &a_mtxShape,
tVector3fList *apPosList, tIntList *apNumList);
void ResetGraphicsUpdated();
// Node states
cNode3D *GetNodeState(int alIndex);
int GetNodeStateIndex(const tString &asName);
cNode3D *GetNodeStateFromName(const tString &asName);
int GetNodeStateNum();
bool HasNodes() { return mbHasNodes; }
bool AttachEntityToParent(iEntity3D *apEntity, const tString &asParent);
// Entity implementation
tString GetEntityType() { return "Mesh"; }
bool IsVisible() { return IsRendered(); }
void SetVisible(bool abVisible) { SetRendered(abVisible); }
void UpdateLogic(float afTimeStep);
// Renderable implementation.
void UpdateGraphics(cCamera3D *apCamera, float afFrameTime, cRenderList *apRenderList);
void SetRendered(bool abX);
iMaterial *GetMaterial();
iVertexBuffer *GetVertexBuffer();
bool IsShadowCaster();
cBoundingVolume *GetBoundingVolume();
cMatrixf *GetModelMatrix(cCamera3D *apCamera);
int GetMatrixUpdateCount();
eRenderableType GetRenderType();
void SetBody(iPhysicsBody *apBody) { mpBody = apBody; }
iPhysicsBody *GetBody() { return mpBody; }
// SaveObject implementation
virtual iSaveData *CreateSaveData();
virtual void SaveToSaveData(iSaveData *apSaveData);
virtual void LoadFromSaveData(iSaveData *apSaveData);
virtual void SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame);
private:
void UpdateNodeMatrixRec(const cMatrixf &a_mtxParentWorld, cNode3D *apNode);
void HandleAnimationEvent(cAnimationEvent *apEvent);
void SetBoneMatrixFromBodyRec(const cMatrixf &a_mtxParentWorld, cBoneState *apBoneState);
void UpdateBVFromSubs();
void BuildBoneStatesRec(cBone *apBone, cNode3D *apParent);
cMaterialManager *mpMaterialManager;
cMeshManager *mpMeshManager;
cAnimationManager *mpAnimationManager;
cWorld3D *mpWorld;
tSubMeshEntityVec mvSubMeshes;
tSubMeshEntityMap m_mapSubMeshes;
tAnimationStateVec mvAnimationStates;
tAnimationStateIndexMap m_mapAnimationStateIndices;
tNodeStateVec mvBoneStates;
tNodeStateIndexMap m_mapBoneStateIndices;
tNodeStateVec mvTempBoneStates;
Common::Array<cMatrixf> mvBoneMatrices;
bool mbSkeletonPhysics;
bool mbSkeletonPhysicsFading;
float mfSkeletonPhysicsFadeSpeed;
float mfSkeletonPhysicsWeight;
bool mbSkeletonPhysicsSleeping;
bool mbSkeletonPhysicsCanSleep;
bool mbSkeletonColliders;
bool mbUpdatedBones;
bool mbHasNodes;
tNodeStateVec mvNodeStates;
tNodeStateIndexMap m_mapNodeStateIndices;
int mlStartSleepCount;
int mlUpdateCount;
float mfTimeStepAccum;
cMesh *mpMesh;
cNode3D *mpRootNode;
cMeshEntityRootNodeUpdate *mpRootCallback;
cMeshEntityCallback *mpCallback;
tEntity3DList mlstAttachedEntities;
cMatrixf mtxTemp;
iPhysicsBody *mpBody;
// Properies:
bool mbCastShadows;
};
//-----------------------------------------------------------------------
} // namespace hpl
#endif // HPL_MESH_ENTITY_H