00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00027 #include "../Include/Globals.h"
00028 #include "../Include/FlyLegacy.h"
00029 #include "../Include/Utility.h"
00030
00031
00032
00033
00034
00035 typedef struct {
00036 float x, y, z;
00037 float nx, ny, nz;
00038 float u, v;
00039 } SVertex;
00040
00041
00042 CModelSMF::CModelSMF (const char* smfFilename)
00043 {
00044 top = new ssgTransform;
00045 top->setName (smfFilename);
00046
00047
00048 PODFILE *p = popen (&globals->pfs, smfFilename);
00049 if (p == NULL) {
00050 gtfo ("CModelSMF : Could not open SMF model %s", smfFilename);
00051 }
00052
00053 GLuint texid = 0;
00054 char texfilename[256];
00055
00056 static const int LINE_LENGTH = 128;
00057 char s[LINE_LENGTH+1];
00058
00059
00060 pgets (s, LINE_LENGTH, p);
00061 if (strncmp (s, "C3DModel", strlen("C3DModel")) != 0) {
00062 globals->logWarning->Write ("CModelSMF : Incorrect object type in %s", smfFilename);
00063 }
00064
00065
00066 pgets (s, LINE_LENGTH, p);
00067
00068
00069 int nParts;
00070 pgets (s, LINE_LENGTH, p);
00071 if (sscanf (s, "%d", &nParts) != 1) {
00072
00073 gtfo ("CModelSMF : Error parsing part cound in %s", smfFilename);
00074 }
00075
00076
00077 int autoDetail;
00078 float detailPixelHeight;
00079 pgets (s, LINE_LENGTH, p);
00080 if (sscanf (s, "%d,%f", &autoDetail, &detailPixelHeight) != 2) {
00081
00082 gtfo ("CModelSMF : Invalid auto detail data in %s", smfFilename);
00083 }
00084
00085
00086 for (int i=0; i<nParts; i++) {
00087
00088 char name[LINE_LENGTH];
00089 pgets (s, LINE_LENGTH, p);
00090 char *q = s + strlen(s) - 1;
00091 while (isspace(*q)) q--;
00092 q++;
00093 *q = '\0';
00094 strcpy (name, s);
00095
00096
00097 pgets (s, LINE_LENGTH, p);
00098
00099
00100 pgets (s, LINE_LENGTH, p);
00101
00102
00103 int nVerts, nFrames, nFaces, dummy;
00104 pgets (s, LINE_LENGTH, p);
00105 if (sscanf (s, "%d,%d,%d,%d", &nVerts, &nFrames, &nFaces, &dummy) != 4) {
00106
00107 gtfo ("CModelSMF : Error parsing vertex and face counts in %s", smfFilename);
00108 }
00109
00110
00111 bool v1flag = false;
00112 pgets (s, LINE_LENGTH, p);
00113 if (strncmp (s, "v1", 2) == 0) {
00114
00115 v1flag = true;
00116
00117 pgets (s, LINE_LENGTH, p);
00118 }
00119
00120
00121
00122 int diffuse, specular, specpower, transparent, envmap;
00123 char texturename[LINE_LENGTH];
00124 if (sscanf (s, "%d,%d,%d,%d,%d,%s",
00125 &diffuse, &specular, &specpower, &transparent, &envmap, texturename) != 6) {
00126
00127 gtfo ("CModelSMF : Error parsing material parameters for part %d in %s",
00128 i, smfFilename) ;
00129 }
00130
00131
00132 if (texid == 0) {
00133
00134 strcpy (texfilename, texturename);
00135 char texfullname[256];
00136 strcpy (texfullname, "Art\\");
00137 strcat (texfullname, texfilename);
00138
00139
00140 char *p = strrchr (texturename, '.');
00141 if (p) {
00142
00143 if (stricmp (p, ".RAW") == 0) {
00144 CRawImage *raw = new CRawImage (texfullname);
00145 texid = raw->GetTexture (true);
00146 delete raw;
00147 } else if (stricmp (p, ".TIF") == 0) {
00148 CImageTIFF *tif = new CImageTIFF (texfullname);
00149 texid = tif->CreateTexture (true);
00150 delete tif;
00151 } else {
00152 gtfo ("SModelSMF : Unsupported texture %s in %s", texturename, smfFilename);
00153 }
00154 } else {
00155 gtfo ("SModelSMF : Invalid texture filename %s in %s",
00156 texturename, smfFilename);
00157 }
00158 } else {
00159
00160 if (strcmp (texfilename, texturename) != 0) {
00161 globals->logWarning->Write ("CModelSMF : More than one texture filename at part %d in %s",
00162 i, smfFilename);
00163 }
00164 }
00165
00166
00167 ssgSimpleState *state = new ssgSimpleState ();
00168
00169 sgVec4 spec = { 0.0f, 0.0f, 0.0f, 1.0f };
00170 sgVec4 emis = { 0.0f, 0.0f, 0.0f, 1.0f } ;
00171 float shi = { 0.0f } ;
00172
00173 state->setMaterial ( GL_SPECULAR, spec ) ;
00174 state->setMaterial ( GL_EMISSION, emis ) ;
00175 state->setShininess ( shi ) ;
00176 state->enable ( GL_COLOR_MATERIAL ) ;
00177 state->setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ;
00178 state->enable ( GL_LIGHTING ) ;
00179 state->setShadeModel ( GL_SMOOTH ) ;
00180
00181 if (texid != 0) {
00182
00183 state->enable (GL_TEXTURE_2D);
00184 state->setTexture (texid);
00185
00186
00187 if (transparent) {
00188 state->enable ( GL_BLEND ) ;
00189 state->enable (GL_ALPHA_TEST);
00190 state->setTranslucent();
00191 } else {
00192 state->disable ( GL_BLEND ) ;
00193 state->disable (GL_ALPHA_TEST);
00194 state->setOpaque();
00195 }
00196 } else {
00197 state->disable (GL_TEXTURE_2D);
00198 state->disable ( GL_BLEND ) ;
00199 }
00200
00201
00202
00203 if (v1flag) {
00204 pgets (s, LINE_LENGTH, p);
00205 }
00206
00207
00208
00209 SVertex *vt = new SVertex[nVerts];
00210
00211
00212 for (int j=0; j<nVerts; j++) {
00213
00214 float x, y, z, nx, ny, nz, u, v;
00215 pgets (s, LINE_LENGTH, p);
00216 if (sscanf (s, "%f,%f,%f,%f,%f,%f,%f,%f",
00217 &x, &y, &z, &nx, &ny, &nz, &u, &v) != 8) {
00218
00219 gtfo ("CModelSMF : Error parsing vertex %d for part %d in %s",
00220 j, i, smfFilename) ;
00221 }
00222
00223
00224 SVertex *pNext = &vt[j];
00225 pNext->x = x;
00226 pNext->y = z;
00227 pNext->z = y;
00228 pNext->nx = nx;
00229 pNext->ny = nz;
00230 pNext->nz = ny;
00231 pNext->u = u;
00232 pNext->v = v;
00233
00234 }
00235
00236
00237
00238 ssgVertexArray *va = new ssgVertexArray(nFaces*3);
00239 ssgNormalArray *na = new ssgNormalArray(nFaces*3);
00240 ssgTexCoordArray *tca = new ssgTexCoordArray(nFaces*3);
00241
00242
00243 for (int k=0; k<nFaces; k++) {
00244
00245 int i1, i2, i3;
00246 pgets (s, LINE_LENGTH, p);
00247 if (sscanf (s, "%d,%d,%d",
00248 &i1, &i2, &i3) != 3)
00249 {
00250
00251 gtfo ("CModelSMF : Error parsing face %d for part %d in %s",
00252 k, i, smfFilename);
00253 }
00254
00255
00256
00257
00258
00259
00260 sgVec3 v1, v2, v3;
00261 sgSetVec3 (v1, vt[i1].x, vt[i1].y, vt[i1].z);
00262 sgSetVec3 (v2, vt[i2].x, vt[i2].y, vt[i2].z);
00263 sgSetVec3 (v3, vt[i3].x, vt[i3].y, vt[i3].z);
00264 va->add (v3);
00265 va->add (v2);
00266 va->add (v1);
00267
00268
00269 sgVec3 n1, n2, n3;
00270 sgSetVec3 (n1, vt[i1].nx, vt[i1].ny, vt[i1].nz);
00271 sgSetVec3 (n2, vt[i2].nx, vt[i2].ny, vt[i2].nz);
00272 sgSetVec3 (n3, vt[i3].nx, vt[i3].ny, vt[i3].nz);
00273 na->add (n3);
00274 na->add (n2);
00275 na->add (n1);
00276
00277
00278 sgVec2 tc1, tc2, tc3;
00279 sgSetVec2 (tc1, vt[i1].u, vt[i1].v);
00280 sgSetVec2 (tc2, vt[i2].u, vt[i2].v);
00281 sgSetVec2 (tc3, vt[i3].u, vt[i3].v);
00282 tca->add (tc3);
00283 tca->add (tc2);
00284 tca->add (tc1);
00285 }
00286
00287
00288 delete vt;
00289
00290
00291 ssgVtxTable *vtab = new ssgVtxTable (GL_TRIANGLES, va, na, tca, NULL);
00292 vtab->setName (name);
00293 vtab->setState (state);
00294
00295
00296 if ((strcmp (name, "OPAQUE") == 0) ||
00297 (strcmp (name, "TRANSP") == 0) ||
00298 (nParts == 1))
00299 {
00300
00301 top->addKid (vtab);
00302 } else {
00303
00304
00305 delete vtab;
00306 }
00307 }
00308
00309
00310 pclose (p);
00311
00312
00313 sgMat4 T;
00314 sgMakeIdentMat4 (T);
00315 top->setTransform (T);
00316 }
00317
00318 CModelSMF::~CModelSMF (void)
00319 {
00320 if (top->getRef() == 0) {
00321 top->removeAllKids();
00322 delete top;
00323 }
00324 }
00325
00326 ssgEntity *CModelSMF::GetSSGEntity()
00327 {
00328 return top;
00329 }
00330