3
*************************************************************************
5
ArmageTron -- Just another Tron Lightcycle Game in 3D.
6
Copyright (C) 2000 Manuel Moos (manuel@moosnet.de)
8
**************************************************************************
10
This program is free software; you can redistribute it and/or
11
modify it under the terms of the GNU General Public License
12
as published by the Free Software Foundation; either version 2
13
of the License, or (at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
***************************************************************************
34
#include "tDirectories.h"
35
#include "tConfiguration.h"
40
static rModel *sr_ModelAnchor;
42
static tConfItem<bool> mod_udl("USE_DISPLAYLISTS", sr_useDisplayLists);
46
void Vec3::RenderVertex(){
47
glVertex3f(x[0],x[1],x[2]);
50
void Vec3::RenderNormal(){
51
glNormal3f(x[0],x[1],x[2]);
55
void rModel::Load(std::istream &in,const char *fileName){
58
bool calc_normals=true;
60
if (strstr(fileName,".mod")){ // old loader
61
REAL xmax=-1E+32f, xmin=1E+32f;
62
REAL zmax=-1E+32f, zmin=1E+32f;
64
while (in && !in.eof()){
74
in >> num >> x >> y >> z;
85
vertices[num]=Vec3(x,y,z);
86
normals[num]=Vec3(0,0,0);
91
modelFaces[modelFaces.Len()]=rModelFace(A,B,C);
100
for (i = vertices.Len()-1; i>=0; i--)
102
Vec3 &v = vertices[i];
103
texVert[i] = Vec3((v.x[0]-xmin)/(xmax-xmin), (zmax-v.x[2])/(zmax-zmin), 0);
105
for (i = modelFaces.Len()-1; i>=0; i--)
107
modelTexFaces[i] = modelFaces[i];
111
else{ // new 3DSMax loader
113
int current_vertex=0; //
115
#define MAXVERT 10000
117
int translate[MAXVERT];
119
enum {VERTICES,FACES} status=VERTICES;
123
while(in && !in.eof()){
129
if (!strcmp(word,"MESH_TVERT")){
132
in >> n >> x >> y >> z;
133
texVert[n]=Vec3(x,1-y,z);
136
if (!strcmp(word,"MESH_TFACE")){
139
in >> n >> a >> b >> c;
140
modelTexFaces[n]=rModelFace(a,b,c);
143
if (!strcmp(word,"MESH_VERTEX")){
146
offset+=current_vertex+1;
150
in >> current_vertex >> vec[0] >> vec[1] >> vec[2];
151
int realvert=current_vertex+offset;
153
translate[realvert]=-1;
155
for(int i=realvert-1;i>0;i--){
157
for(int j=2;j>=0;j--)
158
dist+= (vec[j]-vertices[i].x[j])*(vec[j]-vertices[i].x[j]);
160
translate[realvert]=i;
163
if (translate[realvert]<0){
164
translate[realvert]=my_vert;
165
//std::cerr << "v " << my_vert;
166
for(int i=0;i<3;i++){
167
//std::cerr << '\t' << vec[i]*.025; // change inch to meters
168
vertices[my_vert].x[i]=vec[i]*.025;
174
if (!strcmp(word,"MESH_FACE")){
180
int face=modelFaces.Len();
182
if (strcmp(word,"A:")){
183
std::cerr << "wrong face format: expected A:, got " << word << '\n';
188
modelFaces[face].A[0]=translate[n+offset];
189
//std::cerr << '\t' << translate[n+offset];
192
if (strcmp(word,"B:")){
193
std::cerr << "wrong face format: expected B:, got " << word << '\n';
197
modelFaces[face].A[1]=translate[n+offset];
198
// std::cerr << '\t' << translate[n+offset];
201
if (strcmp(word,"C:")){
202
std::cerr << "wrong face format: expected C:, got " << word << '\n';
206
modelFaces[face].A[2]=translate[n+offset];
207
// std::cerr << '\t' << translate[n+offset];
209
// std::cerr << '\n';
219
for(int i=modelFaces.Len()-1;i>=0;i--){
220
Vec3 &A=vertices(modelFaces[i].A[0]);
221
Vec3 &B=vertices(modelFaces[i].A[1]);
222
Vec3 &C=vertices(modelFaces[i].A[2]);
223
Vec3 X(B.x[0]-A.x[0],B.x[1]-A.x[1],B.x[2]-A.x[2]);
224
Vec3 Y(C.x[0]-A.x[0],C.x[1]-A.x[1],C.x[2]-A.x[2]);
225
Vec3 normal(X.x[1]*Y.x[2]-X.x[2]*Y.x[1],
226
X.x[2]*Y.x[0]-X.x[0]*Y.x[2],
227
X.x[0]*Y.x[1]-X.x[1]*Y.x[0]);
228
normal=normal*(1/normal.Norm());
230
for(int j=2;j>=0;j--)
231
normals[modelFaces[i].A[j]]+=normal;
233
for(int i=normals.Len()-1;i>=0;i--){
234
normals[i]=normals[i]*(1/normals[i].Norm());
240
rModel::rModel(const char *fileName,const char *fileName_alt)
241
:tListItem<rModel>(sr_ModelAnchor), displayList(0)
242
// ,vertices(0),normals(0),modelFaces(0)
251
if ( !tDirectories::Data().Open( in, fileName ) )
255
tDirectories::Data().Open( in2, fileName_alt );
258
tERR_ERROR("\n\nModel file " << fileName_alt << " could not be found.\n" <<
259
"are you sure you are running " << tOutput("$program_name") << " in it's own directory?\n\n");
262
Load(in2,fileName_alt);
265
tERR_ERROR("\n\nModel file " << fileName << " could not be found.\n" <<
266
"are you sure you are running " << tOutput("$program_name") << " in it's own directory?\n\n");
275
void rModel::Render(){
279
glCallList(displayList);
282
if (sr_useDisplayLists)
284
displayList=glGenLists(1);
285
glNewList(displayList,GL_COMPILE_AND_EXECUTE);
288
if (normals.Len()>=vertices.Len()){
289
glNormalPointer(GL_FLOAT,0,&normals[0]);
290
glEnableClientState(GL_NORMAL_ARRAY);
292
glVertexPointer(3,GL_FLOAT,0,&vertices[0]);
293
glEnableClientState(GL_VERTEX_ARRAY);
299
if (modelTexFaces.Len()!=modelFaces.Len())
303
glEnable(GL_CULL_FACE);
306
glBegin(GL_TRIANGLES);
307
for(int i=modelFaces.Len()-1;i>=0;i--){
308
for(int j=0;j<=2;j++){
309
glTexCoord3fv(reinterpret_cast<REAL *>(&(texVert(modelTexFaces(i).A[j]))));
310
glArrayElement(modelFaces(i).A[j]);
317
glDrawElements(GL_TRIANGLES,
323
glDisableClientState(GL_VERTEX_ARRAY);
324
glDisableClientState(GL_NORMAL_ARRAY);
326
glDisable(GL_CULL_FACE);
328
if (sr_useDisplayLists)
338
if (displayList) glDeleteLists(displayList,1);
344
void rModel::UnloadAllDisplayLists()
347
rModel *run = sr_ModelAnchor;
350
if (run->displayList && sr_glOut)
352
glDeleteLists(run->displayList, 1);
353
run->displayList = 0;
361
static rCallbackBeforeScreenModeChange unload(&rModel::UnloadAllDisplayLists);