1 |
c137512e
|
Oto Šťáva
|
#include "wall.hpp"
|
2 |
|
|
|
3 |
|
|
const float Wall::DEFORM = 0.5f;
|
4 |
|
|
const float Wall::SCALING_FRONT = 1.2f;
|
5 |
|
|
const float Wall::SCALING_BACK = 0.6f;
|
6 |
|
|
const int Wall::FLOOR_SPLIT = 5;
|
7 |
|
|
const int Wall::CEILING_SPLIT = 3;
|
8 |
|
|
const int Wall::SIDE_SPLIT = 8;
|
9 |
|
|
const int Wall::ENLARGE = 6;
|
10 |
|
|
|
11 |
|
|
Wall::Wall(const TYPE type): Element(Element::WALL)
|
12 |
|
|
{
|
13 |
|
|
this->type = type;
|
14 |
|
|
}
|
15 |
|
|
|
16 |
|
|
void Wall::setData(QVector3D minimum, QVector3D maximum, float sphereRadius)
|
17 |
|
|
{
|
18 |
|
|
// Odstranit ulozene hodnoty ke "stare" zdi.
|
19 |
|
|
clear();
|
20 |
|
|
|
21 |
|
|
// Minimalni kvadr rozsirit tak, aby se do mistnosti vesly i sipky (podle
|
22 |
|
|
// polomeru koule).
|
23 |
|
|
sphereRadius *= ENLARGE;
|
24 |
|
|
minimum += QVector3D(-1.0f * sphereRadius, -1.0f * sphereRadius, -1.0f * sphereRadius);
|
25 |
|
|
maximum += QVector3D(sphereRadius, sphereRadius, sphereRadius);
|
26 |
|
|
|
27 |
|
|
// Urceni poloviny vysledneho rozsahu pro osy X a Y pro predni a zadni stenu.
|
28 |
|
|
float rangeFrontX = abs(maximum.x() - minimum.x()) * SCALING_FRONT / 2.0f;
|
29 |
|
|
float rangeBackX = abs(maximum.x() - minimum.x()) * SCALING_BACK / 2.0f;
|
30 |
|
|
float rangeFrontY = abs(maximum.y() - minimum.y()) * SCALING_FRONT / 2.0f;
|
31 |
|
|
float rangeBackY = abs(maximum.y() - minimum.y()) * SCALING_BACK / 2.0f;
|
32 |
|
|
|
33 |
|
|
// Urceni souradnic "deformovaneho" kvadru.
|
34 |
|
|
QVector3D F00 = QVector3D(-1.0f * rangeFrontX, -1.0f * rangeFrontY, maximum.z());
|
35 |
|
|
QVector3D F10 = QVector3D(-1.0f * rangeFrontX, rangeFrontY, maximum.z());
|
36 |
|
|
QVector3D F11 = QVector3D(rangeFrontX, rangeFrontY, maximum.z());
|
37 |
|
|
QVector3D F01 = QVector3D(rangeFrontX, -1.0f * rangeFrontY, maximum.z());
|
38 |
|
|
|
39 |
|
|
QVector3D B00 = QVector3D(-1.0f * rangeBackX, -1.0f * rangeBackY, minimum.z());
|
40 |
|
|
QVector3D B10 = QVector3D(-1.0f * rangeBackX, rangeBackY, minimum.z());
|
41 |
|
|
QVector3D B11 = QVector3D(rangeBackX, rangeBackY, minimum.z());
|
42 |
|
|
QVector3D B01 = QVector3D(rangeBackX, -1.0f * rangeBackY, minimum.z());
|
43 |
|
|
|
44 |
|
|
// Rozdeleni steny na mensi casti, do kterych bude vykreslovana textura.
|
45 |
|
|
if (type == TYPE::FLOOR)
|
46 |
|
|
{
|
47 |
|
|
// Podlaha
|
48 |
|
|
split(F01, F00, B00, B01, FLOOR_SPLIT);
|
49 |
|
|
}
|
50 |
|
|
else if (type == TYPE::CEILING)
|
51 |
|
|
{
|
52 |
|
|
// Strop
|
53 |
|
|
split(F10, F11, B11, B10, CEILING_SPLIT);
|
54 |
|
|
}
|
55 |
|
|
else
|
56 |
|
|
{
|
57 |
|
|
// Stena vzadu
|
58 |
|
|
split(B00, B10, B11, B01, SIDE_SPLIT, false);
|
59 |
|
|
// Stena nalevo
|
60 |
|
|
split(F00, F10, B10, B00, SIDE_SPLIT);
|
61 |
|
|
// Stena napravo
|
62 |
|
|
split(F11, F01, B01, B11, SIDE_SPLIT);
|
63 |
|
|
}
|
64 |
|
|
}
|
65 |
|
|
|
66 |
|
|
void Wall::split(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &d, const int parts, const bool deform)
|
67 |
|
|
{
|
68 |
|
|
// Obecny ctyruhelnik. Deformace smerem doprava (pokud je nastavena), tj. od AB do DC.
|
69 |
|
|
// b
|
70 |
|
|
// c
|
71 |
|
|
//
|
72 |
|
|
// a d
|
73 |
|
|
|
74 |
|
|
// Urceni bocnich vektoru (zdola nahoru), ktere definuji vysku jednoho pruhu.
|
75 |
|
|
// Vyska pruhu se deformovat nemusi vubec, je pro kazdy pruh stejna.
|
76 |
|
|
QVector3D leftUp = (b - a) / (float) parts;
|
77 |
|
|
QVector3D rightUp = (c - d) / (float) parts;
|
78 |
|
|
|
79 |
|
|
for (int y = 0; y < parts; y++)
|
80 |
|
|
{
|
81 |
|
|
// Zjisteni souradnic ctyruhelnika predstavujici jeden pruh.
|
82 |
|
|
QVector3D leftBottom = a + y * leftUp;
|
83 |
|
|
QVector3D leftTop = a + (y + 1) * leftUp;
|
84 |
|
|
QVector3D rightBottom = d + y * rightUp;
|
85 |
|
|
QVector3D rightTop = d + (y + 1) * rightUp;
|
86 |
|
|
|
87 |
|
|
// Urceni horniho a dolniho vektoru (zleva doprava), ktere definuji sirku
|
88 |
|
|
// jednoho sloupce (dany sloupec ma ve vsech pruzich stejnou sirku).
|
89 |
|
|
// Pokud je nastavena deformace, bude se tykat prave sirek sloupcu, viz dale.
|
90 |
|
|
QVector3D topRight = (rightTop - leftTop) / (float) parts;
|
91 |
|
|
QVector3D bottomRight = (rightBottom - leftBottom) / (float) parts;
|
92 |
|
|
|
93 |
|
|
QVector3D topRightFirst, topRightDiff, bottomRightFirst, bottomRightDiff, topRightAct, bottomRightAct, topOneOnRightAct, bottomOneOnRightAct;
|
94 |
|
|
if (deform)
|
95 |
|
|
{
|
96 |
|
|
// Jestlize ma dochazet k deformaci, vypocitani sirky prvniho sloupce
|
97 |
|
|
// a rozdilu sirek mezi dvema sloupci.
|
98 |
|
|
|
99 |
|
|
// Horni sirka prvniho sloupce (nejvice vlevo).
|
100 |
|
|
topRightFirst = (1.0f + DEFORM) * topRight;
|
101 |
|
|
// O kolik se ma linearne snizovat horni sirka sloupce.
|
102 |
|
|
topRightDiff = (topRightFirst - (1.0f - DEFORM) * topRight) / (float) (parts - 1);
|
103 |
|
|
|
104 |
|
|
// Dolni sirka prvniho sloupce (nejvice vlevo).
|
105 |
|
|
bottomRightFirst = (1.0f + DEFORM) * bottomRight;
|
106 |
|
|
// O kolik se ma linearne snizovat dolni sirka sloupce.
|
107 |
|
|
bottomRightDiff = (bottomRightFirst - (1.0f - DEFORM) * bottomRight) / (float) (parts - 1);
|
108 |
|
|
|
109 |
|
|
// Nastaveni souradnic prvniho ctyruhelnika.
|
110 |
|
|
topRightAct = leftTop;
|
111 |
|
|
bottomRightAct = leftBottom;
|
112 |
|
|
topOneOnRightAct = topRightAct + topRightFirst;
|
113 |
|
|
bottomOneOnRightAct = bottomRightAct + bottomRightFirst;
|
114 |
|
|
}
|
115 |
|
|
|
116 |
|
|
for (int x = 0; x < parts; x++)
|
117 |
|
|
{
|
118 |
|
|
if (!deform)
|
119 |
|
|
{
|
120 |
|
|
// Pokud nema dojit k deformaci - rovnomerne rozdeleni.
|
121 |
|
|
bottomRightAct = leftBottom + x * bottomRight;
|
122 |
|
|
bottomOneOnRightAct = leftBottom + (x + 1) * bottomRight;
|
123 |
|
|
topRightAct = leftTop + x * topRight;
|
124 |
|
|
topOneOnRightAct = leftTop + (x + 1) * topRight;
|
125 |
|
|
}
|
126 |
|
|
|
127 |
|
|
// Ulozit ctyruhelnik.
|
128 |
|
|
addTetragon(bottomRightAct, topRightAct, topOneOnRightAct, bottomOneOnRightAct);
|
129 |
|
|
|
130 |
|
|
if (deform)
|
131 |
|
|
{
|
132 |
|
|
// Pokud dochazi k deformaci, snizit sirku sloupce, presunout se
|
133 |
|
|
// na zacatek dalsiho a urcit jeho prave souradnice.
|
134 |
|
|
|
135 |
|
|
topRightAct = topOneOnRightAct;
|
136 |
|
|
bottomRightAct = bottomOneOnRightAct;
|
137 |
|
|
|
138 |
|
|
topRightFirst -= topRightDiff;
|
139 |
|
|
bottomRightFirst -= bottomRightDiff;
|
140 |
|
|
|
141 |
|
|
topOneOnRightAct += topRightFirst;
|
142 |
|
|
bottomOneOnRightAct += bottomRightFirst;
|
143 |
|
|
}
|
144 |
|
|
}
|
145 |
|
|
}
|
146 |
|
|
}
|
147 |
|
|
|
148 |
|
|
void Wall::addTetragon(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &d)
|
149 |
|
|
{
|
150 |
|
|
// Obecny ctyruhelnik - mapovani na souradnice textury (souradnice UV).
|
151 |
|
|
// b [0,1]
|
152 |
|
|
// c [1,1]
|
153 |
|
|
// a [0,0] d [1,0]
|
154 |
|
|
|
155 |
|
|
QVector3D n = normal(a, d, b);
|
156 |
|
|
|
157 |
|
|
// Pro kazdy vrchol upravovat ukladanou kategorii (typ prvku), ktera u "zdi"
|
158 |
|
|
// predstavuje vrchol textury (ctyri vrcholy textury se musi namapovat na
|
159 |
|
|
// vrcholy ctyruhelnika).
|
160 |
|
|
category = Element::WALL + 0;
|
161 |
|
|
addVertex(a, n);
|
162 |
|
|
category = Element::WALL + 2;
|
163 |
|
|
addVertex(d, n);
|
164 |
|
|
category = Element::WALL + 3;
|
165 |
|
|
addVertex(c, n);
|
166 |
|
|
category = Element::WALL + 1;
|
167 |
|
|
addVertex(b, n);
|
168 |
|
|
}
|