00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <wx/filename.h>
00013 #include <wx/event.h>
00014 #include "objparser.h"
00015 #include "../../module.h"
00016 #include "../../geometrynode.h"
00017
00018 using namespace VRUT;
00019
00020
00021 OBJParser::OBJParser(wxInputStream * _inputStream, SCENE_ID _sceneID, const wxString _scenePath, Module * _module)
00022 : inputStream(_inputStream), sceneID(_sceneID), module(_module)
00023 {
00024 fileName = wxFileName(_scenePath).GetName();
00025 }
00026
00027
00028 OBJParser::~OBJParser()
00029 {
00031 }
00032
00033 bool OBJParser::parseIndices(TextParser &textParser, std::vector<GeometryTriangles::Indice> * indices, GeometryTriangles::TriDescList *triDescList,
00034 GeometryTriangles::PRIMITIVE_TYPE primType, std::vector<VECTOR3> &v, std::vector<GeometryTriangles::TexCoord> &vt, std::vector<VECTOR3> &vn,
00035 std::vector<VECTOR3> *vertices, std::vector<GeometryTriangles::TexCoord> *texCoords, std::vector<VECTOR3> *normals)
00036 {
00037 std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> indType((GeometryTriangles::Indice)indices->size(), primType);
00038 triDescList->push_back(indType);
00039 size_t maxV=v.size()+1, maxVT=vt.size()+1, maxVN=vn.size()+1;
00040
00041 while (!textParser.NextCharIs('\n'))
00042 {
00043 long i;
00044 if (!textParser.ParseLong(&i, NULL, false))
00045 break;
00046 if ((i == 0) || (abs(i) > long(maxV)))
00047 {
00048 LOGERROR(wxString::Format(wxT("<OBJParser>Error parseIndices, v=%i "), i)+textParser.GetWxString("\r\n"));
00049 return false;
00050 }
00051 vertices->push_back(v[(i>0)?i-1:maxV-i]);
00052 indices->push_back((GeometryTriangles::Indice)(vertices->size()-1));
00053 i=0;
00054 if (textParser.NextCharIs('/', NULL, false))
00055 {
00056 textParser.GetChar(NULL, false);
00057 if (!textParser.NextCharIs('/', NULL, false))
00058 {
00059 textParser.ParseLong(&i, NULL, false);
00060 if ((i == 0) || (abs(i) > long(maxVT)))
00061 {
00062 LOGERROR(wxString::Format(wxT("<OBJParser>Error parseIndices, vt=%i "), i)+textParser.GetWxString("\r\n"));
00063 return false;
00064 }
00065 texCoords->push_back(vt[(i>0)?i-1:maxVT-i]);
00066 }
00067 }
00068 if (i==0)
00069 texCoords->push_back(GeometryTriangles::TexCoord(0,0));
00070 i=0;
00071 if (textParser.NextCharIs('/', NULL, false))
00072 {
00073 textParser.GetChar(NULL, false);
00074 if (!textParser.NextCharIs('/', NULL, false))
00075 {
00076 textParser.ParseLong(&i, NULL, false);
00077 if ((i == 0) || (abs(i) > long(maxVN)))
00078 {
00079 LOGERROR(wxString::Format(wxT("<OBJParser>Error parseIndices, vn=%i "), i)+textParser.GetWxString("\r\n"));
00080 return false;
00081 }
00082 normals->push_back(vn[(i>0)?i-1:maxVN-i]);
00083 }
00084 }
00085 if (i==0)
00086 normals->push_back(VECTOR3(0,0,0));
00087 }
00088 return true;
00089 }
00090
00091 bool OBJParser::parseFile(GeometryNode *node, GeometryTriangles *geometry)
00092 {
00093 TextParser textParser(inputStream, 10000, 1000);
00094
00096 std::vector<VECTOR3> * vertices = &(geometry->vertices);
00097 std::vector<VECTOR3> * normals = &(geometry->normals);
00098 std::vector<GeometryTriangles::TexCoord> * texCoords = &(geometry->texCoords);
00099 std::vector<GeometryTriangles::Indice> * indices = &(geometry->indices);
00100
00101 std::vector<VECTOR3> v;
00102 std::vector<GeometryTriangles::TexCoord> vt;
00103 std::vector<VECTOR3> vn;
00104
00105
00107 const char *keywords[]={"v", "vn", "vt", "f", "l", "p", "g", "s", "mg", "o", "lod", "usemtl", "mtllib", "shadow_obj",
00108 "vp", "cstype", "deg", "bmat", "step", "curv", "curv2", "surf", "parm", "trim", "hole", "scrv", "sp", "end", "con", "bevel", "c_interp", "d_interp", "trace_obj", "ctech", "stech", ""};
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 unsigned int index = 0;
00147 while (!textParser.IsEmpty())
00148 {
00149 switch (textParser.KeywordsSwitch(keywords))
00150 {
00151 case 0:
00152 {
00153 VECTOR3 vert;
00154 if (textParser.ParseVector(vert._v, 3, true) != 3)
00155 {
00156 LOGERROR(wxT("<OBJParser>Error parsing 'v'."));
00157 return false;
00158 }
00159 v.push_back(vert);
00160 break;
00161 }
00162 case 1:
00163 {
00164 VECTOR3 norm;
00165 if (textParser.ParseVector(norm._v, 3, true) != 3)
00166 {
00167 LOGERROR(wxT("<OBJParser>Error parsing 'vn'."));
00168 return false;
00169 }
00170 vn.push_back(norm);
00171 break;
00172 }
00173 case 2:
00174 {
00175 GeometryTriangles::TexCoord texCoord;
00176 if (textParser.ParseVector(texCoord._v, 2, true) != 2)
00177 {
00178 LOGERROR(wxT("<OBJParser>Error parsing 'vt'."));
00179 return false;
00180 }
00181 vt.push_back(texCoord);
00182 break;
00183 }
00184 case 3:
00185 if (!parseIndices(textParser, indices, &(geometry->triDescList), GeometryTriangles::POLYGON, v, vt, vn, vertices, texCoords, normals))
00186 {
00187 LOGERROR(wxT("<OBJParser>Error parsing 'f'."));
00188 return false;
00189 }
00190 break;
00191 case 4:
00192 if (!parseIndices(textParser, indices, &(geometry->triDescList), GeometryTriangles::LINES, v, vt, vn, vertices, texCoords, normals))
00193 {
00194 LOGERROR(wxT("<OBJParser>Error parsing 'l'."));
00195 return false;
00196 }
00197 break;
00198 case 5:
00199 if (!parseIndices(textParser, indices, &(geometry->triDescList), GeometryTriangles::POINTS, v, vt, vn, vertices, texCoords, normals))
00200 {
00201 LOGERROR(wxT("<OBJParser>Error parsing 'p'."));
00202 return false;
00203 }
00204 break;
00205 case 6:
00206 break;
00207 case 7:
00208 break;
00209 case 8:
00210 break;
00211 case 9:
00212 {
00213 wxString nodeName=textParser.GetWxLine();
00214 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_NAME_SET(sceneID, node->GetUid(), nodeName);
00215 module->PostToKernel(ev);
00216 break;
00217 }
00218 case 10:
00219 break;
00220 case 11:
00221 textParser.GetWxLine();
00222 break;
00223 case 12:
00224 break;
00225 case 13:
00226 break;
00227 default:
00228 LOGERROR(wxT("<OBJParser>Unexpected token: '" + textParser.GetWxLine() + wxT("'")));
00229 return false;
00230 }
00231 }
00232 return true;
00233 }
00234
00235 bool OBJParser::Parse(const wxString & rootUid)
00236 {
00237 wxCommandEvent evName = Event::GET_EVT_SCENE_NODE_NAME_SET(sceneID, rootUid, fileName);
00238 module->PostToKernel(evName);
00239
00240
00241 Material * material = new Material(wxT("OBJDefault"));
00242 material->diffuse = VECTOR4(0.5, 0.5, 0.5, 1);
00243 material->specular = VECTOR4(0.5, 0.5, 0.5, 1);
00244 material->flags = Material::DOUBLE_SIDED;
00245 wxCommandEvent evMat = Event::GET_EVT_SCENE_MATERIAL_ADD(sceneID, material);
00246 module->PostToKernel(evMat);
00247
00248
00250 wxString nodeUid = fileName + wxT("_node");
00251 GeometryNode * node = new GeometryNode(nodeUid, nodeUid);
00252 wxCommandEvent evNode = Event::GET_EVT_SCENE_NODE_INSERT(sceneID, node, fileName);
00253 module->PostToKernel(evNode);
00254 wxCommandEvent evMatSet = Event::GET_EVT_SCENE_NODE_MATERIAL_SET(sceneID, nodeUid, material->name);
00255 module->PostToKernel(evMatSet);
00256
00258 GeometryTriangles *geometry = new GeometryTriangles(nodeUid);
00259
00260
00261 if (!parseFile(node, geometry))
00262 {
00263 LOGERROR(wxT("<OBJParser>Scene not loaded properly"));
00264 return false;
00265 }
00266 else
00267 {
00269 wxCommandEvent evGeom = Event::GET_EVT_SCENE_GEOMETRY_ADD(sceneID, geometry);
00270 module->PostToKernel(evGeom);
00271 wxCommandEvent evGeomSet = Event::GET_EVT_SCENE_NODE_GEOMETRY_SET(sceneID, nodeUid, geometry->GetName());
00272 module->PostToKernel(evGeomSet);
00273 }
00274 return true;
00275 }
00276