~ubuntu-branches/ubuntu/natty/spring/natty

« back to all changes in this revision

Viewing changes to rts/Rendering/Models/3DModel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Ritchie
  • Date: 2010-09-23 18:56:03 UTC
  • mfrom: (3.1.9 experimental)
  • Revision ID: james.westby@ubuntu.com-20100923185603-st97s5chplo42y7w
Tags: 0.82.5.1+dfsg1-1ubuntu1
* Latest upstream version for online play
* debian/control: Replace (rather than conflict) spring-engine
  - spring-engine will be a dummy package (LP: #612905)
  - also set maintainer to MOTU

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
 
2
 
 
3
#include "StdAfx.h"
 
4
 
 
5
#include <algorithm>
 
6
#include <cctype>
 
7
#include "mmgr.h"
 
8
 
 
9
#include "3DModel.h"
 
10
#include "3DOParser.h"
 
11
#include "S3OParser.h"
 
12
#include "Rendering/FarTextureHandler.h"
 
13
#include "Rendering/GL/myGL.h"
 
14
#include "Sim/Misc/CollisionVolume.h"
 
15
#include "System/Exceptions.h"
 
16
#include "System/Util.h"
 
17
#include "System/LogOutput.h"
 
18
 
 
19
 
 
20
//////////////////////////////////////////////////////////////////////
 
21
// S3DModelPiece
 
22
//
 
23
 
 
24
void S3DModelPiece::DrawStatic() const
 
25
{
 
26
        glPushMatrix();
 
27
        glTranslatef(offset.x, offset.y, offset.z);
 
28
        glCallList(displist);
 
29
        for (std::vector<S3DModelPiece*>::const_iterator ci = childs.begin(); ci != childs.end(); ci++) {
 
30
                (*ci)->DrawStatic();
 
31
        }
 
32
        glPopMatrix();
 
33
}
 
34
 
 
35
 
 
36
S3DModelPiece::~S3DModelPiece()
 
37
{
 
38
        glDeleteLists(displist, 1);
 
39
        delete colvol;
 
40
}
 
41
 
 
42
 
 
43
/******************************************************************************/
 
44
/******************************************************************************/
 
45
//
 
46
//  LocalModel
 
47
//
 
48
 
 
49
LocalModel::~LocalModel()
 
50
{
 
51
        // delete the local piece copies
 
52
        for (std::vector<LocalModelPiece*>::iterator pi = pieces.begin(); pi != pieces.end(); pi++) {
 
53
                delete (*pi)->colvol;
 
54
                delete (*pi);
 
55
        }
 
56
        pieces.clear();
 
57
}
 
58
 
 
59
 
 
60
void LocalModel::SetLODCount(unsigned int count)
 
61
{
 
62
        lodCount = count;
 
63
        pieces[0]->SetLODCount(count);
 
64
}
 
65
 
 
66
 
 
67
void LocalModel::ApplyRawPieceTransform(int piecenum) const
 
68
{
 
69
        pieces[piecenum]->ApplyTransform();
 
70
}
 
71
 
 
72
 
 
73
float3 LocalModel::GetRawPiecePos(int piecenum) const
 
74
{
 
75
        return pieces[piecenum]->GetPos();
 
76
}
 
77
 
 
78
 
 
79
CMatrix44f LocalModel::GetRawPieceMatrix(int piecenum) const
 
80
{
 
81
        return pieces[piecenum]->GetMatrix();
 
82
}
 
83
 
 
84
 
 
85
 
 
86
 
 
87
void LocalModel::GetRawEmitDirPos(int piecenum, float3 &pos, float3 &dir) const
 
88
{
 
89
        pieces[piecenum]->GetEmitDirPos(pos, dir);
 
90
}
 
91
 
 
92
 
 
93
//Only useful for special pieces used for emit-sfx
 
94
float3 LocalModel::GetRawPieceDirection(int piecenum) const
 
95
{
 
96
        return pieces[piecenum]->GetDirection();
 
97
}
 
98
 
 
99
 
 
100
/******************************************************************************/
 
101
/******************************************************************************/
 
102
//
 
103
//  LocalModelPiece
 
104
//
 
105
 
 
106
static const float RADTOANG  = 180 / PI;
 
107
 
 
108
void LocalModelPiece::Draw() const
 
109
{
 
110
        if (!visible && childs.size()==0)
 
111
                return;
 
112
 
 
113
        glPushMatrix();
 
114
 
 
115
        if (pos.x || pos.y || pos.z) { glTranslatef(pos.x, pos.y, pos.z); }
 
116
        if (rot[1]) { glRotatef(rot[1] * RADTOANG, 0.0f, 1.0f, 0.0f); }
 
117
        if (rot[0]) { glRotatef(rot[0] * RADTOANG, 1.0f, 0.0f, 0.0f); }
 
118
        if (rot[2]) { glRotatef(rot[2] * RADTOANG, 0.0f, 0.0f, 1.0f); }
 
119
 
 
120
        if (visible)
 
121
                glCallList(displist);
 
122
 
 
123
        for (unsigned int i = 0; i < childs.size(); i++) {
 
124
                childs[i]->Draw();
 
125
        }
 
126
 
 
127
        glPopMatrix();
 
128
}
 
129
 
 
130
 
 
131
void LocalModelPiece::DrawLOD(unsigned int lod) const
 
132
{
 
133
        if (!visible && childs.size()==0)
 
134
                return;
 
135
 
 
136
        glPushMatrix();
 
137
 
 
138
        if (pos.x || pos.y || pos.z) { glTranslatef(pos.x, pos.y, pos.z); }
 
139
        if (rot[1]) { glRotatef(rot[1] * RADTOANG, 0.0f, 1.0f, 0.0f); }
 
140
        if (rot[0]) { glRotatef(rot[0] * RADTOANG, 1.0f, 0.0f, 0.0f); }
 
141
        if (rot[2]) { glRotatef(rot[2] * RADTOANG, 0.0f, 0.0f, 1.0f); }
 
142
 
 
143
        if (visible)
 
144
                glCallList(lodDispLists[lod]);
 
145
 
 
146
        for (unsigned int i = 0; i < childs.size(); i++) {
 
147
                childs[i]->DrawLOD(lod);
 
148
        }
 
149
 
 
150
        glPopMatrix();
 
151
}
 
152
 
 
153
 
 
154
void LocalModelPiece::ApplyTransform() const
 
155
{
 
156
        if (parent) {
 
157
                parent->ApplyTransform();
 
158
        }
 
159
 
 
160
        if (pos.x || pos.y || pos.z) { glTranslatef(pos.x, pos.y, pos.z); }
 
161
        if (rot[1]) { glRotatef(rot[1] * RADTOANG, 0.0f, 1.0f, 0.0f); }
 
162
        if (rot[0]) { glRotatef(rot[0] * RADTOANG, 1.0f, 0.0f, 0.0f); }
 
163
        if (rot[2]) { glRotatef(rot[2] * RADTOANG, 0.0f, 0.0f, 1.0f); }
 
164
}
 
165
 
 
166
 
 
167
void LocalModelPiece::GetPiecePosIter(CMatrix44f* mat) const
 
168
{
 
169
        if (parent) {
 
170
                parent->GetPiecePosIter(mat);
 
171
        }
 
172
 
 
173
        if (pos.x || pos.y || pos.z) { mat->Translate(pos.x, pos.y, pos.z); }
 
174
        if (rot[1]) { mat->RotateY(-rot[1]); }
 
175
        if (rot[0]) { mat->RotateX(-rot[0]); }
 
176
        if (rot[2]) { mat->RotateZ(-rot[2]); }
 
177
}
 
178
 
 
179
 
 
180
void LocalModelPiece::SetLODCount(unsigned int count)
 
181
{
 
182
        const unsigned int oldCount = lodDispLists.size();
 
183
 
 
184
        lodDispLists.resize(count);
 
185
        for (unsigned int i = oldCount; i < count; i++) {
 
186
                lodDispLists[i] = 0;
 
187
        }
 
188
 
 
189
        for (unsigned int i = 0; i < childs.size(); i++) {
 
190
                childs[i]->SetLODCount(count);
 
191
        }
 
192
}
 
193
 
 
194
 
 
195
#if defined(USE_GML) && defined(__GNUC__) && (__GNUC__ == 4)
 
196
// This is supposed to fix some GCC crashbug related to threading
 
197
// The MOVAPS SSE instruction is otherwise getting misaligned data
 
198
__attribute__ ((force_align_arg_pointer))
 
199
#endif
 
200
float3 LocalModelPiece::GetPos() const
 
201
{
 
202
        CMatrix44f mat;
 
203
        GetPiecePosIter(&mat);
 
204
 
 
205
        if (type == MODELTYPE_3DO) {
 
206
                // fix for valkyres
 
207
                const S3DOPiece* p3 = static_cast<S3DOPiece*>(original);
 
208
                if (p3 && (p3->vertices.size() == 2)) {
 
209
                        const std::vector<S3DOVertex>& pv = p3->vertices;
 
210
                        if (pv[0].pos.y > pv[1].pos.y) {
 
211
                                mat.Translate(pv[0].pos.x, pv[0].pos.y, -pv[0].pos.z);
 
212
                        } else {
 
213
                                mat.Translate(pv[1].pos.x, pv[1].pos.y, -pv[1].pos.z);
 
214
                        }
 
215
                }
 
216
        }
 
217
 
 
218
        // we use a 'right' vector, and the positive x axis points to the left
 
219
        float3 pos = mat.GetPos();
 
220
        pos.x = -pos.x;
 
221
        return pos;
 
222
}
 
223
 
 
224
 
 
225
CMatrix44f LocalModelPiece::GetMatrix() const
 
226
{
 
227
        CMatrix44f mat;
 
228
        GetPiecePosIter(&mat);
 
229
 
 
230
        return mat;
 
231
}
 
232
 
 
233
 
 
234
float3 LocalModelPiece::GetDirection() const
 
235
{
 
236
        const S3DModelPiece* piece = original;
 
237
        const unsigned int count = piece->GetVertexCount();
 
238
        if (count < 2) {
 
239
                return float3(1.0f, 1.0f, 1.0f);
 
240
        }
 
241
        return (piece->GetVertexPos(0) - piece->GetVertexPos(1));
 
242
}
 
243
 
 
244
 
 
245
bool LocalModelPiece::GetEmitDirPos(float3 &pos, float3 &dir) const
 
246
{
 
247
        CMatrix44f mat;
 
248
        GetPiecePosIter(&mat);
 
249
 
 
250
        const S3DModelPiece* piece = original;
 
251
 
 
252
        if (piece == NULL)
 
253
                return false;
 
254
 
 
255
        const unsigned int count = piece->GetVertexCount();
 
256
 
 
257
        if (count == 0) {
 
258
                pos = mat.GetPos();
 
259
                dir = mat.Mul(float3(0.0f, 0.0f, 1.0f)) - pos;
 
260
        } else if (count == 1) {
 
261
                pos = mat.GetPos();
 
262
                dir = mat.Mul(piece->GetVertexPos(0)) - pos;
 
263
        } else if (count >= 2) {
 
264
                float3 p1 = mat.Mul(piece->GetVertexPos(0));
 
265
                float3 p2 = mat.Mul(piece->GetVertexPos(1));
 
266
 
 
267
                pos = p1;
 
268
                dir = p2 - p1;
 
269
        } else {
 
270
                return false;
 
271
        }
 
272
 
 
273
        // we use a 'right' vector, and the positive x axis points to the left
 
274
        pos.x = -pos.x;
 
275
        dir.x = -dir.x;
 
276
 
 
277
        return true;
 
278
}
 
279
 
 
280
/******************************************************************************/
 
281
/******************************************************************************/