New files, 3DS import demo from Bertrand.
authormtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 10 Jul 2007 10:22:46 +0000 (10:22 +0000)
committermtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 10 Jul 2007 10:22:46 +0000 (10:22 +0000)
EVE/test-macros/nasashuttle.3ds [new file with mode: 0644]
EVE/test-macros/view3ds.C [new file with mode: 0644]

diff --git a/EVE/test-macros/nasashuttle.3ds b/EVE/test-macros/nasashuttle.3ds
new file mode 100644 (file)
index 0000000..5f712ba
Binary files /dev/null and b/EVE/test-macros/nasashuttle.3ds differ
diff --git a/EVE/test-macros/view3ds.C b/EVE/test-macros/view3ds.C
new file mode 100644 (file)
index 0000000..a47f3d8
--- /dev/null
@@ -0,0 +1,577 @@
+#include "TCanvas.h"
+#include "TStyle.h"
+#include "TFile.h"
+#include "TStopwatch.h"
+#include "TError.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+namespace Reve {
+   class TriangleSet;
+}
+Reve::TriangleSet *ts[2048];
+
+// Believe3D Model file defines
+#define MAGICNUMBER 0xB3D0
+
+// types of 3DS Chunks
+#define CHUNKMAIN                   0x4D4D
+#define CHUNKMAINVERSION            0x0002
+#define CHUNK3D                     0x3D3D
+#define CHUNK3DVERSION              0x3D3E
+#define CHUNK3DOBJECT               0x4000
+#define CHUNK3DOBJECTMESH           0x4100
+#define CHUNK3DOBJECTMESHVERTICES   0x4110
+#define CHUNK3DOBJECTMESHFACES      0x4120
+#define CHUNK3DOBJECTMESHMATGROUP   0x4130
+#define CHUNK3DOBJECTMESHMAPPING    0x4140
+
+#define CHUNK3DMATERIAL             0xAFFF
+// Sub defines of MATERIAL
+#define MATNAME                     0xA000
+#define MATDIFFUSE                  0xA020
+#define MATSPECULAR                 0xA030
+#define MATTRANSPARENCY             0xA050
+
+#define COLOR_F                     0x0010
+#define COLOR_24                    0x0011
+#define LIN_COLOR_24                0x0012
+#define LIN_COLOR_F                 0x0013
+#define INT_PERCENTAGE              0x0030
+#define FLOAT_PERCENTAGE            0x0031
+
+//////////////////////////////////////
+//The tMaterialInfo Struct
+//////////////////////////////////////
+class Material {
+public:
+   char     name[256];
+   UChar_t  color[3];
+   UShort_t transparency;
+
+   Material() {
+      sprintf(name, "");
+      color[0] = color[1] = color[2] = 0;
+      transparency = 0;
+   }
+   ~Material() { }
+};
+
+
+// Chunk structure
+typedef struct _Chunk {
+   UShort_t idnum;
+   ULong_t  offset, len, endoffset;
+} Chunk;
+
+// vertex structure
+typedef struct _Vertex {
+   Float_t x, y, z;
+   Float_t u, v;
+} Vertex;
+
+// face structure
+typedef struct _Face {
+   ULong_t v1, v2, v3;
+} Face;
+
+// model structure
+class Model {
+public:
+   char     name[256];
+   char     matname[256];
+   Vertex   *vlist;
+   Face     *flist;
+   ULong_t  numverts, numfaces;
+   
+   Model() {  
+      sprintf(name,"");
+      sprintf(matname,"");
+      vlist = 0;
+      flist = 0;
+      numverts = numfaces = 0;
+   }
+   ~Model() { 
+      if (vlist != 0) delete [] vlist;
+      if (flist != 0) delete [] flist;
+   }
+};
+
+// chunk reading routines
+Int_t ReadChunk(FILE*, Chunk*);
+
+// data reading routines
+Int_t ReadMainChunk(FILE*);
+Int_t Read3DChunk(FILE*, ULong_t);
+Int_t ReadObjectChunk(FILE*, ULong_t);
+Int_t ReadMeshChunk(FILE*, ULong_t, char*);
+Int_t ReadVerticesChunk(FILE*);
+Int_t ReadFacesChunk(FILE*);
+Int_t ReadMappingChunk(FILE*);
+Int_t ReadASCIIZ(FILE*, char*);
+Int_t ReadMaterialChunk(FILE *, ULong_t);
+Int_t ReadColor(FILE *, ULong_t);
+Int_t ReadTransparency(FILE *, ULong_t);
+Int_t ReadObjectMaterial(FILE *);
+Int_t ConvertModel();
+
+// global variables
+Int_t nummodels = 0;
+Model model = {"","",0,0,0,0};
+
+Int_t nummaterials = 0;
+Material *material[1024];
+
+//______________________________________________________________________________
+Int_t Read3DSFile(const char *fname)
+{
+   // main function
+
+   FILE *infile;
+
+   infile = fopen(fname, "rb");
+   if (infile == 0) {
+      printf("Error : Input File Could Not Be Opened!\n");
+      return -1;
+   }
+   UShort_t magic = MAGICNUMBER;
+   if (ReadMainChunk(infile) != 0) {
+      printf("Error : Input File Could Not Be Read!\n");
+   }
+   fclose(infile);
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadChunk(FILE *f, Chunk *c)
+{
+   // reads a chunk from an opened file
+
+   if (feof(f)) return(-1);
+   c->idnum = 0;
+   c->offset = c->len = 0;
+   c->offset = (ULong_t) ftell(f);
+   fread(&c->idnum, sizeof(UShort_t), 1, f);
+   fread(&c->len, sizeof(ULong_t), 1, f);
+   c->endoffset = c->offset + c->len;
+   return(0);
+}
+
+//______________________________________________________________________________
+Int_t ReadMainChunk(FILE *f)
+{
+   // handles the main body of the 3DS file
+
+   Chunk chunk;
+
+   ReadChunk(f, &chunk);
+   if (chunk.idnum != CHUNKMAIN) return(-1);
+   while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
+      if (chunk.idnum == CHUNK3D) {
+         Read3DChunk(f, chunk.endoffset);
+      }
+      else {
+         //printf("Debug : Unknown Chunk [Main Chunk] [0x%x]\n", chunk.idnum);
+         fseek(f, chunk.offset + chunk.len, SEEK_SET);
+      }
+   }
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t Read3DChunk(FILE *f, ULong_t len)
+{
+   // reads the 3D Edit Chunk
+
+   Chunk chunk;
+
+   while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
+      if (chunk.idnum == CHUNK3DOBJECT) {
+         ReadObjectChunk(f, chunk.endoffset);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else if (chunk.idnum == CHUNK3DMATERIAL) {
+         ReadMaterialChunk(f, chunk.endoffset);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else {
+         if (chunk.endoffset < len) {
+            //printf("Debug : Unknown Chunk [3D Chunk] [0x%x]\n", chunk.idnum);
+            fseek(f, chunk.endoffset, SEEK_SET);
+         }
+         else {
+            break;
+         }
+      }
+   }
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadMaterialChunk(FILE *f, ULong_t len)
+{
+   // reads the Material sub-chunk of the 3D Edit Chunk
+
+   Chunk chunk;
+   char name[256];
+   char rgb[3];
+   material[nummaterials] = new Material();
+   while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
+      if (chunk.idnum == MATNAME) {
+         ReadASCIIZ(f, name);
+         strcpy(material[nummaterials]->name, name);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else if (chunk.idnum == MATDIFFUSE) {
+         ReadColor(f, chunk.endoffset);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else if (chunk.idnum == MATTRANSPARENCY) {
+         ReadTransparency(f, chunk.endoffset);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else {
+         if (chunk.endoffset < len) {
+            //printf("Debug : Unknown Chunk [Object Chunk] [0x%x]\n", chunk.idnum);
+            fseek(f, chunk.endoffset, SEEK_SET);
+         }
+         else {
+            break;
+         }
+      }
+   }
+   nummaterials++;
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadColor(FILE *f, ULong_t len)
+{
+   // reads the Color property of the Material Chunk
+   
+   Chunk chunk;
+   float fr, fg, fb;
+   int   irgb[3];
+   while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
+      if (chunk.idnum == LIN_COLOR_24) {
+         fread(&material[nummaterials]->color[0], sizeof(UChar_t), 1, f);
+         fread(&material[nummaterials]->color[1], sizeof(UChar_t), 1, f);
+         fread(&material[nummaterials]->color[2], sizeof(UChar_t), 1, f);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else if (chunk.idnum == COLOR_24) {
+         fread(&material[nummaterials]->color[0], sizeof(UChar_t), 1, f);
+         fread(&material[nummaterials]->color[1], sizeof(UChar_t), 1, f);
+         fread(&material[nummaterials]->color[2], sizeof(UChar_t), 1, f);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else if (chunk.idnum == LIN_COLOR_F) {
+         fread(&fr, sizeof(Float_t), 1, f);
+         fread(&fg, sizeof(Float_t), 1, f);
+         fread(&fb, sizeof(Float_t), 1, f);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else if (chunk.idnum == COLOR_F) {
+         fread(&fr, sizeof(Float_t), 1, f);
+         fread(&fg, sizeof(Float_t), 1, f);
+         fread(&fb, sizeof(Float_t), 1, f);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else {
+         if (chunk.endoffset < len) {
+            //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum);
+            fseek(f, chunk.endoffset, SEEK_SET);
+         }
+         else {
+            break;
+         }
+      }
+   }
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadTransparency(FILE *f, ULong_t len)
+{
+   // reads the Transparency property of the Material Chunk
+   
+   Chunk    chunk;
+   char     byte[2];
+   float    ftransp;
+   UShort_t stransp;
+   while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
+      if (chunk.idnum == INT_PERCENTAGE) {
+         fread(&stransp, sizeof(UShort_t), 1, f);
+         material[nummaterials]->transparency = stransp;
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else if (chunk.idnum == FLOAT_PERCENTAGE) {
+         fread(&ftransp, sizeof(float), 1, f);
+         fseek(f, chunk.endoffset, SEEK_SET);
+      }
+      else {
+         if (chunk.endoffset < len) {
+            //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum);
+            fseek(f, chunk.endoffset, SEEK_SET);
+         }
+         else {
+            break;
+         }
+      }
+   }
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadObjectMaterial(FILE *f)
+{
+   // reads the name of material associated to the current Chunk
+
+   ReadASCIIZ(f, model.matname);
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadObjectChunk(FILE *f, ULong_t len)
+{
+   // reads the Object sub-chunk of the 3D Edit Chunk
+
+   Chunk chunk;
+   char name[256];
+   ReadASCIIZ(f, name);
+   while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
+      if (chunk.idnum == CHUNK3DOBJECTMESH) {
+         ReadMeshChunk(f, chunk.endoffset, name);
+      }
+      else {
+         if (chunk.endoffset < len) {
+            //printf("Debug : Unknown Chunk [Object Chunk] [0x%x]\n", chunk.idnum);
+            fseek(f, chunk.endoffset, SEEK_SET);
+         }
+         else {
+            break;
+         }
+      }
+   }
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadMeshChunk(FILE *f, ULong_t len, char *objname)
+{
+   // reads the TriMesh sub-chunk of the Object Chunk
+
+   Int_t i;
+   Chunk chunk;
+   model.vlist = 0;
+   model.flist = 0;
+   model.numverts = model.numfaces = 0;
+   sprintf(model.name, "%s", objname);
+   printf("Reading Mesh : %s\n", objname);
+   while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) {
+      if (chunk.idnum == CHUNK3DOBJECTMESHVERTICES) {
+         ReadVerticesChunk(f);
+      }
+      else if (chunk.idnum == CHUNK3DOBJECTMESHFACES) {
+         ReadFacesChunk(f);
+      }
+      else if (chunk.idnum == CHUNK3DOBJECTMESHMAPPING) {
+         ReadMappingChunk(f);
+      }
+      else if (chunk.idnum == CHUNK3DOBJECTMESHMATGROUP) {
+         ReadObjectMaterial(f);
+      }
+      else {
+         if (chunk.endoffset < len) {
+            //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum);
+            fseek(f, chunk.endoffset, SEEK_SET);
+         }
+         else {
+            break;
+         }
+      }
+   }
+   if (model.numverts != 0 && model.numfaces != 0 &&
+       model.vlist != 0 && model.flist != 0) {
+      ConvertModel();
+   }
+   if (model.vlist != 0) delete [] model.vlist;
+   if (model.flist != 0) delete [] model.flist;
+   model.vlist = 0;
+   model.flist = 0;
+   model.numverts = model.numfaces = 0;
+   sprintf(model.name,"");
+   nummodels++;
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadVerticesChunk(FILE *f)
+{
+   // reads Vertex data of the TriMesh Chunk
+
+   Int_t i;
+   UShort_t numv = 0;
+   Float_t x, y, z;
+
+   fread(&numv, sizeof(UShort_t), 1, f);
+   printf("Reading %i Vertices...", numv);
+   model.vlist = new Vertex[numv];
+   if (model.vlist == 0) {
+      for (i = 0; i < numv; i++) {
+         fread(&x, sizeof(Float_t), 1, f);
+         fread(&y, sizeof(Float_t), 1, f);
+         fread(&z, sizeof(Float_t), 1, f);
+      }
+      printf("\nWarning : Insufficient Memory to Load Vertices!\n");
+      return -1;
+   }
+   for (i = 0; i < numv; i++) {
+      fread(&model.vlist[i].x, sizeof(Float_t), 1, f);
+      fread(&model.vlist[i].y, sizeof(Float_t), 1, f);
+      fread(&model.vlist[i].z, sizeof(Float_t), 1, f);
+   }
+   model.numverts = (ULong_t) numv;
+   printf("Done!\n");
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadFacesChunk(FILE *f)
+{
+   // reads Face data of the TriMesh Chunk
+
+   Int_t i;
+   UShort_t numf = 0, v1, v2, v3, attr;
+
+   fread(&numf, sizeof(UShort_t), 1, f);
+   printf("Reading %i Faces...", numf);
+   model.flist = new Face[numf];
+   if (model.flist == 0) {
+      for (i = 0; i < numf; i++) {
+         fread(&v1, sizeof(UShort_t), 1, f);
+         fread(&v2, sizeof(UShort_t), 1, f);
+         fread(&v3, sizeof(UShort_t), 1, f);
+         fread(&attr, sizeof(UShort_t), 1, f);
+      }
+      printf("\nWarning : Insufficient Memory to Load Faces!\n");
+      return -1;
+   }
+   for (i = 0; i < numf; i++) {
+      fread(&v1, sizeof(UShort_t), 1, f);
+      fread(&v2, sizeof(UShort_t), 1, f);
+      fread(&v3, sizeof(UShort_t), 1, f);
+      fread(&attr, sizeof(UShort_t), 1, f);
+      model.flist[i].v1 = (ULong_t)(v1);
+      model.flist[i].v2 = (ULong_t)(v2);
+      model.flist[i].v3 = (ULong_t)(v3);
+   }
+   model.numfaces = (ULong_t)(numf);
+   printf("Done!\n");
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadMappingChunk(FILE *f)
+{
+   // reads Texture Mapping data of the TriMesh Chunk
+
+   UShort_t numuv = 0, i;
+   Float_t u, v;
+
+   fread(&numuv, sizeof(UShort_t), 1, f);
+   printf("Reading %i Texture Coordinates...", numuv);
+   if (numuv != model.numverts) {
+      for (i = 0; i < numuv; i++) {
+         fread(&u, sizeof(Float_t), 1, f);
+         fread(&v, sizeof(Float_t), 1, f);
+      }
+      printf("\nWarning : Number of Vertices and Mapping Data do not match!\n");
+      return -1;
+   }
+   for (i = 0; i < numuv; i++) {
+      fread(&model.vlist[i].u, sizeof(Float_t), 1, f);
+      fread(&model.vlist[i].v, sizeof(Float_t), 1, f);
+   }
+   printf("Done!\n");
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ReadASCIIZ(FILE *f, char *name)
+{
+   // reads a null-terminated string from the given file
+
+   char c = -1;
+   Int_t index = 0;
+
+   do {
+      fread(&c, sizeof(char), 1, f);
+      name[index] = c;
+      index++;
+      if (index == 255) {
+         name[index] = 0;
+         c = 0;
+      }
+   } while ((c != 0) && (!feof(f)));
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t ConvertModel()
+{
+   // Convert from Model structure to Reve::TriangleSet
+
+   Int_t i;
+
+   ts[nummodels] = new Reve::TriangleSet(model.numverts, model.numfaces);
+   if (ts[nummodels] == 0)
+      return -1;
+   for (i=0; i<model.numverts; ++i) {
+      ts[nummodels]->SetVertex(i, model.vlist[i].x, model.vlist[i].y,
+                               model.vlist[i].z);
+   }
+   for (i=0; i<model.numfaces; ++i) {
+      ts[nummodels]->SetTriangle(i, model.flist[i].v1, model.flist[i].v2,
+                                 model.flist[i].v3);
+   }
+   ts[nummodels]->SetName(model.name);
+   ts[nummodels]->SetTransparency(0);
+   ts[nummodels]->SetColor(0);
+   for (i = 0; i < nummaterials; i++) {
+      if (strcmp(model.matname, material[i]->name) == 0) {
+         ts[nummodels]->SetTransparency(material[i]->transparency);
+         ts[nummodels]->SetColor(Color_t(TColor::GetColor(material[i]->color[0], 
+                                 material[i]->color[1], material[i]->color[2])));
+         break;
+      }
+   }
+   return 0;
+}
+
+//______________________________________________________________________________
+void view3ds(const char *fname = "nasashuttle.3ds") //"eventhorizon.3ds")
+{
+   // main...
+
+   Int_t i;
+   for (i=0;i<2048;i++) ts[i] = 0;
+   for (i=0;i<1024;i++) material[i] = 0;
+   model.vlist = 0;
+   model.flist = 0;
+   nummodels = 0;
+   if (Read3DSFile(fname) == 0) {
+      for (i=0;i<nummodels;i++) {
+         if (ts[i]) {
+            ts[i]->GenerateTriangleNormals();
+            gReve->AddRenderElement(ts[i]);
+         }
+      }
+      gReve->Redraw3D(kTRUE);
+   }
+   for (i = 0; i < nummaterials; i++)
+      if (material[i] != 0) delete material[i];
+}