-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathAnimModel.h
185 lines (165 loc) · 6.33 KB
/
AnimModel.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
/*
MaSzyna EU07 locomotive simulator
Copyright (C) 2001-2004 Marcin Wozniak and others
*/
#pragma once
#include "Model3d.h"
#include "material.h"
#include "DynObj.h"
const int iMaxNumLights = 8;
// typy stanu świateł
enum TLightState
{
ls_Off = 0, // zgaszone
ls_On = 1, // zapalone
ls_Blink = 2, // migające
ls_Dark = 3 // Ra: zapalajce się automatycznie, gdy zrobi się ciemno
};
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
TAnimContainer();
~TAnimContainer();
bool Init(TSubModel *pNewSubModel);
inline
std::string NameGet() {
return (pSubModel ? pSubModel->pName : ""); };
void SetRotateAnim(vector3 vNewRotateAngles, double fNewRotateSpeed);
void SetTranslateAnim(vector3 vNewTranslate, double fNewSpeed);
void AnimSetVMD(double fNewSpeed);
void PrepareModel();
void UpdateModel();
void UpdateModelIK();
bool InMovement(); // czy w trakcie animacji?
inline
double AngleGet() {
return vRotateAngles.z; }; // jednak ostatnia, T3D ma inny układ
inline
vector3 TransGet() {
return vector3(-vTranslation.x, vTranslation.z, vTranslation.y); }; // zmiana, bo T3D ma inny układ
inline
void WillBeAnimated() {
if (pSubModel)
pSubModel->WillBeAnimated(); };
void EventAssign(TEvent *ev);
inline
TEvent * 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;
TAnimAdvanced();
~TAnimAdvanced();
int SortByBone();
};
// opakowanie modelu, określające stan egzemplarza
class TAnimModel : public editor::basic_node {
friend class opengl_renderer;
public:
// constructors
TAnimModel( scene::node_data const &Nodedata );
TAnimModel();
// destructor
~TAnimModel();
// methods
static void AnimUpdate( double dt );
bool Init(TModel3d *pNewModel);
bool Init(std::string const &asName, std::string const &asReplacableTexture);
bool Load(cParser *parser, bool ter = false);
TAnimContainer * AddContainer(std::string const &Name);
TAnimContainer * GetContainer(std::string const &Name = "");
void RaAnglesSet( glm::vec3 Angles ) {
vAngle.x = Angles.x;
vAngle.y = Angles.y;
vAngle.z = Angles.z; };
void LightSet( int n, float v );
void AnimationVND( void *pData, double a, double b, double c, double d );
bool TerrainLoaded();
int TerrainCount();
TSubModel * TerrainSquare(int n);
int Flags();
inline
material_data const *
Material() const {
return &m_materialdata; }
// members
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
private:
// methods
void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu
void RaAnimate( unsigned int const Framestamp ); // przeliczenie animacji egzemplarza
void Advanced();
// members
TAnimContainer *pRoot { nullptr }; // pojemniki sterujące, tylko dla aniomowanych submodeli
TModel3d *pModel { nullptr };
double fBlinkTimer { 0.0 };
int iNumLights { 0 };
TSubModel *LightsOn[ iMaxNumLights ]; // Ra: te wskaźniki powinny być w ramach TModel3d
TSubModel *LightsOff[ iMaxNumLights ];
vector3 vAngle; // bazowe obroty egzemplarza względem osi
material_data m_materialdata;
std::string asText; // tekst dla wyświetlacza znakowego
TAnimAdvanced *pAdvanced { nullptr };
TLightState lsLights[ iMaxNumLights ];
float fDark { 0.25f }; // poziom zapalanie światła (powinno być chyba powiązane z danym światłem?)
float fOnTime { 0.66f };
float fOffTime { 0.66f + 0.66f }; // były stałymi, teraz mogą być zmienne dla każdego egzemplarza
unsigned int m_framestamp { 0 }; // id of last rendered gfx frame
};
class instance_table : public basic_table<TAnimModel> {
};
//---------------------------------------------------------------------------