Projekt

Obecné

Profil

Stáhnout (6.58 KB) Statistiky
| Větev: | Tag: | Revize:
1
#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
}
(9-9/10)