//--------------------------------------------------------------------------- #ifndef AnimModelH #define AnimModelH #include "Model3d.h" const int iMaxNumLights=8; //typy stanu świateł typedef enum { ls_Off=0, //zgaszone ls_On=1, //zapalone ls_Blink=2, //migające ls_Dark=3 //Ra: zapalajce się automatycznie, gdy zrobi się ciemno } TLightState; class TAnimVocaloidFrame {//ramka animacji typu Vocaloid Motion Data z programu MikuMikuDance public: char cBone[15]; //nazwa kości, może być po japońsku int iFrame; //numer ramki float3 f3Vector; //przemieszczenie float4 qAngle; //kwaternion obrotu char cBezier[64]; //krzywe Béziera do interpolacji dla x,y,z i obrotu }; class TEvent; class TAnimContainer {//opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista friend class TAnimModel; private: vector3 vRotateAngles; //dla obrotów Eulera vector3 vDesiredAngles; double fRotateSpeed; vector3 vTranslation; vector3 vTranslateTo; double fTranslateSpeed; //może tu dać wektor? float4 qCurrent; //aktualny interpolowany float4 qStart; //pozycja początkowa (0 dla interpolacji) float4 qDesired; //pozycja końcowa (1 dla interpolacji) float fAngleCurrent; //parametr interpolacyjny: 0=start, 1=docelowy float fAngleSpeed; //zmiana parametru interpolacji w sekundach TSubModel *pSubModel; float4x4 *mAnim; //macierz do animacji kwaternionowych //dla kinematyki odwróconej używane są kwaterniony float fLength; //długość kości dla IK int iAnim; //animacja: +1-obrót Eulera, +2-przesuw, +4-obrót kwaternionem, +8-IK //+0x80000000: animacja z eventem, wykonywana poza wyświetlaniem //+0x100: pierwszy stopień IK - obrócić w stronę pierwszego potomnego (dziecka) //+0x200: drugi stopień IK - dostosować do pozycji potomnego potomnego (wnuka) union {//mogą być animacje klatkowe różnego typu, wskaźniki używa AnimModel TAnimVocaloidFrame *pMovementData; //wskaźnik do klatki }; TEvent *evDone; //ewent wykonywany po zakończeniu animacji, np. zapór, obrotnicy public: TAnimContainer *pNext; TAnimContainer *acAnimNext; //lista animacji z eventem, które muszą być przeliczane również bez wyświetlania __fastcall TAnimContainer(); __fastcall ~TAnimContainer(); bool __fastcall Init(TSubModel *pNewSubModel); //std::string inline __fastcall GetName() { return std::string(pSubModel?pSubModel->asName.c_str():""); }; //std::string inline __fastcall GetName() { return std::string(pSubModel?pSubModel->pName:""); }; char* __fastcall NameGet() {return (pSubModel?pSubModel->pName:NULL);}; //void __fastcall SetRotateAnim(vector3 vNewRotateAxis, double fNewDesiredAngle, double fNewRotateSpeed, bool bResetAngle=false); void __fastcall SetRotateAnim(vector3 vNewRotateAngles, double fNewRotateSpeed); void __fastcall SetTranslateAnim(vector3 vNewTranslate, double fNewSpeed); void __fastcall AnimSetVMD(double fNewSpeed); void __fastcall PrepareModel(); void __fastcall UpdateModel(); void __fastcall UpdateModelIK(); bool __fastcall InMovement(); //czy w trakcie animacji? double _fastcall AngleGet() {return vRotateAngles.z;}; //jednak ostatnia, T3D ma inny układ vector3 _fastcall TransGet() {return vector3(-vTranslation.x,vTranslation.z,vTranslation.y);}; //zmiana, bo T3D ma inny układ void __fastcall WillBeAnimated() {if (pSubModel) pSubModel->WillBeAnimated();}; void __fastcall EventAssign(TEvent *ev); TEvent* __fastcall Event() {return evDone;}; }; class TAnimAdvanced {//obiekt zaawansowanej animacji submodelu public: TAnimVocaloidFrame *pMovementData; unsigned char *pVocaloidMotionData; //plik animacyjny dla egzemplarza (z eventu) double fFrequency; //przeliczenie czasu rzeczywistego na klatki animacji double fCurrent; //klatka animacji wyświetlona w poprzedniej klatce renderingu double fLast; //klatka kończąca animację int iMovements; __fastcall TAnimAdvanced(); __fastcall ~TAnimAdvanced(); int __fastcall SortByBone(); }; class TAnimModel {//opakowanie modelu, określające stan egzemplarza private: TAnimContainer *pRoot; //pojemniki sterujące, tylko dla aniomowanych submodeli TModel3d *pModel; double fBlinkTimer; int iNumLights; TSubModel *LightsOn[iMaxNumLights]; //Ra: te wskaźniki powinny być w ramach TModel3d TSubModel *LightsOff[iMaxNumLights]; vector3 vAngle; //bazowe obroty egzemplarza względem osi int iTexAlpha; //żeby nie sprawdzać za każdym razem, dla 4 wymiennych tekstur AnsiString asText; //tekst dla wyświetlacza znakowego TAnimAdvanced *pAdvanced; void __fastcall Advanced(); TLightState lsLights[iMaxNumLights]; float fDark; //poziom zapalanie światła (powinno być chyba powiązane z danym światłem?) float fOnTime,fOffTime; //były stałymi, teraz mogą być zmienne dla każdego egzemplarza private: void __fastcall RaAnimate(); //przeliczenie animacji egzemplarza void __fastcall RaPrepare(); //ustawienie animacji egzemplarza na wzorcu public: GLuint ReplacableSkinId[5]; //McZapkie-020802: zmienialne skory static TAnimContainer *acAnimList; //lista animacji z eventem, które muszą być przeliczane również bez wyświetlania __fastcall TAnimModel(); __fastcall ~TAnimModel(); bool __fastcall Init(TModel3d *pNewModel); bool __fastcall Init(AnsiString asName,AnsiString asReplacableTexture); bool __fastcall Load(cParser *parser, bool ter=false); TAnimContainer* __fastcall AddContainer(char *pName); TAnimContainer* __fastcall GetContainer(char *pName); void __fastcall RenderDL(vector3 pPosition=vector3(0,0,0),double fAngle=0); void __fastcall RenderAlphaDL(vector3 pPosition=vector3(0,0,0),double fAngle=0); void __fastcall RenderVBO(vector3 pPosition=vector3(0,0,0),double fAngle=0); void __fastcall RenderAlphaVBO(vector3 pPosition=vector3(0,0,0),double fAngle=0); void __fastcall RenderDL(vector3* vPosition); void __fastcall RenderAlphaDL(vector3* vPosition); void __fastcall RenderVBO(vector3* vPosition); void __fastcall RenderAlphaVBO(vector3* vPosition); int __fastcall Flags(); void __fastcall RaAnglesSet(double a,double b,double c) {vAngle.x=a; vAngle.y=b; vAngle.z=c;}; bool __fastcall TerrainLoaded(); int __fastcall TerrainCount(); TSubModel* __fastcall TerrainSquare(int n); void __fastcall TerrainRenderVBO(int n); void __fastcall AnimationVND(void* pData, double a, double b, double c, double d); void __fastcall LightSet(int n,float v); static void __fastcall AnimUpdate(double dt); }; TAnimContainer *TAnimModel::acAnimList=NULL; //--------------------------------------------------------------------------- #endif