21 class TEveTriangleSet;
23 TEveTriangleSet *ts[2048];
26 #define MAGICNUMBER 0xB3D0
29 #define CHUNKMAIN 0x4D4D
30 #define CHUNKMAINVERSION 0x0002
31 #define CHUNK3D 0x3D3D
32 #define CHUNK3DVERSION 0x3D3E
33 #define CHUNK3DOBJECT 0x4000
34 #define CHUNK3DOBJECTMESH 0x4100
35 #define CHUNK3DOBJECTMESHVERTICES 0x4110
36 #define CHUNK3DOBJECTMESHFACES 0x4120
37 #define CHUNK3DOBJECTMESHMATGROUP 0x4130
38 #define CHUNK3DOBJECTMESHMAPPING 0x4140
40 #define CHUNK3DMATERIAL 0xAFFF
42 #define MATNAME 0xA000
43 #define MATDIFFUSE 0xA020
44 #define MATSPECULAR 0xA030
45 #define MATTRANSPARENCY 0xA050
47 #define COLOR_F 0x0010
48 #define COLOR_24 0x0011
49 #define LIN_COLOR_24 0x0012
50 #define LIN_COLOR_F 0x0013
51 #define INT_PERCENTAGE 0x0030
52 #define FLOAT_PERCENTAGE 0x0031
61 UShort_t transparency;
65 color[0] = color[1] = color[2] = 0;
73 typedef struct _Chunk {
75 UInt_t offset, len, endoffset;
79 typedef struct _Vertex {
85 typedef struct _Face {
96 UInt_t numverts, numfaces;
103 numverts = numfaces = 0;
106 if (vlist != 0)
delete [] vlist;
107 if (flist != 0)
delete [] flist;
112 Int_t ReadChunk(FILE*, Chunk*);
115 Int_t ReadMainChunk(FILE*);
116 Int_t Read3DChunk(FILE*, UInt_t);
117 Int_t ReadObjectChunk(FILE*, UInt_t);
118 Int_t ReadMeshChunk(FILE*, UInt_t,
char*);
119 Int_t ReadVerticesChunk(FILE*);
120 Int_t ReadFacesChunk(FILE*);
121 Int_t ReadMappingChunk(FILE*);
122 Int_t ReadASCIIZ(FILE*,
char*);
123 Int_t ReadMaterialChunk(FILE *, UInt_t);
124 Int_t ReadColor(FILE *, UInt_t);
125 Int_t ReadTransparency(FILE *, UInt_t);
126 Int_t ReadObjectMaterial(FILE *);
127 Int_t ConvertModel();
133 Int_t nummaterials = 0;
134 Material *material[1024];
137 Int_t Read3DSFile(
const char *fname)
143 infile = fopen(fname,
"rb");
145 printf(
"Error : Input File Could Not Be Opened!\n");
148 UShort_t magic = MAGICNUMBER;
149 if (ReadMainChunk(infile) != 0) {
150 printf(
"Error : Input File Could Not Be Read!\n");
157 Int_t ReadChunk(FILE *f, Chunk *c)
161 if (feof(f))
return(-1);
163 c->offset = c->len = 0;
164 c->offset = (UInt_t) ftell(f);
165 fread(&c->idnum,
sizeof(UShort_t), 1, f);
166 fread(&c->len,
sizeof(UInt_t), 1, f);
167 c->endoffset = c->offset + c->len;
172 Int_t ReadMainChunk(FILE *f)
178 ReadChunk(f, &chunk);
179 if (chunk.idnum != CHUNKMAIN)
return(-1);
180 while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
181 if (chunk.idnum == CHUNK3D) {
182 Read3DChunk(f, chunk.endoffset);
186 fseek(f, chunk.offset + chunk.len, SEEK_SET);
193 Int_t Read3DChunk(FILE *f, UInt_t len)
199 while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
200 if (chunk.idnum == CHUNK3DOBJECT) {
201 ReadObjectChunk(f, chunk.endoffset);
202 fseek(f, chunk.endoffset, SEEK_SET);
204 else if (chunk.idnum == CHUNK3DMATERIAL) {
205 ReadMaterialChunk(f, chunk.endoffset);
206 fseek(f, chunk.endoffset, SEEK_SET);
209 if (chunk.endoffset < len) {
211 fseek(f, chunk.endoffset, SEEK_SET);
222 Int_t ReadMaterialChunk(FILE *f, UInt_t len)
228 material[nummaterials] =
new Material();
229 while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
230 if (chunk.idnum == MATNAME) {
232 strcpy(material[nummaterials]->name, name);
233 fseek(f, chunk.endoffset, SEEK_SET);
235 else if (chunk.idnum == MATDIFFUSE) {
236 ReadColor(f, chunk.endoffset);
237 fseek(f, chunk.endoffset, SEEK_SET);
239 else if (chunk.idnum == MATTRANSPARENCY) {
240 ReadTransparency(f, chunk.endoffset);
241 fseek(f, chunk.endoffset, SEEK_SET);
244 if (chunk.endoffset < len) {
246 fseek(f, chunk.endoffset, SEEK_SET);
258 Int_t ReadColor(FILE *f, UInt_t len)
264 while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
265 if (chunk.idnum == LIN_COLOR_24) {
266 fread(&material[nummaterials]->color[0],
sizeof(UChar_t), 1, f);
267 fread(&material[nummaterials]->color[1],
sizeof(UChar_t), 1, f);
268 fread(&material[nummaterials]->color[2],
sizeof(UChar_t), 1, f);
269 fseek(f, chunk.endoffset, SEEK_SET);
271 else if (chunk.idnum == COLOR_24) {
272 fread(&material[nummaterials]->color[0],
sizeof(UChar_t), 1, f);
273 fread(&material[nummaterials]->color[1],
sizeof(UChar_t), 1, f);
274 fread(&material[nummaterials]->color[2],
sizeof(UChar_t), 1, f);
275 fseek(f, chunk.endoffset, SEEK_SET);
277 else if (chunk.idnum == LIN_COLOR_F) {
278 fread(&fr,
sizeof(Float_t), 1, f);
279 fread(&fg,
sizeof(Float_t), 1, f);
280 fread(&fb,
sizeof(Float_t), 1, f);
281 fseek(f, chunk.endoffset, SEEK_SET);
283 else if (chunk.idnum == COLOR_F) {
284 fread(&fr,
sizeof(Float_t), 1, f);
285 fread(&fg,
sizeof(Float_t), 1, f);
286 fread(&fb,
sizeof(Float_t), 1, f);
287 fseek(f, chunk.endoffset, SEEK_SET);
290 if (chunk.endoffset < len) {
292 fseek(f, chunk.endoffset, SEEK_SET);
303 Int_t ReadTransparency(FILE *f, UInt_t len)
310 while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
311 if (chunk.idnum == INT_PERCENTAGE) {
312 fread(&stransp,
sizeof(UShort_t), 1, f);
313 material[nummaterials]->transparency = stransp;
314 fseek(f, chunk.endoffset, SEEK_SET);
316 else if (chunk.idnum == FLOAT_PERCENTAGE) {
317 fread(&ftransp,
sizeof(
float), 1, f);
318 fseek(f, chunk.endoffset, SEEK_SET);
321 if (chunk.endoffset < len) {
323 fseek(f, chunk.endoffset, SEEK_SET);
334 Int_t ReadObjectMaterial(FILE *f)
338 ReadASCIIZ(f, model.matname);
343 Int_t ReadObjectChunk(FILE *f, UInt_t len)
350 while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
351 if (chunk.idnum == CHUNK3DOBJECTMESH) {
352 ReadMeshChunk(f, chunk.endoffset, name);
355 if (chunk.endoffset < len) {
357 fseek(f, chunk.endoffset, SEEK_SET);
368 Int_t ReadMeshChunk(FILE *f, UInt_t len,
char *objname)
375 model.numverts = model.numfaces = 0;
376 sprintf(model.name,
"%s", objname);
377 printf(
"Reading Mesh : %s\n", objname);
378 while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
379 if (chunk.idnum == CHUNK3DOBJECTMESHVERTICES) {
380 ReadVerticesChunk(f);
382 else if (chunk.idnum == CHUNK3DOBJECTMESHFACES) {
385 else if (chunk.idnum == CHUNK3DOBJECTMESHMAPPING) {
388 else if (chunk.idnum == CHUNK3DOBJECTMESHMATGROUP) {
389 ReadObjectMaterial(f);
392 if (chunk.endoffset < len) {
394 fseek(f, chunk.endoffset, SEEK_SET);
402 if (model.vlist != 0)
delete [] model.vlist;
403 if (model.flist != 0)
delete [] model.flist;
406 model.numverts = model.numfaces = 0;
407 sprintf(model.name,
"");
413 Int_t ReadVerticesChunk(FILE *f)
421 fread(&numv,
sizeof(UShort_t), 1, f);
422 printf(
"Reading %i Vertices...", numv);
423 model.vlist =
new Vertex[numv];
424 if (model.vlist == 0) {
425 for (i = 0; i < numv; i++) {
426 fread(&x,
sizeof(Float_t), 1, f);
427 fread(&y,
sizeof(Float_t), 1, f);
428 fread(&z,
sizeof(Float_t), 1, f);
430 printf(
"\nWarning : Insufficient Memory to Load Vertices!\n");
433 for (i = 0; i < numv; i++) {
434 fread(&model.vlist[i].x,
sizeof(Float_t), 1, f);
435 fread(&model.vlist[i].y,
sizeof(Float_t), 1, f);
436 fread(&model.vlist[i].z,
sizeof(Float_t), 1, f);
438 model.numverts = (UInt_t) numv;
444 Int_t ReadFacesChunk(FILE *f)
449 UShort_t numf = 0, v1, v2, v3, attr;
451 fread(&numf,
sizeof(UShort_t), 1, f);
452 printf(
"Reading %i Faces...", numf);
453 model.flist =
new Face[numf];
454 if (model.flist == 0) {
455 for (i = 0; i < numf; i++) {
456 fread(&v1,
sizeof(UShort_t), 1, f);
457 fread(&v2,
sizeof(UShort_t), 1, f);
458 fread(&v3,
sizeof(UShort_t), 1, f);
459 fread(&attr,
sizeof(UShort_t), 1, f);
461 printf(
"\nWarning : Insufficient Memory to Load Faces!\n");
464 for (i = 0; i < numf; i++) {
465 fread(&v1,
sizeof(UShort_t), 1, f);
466 fread(&v2,
sizeof(UShort_t), 1, f);
467 fread(&v3,
sizeof(UShort_t), 1, f);
468 fread(&attr,
sizeof(UShort_t), 1, f);
469 model.flist[i].v1 = (UInt_t)(v1);
470 model.flist[i].v2 = (UInt_t)(v2);
471 model.flist[i].v3 = (UInt_t)(v3);
473 model.numfaces = (UInt_t)(numf);
479 Int_t ReadMappingChunk(FILE *f)
483 UShort_t numuv = 0, i;
486 fread(&numuv,
sizeof(UShort_t), 1, f);
487 printf(
"Reading %i Texture Coordinates...", numuv);
488 if (numuv != model.numverts) {
489 for (i = 0; i < numuv; i++) {
490 fread(&u,
sizeof(Float_t), 1, f);
491 fread(&v,
sizeof(Float_t), 1, f);
493 printf(
"\nWarning : Number of Vertices and Mapping Data do not match!\n");
496 for (i = 0; i < numuv; i++) {
497 fread(&model.vlist[i].u,
sizeof(Float_t), 1, f);
498 fread(&model.vlist[i].v,
sizeof(Float_t), 1, f);
505 Int_t ReadASCIIZ(FILE *f,
char *name)
513 fread(&c,
sizeof(
char), 1, f);
520 }
while ((c != 0) && (!feof(f)));
531 ts[nummodels] =
new TEveTriangleSet(model.numverts, model.numfaces);
532 if (ts[nummodels] == 0)
534 for (i=0; i<model.numverts; ++i) {
535 ts[nummodels]->SetVertex(i, model.vlist[i].x, model.vlist[i].y,
538 for (i=0; i<model.numfaces; ++i) {
539 ts[nummodels]->SetTriangle(i, model.flist[i].v1, model.flist[i].v2,
542 ts[nummodels]->SetName(model.name);
543 ts[nummodels]->SetMainTransparency(0);
544 ts[nummodels]->SetMainColor(0);
545 for (i = 0; i < nummaterials; i++) {
546 if (strcmp(model.matname, material[i]->name) == 0) {
547 ts[nummodels]->SetMainTransparency(material[i]->transparency);
548 ts[nummodels]->SetMainColorRGB(material[i]->color[0],
549 material[i]->color[1],
550 material[i]->color[2]);
558 void view3ds(
const char *fname =
"nasashuttle.3ds")
562 TEveManager::Create();
565 for (i=0;i<2048;i++) ts[i] = 0;
566 for (i=0;i<1024;i++) material[i] = 0;
570 if (Read3DSFile(fname) == 0) {
571 TEveTriangleSet* parent =
new TEveTriangleSet(0, 0);
572 parent->SetName(fname);
573 gEve->AddElement(parent);
574 for (i=0;i<nummodels;i++) {
576 ts[i]->GenerateTriangleNormals();
577 ts[i]->RefMainTrans().RotateLF(1, 2, TMath::Pi());
578 parent->AddElement(ts[i]);
581 gEve->Redraw3D(kTRUE);
583 for (i = 0; i < nummaterials; i++)
584 if (material[i] != 0)
delete material[i];