Blender V2.61 - r43446
|
00001 00028 #include "LOD_decimation.h" 00029 #include "ply/ply.h" 00030 #include "MEM_SmartPtr.h" 00031 #include "common/GlutDrawer.h" 00032 #include "GlutMeshDrawer.h" 00033 #include "MyGlutKeyHandler.h" 00034 #include "MyGlutMouseHandler.h" 00035 #include "MT_Vector3.h" 00036 #include "LOD_GhostTestApp.h" 00037 00038 #include <memory> 00039 00040 #define DEBUG_PRINT 0 00041 00042 struct LoadVertex { 00043 float x,y,z; /* the usual 3-space position of a vertex */ 00044 }; 00045 00046 struct LoadFace { 00047 unsigned char intensity; /* this user attaches intensity to faces */ 00048 unsigned char nverts; /* number of vertex indices in list */ 00049 int *verts; /* vertex index list */ 00050 }; 00051 00052 00053 LOD_Decimation_InfoPtr 00054 NewVertsFromFile( 00055 char * file_name, 00056 MT_Vector3 &min, 00057 MT_Vector3 &max 00058 ) { 00059 00060 min = MT_Vector3(MT_INFINITY,MT_INFINITY,MT_INFINITY); 00061 max = MT_Vector3(-MT_INFINITY,-MT_INFINITY,-MT_INFINITY); 00062 00063 00064 PlyProperty vert_props[] = { /* list of property information for a vertex */ 00065 {"x", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,x), 0, 0, 0, 0}, 00066 {"y", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,y), 0, 0, 0, 0}, 00067 {"z", PLY_FLOAT, PLY_FLOAT, offsetof(LoadVertex,z), 0, 0, 0, 0}, 00068 }; 00069 00070 PlyProperty face_props[] = { /* list of property information for a vertex */ 00071 {"intensity", PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,intensity), 0, 0, 0, 0}, 00072 {"vertex_indices", PLY_INT, PLY_INT, offsetof(LoadFace,verts), 00073 1, PLY_UCHAR, PLY_UCHAR, offsetof(LoadFace,nverts)}, 00074 }; 00075 #if 0 00076 MEM_SmartPtr<std::vector<float> > verts = new std::vector<float>; 00077 MEM_SmartPtr<std::vector<float> > vertex_normals = new std::vector<float>; 00078 00079 MEM_SmartPtr<std::vector<int> > faces = new std::vector<int>; 00080 #else 00081 std::vector<float>* verts = new std::vector<float>; 00082 std::vector<float>* vertex_normals = new std::vector<float>; 00083 00084 std::vector<int> * faces = new std::vector<int>; 00085 #endif 00086 00087 int i,j; 00088 PlyFile *ply; 00089 int nelems; 00090 char **elist; 00091 int file_type; 00092 float version; 00093 int nprops; 00094 int num_elems; 00095 PlyProperty **plist; 00096 00097 char *elem_name; 00098 00099 LoadVertex load_vertex; 00100 LoadFace load_face; 00101 00102 /* open a PLY file for reading */ 00103 ply = ply_open_for_reading(file_name, &nelems, &elist, &file_type, &version); 00104 00105 if (ply == NULL) return NULL; 00106 /* go through each kind of element that we learned is in the file */ 00107 /* and read them */ 00108 00109 for (i = 0; i < nelems; i++) { 00110 00111 /* get the description of the first element */ 00112 00113 elem_name = elist[i]; 00114 plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops); 00115 00116 /* print the name of the element, for debugging */ 00117 00118 /* if we're on vertex elements, read them in */ 00119 if (equal_strings ("vertex", elem_name)) { 00120 00121 /* set up for getting vertex elements */ 00122 00123 ply_get_property (ply, elem_name, &vert_props[0]); 00124 ply_get_property (ply, elem_name, &vert_props[1]); 00125 ply_get_property (ply, elem_name, &vert_props[2]); 00126 00127 // make some memory for the vertices 00128 verts->reserve(num_elems); 00129 00130 /* grab all the vertex elements */ 00131 for (j = 0; j < num_elems; j++) { 00132 00133 /* grab and element from the file */ 00134 ply_get_element (ply, (void *)&load_vertex); 00135 // pass the vertex into the mesh builder. 00136 00137 00138 if (load_vertex.x < min.x()) { 00139 min.x() = load_vertex.x; 00140 } else 00141 if (load_vertex.x > max.x()) { 00142 max.x()= load_vertex.x; 00143 } 00144 00145 if (load_vertex.y < min.y()) { 00146 min.y() = load_vertex.y; 00147 } else 00148 if (load_vertex.y > max.y()) { 00149 max.y()= load_vertex.y; 00150 } 00151 00152 if (load_vertex.z < min.z()) { 00153 min.z() = load_vertex.z; 00154 } else 00155 if (load_vertex.z > max.z()) { 00156 max.z()= load_vertex.z; 00157 } 00158 00159 verts->push_back(load_vertex.x); 00160 verts->push_back(load_vertex.y); 00161 verts->push_back(load_vertex.z); 00162 00163 vertex_normals->push_back(1.0f); 00164 vertex_normals->push_back(0.0f); 00165 vertex_normals->push_back(0.0f); 00166 00167 00168 } 00169 } 00170 00171 /* if we're on face elements, read them in */ 00172 if (equal_strings ("face", elem_name)) { 00173 00174 /* set up for getting face elements */ 00175 00176 // ply_get_property (ply, elem_name, &face_props[0]); 00177 ply_get_property (ply, elem_name, &face_props[1]); 00178 00179 /* grab all the face elements */ 00180 for (j = 0; j < num_elems; j++) { 00181 00182 ply_get_element (ply, (void *)&load_face); 00183 00184 faces->push_back(load_face.verts[0]); 00185 faces->push_back(load_face.verts[1]); 00186 faces->push_back(load_face.verts[2]); 00187 00188 // free up the memory this pile of shit used to allocate the polygon's vertices 00189 00190 free (load_face.verts); 00191 } 00192 00193 } 00194 } 00195 /* close the PLY file */ 00196 ply_close (ply); 00197 00198 LOD_Decimation_InfoPtr output = new LOD_Decimation_Info; 00199 00200 output->vertex_buffer = verts->begin(); 00201 output->vertex_num = verts->size()/3; 00202 00203 output->triangle_index_buffer = faces->begin(); 00204 output->face_num = faces->size()/3; 00205 output->intern = NULL; 00206 output->vertex_normal_buffer = vertex_normals->begin(); 00207 00208 // memory leaks 'r' us 00209 #if 0 00210 verts.Release(); 00211 vertex_normals.Release(); 00212 faces.Release(); 00213 #endif 00214 return output; 00215 } 00216 00217 00218 void 00219 init(MT_Vector3 min,MT_Vector3 max) 00220 { 00221 00222 GLfloat light_diffuse0[] = {1.0, 0.0, 0.0, 0.5}; /* Red diffuse light. */ 00223 GLfloat light_position0[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */ 00224 00225 GLfloat light_diffuse1[] = {1.0, 1.0, 1.0, 0.5}; /* Red diffuse light. */ 00226 GLfloat light_position1[] = {1.0, 0, 0, 0.0}; /* Infinite light location. */ 00227 00228 /* Enable a single OpenGL light. */ 00229 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0); 00230 glLightfv(GL_LIGHT0, GL_POSITION, light_position0); 00231 00232 glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1); 00233 glLightfv(GL_LIGHT1, GL_POSITION, light_position1); 00234 00235 glEnable(GL_LIGHT0); 00236 // glEnable(GL_LIGHT1); 00237 glEnable(GL_LIGHTING); 00238 00239 // use two sided lighting model 00240 00241 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); 00242 00243 /* Use depth buffering for hidden surface elimination. */ 00244 glEnable(GL_DEPTH_TEST); 00245 00246 /* Setup the view of the cube. */ 00247 glMatrixMode(GL_PROJECTION); 00248 00249 // center of the box + 3* depth of box 00250 00251 MT_Vector3 center = (min + max) * 0.5; 00252 MT_Vector3 diag = max - min; 00253 00254 float depth = diag.length(); 00255 float distance = 2; 00256 00257 gluPerspective( 00258 /* field of view in degree */ 40.0, 00259 /* aspect ratio */ 1.0, 00260 /* Z near */ 1.0, 00261 /* Z far */ distance * depth * 2 00262 ); 00263 glMatrixMode(GL_MODELVIEW); 00264 00265 00266 gluLookAt( 00267 center.x(), center.y(), center.z() + distance*depth, /* eye is at (0,0,5) */ 00268 center.x(), center.y(), center.z(), /* center is at (0,0,0) */ 00269 0.0, 1.0, 0.); /* up is in positive Y direction */ 00270 00271 glPushMatrix(); 00272 00273 00274 } 00275 00276 int 00277 main(int argc, char **argv) 00278 { 00279 00280 // load in the mesh 00281 00282 MT_Vector3 mesh_min,mesh_max; 00283 00284 LOD_Decimation_InfoPtr LOD_info = NewVertsFromFile("beethoven.ply",mesh_min,mesh_max); 00285 00286 // load the mesh data 00287 00288 int load_result = LOD_LoadMesh(LOD_info); 00289 int preprocess_result = LOD_PreprocessMesh(LOD_info); 00290 00291 if (!(load_result && preprocess_result)) { 00292 cout << " could not load mesh! \n"; 00293 return 0; 00294 } 00295 00296 // make and install a mouse handler 00297 00298 MEM_SmartPtr<MyGlutMouseHandler> mouse_handler(MyGlutMouseHandler::New()); 00299 GlutMouseManager::Instance()->InstallHandler(mouse_handler); 00300 00301 // instantiate the drawing class 00302 00303 MEM_SmartPtr<GlutMeshDrawer> drawer(GlutMeshDrawer::New()); 00304 GlutDrawManager::Instance()->InstallDrawer(drawer); 00305 drawer->SetLODInfo(LOD_info); 00306 drawer->SetMouseHandler(mouse_handler); 00307 00308 // make and install a keyhandler 00309 00310 MEM_SmartPtr<MyGlutKeyHandler> key_handler(MyGlutKeyHandler::New(LOD_info)); 00311 GlutKeyboardManager::Instance()->InstallHandler(key_handler); 00312 00313 00314 LOD_GhostTestApp LOD_app; 00315 00316 LOD_app.InitApp(); 00317 init(mesh_min,mesh_max); 00318 00319 LOD_app.Run(); 00320 00321 00322 return 0; /* ANSI C requires main to return int. */ 00323 }