/* =========================================================================== Copyright (C) 2023 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code 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 2 of the License, or (at your option) any later version. OpenMoHAA source code 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 OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // skeletor.h : General skeletor structures #pragma once #include "../tiki/tiki_shared.h" #include "SkelVec3.h" #include "SkelVec4.h" #include "SkelMat3.h" #include "SkelMat4.h" #include "SkelQuat.h" #include "skeletor_animation_file_format.h" #include "skeletor_model_file_format.h" #include "skeletor_name_lists.h" #include "skeletor_internal.h" #define MAX_SKEL_BLEND_MOVEMENT_FRAMES 32 #define MAX_SKEL_BLEND_ACTION_FRAMES 32 #define MAX_SKEL_BLEND_FRAMES (MAX_SKEL_BLEND_MOVEMENT_FRAMES + MAX_SKEL_BLEND_ACTION_FRAMES) typedef struct skelAnimFrame_s { float radius; SkelVec3 bounds[2]; SkelMat4 bones[1]; } skelAnimFrame_t; typedef struct { float seconds; } skelAnimTime_t; typedef struct { float weight; skelAnimDataGameHeader_t *pAnimationData; skelAnimGameFrame_t *frame; } skelAnimBlendFrame_t; typedef struct { float weight; skelAnimDataGameHeader_t *pAnimationData; int frame; } skanBlendInfo; #ifdef __cplusplus template class Container; # include "container.h" class skelAnimStoreFrameList_c { public: short int numMovementFrames; short int numActionFrames; float actionWeight; skanBlendInfo m_blendInfo[MAX_SKEL_BLEND_FRAMES]; public: SkelQuat GetSlerpValue(int globalChannelNum) const; void GetLerpValue3(int globalChannelNum, SkelVec3 *outVec) const; }; class skeletor_c { public: dtiki_t *m_Tiki; static ChannelNameTable m_boneNames; static ChannelNameTable m_channelNames; static skelBone_World m_worldBone; private: SkelVec3 m_frameBounds[2]; float m_frameRadius; skelAnimStoreFrameList_c m_frameList; short int m_targetLookLeft; short int m_targetLookRight; short int m_targetLookUp; short int m_targetLookDown; short int m_targetLookCrossed; short int m_targetBlink; short int m_timeNextBlink; short int m_headBoneIndex; vec3_t m_eyeTargetPos; vec3_t m_eyePrevTargetPos; class skelBone_Base *m_leftFoot; class skelBone_Base *m_rightFoot; skelChannelList_c m_morphTargetList; class skelBone_Base **m_bone; public: skeletor_c(dtiki_t *tiki); ~skeletor_c(); static skelAnimDataGameHeader_t * ConvertSkelFileToGame(skelAnimDataFileHeader_t *pHeader, int iBuffLength, const char *path); static void SaveProcessedAnim(skelAnimDataGameHeader_t *enAnim, const char *path, skelAnimDataFileHeader_t *pHeader); static skelAnimDataGameHeader_t *LoadProcessedAnim(const char *path, void *buffer, int len, const char *name); static skelAnimDataGameHeader_t *LoadProcessedAnimEx(const char *path, void *buffer, int len, const char *name); void PrintBoneCacheList(); void PrintBoneList(); void LoadMorphTargetNames(skelHeaderGame_t *modelHeader); void GetFrame(skelAnimFrame_t *newFrame); int GetMorphWeightFrame(int *data); SkelMat4 & GetBoneFrame(int boneIndex) const; void GetFrameBounds(SkelVec3 *, SkelVec3 *); float GetModelLODRadius(); bool IsBoneOnGround(int boneIndex, float threshold); int GetMorphWeightFrame(int index, float time, int *data); qboolean LoadSKB(const char *); float GetRadius(); float GetCentroidRadius(float *centroid); void SetPose(const frameInfo_t *frameInfo, const int *contIndices, const vec4_t *contValues, float actionWeight); void SetEyeTargetPos(const float *pEyeTargetPos); int GetBoneParent(int boneIndex); static class ChannelNameTable* ChannelNames(); private: void Init(); SkelMat4 *BoneTransformation(int, int *, float (*)[4]); }; #endif #ifdef __cplusplus extern "C" { #endif // // skeletor.cpp // void ConvertToRotationName(const char *boneName, char *rotChannelName); void ConvertToPositionName(const char *boneName, char *posChannelName); void ConvertToFKRotationName(const char *boneName, char *rotChannelName); void ConvertToFKPositionName(const char *boneName, char *rotChannelName); void AddToBounds(SkelVec3 *bounds, SkelVec3 *newBounds); #ifdef __cplusplus void BoneGetFrames( skelHeaderGame_t *skelmodel, skelAnimDataGameHeader_t *animData, skelChannelList_c *boneList, int boneNum, Container& outFrames ); void TIKI_GetSkelAnimFrameInternal2( dtiki_t *tiki, skelBoneCache_t *bones, skelAnimStoreFrameList_c *frameList, float *radius, vec3_t *mins, vec3_t *maxes ); void SkeletorGetAnimFrame2( skelHeaderGame_t *skelmodel, skelChannelList_c *boneList, skelBoneCache_t *bones, skelAnimStoreFrameList_c *frameList, float *radius, vec3_t *mins, vec3_t *maxes ); #endif void SkeletorGetAnimFrame( skelHeaderGame_t *skelmodel, skelAnimDataGameHeader_t *animData, skelChannelList_c *boneList, skelBoneCache_t *bones, int frame, float *radius, vec3_t *mins, vec3_t *maxes ); void TIKI_GetSkelAnimFrame(dtiki_t *tiki, skelBoneCache_t *bones, float *radius, vec3_t *mins, vec3_t *maxes); void TIKI_GetSkelAnimFrame2( dtiki_t *tiki, skelBoneCache_t *bones, int anim, int frame, float *radius, vec3_t *mins, vec3_t *maxes ); void TIKI_GetSkelAnimFrameInternal( dtiki_t *tiki, skelBoneCache_t *bones, skelAnimDataGameHeader_t *animData, int frame, float *radius, vec3_t *mins, vec3_t *maxes ); // // skeletor_imports.cpp // void Skel_DPrintf(const char *fmt, ...); #ifndef _DEBUG_MEM void Skel_Free(void *ptr); void *Skel_Alloc(size_t size); #else # define Skel_Free(ptr) free(ptr) # define Skel_Alloc(size) malloc(size) #endif void Skel_FreeFile(void *buffer); int Skel_ReadFileEx(const char *qpath, void **buffer, qboolean quiet); // // skeletor_utilities.cpp // void SKEL_Message(const char *fmt, ...); void SKEL_Warning(const char *fmt, ...); void SKEL_Error(const char *fmt, ...); void Skel_ExtractFilePath(const char *path, char *dest); void Skel_ExtractFileBase(const char *path, char *dest); void Skel_ExtractFileExtension(const char *path, char *dest); //const char *Skel_ExtractFileExtension( const char *in ); void Skel_ExtractFileName(const char *path, char *dest); int FileLength(FILE *pFile); // // skeletorbones.cpp // void SkeletorLoadBoneFromBuffer(skelChannelList_c *boneList, boneData_t *boneData, skelBone_Base **bone); void SkeletorLoadBonesFromBuffer(skelChannelList_c *boneList, skelHeaderGame_t *buffer, skelBone_Base **bone); #ifdef __cplusplus } #endif