/* 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 . * */ /* * 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 mvSubEntities; cContainerVec 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 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