forked from eu07/maszyna
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGround.h
403 lines (379 loc) · 15.9 KB
/
Ground.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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/*
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/.
*/
#ifndef groundH
#define groundH
#include "dumb3d.h"
#include "ResourceManager.h"
#include "VBO.h"
#include "Classes.h"
using namespace Math3D;
// Ra: zmniejszone liczby, aby zrobić tabelkę i zoptymalizować wyszukiwanie
const int TP_MODEL = 10;
const int TP_MESH = 11; // Ra: specjalny obiekt grupojący siatki dla tekstury
const int TP_DUMMYTRACK = 12; // Ra: zdublowanie obiektu toru dla rozdzielenia tekstur
const int TP_TERRAIN = 13; // Ra: specjalny model dla terenu
const int TP_DYNAMIC = 14;
const int TP_SOUND = 15;
const int TP_TRACK = 16;
// const int TP_GEOMETRY=17;
const int TP_MEMCELL = 18;
const int TP_EVLAUNCH = 19; // MC
const int TP_TRACTION = 20;
const int TP_TRACTIONPOWERSOURCE = 21; // MC
// const int TP_ISOLATED=22; //Ra
const int TP_SUBMODEL = 22; // Ra: submodele terenu
const int TP_LAST = 25; // rozmiar tablicy
struct DaneRozkaz
{ // struktura komunikacji z EU07.EXE
int iSygn; // sygnatura 'EU07'
int iComm; // rozkaz/status (kod ramki)
union
{
float fPar[62];
int iPar[62];
char cString[248]; // upakowane stringi
};
};
typedef int TGroundNodeType;
struct TGroundVertex
{
vector3 Point;
vector3 Normal;
float tu, tv;
void HalfSet(const TGroundVertex &v1, const TGroundVertex &v2)
{ // wyliczenie współrzędnych i mapowania punktu na środku odcinka v1<->v2
Point = 0.5 * (v1.Point + v2.Point);
Normal = 0.5 * (v1.Normal + v2.Normal);
tu = 0.5 * (v1.tu + v2.tu);
tv = 0.5 * (v1.tv + v2.tv);
}
void SetByX(const TGroundVertex &v1, const TGroundVertex &v2, double x)
{ // wyliczenie współrzędnych i mapowania punktu na odcinku v1<->v2
double i = (x - v1.Point.x) / (v2.Point.x - v1.Point.x); // parametr równania
double j = 1.0 - i;
Point = j * v1.Point + i * v2.Point;
Normal = j * v1.Normal + i * v2.Normal;
tu = j * v1.tu + i * v2.tu;
tv = j * v1.tv + i * v2.tv;
}
void SetByZ(const TGroundVertex &v1, const TGroundVertex &v2, double z)
{ // wyliczenie współrzędnych i mapowania punktu na odcinku v1<->v2
double i = (z - v1.Point.z) / (v2.Point.z - v1.Point.z); // parametr równania
double j = 1.0 - i;
Point = j * v1.Point + i * v2.Point;
Normal = j * v1.Normal + i * v2.Normal;
tu = j * v1.tu + i * v2.tu;
tv = j * v1.tv + i * v2.tv;
}
};
class TSubRect; // sektor (aktualnie 200m×200m, ale może być zmieniony)
class TGroundNode : public Resource
{ // obiekt scenerii
private:
public:
TGroundNodeType iType; // typ obiektu
union
{ // Ra: wskażniki zależne od typu - zrobić klasy dziedziczone zamiast
void *Pointer; // do przypisywania NULL
TSubModel *smTerrain; // modele terenu (kwadratow kilometrowych)
TAnimModel *Model; // model z animacjami
TDynamicObject *DynamicObject; // pojazd
vector3 *Points; // punkty dla linii
TTrack *pTrack; // trajektoria ruchu
TGroundVertex *Vertices; // wierzchołki dla trójkątów
TMemCell *MemCell; // komórka pamięci
TEventLauncher *EvLaunch; // wyzwalacz zdarzeń
TTraction *hvTraction; // drut zasilający
TTractionPowerSource *psTractionPowerSource; // zasilanie drutu (zaniedbane w sceneriach)
TTextSound *tsStaticSound; // dźwięk przestrzenny
TGroundNode *nNode; // obiekt renderujący grupowo ma tu wskaźnik na listę obiektów
};
AnsiString asName; // nazwa (nie zawsze ma znaczenie)
union
{
int iNumVerts; // dla trójkątów
int iNumPts; // dla linii
int iCount; // dla terenu
// int iState; //Ra: nie używane - dźwięki zapętlone
};
vector3 pCenter; // współrzędne środka do przydzielenia sektora
union
{
// double fAngle; //kąt obrotu dla modelu
double fLineThickness; // McZapkie-120702: grubosc linii
// int Status; //McZapkie-170303: status dzwieku
};
double fSquareRadius; // kwadrat widoczności do
double fSquareMinRadius; // kwadrat widoczności od
// TGroundNode *nMeshGroup; //Ra: obiekt grupujący trójkąty w TSubRect dla tekstury
int iVersion; // wersja siatki (do wykonania rekompilacji)
// union ?
GLuint DisplayListID; // numer siatki DisplayLists
bool PROBLEND;
int iVboPtr; // indeks w buforze VBO
GLuint TextureID; // główna (jedna) tekstura obiektu
int iFlags; // tryb przezroczystości: 0x10-nieprz.,0x20-przezroczysty,0x30-mieszany
int Ambient[4], Diffuse[4], Specular[4]; // oświetlenie
bool bVisible;
TGroundNode *nNext; // lista wszystkich w scenerii, ostatni na początku
TGroundNode *nNext2; // lista obiektów w sektorze
TGroundNode *nNext3; // lista obiektów renderowanych we wspólnym cyklu
TGroundNode();
TGroundNode(TGroundNodeType t, int n = 0);
~TGroundNode();
void Init(int n);
void InitCenter(); // obliczenie współrzędnych środka
void InitNormals();
void MoveMe(vector3 pPosition); // przesuwanie (nie działa)
// bool Disable();
inline TGroundNode *__fastcall Find(const AnsiString &asNameToFind, TGroundNodeType iNodeType)
{ // wyszukiwanie czołgowe z typem
if ((iNodeType == iType) && (asNameToFind == asName))
return this;
else if (nNext)
return nNext->Find(asNameToFind, iNodeType);
return NULL;
};
void Compile(bool many = false);
void Release();
bool GetTraction();
void RenderHidden(); // obsługa dźwięków i wyzwalaczy zdarzeń
void RenderDL(); // renderowanie nieprzezroczystych w Display Lists
void RenderAlphaDL(); // renderowanie przezroczystych w Display Lists
// (McZapkie-131202)
void RaRenderVBO(); // renderowanie (nieprzezroczystych) ze wspólnego VBO
void RenderVBO(); // renderowanie nieprzezroczystych z własnego VBO
void RenderAlphaVBO(); // renderowanie przezroczystych z (własnego) VBO
};
class TSubRect : public Resource, public CMesh
{ // sektor składowy kwadratu kilometrowego
public:
int iTracks; // ilość torów w (tTracks)
TTrack **tTracks; // tory do renderowania pojazdów
protected:
TTrack *tTrackAnim; // obiekty do przeliczenia animacji
TGroundNode *nRootMesh; // obiekty renderujące wg tekstury (wtórne, lista po nNext2)
TGroundNode *nMeshed; // lista obiektów dla których istnieją obiekty renderujące grupowo
public:
TGroundNode *
nRootNode; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
TGroundNode *
nRenderHidden; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
TGroundNode *nRenderRect; // z poziomu sektora - nieprzezroczyste (nNext3)
TGroundNode *nRenderRectAlpha; // z poziomu sektora - przezroczyste (nNext3)
TGroundNode *nRenderWires; // z poziomu sektora - druty i inne linie (nNext3)
TGroundNode *nRender; // indywidualnie - nieprzezroczyste (nNext3)
TGroundNode *nRenderMixed; // indywidualnie - nieprzezroczyste i przezroczyste (nNext3)
TGroundNode *nRenderAlpha; // indywidualnie - przezroczyste (nNext3)
int iNodeCount; // licznik obiektów, do pomijania pustych sektorów
public:
void LoadNodes(); // utworzenie VBO sektora
public:
TSubRect();
virtual ~TSubRect();
virtual void Release(); // zwalnianie VBO sektora
void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory
void RaNodeAdd(TGroundNode *Node); // dodanie obiektu do listy renderowania
void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur)
TTrack *__fastcall FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude);
TTraction *__fastcall FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude);
bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i
// (nRenderWires)
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
void RaAnimate(); // przeliczenie animacji torów
void RenderDL(); // renderowanie nieprzezroczystych w Display Lists
void RenderAlphaDL(); // renderowanie przezroczystych w Display Lists
// (McZapkie-131202)
void RenderVBO(); // renderowanie nieprzezroczystych z własnego VBO
void RenderAlphaVBO(); // renderowanie przezroczystych z (własnego) VBO
void RenderSounds(); // dźwięki pojazdów z niewidocznych sektorów
};
// Ra: trzeba sprawdzić wydajność siatki
const int iNumSubRects = 5; // na ile dzielimy kilometr
const int iNumRects = 500;
// const double fHalfNumRects=iNumRects/2.0; //połowa do wyznaczenia środka
const int iTotalNumSubRects = iNumRects * iNumSubRects;
const double fHalfTotalNumSubRects = iTotalNumSubRects / 2.0;
const double fSubRectSize = 1000.0 / iNumSubRects;
const double fRectSize = fSubRectSize * iNumSubRects;
class TGroundRect : public TSubRect
{ // kwadrat kilometrowy
// obiekty o niewielkiej ilości wierzchołków będą renderowane stąd
// Ra: 2012-02 doszły submodele terenu
private:
int iLastDisplay; // numer klatki w której był ostatnio wyświetlany
TSubRect *pSubRects;
void Init()
{
pSubRects = new TSubRect[iNumSubRects * iNumSubRects];
};
public:
static int iFrameNumber; // numer kolejny wyświetlanej klatki
TGroundNode *nTerrain; // model terenu z E3D - użyć nRootMesh?
TGroundRect();
virtual ~TGroundRect();
TSubRect *__fastcall SafeGetRect(int iCol, int iRow)
{ // pobranie wskaźnika do małego kwadratu, utworzenie jeśli trzeba
if (!pSubRects)
Init(); // utworzenie małych kwadratów
return pSubRects + iRow * iNumSubRects + iCol; // zwrócenie właściwego
};
TSubRect *__fastcall FastGetRect(int iCol, int iRow)
{ // pobranie wskaźnika do małego kwadratu, bez tworzenia jeśli nie ma
return (pSubRects ? pSubRects + iRow * iNumSubRects + iCol : NULL);
};
void Optimize()
{ // optymalizacja obiektów w sektorach
if (pSubRects)
for (int i = iNumSubRects * iNumSubRects - 1; i >= 0; --i)
pSubRects[i].Sort(); // optymalizacja obiektów w sektorach
};
void RenderDL();
void RenderVBO();
};
class TGround
{
vector3 CameraDirection; // zmienna robocza przy renderowaniu
int const *iRange; // tabela widoczności
// TGroundNode *nRootNode; //lista wszystkich węzłów
TGroundNode *nRootDynamic; // lista pojazdów
TGroundRect Rects[iNumRects][iNumRects]; // mapa kwadratów kilometrowych
TEvent *RootEvent; // lista zdarzeń
TEvent *QueryRootEvent, *tmpEvent, *tmp2Event, *OldQRE;
TSubRect *pRendered[1500]; // lista renderowanych sektorów
int iNumNodes;
vector3 pOrigin;
vector3 aRotate;
bool bInitDone;
TGroundNode *nRootOfType[TP_LAST]; // tablica grupująca obiekty, przyspiesza szukanie
// TGroundNode *nLastOfType[TP_LAST]; //ostatnia
TSubRect srGlobal; // zawiera obiekty globalne (na razie wyzwalacze czasowe)
int hh, mm, srh, srm, ssh, ssm; // ustawienia czasu
// int tracks,tracksfar; //liczniki torów
TNames *sTracks; // posortowane nazwy torów i eventów
private: // metody prywatne
bool EventConditon(TEvent *e);
public:
bool bDynamicRemove; // czy uruchomić procedurę usuwania pojazdów
TDynamicObject *LastDyn; // ABu: paskudnie, ale na bardzo szybko moze jakos przejdzie...
// TTrain *pTrain;
// double fVDozwolona;
// bool bTrabil;
TGround();
~TGround();
void Free();
bool Init(AnsiString asFile, HDC hDC);
void FirstInit();
void InitTracks();
void InitTraction();
bool InitEvents();
bool InitLaunchers();
TTrack *__fastcall FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude);
TTraction *__fastcall FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude);
TTraction *__fastcall TractionNearestFind(vector3 &p, int dir, TGroundNode *n);
// TGroundNode* CreateGroundNode();
TGroundNode *__fastcall AddGroundNode(cParser *parser);
bool AddGroundNode(double x, double z, TGroundNode *Node)
{
TSubRect *tmp = GetSubRect(x, z);
if (tmp)
{
tmp->NodeAdd(Node);
return true;
}
else
return false;
};
// bool Include(TQueryParserComp *Parser);
// TGroundNode* GetVisible(AnsiString asName);
TGroundNode *__fastcall GetNode(AnsiString asName);
bool AddDynamic(TGroundNode *Node);
void MoveGroundNode(vector3 pPosition);
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
bool AddToQuery(TEvent *Event, TDynamicObject *Node);
bool GetTraction(TDynamicObject *model);
bool RenderDL(vector3 pPosition);
bool RenderAlphaDL(vector3 pPosition);
bool RenderVBO(vector3 pPosition);
bool RenderAlphaVBO(vector3 pPosition);
bool CheckQuery();
// GetRect(double x, double z) { return
// &(Rects[int(x/fSubRectSize+fHalfNumRects)][int(z/fSubRectSize+fHalfNumRects)]); };
/*
int GetRowFromZ(double z) { return (z/fRectSize+fHalfNumRects); };
int GetColFromX(double x) { return (x/fRectSize+fHalfNumRects); };
int GetSubRowFromZ(double z) { return (z/fSubRectSize+fHalfNumSubRects); };
int GetSubColFromX(double x) { return (x/fSubRectSize+fHalfNumSubRects); };
*/
/*
inline TGroundNode* FindGroundNode(const AnsiString &asNameToFind )
{
if (RootNode)
return (RootNode->Find( asNameToFind ));
else
return NULL;
}
*/
TGroundNode *__fastcall DynamicFindAny(AnsiString asNameToFind);
TGroundNode *__fastcall DynamicFind(AnsiString asNameToFind);
void DynamicList(bool all = false);
TGroundNode *__fastcall FindGroundNode(AnsiString asNameToFind, TGroundNodeType iNodeType);
TGroundRect *__fastcall GetRect(double x, double z)
{
return &Rects[GetColFromX(x) / iNumSubRects][GetRowFromZ(z) / iNumSubRects];
};
TSubRect *__fastcall GetSubRect(double x, double z)
{
return GetSubRect(GetColFromX(x), GetRowFromZ(z));
};
TSubRect *__fastcall FastGetSubRect(double x, double z)
{
return FastGetSubRect(GetColFromX(x), GetRowFromZ(z));
};
TSubRect *__fastcall GetSubRect(int iCol, int iRow);
TSubRect *__fastcall FastGetSubRect(int iCol, int iRow);
int GetRowFromZ(double z)
{
return (z / fSubRectSize + fHalfTotalNumSubRects);
};
int GetColFromX(double x)
{
return (x / fSubRectSize + fHalfTotalNumSubRects);
};
TEvent *__fastcall FindEvent(const AnsiString &asEventName);
TEvent *__fastcall FindEventScan(const AnsiString &asEventName);
void TrackJoin(TGroundNode *Current);
private:
void OpenGLUpdate(HDC hDC);
void RaTriangleDivider(TGroundNode *node);
void Navigate(String ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
bool PROBLEND;
public:
void WyslijEvent(const AnsiString &e, const AnsiString &d);
int iRendered; // ilość renderowanych sektorów, pobierana przy pokazywniu FPS
void WyslijString(const AnsiString &t, int n);
void WyslijWolny(const AnsiString &t);
void WyslijNamiary(TGroundNode *t);
void WyslijParam(int nr, int fl);
void RadioStop(vector3 pPosition);
TDynamicObject *__fastcall DynamicNearest(vector3 pPosition, double distance = 20.0,
bool mech = false);
TDynamicObject *__fastcall CouplerNearest(vector3 pPosition, double distance = 20.0,
bool mech = false);
void DynamicRemove(TDynamicObject *dyn);
void TerrainRead(const AnsiString &f);
void TerrainWrite();
void TrackBusyList();
void IsolatedBusyList();
void IsolatedBusy(const AnsiString t);
void Silence(vector3 gdzie);
};
//---------------------------------------------------------------------------
#endif