forked from eu07/maszyna
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathAnimModel.h
207 lines (186 loc) · 7.46 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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/*
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 "Classes.h"
#include "dumb3d.h"
#include "Float3d.h"
#include "Model3d.h"
#include "DynObj.h"
#include "scenenode.h"
const int iMaxNumLights = 8;
float const DefaultDarkThresholdLevel { 0.325f };
// 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
ls_Home = 4 // like ls_dark but off late at night
};
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 basic_event;
class TAnimContainer
{ // opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista
friend TAnimModel;
private:
Math3D::vector3 vRotateAngles; // dla obrotów Eulera
Math3D::vector3 vDesiredAngles;
double fRotateSpeed;
Math3D::vector3 vTranslation;
Math3D::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
};
basic_event *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( Math3D::vector3 vNewRotateAngles, double fNewRotateSpeed);
void SetTranslateAnim( Math3D::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
Math3D::vector3 TransGet() {
return Math3D::vector3(-vTranslation.x, vTranslation.z, vTranslation.y); }; // zmiana, bo T3D ma inny układ
inline
void WillBeAnimated() {
if (pSubModel)
pSubModel->WillBeAnimated(); };
void EventAssign(basic_event *ev);
inline
basic_event * 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 scene::basic_node {
friend opengl_renderer;
friend itemproperties_panel;
public:
// constructors
explicit TAnimModel( scene::node_data const &Nodedata );
// destructor
~TAnimModel();
// methods
static void AnimUpdate( double dt );
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 LightSet( int const n, float const v );
void AnimationVND( void *pData, double a, double b, double c, double d );
int TerrainCount();
TSubModel * TerrainSquare(int n);
int Flags();
inline
material_data const *
Material() const {
return &m_materialdata; }
inline
TModel3d *
Model() const {
return pModel; }
inline
void
Angles( glm::vec3 const &Angles ) {
vAngle = Angles; }
inline
glm::vec3
Angles() const {
return vAngle; }
// 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();
// radius() subclass details, calculates node's bounding radius
float radius_();
// serialize() subclass details, sends content of the subclass to provided stream
void serialize_( std::ostream &Output ) const;
// deserialize() subclass details, restores content of the subclass from provided stream
void deserialize_( std::istream &Input );
// export() subclass details, sends basic content of the class in legacy (text) format to provided stream
void export_as_text_( std::ostream &Output ) const;
// members
TAnimContainer *pRoot { nullptr }; // pojemniki sterujące, tylko dla aniomowanych submodeli
TModel3d *pModel { nullptr };
glm::vec3 vAngle; // bazowe obroty egzemplarza względem osi
material_data m_materialdata;
std::string asText; // tekst dla wyświetlacza znakowego
TAnimAdvanced *pAdvanced { nullptr };
// TODO: wrap into a light state struct, remove fixed element count
int iNumLights { 0 };
std::array<TSubModel *, iMaxNumLights> LightsOn {}; // Ra: te wskaźniki powinny być w ramach TModel3d
std::array<TSubModel *, iMaxNumLights> LightsOff {};
std::array<float, iMaxNumLights> lsLights {}; // ls_Off
std::array<glm::vec3, iMaxNumLights> m_lightcolors; // -1 in constructor
std::array<float, iMaxNumLights> m_lighttimers {};
std::array<float, iMaxNumLights> m_lightopacities; // {1} in constructor
float fOnTime { 1.f / 2 };// { 60.f / 45.f / 2 };
float fOffTime { 1.f / 2 };// { 60.f / 45.f / 2 }; // były stałymi, teraz mogą być zmienne dla każdego egzemplarza
float fTransitionTime { fOnTime * 0.9f }; // time
unsigned int m_framestamp { 0 }; // id of last rendered gfx frame
};
class instance_table : public basic_table<TAnimModel> {
};
//---------------------------------------------------------------------------