00001
00011 #include <wx/event.h>
00012 #include "vrmlparser.h"
00013 using namespace VRUT;
00014
00015 VRMLParser* VRMLParser::Node::vrmlp;
00016
00017 VRMLParser::VRMLParser(wxInputStream * _inputStream, SCENE_ID _sceneID, const wxString _scenePath, Module * _module)
00018 : module(_module)
00019 {
00020 textParser = new TextParser(_inputStream, 10000, 100);
00021 wxFileName filename(_scenePath);
00022 scenePath = filename.GetPath() + filename.GetPathSeparator();
00023 sceneID = _sceneID;
00024 Node::vrmlp = this;
00025 fromVRUT = false;
00026 }
00027
00028
00029 VRMLParser::~VRMLParser()
00030 {
00031 delete textParser;
00032
00033 for(DefNamesListV3::iterator it = defNamesListV3.begin(); it != defNamesListV3.end(); it++)
00034 delete it->second;
00035 for(DefNamesListV2::iterator it = defNamesListV2.begin(); it != defNamesListV2.end(); it++)
00036 delete it->second;
00037 for(DefNamesListM::iterator it = defNamesListM.begin(); it != defNamesListM.end(); it++)
00038 delete it->second;
00039 for(std::vector<Node*>::iterator it = defNamesListSND.begin(); it != defNamesListSND.end(); it++)
00040 delete (*it);
00041 }
00042
00043 void VRMLParser::logWarnMsg(WARN_MSG msg, const wxString& name = wxT("")){
00044 switch(msg){
00045 case TRIANGULATE:
00046 LOGWARNING(wxT("<VRMLParser>Triangulation not yet supported."));
00047 break;
00048 case DISABLED:
00049 LOGWARNING(wxT("<VRMLParser>Triangulation disabled."));
00050 break;
00051 case UNSUPPORTED:
00052 LOGWARNING(wxT("<VRMLParser>Node ") + name + wxT(" not yet supported"));
00053 break;
00054 case UNSUPPORTED_ATTR:
00055 LOGWARNING(wxT("<VRMLParser>Attribute ") + name + wxT(" not yet supported"));
00056 break;
00057 }
00058 return;
00059 }
00060
00061 bool VRMLParser::logErrorMsg(ERROR_MSG msg, const wxString & line, const wxChar * expected)
00062 {
00063 if (module->TestExit())
00064 return false;
00065
00066 switch (msg)
00067 {
00068 case EXPECTED:
00069 if (expected)
00070 {
00071 LOGERROR(wxT("<VRMLParser>Expected '") + wxString(expected) + wxT("' before '") + line + wxT("'"));
00072 break;
00073 }
00074 case UNEXPECTED:
00075 if (wxString(line).Trim().IsEmpty())
00076 LOGERROR(wxT("<VRMLParser>Unexpected end of file"));
00077 else
00078 LOGERROR(wxT("<VRMLParser>Unexpected token: '" + line + wxT("'")));
00079 break;
00080 case VECTOR:
00081 LOGERROR(wxT("<VRMLParser>Vector parse error, invalid dimension or format: '" + line + wxT("'")));
00082 break;
00083 case MATERIAL:
00084 LOGERROR(wxT("<VRMLParser>Material not defined: '" + line + wxT("'")));
00085 break;
00086 }
00087 return false;
00088 }
00089
00090
00091 const wxString VRMLParser::getUniqueUid(const wxString & uid)
00092 {
00093
00094 wxString unqUid = CloneWxString(uid);
00095 unsigned cnt = 0;
00096 while (nodeUidsList.find(unqUid) != nodeUidsList.end())
00097 unqUid = wxString::Format(wxT("%s_%i"), uid.c_str(), cnt++);
00098 nodeUidsList.insert(NodeUidsList::value_type(unqUid, false));
00099 return unqUid;
00100 }
00101
00102 bool VRMLParser::externproto(){
00103
00104 logWarnMsg(UNSUPPORTED, wxT("EXTERNPROTO"));
00105 textParser->GetWxString();
00106 textParser->GetChar();
00107 skip(']');
00108 return ( URLList());
00109 }
00110
00111 bool VRMLParser::node(const wxString & parentUid, bool just_define){
00112
00113 static const char *keywords[]={"Anchor", "AudioClip", "Background", "Billboard", "Collision", "ColorInterpolator", "CoordinateInterpolator", "CylinderSensor", "DirectionalLight", "Fog", "Group", "Inline", "LOD", "NavigationInfo", "NormalInterpolator", "OrientationInterpolator",
00114 "PlaneSensor", "PointLight", "PositionInterpolator", "ProximitySensor", "ScalarInterpolator", "Script", "Shape", "Sound", "SphereSensor", "SpotLight", "Switch", "TimeSensor", "TouchSensor", "Transform", "Viewpoint", "VisibilitySensor", "WorldInfo", "NULL", ""};
00115
00116 wxString defName = wxT("");
00117 wxString useName;
00118 if ( textParser->NextKeywordIs("DEF"," \t\n\r,"))
00119 defName = textParser->GetWxString();
00120
00121 if ( textParser->NextKeywordIs("USE"," \t\n\r,") ){
00122 useName = textParser->GetWxString();
00123 DefNamesListSN::iterator it = defNamesListSN.find(useName);
00124 if ( it != defNamesListSN.end()){
00125 wxCommandEvent ev1 = Event::GET_EVT_SCENE_NODE_COPY(sceneID, it->second, parentUid);
00126 module->PostToKernel(ev1);
00127 return true;
00128 }
00129
00130 DefNamesListSNDindex::iterator it1 = defNamesListSNDindex.find(useName);
00131 if ( it1 != defNamesListSNDindex.end()){
00132 defNamesListSND[it1->second]->addToScene(parentUid);
00133 delete defNamesListSND[it1->second];
00134 return true;
00135 }
00136
00137
00138
00139 LOGWARNING(wxT("Not supported type of node! Skipped."));
00140 return true;
00141 }
00142
00143 int index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00144 switch(index){
00145 case 0: return Anchor(parentUid, just_define);
00146 case 1:
00147 logWarnMsg(UNSUPPORTED, wxT("AudioClip"));
00148 skip('}'); return true;
00149 case 2:
00150 logWarnMsg(UNSUPPORTED, wxT("Background"));
00151 skip('}');
00152 return true;
00153 case 3: return Billboard(parentUid, just_define);
00154 case 4: return Collision(parentUid, just_define);
00155 case 5:
00156 logWarnMsg(UNSUPPORTED, wxT("ColorInterpolator"));
00157 skip('}');
00158 return true;
00159 case 6:
00160 logWarnMsg(UNSUPPORTED, wxT("CoordinateInterpolator"));
00161 skip('}');
00162 return true;
00163 case 7:
00164 logWarnMsg(UNSUPPORTED, wxT("CylinderSensor"));
00165 skip('}');
00166 return true;
00167 case 8: {
00168
00169 if ( just_define && defName == wxT("")){
00170 skip('}');
00171 return true;
00172 }
00173
00174 wxString nodeName;
00175 if ( defName == wxT(""))
00176 nodeName = wxT("light");
00177 else nodeName = defName;
00178 wxString nodeUid = getUniqueUid(nodeName);
00179 LightNode * node = new LightNode(nodeUid, nodeName);
00180
00181 Light * light = new Light;
00182 if (!DirectionalLight(light)){
00183 LOGERROR(wxT("<VRMLParser>Failed parsing light '") + nodeName + wxT("'"));
00184 SAFE_DELETE(light);
00185 SAFE_DELETE(node);
00186 return false;
00187 }
00188
00189 if ( !just_define){
00190 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_INSERT(sceneID, node, parentUid);
00191 module->PostToKernel(ev);
00192 wxCommandEvent ev2 = Event::GET_EVT_SCENE_NODE_LIGHT_SET(sceneID, nodeUid, light);
00193 module->PostToKernel(ev2);
00194 if ( defName != wxT(""))
00195 defNamesListSN[nodeName] = defName;
00196 return true;
00197 }
00198
00199 defNamesListSNDindex[defName] = (DefNamesListSNDindex::mapped_type)defNamesListSND.size();
00200 LNode* ln = new LNode( nodeName, node, defName);
00201 ln -> setParam ( light);
00202 defNamesListSND.push_back(ln);
00203 return true;
00204 }
00205 case 9:
00206 logWarnMsg(UNSUPPORTED, wxT("Fog"));
00207 skip('}');
00208 return true;
00209 case 10: return Group(parentUid, just_define);
00210 case 11:
00211 return Inline(parentUid);
00212 case 12: return LOD(parentUid, just_define);
00213 case 13:
00214 logWarnMsg(UNSUPPORTED, wxT("NavigationInfo"));
00215 skip('}');
00216 return true;
00217 case 14:
00218 logWarnMsg(UNSUPPORTED, wxT("NormalInterpolator"));
00219 skip('}');
00220 return true;
00221 case 15:
00222 logWarnMsg(UNSUPPORTED, wxT("OrientationInterpolator"));
00223 skip('}');
00224 return true;
00225 case 16:
00226 logWarnMsg(UNSUPPORTED, wxT("PlaneSensor"));
00227 skip('}');
00228 return true;
00229 case 17: {
00230
00231 if ( just_define && defName == wxT("")){
00232 skip('}');
00233 return true;
00234 }
00235
00236 wxString nodeName;
00237 if ( defName == wxT(""))
00238 nodeName = wxT("light");
00239 else nodeName = defName;
00240 wxString nodeUid = getUniqueUid(nodeName);
00241 LightNode * node = new LightNode(nodeUid, nodeName);
00242
00243 Light * light = new Light;
00244 if (!PointLight(light)){
00245 LOGERROR(wxT("<VRMLParser>Failed parsing light '") + nodeName + wxT("'"));
00246 SAFE_DELETE(light);
00247 SAFE_DELETE(node);
00248 return false;
00249 }
00250
00251 if ( !just_define){
00252 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_INSERT(sceneID, node, parentUid);
00253 module->PostToKernel(ev);
00254 wxCommandEvent ev2 = Event::GET_EVT_SCENE_NODE_LIGHT_SET(sceneID, nodeUid, light);
00255 module->PostToKernel(ev2);
00256 if ( defName != wxT(""))
00257 defNamesListSN[nodeName] = defName;
00258 return true;
00259 }
00260
00261 defNamesListSNDindex[defName] = (DefNamesListSNDindex::mapped_type)defNamesListSND.size();
00262 LNode* ln = new LNode( nodeName, node, defName);
00263 ln -> setParam ( light);
00264 defNamesListSND.push_back(ln);
00265 return true;
00266 }
00267 case 18:
00268 logWarnMsg(UNSUPPORTED, wxT("PositionInterpolator"));
00269 skip('}');
00270 return true;
00271 case 19:
00272 logWarnMsg(UNSUPPORTED, wxT("ProximitySensor"));
00273 skip('}');
00274 return true;
00275 case 20:
00276 logWarnMsg(UNSUPPORTED, wxT("ScalarInterpolator"));
00277 skip('}');
00278 return true;
00279 case 21:
00280 logWarnMsg(UNSUPPORTED, wxT("Script"));
00281 skip_stack('}', '{');
00282 return true;
00283 case 22: {
00284
00285 GeometryNode *node = NULL;
00286 wxString nodeName;
00287 wxString nodeUid;
00288 GNode* ln = NULL;
00289
00290 if ( !just_define || defName != wxT("")){
00291 if ( defName == wxT(""))
00292 nodeName = wxT("shape");
00293 else nodeName = defName;
00294 nodeUid = getUniqueUid(nodeName);
00295 node = new GeometryNode(nodeUid, nodeName);
00296 }
00297 if ( !just_define){
00298 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_INSERT(sceneID, node, parentUid);
00299 module->PostToKernel(ev);
00300 }
00301 if ( just_define && defName != wxT("")){
00302 defNamesListSNDindex[defName] = (DefNamesListSNDindex::mapped_type)defNamesListSND.size();
00303 ln = new GNode( nodeName, node, defName);
00304 defNamesListSND.push_back(ln);
00305 }
00306 if (!Shape(nodeUid, just_define, ln)){
00307 LOGERROR(wxT("<VRMLParser>Failed parsing Shape "));
00308 return false;
00309 }
00310 if ( !just_define && defName != wxT(""))
00311 defNamesListSN.insert(DefNamesListSN::value_type(defName, nodeName ));
00312 return true;
00313 }
00314 case 23:
00315 logWarnMsg(UNSUPPORTED, wxT("Sound"));
00316 skip_stack('}', '{');
00317 return true;
00318 case 24:
00319 logWarnMsg(UNSUPPORTED, wxT("SphereSensor"));
00320 skip('}');
00321 return true;
00322 case 25: {
00323
00324 if ( just_define && defName == wxT("")){
00325 skip('}');
00326 return true;
00327 }
00328
00329 wxString nodeName;
00330 if ( defName == wxT(""))
00331 nodeName = wxT("light");
00332 else nodeName = defName;
00333 wxString nodeUid = getUniqueUid(nodeName);
00334 LightNode * node = new LightNode(nodeUid, nodeName);
00335
00336 Light * light = new Light;
00337 if (!SpotLight(light)){
00338 LOGERROR(wxT("<VRMLParser>Failed parsing light '") + nodeName + wxT("'"));
00339 SAFE_DELETE(light);
00340 SAFE_DELETE(node);
00341 return false;
00342 }
00343
00344 if ( !just_define){
00345 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_INSERT(sceneID, node, parentUid);
00346 module->PostToKernel(ev);
00347 wxCommandEvent ev2 = Event::GET_EVT_SCENE_NODE_LIGHT_SET(sceneID, nodeUid, light);
00348 module->PostToKernel(ev2);
00349 if ( defName != wxT(""))
00350 defNamesListSN[nodeName] = defName;
00351 return true;
00352 }
00353
00354 defNamesListSNDindex[defName] = (DefNamesListSNDindex::mapped_type)defNamesListSND.size();
00355 LNode* ln = new LNode( nodeName, node, defName);
00356 ln -> setParam ( light);
00357 defNamesListSND.push_back(ln);
00358 return true;
00359 }
00360 case 26: return Switch(parentUid, just_define);
00361 case 27:
00362 logWarnMsg(UNSUPPORTED, wxT("TimeSensor"));
00363 skip('}');
00364 return true;
00365 case 28:
00366 logWarnMsg(UNSUPPORTED, wxT("TouchSensor"));
00367 skip('}');
00368 return true;
00369 case 29:
00370 {
00371 wxString nodeName;
00372 wxString nodeUid;
00373 SceneNode* node = NULL;
00374 ANode* ln = NULL;
00375
00376 if ( !just_define || defName != wxT("")) {
00377 if ( defName == wxT(""))
00378 nodeName = wxT("transform");
00379 else nodeName = defName;
00380 nodeUid = getUniqueUid(nodeName);
00381 node = new SceneNode(nodeUid, nodeName, SceneNode::ASSEMBLY);
00382 }
00383
00384 if ( !just_define){
00385 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_INSERT(sceneID, node, parentUid);
00386 module->PostToKernel(ev);
00387 }
00388 if ( just_define && defName != wxT("")){
00389
00390 defNamesListSNDindex[defName] = (DefNamesListSNDindex::mapped_type)defNamesListSND.size();
00391 ln = new ANode( nodeName, node, defName);
00392 defNamesListSND.push_back(ln);
00393 }
00394 if (!Transform(nodeUid, just_define, ln)){
00395
00396 LOGERROR(wxT("<VRMLParser>Failed parsing transformation "));
00397 return false;
00398 }
00399 if ( !just_define && defName != wxT(""))
00400 defNamesListSN.insert(DefNamesListSN::value_type(defName, nodeName ));
00401 return true;
00402 }
00403 case 30: {
00404
00405
00406 wxString nodeName;
00407
00408 MATRIX trans = MATRIX();
00409 float fov = 0;
00410 if (!Viewpoint(trans,fov)){
00411 LOGERROR(wxT("<VRMLParser>Failed parsing Viewpoint '"));
00412 return false;
00413 }
00414
00415 if ( defName == wxT(""))
00416 nodeName = wxT("camera");
00417 else nodeName = defName;
00418 wxString nodeUid = getUniqueUid(nodeName);
00419 SceneNode* camera = new Camera(nodeUid, nodeName);
00420
00421 wxCommandEvent ev2 = Event::GET_EVT_SCENE_NODE_INSERT(sceneID, camera, parentUid);
00422 module->PostToKernel(ev2);
00423
00424 wxCommandEvent ev1 = Event::GET_EVT_SCENE_NODE_TRANSFORM(sceneID, nodeUid, trans);
00425 module->PostToKernel(ev1);
00426
00427
00428 wxCommandEvent ev3 = Event::GET_EVT_SCENE_CAM_PROJECTION_SET(sceneID, nodeUid,
00429 4,3,0.001,10000,(fov/M_PI)*180);
00430 module->PostToKernel(ev3);
00431
00432 if ( defName != wxT(""))
00433 defNamesListSN[nodeName] = defName;
00434
00435 return true;
00436 }
00437 case 31:
00438 logWarnMsg(UNSUPPORTED, wxT("VisibilitySensor"));
00439 skip('}');
00440 return true;
00441 case 32:
00442 logWarnMsg(UNSUPPORTED, wxT("WorldInfo"));
00443 skip('}');
00444 return true;
00445 case 33:
00446 return true;
00447 default:
00448 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00449 }
00450
00451 }
00452
00453
00454 bool VRMLParser::Anchor(const wxString & parentUid, bool just_define){
00455 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
00456 else textParser->GetChar();
00457
00458 static const char *keywords[]={ "children", "parameter", "url", "bboxCenter", "bboxSize", "description", ""};
00459 int index;
00460 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
00461 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00462 switch(index){
00463 case 0:
00464 if ( textParser->NextCharIs('['," \t\n\r,")){
00465 textParser->GetChar();
00466 while ( !textParser->NextCharIs(']'," \t\n\r,"))
00467 node(parentUid, just_define);
00468 textParser->GetChar();
00469 } else
00470 if ( !node(parentUid, just_define))
00471 return false;
00472 break;
00473 case 1:
00474 logWarnMsg(UNSUPPORTED_ATTR, wxT("parameter"));
00475 skip('"');
00476 skip('"');
00477 break;
00478 case 2:
00479 logWarnMsg(UNSUPPORTED_ATTR, wxT("url"));
00480 if ( textParser->NextCharIs('['," \t\n\r,")) skip(']');
00481 else {skip('"');skip('"');}
00482 break;
00483 case 3:
00484 case 4:
00485 logWarnMsg(UNSUPPORTED_ATTR, wxT("bboxCenter|bboxSize"));
00486 textParser->GetWxString();
00487 textParser->GetWxString();
00488 textParser->GetWxString();
00489 break;
00490 case 5:
00491 logWarnMsg(UNSUPPORTED_ATTR, wxT("description"));
00492 skip('"');
00493 skip('"');
00494 break;
00495 default:
00496 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00497 }
00498 }
00499 textParser->GetChar(" \t\n\r,");
00500 return true;
00501 }
00502
00503 bool VRMLParser::Appearance(const wxString & parentUid, VRUT::Material * material, VECTOR2& translation, float& rotation, VECTOR2& scale, VECTOR2& center){
00504 if ( textParser->GetChar(" \t\n\r,") != '{') {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
00505
00506 static const char *keywords[]={ "material", "texture", "textureTransform", ""};
00507 static const char *keywords_t[]={ "ImageTexture", "MovieTexture", "PixelTexture", ""};
00508 static const char *keywords_tt[] = {"translation", "rotation", "scale", "center",""};
00509
00510 int index;
00511 wxString defName;
00512 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
00513 defName = wxT("");
00514 index = textParser->KeywordsSwitch(keywords, " \t\n\r", " \t\n\r,{}[]");
00515 switch(index){
00516 case 0:
00517 if (textParser->NextKeywordIs("DEF"," \t\n\r,"))
00518 defName = textParser->GetWxString();
00519 if (textParser->NextKeywordIs("USE"," \t\n\r,")){
00520 DefNamesListM::iterator it = defNamesListM.find(textParser->GetWxString());
00521 if ( it != defNamesListM.end()) {
00522 VRUT::Material* temp = it -> second;
00523 material->diffuse = temp->diffuse;
00524 material->emission = temp->emission;
00525 material->specular = temp->specular;
00526 material->ambient = temp->ambient;
00527 material->shininess = temp->shininess;
00528 material->flags = temp->flags;
00529 break;
00530 }
00531 else {
00532 LOGERROR(wxT("Unexpected USE name"));
00533 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00534 }
00535 }
00536 if (textParser->NextKeywordIs("Material"," \t\n\r,")) {
00537 if (!Material(material))
00538 return false;
00539 } else return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00540 if ( defName != wxT(""))
00541 defNamesListM.insert(DefNamesListM::value_type(defName, material->Clone() ));
00542 break;
00543 case 1: {
00544 if (textParser->NextKeywordIs("DEF"," \t\n\r,"))
00545 defName = textParser->GetWxString();
00546 if (textParser->NextKeywordIs("USE"," \t\n\r,")){
00547 DefNamesListM::iterator it = defNamesListM.find(textParser->GetWxString());
00548 if ( it != defNamesListM.end()) {
00549 VRUT::Material* temp = it -> second;
00550 material->imageName = temp->imageName;
00551 material->texFlags = temp->texFlags;
00552 break;
00553 }
00554 else {
00555 LOGERROR(wxT("Unexpected USE name"));
00556 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00557 }
00558 }
00559 index = textParser->KeywordsSwitch(keywords_t, " \t\n\r,", " \t\n\r,{}[]");
00560 switch(index){
00561 case 0:
00562 if (!ImageTexture(material)) return false;
00563 break;
00564 case 1:
00565 logWarnMsg(UNSUPPORTED_ATTR, wxT("MovieTexture"));
00566 skip('}');
00567 break;
00568 case 2:
00569 logWarnMsg(UNSUPPORTED_ATTR, wxT("PixelTexture"));
00570 skip('}');
00571 break;
00572 default:
00573 LOGERROR(wxT("<VRMLParser>Failed parsing texture "));
00574 return false;
00575 }
00576 break;
00577 }
00578 case 2:
00579 if (textParser->NextKeywordIs("NULL"," \t\n\r,")) break;
00580 if (textParser->NextKeywordIs("DEF"," \t\n\r,"))
00581 defName = textParser->GetWxString();
00582 if (textParser->NextKeywordIs("USE"," \t\n\r,")) {
00583 textParser->GetWxString(); break;
00584 }
00585 if (!textParser->NextKeywordIs("TextureTransform")) return false;
00586 if (textParser->GetChar(" \t\n\r,")!='{') return false;
00587 while ( !textParser->NextCharIs('}')){
00588 index = textParser->KeywordsSwitch(keywords_tt, " \t\n\r,", " \t\n\r,{}[]");
00589 switch(index){
00590 case 0:
00591 if ( textParser->ParseVector(translation._v, 2, true) != 2 )
00592 return false;
00593 break;
00594 case 1:
00595 if ( !textParser->ParseFloat(&rotation)) return false;
00596 break;
00597 case 2:
00598 if ( textParser->ParseVector(scale._v, 2, true) != 2 )
00599 return false;
00600 break;
00601 case 3:
00602 if ( textParser->ParseVector(center._v, 2, true) != 2 )
00603 return false;
00604 break;
00605 default: return false;
00606 }
00607 }
00608 textParser->GetChar(" \t\n\r,");
00609 break;
00610 default: logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00611 return false;
00612 }
00613 }
00614 textParser->GetChar(" \t\n\r,");
00615 return true;
00616 }
00617
00618
00619 bool VRMLParser::Billboard(const wxString & parentUid, bool just_define){
00620 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
00621 else textParser->GetChar();
00622
00623 static const char *keywords[]={"axisOfRotation", "bboxCenter", "bboxSize", "children", ""};
00624 int index;
00625 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
00626 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00627 switch(index){
00628 case 0:
00629 case 1:
00630 case 2:
00631 logWarnMsg(UNSUPPORTED_ATTR, wxT("bboxCenter|bboxSize|axisOfRotation"));
00632 textParser->GetWxString();
00633 textParser->GetWxString();
00634 textParser->GetWxString();
00635 break;
00636 case 3:
00637 {
00638 textParser->GetChar();
00639 while ( !textParser->NextCharIs(']'," \t\n\r,") ){
00640 if ( !node(parentUid, just_define)) return false;
00641 }
00642 textParser->GetChar();
00643 break;
00644 }
00645 default: logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00646 return false;
00647 }
00648 }
00649 textParser->GetChar();
00650 return true;
00651 }
00652
00653 bool VRMLParser::Box( GeometryTriangles* geometry){
00654 if ( textParser->GetChar(" \t\n\r,") != '{') {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
00655 vector3 size(2,2,2);
00656 if ( textParser->NextCharIs('}'," \t\n\r,")) {
00657 geometry->AddBox(-size/2, size);
00658 textParser->GetChar();
00659 return true;
00660 }
00661
00662 static const char *keywords[]={ "size",""};
00663 int index;
00664 while ( !textParser->NextCharIs('}') ){
00665 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00666 switch(index){
00667 case 0:
00668 if (!textParser->ParseVector(size._v, 3, true)) {
00669 LOGERROR(wxT("<VRMLParser>Failed parsing box "));
00670 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00671 }
00672 break;
00673 default:
00674 LOGERROR(wxT("<VRMLParser>Failed parsing box "));
00675 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00676 }
00677 }
00678 geometry->AddBox(-size/2, size);
00679 textParser->GetChar(" \t\n\r,");
00680 return true;
00681 }
00682
00683
00684 bool VRMLParser::Collision(const wxString & parentUid, bool just_define){
00685 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
00686 else textParser->GetChar();
00687
00688 static const char *keywords[]={ "collide", "proxy", "bboxCenter", "bboxSize", "children", ""};
00689 int index;
00690 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
00691 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00692 switch(index){
00693 case 0:
00694 case 1:
00695 logWarnMsg(UNSUPPORTED_ATTR, wxT("collide|proxy"));
00696 textParser->GetWxString();
00697 break;
00698 case 2:
00699 case 3:
00700 logWarnMsg(UNSUPPORTED_ATTR, wxT("bboxCenter|bboxSize"));
00701 textParser->GetWxString();
00702 textParser->GetWxString();
00703 textParser->GetWxString();
00704 break;
00705 case 4:
00706 {
00707 static const char *k[] = {"]",""};
00708 textParser->GetWxString();
00709 while ( index = textParser->KeywordsSwitch(k," \t\n\r,"," \t\n\r,{}[]") != 0){
00710 if ( !node(parentUid, just_define)) return false;
00711 }
00712 break;
00713 }
00714 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00715 }
00716 }
00717 textParser->GetChar(" \t\n\r,");
00718 return true;
00719 }
00720
00721 bool VRMLParser::DirectionalLight(Light* light){
00722 if ( textParser->GetChar(" \t\n\r,")!='{') return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));
00723 static const char* keywords[] = {"direction","color","intensity","ambientIntensity","on",""};
00724
00725 VECTOR3 direction(0,0,-1);
00726 VECTOR4 color(1,1,1);
00727 float intensity = 1;
00728 float ambientIntensity = 0;
00729
00730 while( !textParser->NextCharIs('}'," \t\n\r,")){
00731 int index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00732 switch(index){
00733 case 0:
00734 if ( textParser->ParseVector(direction._v, 3, true) != 3 )
00735 return false;
00736 break;
00737 case 1:
00738 if ( textParser->ParseVector(color._v, 3, true) != 3 )
00739 return false;
00740 break;
00741 case 2:
00742 if ( !textParser->ParseFloat(&intensity))
00743 return false;
00744 break;
00745 case 3:
00746 logWarnMsg(UNSUPPORTED_ATTR, wxT("ambientIntensity"));
00747 textParser->GetWxString();
00748 break;
00749 case 4:
00750 logWarnMsg(UNSUPPORTED_ATTR, wxT("on"));
00751 textParser->GetWxString();
00752 break;
00753 default: LOGERROR(wxT("Failed parsing DirectionalLight"));
00754 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00755 }
00756 }
00757 textParser->GetChar(" \t\n\r,");
00758 light->type = Light::DIRECTIONAL;
00759 color._v[3] = intensity;
00760 light->diffuse = color;
00761 light->direction = direction;
00762 return true;
00763 }
00764
00765 bool VRMLParser::ElevationGrid(const wxString & parentUid, GeometryTriangles* geometry, bool just_define){
00766 if ( textParser->GetChar(" \t\n\r,")!='{') return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));
00767
00768 static const char *keywords[]={"color", "normal", "texCoord", "height", "ccw", "colorPerVertex", "creaseAngle", "normalPerVertex", "solid", "xDimension", "xSpacing", "zDimension", "zSpacing", ""};
00769
00770 int index;
00771 int xDimension=0, zDimension=0;
00772 float xSpacing=1, zSpacing=1;
00773 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
00774 if ( textParser ->NextKeywordIs("DEF"," \t\n\r,"))
00775 textParser->GetString();
00776 if ( textParser ->NextKeywordIs("USE"," \t\n\r,")) {
00777 textParser->GetString();
00778 continue;
00779 }
00780 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00781 switch(index){
00782 case 0:
00783 case 1:
00784 case 2:
00785 {
00786 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
00787 std::vector<GeometryTriangles::TexCoord> *temp = dynamic_cast<std::vector<GeometryTriangles::TexCoord> * > (defNamesListV2[textParser->GetWxString()]);
00788 if ( temp == NULL){
00789 LOGERROR(wxT("Unexpected USE name for TextureCoordinate"));
00790 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00791 }
00792 geometry->texCoords.insert(geometry->texCoords.end(), temp->begin(), temp->end());
00793 break;
00794 }
00795 wxString defName = wxT("");
00796 if (textParser->NextKeywordIs("DEF"," \t\n\r,")) {
00797 defName = textParser->GetWxString();
00798 }
00799 if (!parseFArray2(&(geometry->texCoords),"TextureCoordinate","point"))
00800 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00801 if ( defName != wxT(""))
00802 defNamesListV2.insert(DefNamesListV2::value_type(defName, new std::vector<VECTOR2>(geometry->texCoords)));
00803 defName = wxT("");
00804 break;
00805 }
00806 case 3:
00807 {
00808 if (xDimension<2 || zDimension<2)
00809 {
00810 skip(']');
00811 break;
00812 }
00813 if (textParser->GetChar() != '[')
00814 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00815 std::vector<VECTOR3> * verts = &(geometry->vertices);
00816
00817
00818 std::vector<GeometryTriangles::Indice> * inds = &(geometry->indices);
00819 GeometryTriangles::TriDescList *triDescList = &(geometry->triDescList);
00820 size_t firstVert = verts->size();
00821
00822 float y = 0;
00823 for (int i=0; i<zDimension; i++)
00824 {
00825 for (int j=0; j<xDimension; j++)
00826 {
00827 textParser->ParseFloat(&y, " \t\n\r,");
00828 verts->push_back(vector3(xSpacing*j, y, zSpacing*i));
00829 }
00830 }
00831 if (textParser->GetChar(" \t\n\r,") != ']')
00832 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00833
00834
00835 for (int i=1; i<zDimension; i++)
00836 {
00837 std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> indType((GeometryTriangles::Indice)inds->size(), GeometryTriangles::TRI_STRIP);
00838 triDescList->push_back(indType);
00839 inds->push_back(GeometryTriangles::Indice(firstVert+(i-1)*xDimension));
00840 inds->push_back(GeometryTriangles::Indice(firstVert+(i)*xDimension));
00841 for (int j=1; j<xDimension; j++)
00842 {
00843 inds->push_back(GeometryTriangles::Indice(firstVert+(i-1)*xDimension+j));
00844 inds->push_back(GeometryTriangles::Indice(firstVert+i*xDimension+j));
00845 }
00846 }
00847 break;
00848 }
00849 case 4:
00850 case 5:
00851 case 6:
00852 case 7:
00853 case 8:
00854 logWarnMsg(UNSUPPORTED_ATTR, wxT("ccw|colorPerVertex|creaseAngle|normalPerVertex|solid"));
00855 textParser->GetWxString();
00856 break;
00857 case 9:
00858 textParser->ParseInt(&xDimension);
00859 break;
00860 case 10:
00861 textParser->ParseFloat(&xSpacing);
00862 break;
00863 case 11:
00864 textParser->ParseInt(&zDimension);
00865 break;
00866 case 12:
00867 textParser->ParseFloat(&zSpacing);
00868 break;
00869 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00870 }
00871 }
00872 textParser->GetChar(" \t\n\r,");
00873 return true;
00874 }
00875
00876 bool VRMLParser::Extrusion(const wxString& parentUid, GeometryTriangles* geometry){
00877 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
00878 else textParser->GetChar();
00879
00880 std::vector<VECTOR2> profil;
00881 std::vector<VECTOR3> spine;
00882 std::vector<VECTOR2> scale;
00883 float creaseAngle = 0;
00884
00885 static const char *keywords[]={"crossSection", "spine", "scale", "orientation","beginCap","endCap","convex","ccw","solid","creaseAngle",""};
00886 int index;
00887 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
00888 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00889 switch(index){
00890 case 0: if (!parseFArray2(&profil,"","",true)) {
00891 std::cout << textParser->GetString() << " " << textParser->GetString()
00892 << " " << textParser->GetString() << std::endl;
00893 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00894 }
00895 break;
00896 case 1: if (!parseFArray3(&spine,"","",true)) return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00897 break;
00898 case 2: if (!parseFArray2(&scale,"","",true)) return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00899 break;
00900 case 3: skip(']'); break;
00901 case 4:
00902 case 5:
00903 case 6:
00904 case 7:
00905 case 8: logWarnMsg(UNSUPPORTED_ATTR, wxT("beginCap|endCap|convex|ccw|solid"));
00906 textParser->GetWxString();
00907 break;
00908 case 9: textParser->ParseFloat(&creaseAngle);
00909 break;
00910 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
00911 }
00912 }
00913 if ( profil.empty()){
00914 profil.push_back(VECTOR2(1,1));
00915 profil.push_back(VECTOR2(1,-1));
00916 profil.push_back(VECTOR2(-1,-1));
00917 profil.push_back(VECTOR2(-1,1));
00918 profil.push_back(VECTOR2(1,1));
00919 }
00920 if ( spine.empty()){
00921 spine.push_back(VECTOR3(0,0,0));
00922 spine.push_back(VECTOR3(0,1,0));
00923 }
00924 if ( scale.empty())
00925 scale.push_back(VECTOR2(1,1));
00926
00927 size_t i,j;
00928 geometry->triDescList.push_back(std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> ((GeometryTriangles::Indice)( 0),GeometryTriangles::QUADS));
00929 std::vector<VECTOR3> * coord = new std::vector<VECTOR3>;
00930 std::vector<GeometryTriangles::Indice> * c = new std::vector<GeometryTriangles::Indice>;
00931
00932 for ( i = 0; i < spine.size()-1; i++){
00933 for ( j=0; j < profil.size()-1; j++){
00934 if ( scale.size() < i)
00935 coord->push_back(VECTOR3(profil[j]._v[0],spine[i]._v[1], profil[j]._v[1]));
00936 else
00937 coord->push_back(VECTOR3(profil[j]._v[0]*scale[i]._v[0],spine[i]._v[1], profil[j]._v[1]*scale[i]._v[1]));
00938
00939 c->push_back(GeometryTriangles::Indice(i*profil.size()+j));
00940 c->push_back(GeometryTriangles::Indice(i*profil.size()+j+1));
00941 c->push_back(GeometryTriangles::Indice(i*profil.size()+j+1+profil.size()));
00942 c->push_back(GeometryTriangles::Indice(i*profil.size()+j+profil.size()));
00943 }
00944 if (scale.size() < i)
00945 coord->push_back(VECTOR3(profil[j]._v[0],spine[i]._v[1], profil[j]._v[1]));
00946 else
00947 coord->push_back(VECTOR3(profil[j]._v[0]*scale[i]._v[0],spine[i]._v[1], profil[j]._v[1]*scale[i]._v[1]));
00948 }
00949
00950 for ( j=0; j < profil.size(); j++)
00951 coord->push_back(VECTOR3(profil[j]._v[0],spine[i]._v[1], profil[j]._v[1]));
00952
00953 if (creaseAngle > 0){
00954 for ( i = 0; i < c->size(); i++){
00955 geometry->vertices.push_back((*coord)[(*c)[i]]);
00956 geometry->indices.push_back(GeometryTriangles::Indice(i));
00957 }
00958 computeNormals(geometry, creaseAngle);
00959 } else {
00960 geometry->vertices.assign(coord->begin(), coord->end());
00961 geometry->indices.assign(c->begin(), c->end());
00962 }
00963
00964 delete c; delete coord;
00965
00966 return true;
00967 }
00968
00969 bool VRMLParser::Group(const wxString & parentUid, bool just_define){
00970 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
00971 else textParser->GetChar();
00972
00973 static const char *keywords[]={"bboxCenter", "bboxSize", "children", ""};
00974 int index;
00975 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
00976 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
00977 if ( textParser ->NextKeywordIs("DEF"," \t\n\r,"))
00978 textParser->GetString();
00979 if ( textParser ->NextKeywordIs("USE"," \t\n\r,") ){
00980 textParser->GetString();
00981 continue;
00982 }
00983 switch(index){
00984 case 0:
00985 case 1:
00986 logWarnMsg(UNSUPPORTED_ATTR, wxT("bboxCenter|bboxSize"));
00987 textParser->GetWxString();
00988 textParser->GetWxString();
00989 textParser->GetWxString();
00990 break;
00991 case 2:
00992 {
00993 static const char *k[] = {"]",""};
00994 if ( textParser->NextCharIs('[')){
00995 textParser->GetWxString();
00996 while ( index = textParser->KeywordsSwitch(k," \t\n\r,", " \t\n\r,{}[]") != 0){
00997 if ( !node(parentUid, just_define)) return false;
00998 }
00999 } else
01000 if ( !node(parentUid, just_define)) return false;
01001 break;
01002 }
01003 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01004 }
01005 }
01006 textParser->GetChar(" \t\n\r,");
01007 return true;
01008 }
01009
01010 bool VRMLParser::parseFArray3(std::vector<VECTOR3>* array, const char* VRMLnode, const char* VRMLfield, bool skip){
01011 if (!skip){
01012 if ( !textParser->NextKeywordIs(VRMLnode," \t\n\r,")) { return false;}
01013 if ( textParser->GetChar(" \t\n\r,") != '{') { return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01014 if ( !textParser->NextKeywordIs(VRMLfield," \t\n\r,") ) { return logErrorMsg(UNEXPECTED, textParser->GetWxLine());}
01015 }
01016 if ( textParser->GetChar(" \t\n\r,") != '[') { return logErrorMsg(UNEXPECTED, textParser->GetWxLine());}
01017 VECTOR3 v;
01018 while ( !textParser->NextCharIs(']'," \t\n\r,") ){
01019 if (textParser->ParseVector(v._v, 3, true, " \t\n\r,]") != 3)
01020 return false;
01021 array->push_back(v);
01022 }
01023 textParser->GetChar(" \t\n\r,");
01024 if (!skip)
01025 if ( textParser->GetChar(" \t\n\r,") != '}') { return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("}"));}
01026
01027 return true;
01028 }
01029
01030 bool VRMLParser::parseFArray2(std::vector<VECTOR2>* array, const char* VRMLnode, const char* VRMLfield, bool skip){
01031 if (!skip){
01032 if ( !textParser->NextKeywordIs(VRMLnode," \t\n\r,")) { return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01033 if ( textParser->GetChar(" \t\n\r,") != '{') { return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01034 if ( !textParser->NextKeywordIs(VRMLfield," \t\n\r,") ) { return logErrorMsg(UNEXPECTED, textParser->GetWxLine());}
01035 }
01036 if ( textParser->GetChar(" \t\n\r,") != '[') { return logErrorMsg(UNEXPECTED, textParser->GetWxLine());}
01037 VECTOR2 v;
01038 while ( !textParser->NextCharIs(']'," \t\n\r,") ){
01039 if (textParser->ParseVector(v._v, 2, true, " \t\n\r,]") != 2)
01040 return false;
01041 array->push_back(v);
01042 }
01043 textParser->GetChar(" \t\n\r,");
01044 if (!skip){
01045 if ( !textParser->NextCharIs('}'," \t\n\r,")) { return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("}"));}
01046 else textParser->GetChar(" \t\n\r,");
01047 }
01048 return true;
01049 }
01050
01051 bool VRMLParser::parseIndicesTSL(std::vector<GeometryTriangles::Indice> * indices, size_t & count, size_t count_exp)
01052 {
01053
01054 long v;
01055 long vector[3];
01056
01057 for ( int i = 0; i < 3; i++){
01058 if (!textParser->ParseLong(&v," \t\n\r,") || v < 0 ) {
01059 LOGERROR(wxT("coordIndex out of bounds"));
01060 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01061 }
01062 indices->push_back((GeometryTriangles::Indice)v);
01063 }
01064
01065 textParser->SkipChars(" \t\n\r,");
01066 if ( textParser->GetChar() != '-') {
01067 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01068 }else {
01069 textParser->GetChar();
01070 }
01071 textParser->SkipChars(" \t\n\r,");
01072 if ( textParser->NextCharIs(']', " \t\n\r,",false)) return true;
01073
01074 while (!textParser->NextCharIs(']', " \t\n\r,",false))
01075 {
01076 count = 0;
01077 if (!textParser->ParseLong(vector," \t\n\r,",false)){
01078 wxString line = textParser->GetWxLine();
01079 if ( line == wxT("#TL")) {count = 2; return true;}
01080 if ( line == wxT("#TF")) {count = 1; return true;}
01081 if ( line == wxT("#TS")) {count = 0; return true;}
01082 textParser->ParseLong(vector," \t\n\r,");
01083 }
01084
01085 textParser->ParseLong(vector+1," \t\n\r,");
01086 textParser->ParseLong(vector+2," \t\n\r,");
01087
01088 textParser->SkipChars(" \t\n\r,");
01089 if ( !textParser->NextCharIs('-'," \t\n\r,",false)) {
01090 for ( int i =0; i < 3; i++){
01091 if ( vector[i] < 0 ) {
01092 LOGERROR(wxT("coordIndex out of bounds"+vector[i]));
01093 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01094 }
01095 indices->push_back((GeometryTriangles::Indice)vector[i]);
01096 count++;
01097 }
01098 while( !textParser->NextKeywordIs("-1"," \t\n\r,") && !textParser->NextCharIs(']', " \t\n\r,") ){
01099 if (!textParser->ParseLong(&v," \t\n\r,") || v < 0 ) {
01100 LOGERROR(wxT("coordIndex out of bounds"+v));
01101 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01102 }
01103 indices->push_back((GeometryTriangles::Indice)v);
01104 count++;
01105 }
01106 return true;
01107 }
01108
01109 else {
01110 textParser->GetWxString();
01111 if ( vector[2] < 0 ) {
01112 LOGERROR(wxT("coordIndex out of bounds"+vector[2]));
01113 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01114 }
01115 indices->push_back((GeometryTriangles::Indice)vector[2]);
01116 }
01117 textParser->SkipChars(" \t\n\r,");
01118 }
01119 return true;
01120 }
01121
01122
01123 bool VRMLParser::parseIndices(std::vector<GeometryTriangles::Indice> * indices, size_t & count, size_t count_exp)
01124 {
01125
01126 long v;
01127 textParser->SkipChars(" \t\n\r,");
01128 while (!textParser->NextCharIs(']', " \t\n\r,",false))
01129 {
01130 count = 0;
01131
01132 if (!textParser->ParseLong(&v," \t\n\r,",false)){
01133 wxString line = textParser->GetWxLine();
01134 if ( line == wxT("#TL")) {count = 2; return true;}
01135 if ( line == wxT("#TF")) {count = 1; return true;}
01136 if ( line == wxT("#TS")) {count = 0; return true;}
01137 textParser->ParseLong(&v," \t\n\r,");
01138 }
01139 if (v < 0 )
01140 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01141 indices->push_back((GeometryTriangles::Indice)v);
01142 count ++;
01143
01144 for ( ; count < count_exp; count++){
01145 if ( textParser->NextKeywordIs("-1"," \t\n\r,]") || textParser->NextCharIs(']'," \t\n\r,"))
01146 return true;
01147 if (!textParser->ParseLong(&v," \t\n\r,]") || v < 0 )
01148 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01149 indices->push_back((GeometryTriangles::Indice)v);
01150 }
01151
01152 if ( textParser->NextCharIs(']'," \t\n\r,")) return true;
01153 if ( !textParser->NextKeywordIs("-1"," \t\n\r,")){
01154 while( !textParser->NextKeywordIs("-1"," \t\n\r,]") ){
01155 if ( textParser->NextCharIs(']'," \t\n\r,")) return true;
01156 if (!textParser->ParseLong(&v," \t\n\r,") || v < 0 )
01157 return logErrorMsg(UNEXPECTED, textParser->GetWxLine()+textParser->GetWxLine());
01158 indices->push_back((GeometryTriangles::Indice)v);
01159 count++;
01160 }
01161 if ( count < 3 ) return false;
01162 return true;
01163 }
01164 textParser->SkipChars(" \t\n\r,");
01165 }
01166 return true;
01167 }
01168
01169 int cmp(const void* a, const void* b ){
01170 std::pair<VECTOR3,size_t>* a1 = (std::pair<VECTOR3,size_t>*)a;
01171 std::pair<VECTOR3,size_t>* b1 = (std::pair<VECTOR3,size_t>*)b;
01172 return (int)(a1->first < b1->first);
01173 }
01174
01175 void VRMLParser::computeNormals(GeometryTriangles* geometry, float & creaseAngle){
01176 std::vector<VECTOR3> * norms = &(geometry->normals);
01177 norms->resize(geometry->indices.size());
01178 std::pair<VECTOR3,size_t> *vertices = new std::pair<VECTOR3, size_t>[geometry->indices.size()] ;
01179 size_t it_vertices;
01180 size_t endInd;
01181 float x = 0, y = 0, z = 0;
01182 VECTOR3 normal;
01183
01184 unsigned count;
01185 for (GeometryTriangles::TriDescList::iterator it = geometry->triDescList.begin(); it != geometry->triDescList.end(); it++){
01186 GeometryTriangles::TriDescList::const_iterator endIndPrimType = it + 1;
01187 endInd = ( endIndPrimType == geometry->triDescList.end()) ? geometry->indices.size() : endIndPrimType->first ;
01188 endInd = __min( endInd, geometry->indices.size() );
01189 it_vertices = it->first;
01190 count = 0;
01191
01192 while ( it_vertices + count < endInd){
01193 switch (it->second){
01194 case GeometryTriangles::TRI_LIST:
01195 count = 2;
01196 break;
01197 case GeometryTriangles::QUADS:
01198 count = 3;
01199 break;
01200 case GeometryTriangles::POLYGON:
01201 if ( it+1 == geometry->triDescList.end())
01202 count = 3;
01203 else count = (it+1)->first - it->first - 1;
01204 }
01205
01206
01207
01208 x = y = z = 0;
01209 for ( unsigned loop = 0; loop < count; loop++){
01210 x += (geometry->vertices[it_vertices]._v[1] - geometry->vertices[it_vertices+1]._v[1]) * (geometry->vertices[it_vertices]._v[2] + geometry->vertices[it_vertices+1]._v[2]);
01211 y += (geometry->vertices[it_vertices]._v[2] - geometry->vertices[it_vertices+1]._v[2]) * (geometry->vertices[it_vertices]._v[0] + geometry->vertices[it_vertices+1]._v[0]);
01212 z += (geometry->vertices[it_vertices]._v[0] - geometry->vertices[it_vertices+1]._v[0]) * (geometry->vertices[it_vertices]._v[1] + geometry->vertices[it_vertices+1]._v[1]);
01213 it_vertices++;
01214 }
01215 x += (geometry->vertices[it_vertices ]._v[1] - geometry->vertices[it_vertices - count]._v[1]) * (geometry->vertices[it_vertices]._v[2] + geometry->vertices[it_vertices - count]._v[2]);
01216 y += (geometry->vertices[it_vertices ]._v[2] - geometry->vertices[it_vertices - count]._v[2]) * (geometry->vertices[it_vertices]._v[0] + geometry->vertices[it_vertices - count]._v[0]);
01217 z += (geometry->vertices[it_vertices ]._v[0] - geometry->vertices[it_vertices - count]._v[0]) * (geometry->vertices[it_vertices]._v[1] + geometry->vertices[it_vertices - count]._v[1]);
01218
01219 #define PRECISION 0.0001
01220 normal = VECTOR3((abs(x)<PRECISION)?0:x,(abs(y)<PRECISION)?0:y,(abs(z)<PRECISION)?0:z);
01221 normal = normal.Normalize();
01222 it_vertices -= count;
01223
01224 for ( unsigned i = 0; i != count + 1; i++){
01225 vertices[it_vertices] = std::pair<VECTOR3,size_t> (geometry->vertices[it_vertices],it_vertices);
01226 norms->insert(norms->begin() + it_vertices,normal);
01227 it_vertices++;
01228 }
01229 }
01230 }
01231
01232 qsort(vertices,geometry->indices.size()-1,sizeof(std::pair<VECTOR3,size_t>),cmp);
01233
01234 float cosAngle;
01235 size_t number = 0;
01236 VECTOR3 temp(0,0,0);
01237 std::vector<size_t> index;
01238 for ( size_t i = 0; i < geometry->indices.size(); ){
01239 temp = norms->at(vertices[i].second);
01240 number = i;
01241 while ( vertices[number].first == vertices[number+1].first ){
01242 cosAngle = norms->at(vertices[number].second).Dot(norms->at(vertices[number+1].second));
01243 cosAngle = cosAngle / (norms->at(vertices[number].second).Length() * norms->at(vertices[number+1].second).Length());
01244 if ( creaseAngle > acos(cosAngle)){
01245 index.push_back(vertices[number].second);
01246 index.push_back(vertices[number+1].second);
01247 temp += norms->at(vertices[number+1].second);
01248 }
01249 ++number;
01250 }
01251
01252 if ( i < number){
01253 temp = temp.Normalize();
01254 for ( std::vector<size_t>::iterator iter = index.begin(); iter != index.end(); iter++){
01255 (*norms)[*iter] = temp;
01256 }
01257 index.clear();
01258 i = number;
01259 } else ++i;
01260 }
01261
01262 delete [] vertices;
01263 return;
01264 }
01265
01266 bool VRMLParser::IndexedFaceSet(const wxString & parentUid, GeometryTriangles* geometry ){
01267 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01268 else textParser->GetChar(" \t\n\r,");
01269
01270 static const char *keywords[]={"color", "normal", "coord", "texCoord", "ccw", "colorPerVertex", "convex", "creaseAngle", "normalPerVertex", "solid", "colorIndex", "coordIndex", "normalIndex", "texCoordIndex", ""};
01271
01272 std::vector<VECTOR3> * norms = NULL;
01273 std::vector<GeometryTriangles::Indice> * n = NULL;
01274
01275 std::vector<GeometryTriangles::TexCoord> * texs = NULL;
01276 std::vector<GeometryTriangles::Indice> * t = NULL;
01277 typedef std::vector<GeometryTriangles::TexCoord> TexCoord;
01278
01279 std::vector<VECTOR3> * coord = NULL;
01280 std::vector<GeometryTriangles::Indice> * c = NULL;
01281
01282 wxString defName = wxT("");
01283 float creaseAngle = 0;
01284
01285 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
01286 int index = textParser->KeywordsSwitch(keywords," \t\n\r,", " \t\n\r,{}[]");
01287 switch(index){
01288 case 0: {
01289 logWarnMsg(UNSUPPORTED_ATTR, wxT("color"));
01290 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
01291 textParser->GetWxString();
01292 break;
01293 }
01294 if ( textParser->NextKeywordIs("NULL"," \t\n\r,")) break;
01295 skip('}');
01296 break;
01297 }
01298 case 1: {
01299 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
01300 std::vector<VECTOR3>* temp = dynamic_cast<std::vector<VECTOR3> *>(defNamesListV3[textParser->GetWxString()]);
01301 if ( temp == NULL){
01302 LOGERROR(wxT("Unexpected USE name"));
01303 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01304 }
01305 norms = new std::vector<VECTOR3>(*temp);
01306 break;
01307 }
01308 norms = new std::vector<VECTOR3>();
01309 if ( textParser->NextKeywordIs("DEF"," \t\n\r,")){
01310 defName = textParser->GetWxString();
01311 }
01312 if (!parseFArray3(norms, "Normal", "vector") ) {
01313 if (!parseFArray3(norms,"Coordinate", "point")) {
01314 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01315 delete norms;
01316 }
01317 }
01318 if ( defName != wxT(""))
01319 defNamesListV3.insert(DefNamesListV3::value_type(defName, new std::vector<VECTOR3>(*norms)));
01320 defName = wxT("");
01321 break;
01322 }
01323 case 2: {
01324 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
01325 std::vector<VECTOR3> * geom = dynamic_cast<std::vector<VECTOR3> *>(defNamesListV3[textParser->GetWxString()]);
01326 if ( geom == NULL){
01327 LOGERROR(wxT("Unexpected USE name for Coordinate"));
01328 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01329 }
01330 coord = new std::vector<VECTOR3>(*geom);
01331 break;
01332 }
01333 coord = new std::vector<VECTOR3>();
01334 if ( textParser->NextKeywordIs("DEF"," \t\n\r,")){
01335 defName = textParser->GetWxString();
01336
01337 }
01338 if (!parseFArray3(coord, "Coordinate", "point"))
01339 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01340 if ( defName != wxT(""))
01341 defNamesListV3.insert(DefNamesListV3::value_type(defName, new std::vector<VECTOR3>(*coord)));
01342 defName = wxT("");
01343 break;
01344 }
01345 case 3: {
01346 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
01347 TexCoord* temp = dynamic_cast<std::vector<GeometryTriangles::TexCoord> * > (defNamesListV2[textParser->GetWxString()]);
01348 if ( temp == NULL){
01349 LOGERROR(wxT("Unexpected USE name for TextureCoordinate"));
01350 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01351 }
01352 texs = new std::vector<GeometryTriangles::TexCoord>(*temp);
01353 break;
01354 }
01355 texs = new std::vector<GeometryTriangles::TexCoord>();
01356 if (textParser->NextKeywordIs("DEF"," \t\n\r,")) {
01357 defName = textParser->GetWxString();
01358 }
01359 if (!parseFArray2(texs,"TextureCoordinate","point"))
01360 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01361 if ( defName != wxT("")) {
01362 defNamesListV2.insert(DefNamesListV2::value_type(defName, new std::vector<VECTOR2>(*texs)));
01363 defName = wxT("");
01364 }
01365 break;
01366 }
01367 case 4:
01368 case 5:
01369 case 6:
01370 logWarnMsg(UNSUPPORTED_ATTR, wxT("ccw|colorPerVertex|convex"));
01371 textParser->GetWxString();
01372 break;
01373 case 7:
01374 textParser->ParseFloat(&creaseAngle);
01375 break;
01376 case 8:
01377 case 9:
01378 logWarnMsg(UNSUPPORTED_ATTR, wxT("solid|normalPerVertex"));
01379 textParser->GetWxString();
01380 break;
01381 case 10:
01382 logWarnMsg(UNSUPPORTED_ATTR, wxT("colorIndex"));
01383 skip(']');
01384 break;
01385 case 11: {
01386 if ( textParser->GetChar(" \t\n\r,") != '[') { return logErrorMsg(UNEXPECTED, textParser->GetWxLine());}
01387 textParser->SkipChars(" \t\n\r,");
01388 if ( textParser->NextCharIs(']'," \t\n\r,",false)) {
01389 textParser->GetChar(" \t\n\r,");
01390 break;
01391 }
01392
01393 c = new std::vector<GeometryTriangles::Indice>;
01394 GeometryTriangles::PRIMITIVE_TYPE type = GeometryTriangles::TRI_LIST;
01395 size_t count = 0;
01396 size_t count_exp = 0;
01397
01398 while ( !textParser->NextCharIs(']'," \t\n\r,",false) ){
01399
01400 if (!parseIndices(c,count,count_exp )) {
01401 LOGERROR(wxT("Failde parsing coordIndex"));
01402 return false;
01403 }
01404
01405 switch( count) {
01406 case 0:
01407 case 1: fromVRUT = true;
01408 while (count == 1 || count == 0 ){
01409 if (textParser->NextCharIs(']'," \t\n\r,")) break;
01410 if ( count == 0 ) type = GeometryTriangles::TRI_STRIP;
01411 else type = GeometryTriangles::TRI_FAN;
01412 geometry->triDescList.push_back(std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> ((GeometryTriangles::Indice)(c->size()),type));
01413 if (!parseIndicesTSL(c,count,count_exp)) {
01414 LOGERROR(wxT("Failed parsing coordIndex - TRI_STRIP| TRI_FAN"));
01415 return false;
01416 }
01417 }
01418 break;
01419
01420 case 2: type = GeometryTriangles::TRI_LIST;
01421 geometry->triDescList.push_back(std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> ((GeometryTriangles::Indice)(c->size()),type));
01422 count_exp = 3; break;
01423 case 3: type = GeometryTriangles::TRI_LIST;
01424 geometry->triDescList.push_back(std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> ((GeometryTriangles::Indice)(c->size()-count),type));
01425 count_exp = 3; break;
01426 case 4: type = GeometryTriangles::QUADS; count_exp = count;
01427 geometry->triDescList.push_back(std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> ((GeometryTriangles::Indice)(c->size()-count),type));
01428 break;
01429 default: type = GeometryTriangles::POLYGON; count_exp = 0;
01430 geometry->triDescList.push_back(std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> ((GeometryTriangles::Indice)(c->size()-count),type));
01431
01432 }
01433
01434 textParser->SkipChars(" \t\n\r,");
01435 }
01436 textParser->GetChar(" \t\n\r,");
01437 break;
01438 }
01439 case 12: {
01440 if ( textParser->GetChar(" \t\n\r,") != '[')
01441 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01442 if ( textParser->NextCharIs(']'," \t\n\r,")) { textParser->GetChar(); break;}
01443
01444 n = new std::vector<GeometryTriangles::Indice>();
01445 int v;
01446 while ( !textParser->NextCharIs(']'," \t\n\r,") ){
01447 if (!textParser->ParseInt(&v, " \t\n\r,"))
01448 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01449 n->push_back(v);
01450 textParser->NextKeywordIs("-1", " \t\n\r,");
01451 }
01452
01453 textParser->GetChar(" \t\n\r,");
01454 break;
01455 }
01456 case 13: {
01457 if ( textParser->GetChar(" \t\n\r,") != '[')
01458 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01459 if ( textParser->NextCharIs(']'," \t\n\r,")) { textParser->GetChar(" \t\n\r,"); break;}
01460
01461 t = new std::vector<GeometryTriangles::Indice>();
01462 int v;
01463 while ( !textParser->NextCharIs(']'," \t\n\r,") ){
01464 if (!textParser->ParseInt(&v, " \t\n\r,]"))
01465 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01466 t->push_back(v);
01467 if ( textParser->NextCharIs(']'," \t\n\r,")) break;
01468 textParser->NextKeywordIs("-1", " \t\n\r,]");
01469 }
01470
01471 textParser->GetChar(" \t\n\r,");
01472 break;
01473 }
01474 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01475 }
01476 }
01477 textParser->GetChar(" \t\n\r,");
01478 if (!fromVRUT){
01479 if ( coord != NULL && c == NULL){
01480 geometry->vertices.assign(coord->begin(), coord->end());
01481 GeometryTriangles::Indice counter = 0;
01482 for ( std::vector<VECTOR3>::iterator it = coord->begin(); it != coord->end(); it++)
01483 geometry->indices.push_back( counter++);
01484 c = new std::vector<GeometryTriangles::Indice>(geometry->indices);
01485 }
01486 if ( coord != NULL && c != NULL){
01487
01488 GeometryTriangles::Indice counter = 0;
01489 for ( std::vector<GeometryTriangles::Indice>::iterator it = c->begin(); it != c->end(); it++){
01490 if ( *it > coord->max_size()){
01491 LOGERROR(wxT("index out of bounds ") + wxString::Format(wxT("%i"), *it));
01492 return false;
01493 }
01494 geometry->vertices.push_back( (*coord)[(size_t)(*it)] );
01495 geometry->indices.push_back( counter++);
01496 }
01497 }
01498 size_t counter;
01499 if ( texs != NULL && t == NULL && c != NULL){
01500
01501 for ( std::vector<GeometryTriangles::Indice>::iterator it = c->begin(); it != c->end(); it++){
01502 if ( *it > texs->max_size()){
01503 LOGERROR(wxT("texture index out of bounds " ) + wxString::Format(wxT("%i"), *it));
01504 return false;
01505 }
01506 geometry->texCoords.push_back((*texs)[(size_t)(*it)]);
01507 }
01508 }
01509 if ( texs != NULL && t != NULL && coord != NULL){
01510
01511 counter = 0;
01512 for ( std::vector<GeometryTriangles::Indice>::iterator it = t->begin(); it != t->end(); it++){
01513 if ( *it > texs->max_size()){
01514 LOGERROR(wxT("UV index out of bounds " ) + wxString::Format(wxT("%i"), *it));
01515 return false;
01516 }
01517 geometry->texCoords.push_back((*texs)[(size_t)(*it)]);
01518 }
01519 }
01520 if ( norms != NULL && n != NULL && coord != NULL){
01521
01522 counter = 0;
01523 for ( std::vector<GeometryTriangles::Indice>::iterator it = n->begin(); it != n->end(); it++){
01524 if ( *it > norms->max_size()){
01525 LOGERROR(wxT("normal index out of bounds " ) + wxString::Format(wxT("%i"), *it));
01526 return false;
01527 }
01528 geometry->normals.push_back((*norms)[(size_t)(*it)]);
01529 }
01530 }
01531 }else {
01532 if ( coord != NULL) geometry->vertices.assign(coord->begin(), coord->end());
01533 if ( c != NULL) geometry->indices.assign(c->begin(), c->end());
01534 if ( texs!= NULL) geometry->texCoords.assign(texs->begin(), texs->end());
01535 if ( norms!=NULL)
01536 geometry->normals.assign(norms->begin(), norms->end());
01537
01538 }
01539
01540 if ( creaseAngle > 0.0001 && norms == NULL)
01541 computeNormals(geometry, creaseAngle);
01542 SAFE_DELETE(norms);
01543 SAFE_DELETE(n);
01544 SAFE_DELETE(texs);
01545 SAFE_DELETE(t);
01546 SAFE_DELETE(coord);
01547 SAFE_DELETE(c);
01548 return true;
01549 }
01550
01551 bool VRMLParser::IndexedLineSet(const wxString & parentUid,GeometryTriangles* geometry){
01552 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01553 else textParser->GetChar(" \t\n\r,");
01554
01555 static const char *keywords[]={ "color", "coord", "colorPerVertex", "colorIndex", "coordIndex", "" };
01556 std::vector<VECTOR3> * verts = &(geometry->vertices);
01557 std::vector<GeometryTriangles::Indice> * indices = &(geometry->indices);
01558
01559 wxString defName = wxT("");
01560 int index;
01561 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
01562 index = textParser->KeywordsSwitch(keywords, " \t\n\r", " \t\n\r,{}[]");
01563 switch(index){
01564 case 0:
01565 logWarnMsg(UNSUPPORTED_ATTR, wxT("color"));
01566 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
01567 textParser->GetWxString();
01568 break;
01569 }
01570 skip('}');
01571 break;
01572 case 1: {
01573 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
01574 std::vector<VECTOR3> * geom = dynamic_cast<std::vector<VECTOR3> *>(defNamesListV3[textParser->GetWxString()]);
01575 if ( geom == NULL){
01576 LOGERROR(wxT("Unexpected USE name"));
01577 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01578 }
01579 verts->assign(geom->begin(), geom->end());
01580 break;
01581 }
01582 if ( textParser->NextKeywordIs("DEF"," \t\n\r,")){
01583 defName = textParser->GetWxString();
01584
01585 }
01586 if (!parseFArray3(verts, "Coordinate", "point")) {
01587 LOGERROR(wxT("Failed parsing coordinate"));
01588 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01589 }
01590 if ( defName != wxT(""))
01591 defNamesListV3.insert(DefNamesListV3::value_type(defName, new std::vector<VECTOR3>(geometry->vertices)));
01592 break;
01593 }
01594 case 2:
01595 logWarnMsg(UNSUPPORTED_ATTR, wxT("colorPerVertex"));
01596 textParser->GetWxString();
01597 break;
01598 case 3:
01599 logWarnMsg(UNSUPPORTED_ATTR, wxT("colorIndex"));
01600 skip(']');
01601 break;
01602 case 4: {
01603 if ( textParser->GetChar(" \t\n\r,") != '[') { return logErrorMsg(UNEXPECTED, textParser->GetWxLine());}
01604 if ( textParser->NextCharIs(']'," \t\n\r,")) {
01605 textParser->GetChar(" \t\n\r,");
01606 break;
01607 }
01608
01609 GeometryTriangles::PRIMITIVE_TYPE type;
01610 size_t count = 0;
01611 long v;
01612 while ( !textParser->NextCharIs(']'," \t\n\r,") ){
01613 while ( !textParser->NextKeywordIs("-1"," \t\n\r,") ) {
01614 if (!textParser->ParseLong(&v," \t\n\r,") || v < 0 ) {
01615 LOGERROR(wxT("Failed parsing indexes"));
01616 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01617 }
01618 indices->push_back((GeometryTriangles::Indice)v);
01619 count++;
01620 }
01621 if (count == 2) type = GeometryTriangles::LINES;
01622 else type = GeometryTriangles::LINE_STRIP;
01623 geometry->triDescList.push_back(std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> ((GeometryTriangles::Indice)(indices->size()-count),type));
01624 count = 0;
01625 }
01626
01627 textParser->GetChar(" \t\n\r,");
01628 break;
01629 }
01630
01631 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01632 }
01633 }
01634 textParser->GetChar(" \t\n\r,");
01635 return true;
01636 }
01637
01638 bool VRMLParser::Inline(const wxString & parentUid){
01639 if (textParser->GetChar(" \t\n\r,")!= '{' ) return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));
01640 static const char *keywords[] = {"url", "bboxSize", "bboxCenter", ""};
01641 int index;
01642 bool ret = true;
01643
01644 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
01645 index = textParser->KeywordsSwitch(keywords, " \t\n\r", " \t\n\r,{}[]");
01646 switch(index){
01647 case 0:{
01648 wxInputStream * is;
01649 if ( textParser->NextCharIs('['," \t\n\r,")) {
01650 textParser->GetChar();
01651
01652 while ( !textParser->NextCharIs(']'," \t\n\r,")){}
01653 }else {
01654 wxString fname = scenePath+textParser->GetWxString(" \t\n\r,");
01655 is = new wxFileInputStream(wxFileName(fname).GetFullPath());
01656
01657 if (is) {
01658
01659 unsigned char buffer[2];
01660 is -> Read(buffer, sizeof(unsigned char)*2);
01661 if ( buffer[0] == 31 && buffer[1] == 139){
01662 wxFileName wxFname(fname);
01663 delete is;
01664 is = new wxFileInputStream(wxFname.GetFullPath());
01665 is = new wxZlibInputStream(is,wxZLIB_GZIP);
01666 VRMLParser vrmlParser2(is, sceneID, fname, module);
01667 ret = vrmlParser2.Parse(parentUid, true, &nodeUidsList);
01668 nodeUidsList = NodeUidsList(vrmlParser2.getNodeUidsList());
01669 delete is;
01670 }
01671 else {
01672 is -> Ungetch(buffer, sizeof(unsigned char)*2);
01673 VRMLParser vrmlParser(is, sceneID, fname, module);
01674 ret = vrmlParser.Parse(parentUid, true, &nodeUidsList);
01675 nodeUidsList = NodeUidsList(vrmlParser.getNodeUidsList());
01676 delete is;
01677 }
01678 } else {
01679 LOGERROR(wxT("<VRMLParser>File not found")+fname);
01680 return false;
01681 }
01682
01683 if ( !ret) {
01684 LOGERROR(wxT("<VRMLParser>Failed parsing inline file ")+fname);
01685 return false;
01686 }
01687 break;
01688 }
01689 }
01690 case 1:
01691 case 2: logWarnMsg(UNSUPPORTED_ATTR, wxT("bboxSize|bboxCenter"));
01692 textParser->GetWxString();
01693 textParser->GetWxString();
01694 textParser->GetWxString();
01695 break;
01696 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01697 }
01698 }
01699 textParser->GetChar(" \t\n\r,");
01700 return true;
01701 }
01702
01703 bool VRMLParser::ImageTexture(VRUT::Material * material){
01704 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01705 else textParser->GetChar(" \t\n\r,");
01706
01707 static const char *keywords[]={"url", "repeatS", "repeatT", ""};
01708 int index;
01709 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
01710 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
01711 switch(index){
01712 case 0:{
01713 if ( textParser->NextCharIs('['," \t\n\r,")){
01714 textParser->GetChar(" \t\n\r,");
01715 while ( !textParser->NextCharIs(']')){
01716 wxString texPath = scenePath + textParser->GetWxString();
01717 wxCommandEvent texEvt = Event::GET_EVT_SCENE_IMAGE_ADD(texPath);
01718 module->PostToKernel(texEvt);
01719 material->imageName = texPath;
01720 }
01721 textParser->GetChar(" \t\n\r,");
01722 }
01723 else {
01724
01725 wxString texPath = scenePath + textParser->GetWxString();
01726
01727 wxCommandEvent texEvt = Event::GET_EVT_SCENE_IMAGE_ADD(texPath);
01728 module->PostToKernel(texEvt);
01729 material->imageName = texPath;
01730 }
01731 }
01732 break;
01733 case 1:
01734 if ( textParser->NextKeywordIs("TRUE"," \t\n\r,")){
01735 material->texFlags |= ( Material::TEX_UWRAP_REPEAT );
01736 }
01737 else {
01738 textParser->GetWxString();
01739 material->texFlags |= ( Material::TEX_UWRAP_CLAMP );
01740 }
01741 break;
01742 case 2:
01743 if ( textParser->NextKeywordIs("TRUE"," \t\n\r,")){
01744 material->texFlags |= ( Material::TEX_VWRAP_REPEAT );
01745 }
01746 else {
01747 textParser->GetWxString();
01748 material->texFlags |= ( Material::TEX_VWRAP_CLAMP );
01749 }
01750 break;
01751 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01752 }
01753 }
01754
01755 material->texBlendSrc = GL_SRC_ALPHA ;
01756 material->texBlendDst = GL_ONE_MINUS_SRC_ALPHA ;
01757
01758 material->flags |= Material::BLENDED ;
01759
01760 textParser->GetChar(" \t\n\r,");
01761 return true;
01762 }
01763
01764
01765 bool VRMLParser::LOD(const wxString & parentUid, bool just_define){
01766 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01767 else textParser->GetChar();
01768
01769 static const char *keywords[]={"center", "range", "level", ""};
01770 int index;
01771 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
01772 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
01773 switch(index){
01774 case 0:
01775 logWarnMsg(UNSUPPORTED_ATTR, wxT("center"));
01776 textParser->GetWxString();
01777 textParser->GetWxString();
01778 textParser->GetWxString();
01779 break;
01780 case 1:
01781 logWarnMsg(UNSUPPORTED_ATTR, wxT("range"));
01782 skip(']');
01783 break;
01784 case 2:
01785 {
01786 static const char *k[] = {"]",""};
01787 textParser->GetWxString();
01788 while ( index = textParser->KeywordsSwitch(k," \t\n\r,", " \t\n\r,{}[]") != 0){
01789 if ( !node(parentUid, just_define)) return false;
01790 }
01791 break;
01792 }
01793 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01794 }
01795 }
01796 textParser->GetChar(" \t\n\r,");
01797 return true;
01798 }
01799
01800 bool VRMLParser::Material(VRUT::Material * material){
01801 if ( textParser->GetChar(" \t\n\r,") != '{') {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01802
01803 static const char *keywords[]={ "diffuseColor", "emissiveColor", "specularColor", "ambientIntensity", "shininess", "transparency", ""};
01804
01805 VECTOR4 diffuse(0.8,0.8,0.8,1);
01806 VECTOR4 emissive(0,0,0);
01807 VECTOR4 specular(0,0,0);
01808 float ambIntensity = 0.2;
01809 float shininess = 0.2;
01810
01811 int index;
01812 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
01813 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
01814
01815 switch(index){
01816 case 0:
01817 if (textParser->ParseVector(diffuse._v, 3, true) != 3)
01818 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01819 break;
01820 case 1:
01821 if (textParser->ParseVector(emissive._v, 3, true) != 3)
01822 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01823 break;
01824 case 2:
01825 if (textParser->ParseVector(specular._v, 3, true) != 3)
01826 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01827 break;
01828 case 3:
01829 if (!textParser->ParseFloat(&ambIntensity))
01830 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01831 break;
01832 case 4:
01833 if (!textParser->ParseFloat(&shininess))
01834 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01835 break;
01836 case 5:
01837 float temp;
01838
01839
01840 if (textParser->ParseFloat(&temp)){
01841 material->diffuse.w = 1 - temp;
01842 } else
01843 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01844 material->texBlendSrc = GL_SRC_ALPHA;
01845 material->texBlendDst = GL_ONE_MINUS_SRC_ALPHA;
01846 material->flags |= Material::BLENDED;
01847 break;
01848 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01849 }
01850 }
01851 material->diffuse = diffuse;
01852 material->emission = emissive;
01853 material->specular = specular;
01854 material->ambient.w = ambIntensity;
01855 material->shininess = shininess;
01856 textParser->GetChar(" \t\n\r,");
01857 return true;
01858 }
01859
01860 bool VRMLParser::PointLight(Light* light){
01861 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01862 else textParser->GetChar();
01863
01864 static const char *keywords[]={"location", "attenuation", "radius", "intensity", "ambientIntensity","color", "on",""};
01865 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
01866 int index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
01867 switch(index){
01868 case 0:
01869 if ( textParser->ParseVector(light->position._v,3,true) != 3)
01870 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01871 break;
01872 case 1:
01873 logWarnMsg(UNSUPPORTED_ATTR, wxT("attenuation"));
01874 textParser->GetWxString();
01875 textParser->GetWxString();
01876 textParser->GetWxString();
01877 break;
01878 case 2:
01879 case 3:
01880 case 4:
01881 logWarnMsg(UNSUPPORTED_ATTR, wxT("radius|intensity|ambientIntensity"));
01882 textParser->GetWxString();
01883 break;
01884 case 5:
01885 if (textParser->ParseVector(light->diffuse._v, 3,true) != 3)
01886 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01887 break;
01888 case 6:
01889 logWarnMsg(UNSUPPORTED_ATTR, wxT("on"));
01890 textParser->GetWxString();
01891 break;
01892 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01893 }
01894 }
01895 light->type = Light::SPOTLIGHT;
01896 light->angle = 180;
01897 light->exponent = 1;
01898 textParser->GetChar(" \t\n\r,");
01899 return true;
01900 }
01901
01902 bool VRMLParser::PointSet(const wxString & parentUid, GeometryTriangles* geometry){
01903 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01904 else textParser->GetChar();
01905
01906 std::vector<VECTOR3> * verts = &(geometry->vertices);
01907
01908 wxString defName = wxT("");
01909 static const char *keywords[]={"color", "coord", ""};
01910 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
01911
01912 int index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
01913 switch(index){
01914 case 0:
01915 logWarnMsg(UNSUPPORTED_ATTR, wxT("color"));
01916 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
01917 textParser->GetWxString();
01918 break;
01919 }
01920 skip('}');
01921 break;
01922 case 1: {
01923 if ( textParser->NextKeywordIs("USE"," \t\n\r,")){
01924 std::vector<VECTOR3> * geom = dynamic_cast<std::vector<VECTOR3> *>(defNamesListV3[textParser->GetWxString()]);
01925 if ( geom == NULL){
01926 LOGERROR(wxT("Unexpected USE name"));
01927 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01928 }
01929 verts->assign(geom->begin(), geom->end());
01930 break;
01931 }
01932 if ( textParser->NextKeywordIs("DEF"," \t\n\r,")){
01933 defName = textParser->GetWxString();
01934 }
01935 if (!parseFArray3(verts, "Coordinate", "point")) {
01936 LOGERROR(wxT("Failed parsing coordinate"));
01937 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01938 }
01939 if ( defName != wxT(""))
01940 defNamesListV3.insert(DefNamesListV3::value_type(defName, new std::vector<VECTOR3>(geometry->vertices)));
01941 break;
01942 }
01943 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
01944 }
01945 }
01946 GeometryTriangles::Indice counter = 0;
01947 for ( std::vector<VECTOR3>::iterator it = verts->begin(); it != verts->end(); it++)
01948 geometry->indices.push_back(counter++);
01949 if ( verts->size() != 0 )
01950 geometry->triDescList.push_back(std::pair<GeometryTriangles::Indice, GeometryTriangles::PRIMITIVE_TYPE> ((GeometryTriangles::Indice)(0),GeometryTriangles::POINTS));
01951 textParser->GetChar(" \t\n\r,");
01952 return true;
01953 }
01954
01955 bool VRMLParser::Shape(const wxString & nodeUid, bool just_define, GNode* gnode ){
01956 if ( textParser->GetChar(" \t\n\r,") != '{') {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
01957
01958 static const char *keywords[]={"appearance", "geometry", ""};
01959 static const char *keywords_g[]={"Box","Cone","Cylinder","Sphere", "ElevationGrid", "Extrusion", "Text", "IndexedFaceSet", "IndexedLineSet", "PointSet", ""};
01960
01961 int index;
01962 wxString defName;
01963
01964
01965 VECTOR2 translation = VECTOR2(0,0);
01966 float rotation = 0;
01967 VECTOR2 scale = VECTOR2(1,1);
01968 VECTOR2 center = VECTOR2(0,0);
01969
01970 GeometryTriangles *geometry = NULL;
01971 wxString g_name;
01972
01973 while ( !textParser->NextCharIs('}'," \t\n\r,") )
01974 {
01975 defName = wxT("");
01976 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
01977 switch(index)
01978 {
01979 case 0:
01980 {
01981 if ( textParser -> NextKeywordIs("USE"," \t\n\r,")){
01982 wxString useName = textParser->GetWxString();
01983 DefNamesListM::iterator it = defNamesListM.find(useName);
01984 if ( it != defNamesListM.end()){
01985 VRUT::Material* help = it->second;
01986 if ( !just_define ){
01987 wxCommandEvent ev1 = Event::GET_EVT_SCENE_NODE_MATERIAL_SET(sceneID, nodeUid, help->name);
01988 module->PostToKernel(ev1);
01989 }
01990 else
01991 if (gnode!= NULL) gnode->setMaterial(NULL, help->name, useName);
01992 break;
01993 }
01994 else
01995 LOGERROR(wxT("<VRMLParser>Unexpected USE name "));
01996 return false;
01997 }
01998 wxString mat_name;
01999 VRUT::Material* material;
02000
02001 if (textParser->NextKeywordIs("DEF"," \t\n\r,") )
02002 defName = textParser->GetWxString();
02003
02004 if ( defName != wxT(""))
02005 mat_name = getUniqueUid(defName);
02006 else mat_name = getUniqueUid(wxString::FromAscii("material"));
02007 material = new VRUT::Material(mat_name);
02008
02009 if (textParser->NextKeywordIs("Appearance"," \t\n\r,") && Appearance(nodeUid, material, translation, rotation, scale, center)){
02010 if ( !just_define ) {
02011 wxCommandEvent ev = Event::GET_EVT_SCENE_MATERIAL_ADD(sceneID, material);
02012 module->PostToKernel(ev);
02013 wxCommandEvent ev1 = Event::GET_EVT_SCENE_NODE_MATERIAL_SET(sceneID, nodeUid, mat_name);
02014 module->PostToKernel(ev1);
02015 } else {
02016 if (gnode!=NULL) gnode->setMaterial(material, mat_name, defName);
02017 else {
02018 wxCommandEvent ev = Event::GET_EVT_SCENE_MATERIAL_ADD(sceneID, material);
02019 module->PostToKernel(ev);
02020 }
02021 }
02022 } else {
02023 SAFE_DELETE(material);
02024 LOGERROR(wxT("<VRMLParser>Failed parsing material "));
02025 return false;
02026 }
02027 if ( defName != wxT(""))
02028 defNamesListM.insert(DefNamesListM::value_type(defName, material->Clone() ));
02029 break;
02030 }
02031 case 1:
02032 {
02033 if ( textParser -> NextKeywordIs("USE"," \t\n\r,")){
02034 wxString useName = textParser->GetWxString();
02035 DefNamesListG::iterator it = defNamesListG.find(useName);
02036 if ( it != defNamesListG.end() ){
02037 if ( !just_define) {
02038 wxCommandEvent ev = Event::GET_EVT_SCENE_NODE_GEOMETRY_SET(sceneID, nodeUid, it->second);
02039 module->PostToKernel(ev);
02040 } else
02041 gnode->setGeometry(NULL, it->second, useName );
02042 break;
02043 }
02044 else
02045 LOGERROR(wxT("<VRMLParser>Unexpected USE name "));
02046 return false;
02047 }
02048
02049 if (textParser->NextKeywordIs("DEF"," \t\n\r,"))
02050 defName = textParser->GetWxString();
02051
02052 if ( defName == wxT(""))
02053 g_name = getUniqueUid(wxString::FromAscii("geometry"));
02054 else g_name = getUniqueUid(defName);
02055 geometry = new GeometryTriangles(g_name);
02056
02057 index = textParser->KeywordsSwitch(keywords_g, " \t\n\r,", " \t\n\r,{}[]");
02058 switch(index){
02059 case 0:
02060 if (!Box(geometry)) {SAFE_DELETE(geometry); return false;}
02061 break;
02062 case 1:
02063 case 2:
02064 case 3:
02065 logWarnMsg(UNSUPPORTED, wxT("Cone|Cylinder|Sphere"));
02066 skip('}');
02067 break;
02068 case 4:
02069 if (!ElevationGrid(nodeUid, geometry, just_define))
02070 {SAFE_DELETE(geometry); LOGERROR(wxT("<VRMLParser>Failed parsing ElevationGrid")); return false;}
02071 break;
02072 case 5:
02073 if (!Extrusion(nodeUid,geometry)) {SAFE_DELETE(geometry); return false;}
02074 break;
02075 case 6:
02076 logWarnMsg(UNSUPPORTED, wxT("Text"));
02077 skip('{');
02078 skip_stack('}', '{');
02079 break;
02080 case 7:
02081 if (!IndexedFaceSet(nodeUid, geometry))
02082 {SAFE_DELETE(geometry); LOGERROR(wxT("<VRMLParser>Failed parsing IndexedFaceSet")); return false;}
02083 break;
02084 case 8:
02085 if (!IndexedLineSet(nodeUid, geometry))
02086 {SAFE_DELETE(geometry);LOGERROR(wxT("<VRMLParser>Failed parsing IndexedLineSet")); return false;}
02087 break;
02088 case 9:
02089 if (!PointSet(nodeUid, geometry))
02090 {SAFE_DELETE(geometry); LOGERROR(wxT("<VRMLParser>Failed parsing PointSet")); return false;}
02091 break;
02092 default:
02093 LOGERROR(wxT("<VRMLParser>Failed parsing geometry of a Shape"));
02094 SAFE_DELETE(geometry);
02095 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02096 }
02097 break;
02098 }
02099 default:
02100 LOGERROR(wxT("<VRMLParser>Failed parsing Shape attributes"));
02101 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02102 }
02103 }
02104 textParser->GetChar(" \t\n\r,");
02105 if ( geometry != NULL) {
02106 if ( geometry->texCoords.size() != 0) {
02107
02114 if ( translation != VECTOR2(0,0) || rotation != 0 || scale != VECTOR2(1,1)) {
02115 for ( std::vector<GeometryTriangles::TexCoord>::iterator it = geometry->texCoords.begin(); it != geometry->texCoords.end(); it++){
02116 (*it)._v[0] = (*it)._v[0] + translation._v[0];
02117 (*it)._v[1] = (*it)._v[1] + translation._v[1];
02118 }
02119 }
02120 if ( rotation != 0) {
02121 for ( std::vector<GeometryTriangles::TexCoord>::iterator it = geometry->texCoords.begin(); it != geometry->texCoords.end(); it++){
02122 (*it)._v[0] = (*it)._v[0] - center._v[0];
02123 (*it)._v[1] = (*it)._v[1] - center._v[1];
02124 (*it)._v[0] = (*it)._v[0] * cos(rotation) - (*it)._v[0] * sin(rotation);
02125 (*it)._v[1] = (*it)._v[1] * sin(rotation) + (*it)._v[1] * sin(rotation);
02126 (*it)._v[0] = (*it)._v[0] + center._v[0];
02127 (*it)._v[1] = (*it)._v[1] + center._v[1];
02128 }
02129 }
02130 if ( scale != VECTOR2(1,1)) {
02131 for ( std::vector<GeometryTriangles::TexCoord>::iterator it = geometry->texCoords.begin(); it != geometry->texCoords.end(); it++){
02132 (*it)._v[0] = (*it)._v[0] - center._v[0];
02133 (*it)._v[1] = (*it)._v[1] - center._v[1];
02134 (*it)._v[0] = (*it)._v[0] * scale._v[0];
02135 (*it)._v[1] = (*it)._v[1] * scale._v[1];
02136 (*it)._v[0] = (*it)._v[0] + center._v[0];
02137 (*it)._v[1] = (*it)._v[1] + center._v[1];
02138 }
02139 }
02140 }
02141 if ( !just_define) {
02142
02143 wxCommandEvent ev2 = Event::GET_EVT_SCENE_GEOMETRY_ADD(sceneID, geometry);
02144 module->PostToKernel(ev2);
02145
02146 wxCommandEvent ev3 = Event::GET_EVT_SCENE_NODE_GEOMETRY_SET(sceneID, nodeUid, geometry->GetName());
02147 module->PostToKernel(ev3);
02148 } else {
02149 if (gnode != NULL) gnode->setGeometry(geometry, geometry->GetName(), defName);
02150 else {
02151 wxCommandEvent ev2 = Event::GET_EVT_SCENE_GEOMETRY_ADD(sceneID, geometry);
02152 module->PostToKernel(ev2);
02153 }
02154 }
02155 if ( defName != wxT(""))
02156 defNamesListG.insert(DefNamesListG::value_type(defName, geometry->GetName() ));
02157 }
02158 return true;
02159 }
02160
02161 bool VRMLParser::SpotLight(Light* light){
02162 if ( textParser->GetChar(" \t\n\r,") != '{') {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
02163 static const char *keywords[]={"location", "direction", "beamWidth","cutOffAngle",
02164 "radius", "attenuation", "color", "intensity", "ambientIntensity","on", ""};
02165
02166 float beamWidth = 1.570796;
02167 light->angle = 0.785398;
02168 light->direction = VECTOR3(0,0,-1);
02169 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
02170 int index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
02171 switch(index){
02172 case 0:
02173 if ( textParser->ParseVector(light->position._v,3,true) != 3)
02174 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02175 break;
02176 case 1:
02177 if ( textParser->ParseVector(light->direction._v,3,true) != 3 )
02178 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02179 break;
02180 case 2:
02181
02182 logWarnMsg(UNSUPPORTED_ATTR, wxT("beamWidth"));
02183 if ( !textParser->ParseFloat(&beamWidth))
02184 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02185 break;
02186 case 3:
02187 if ( !textParser->ParseFloat(& (light->angle)))
02188 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02189 break;
02190 case 4:
02191 logWarnMsg(UNSUPPORTED_ATTR, wxT("radius"));
02192 textParser->GetWxString();
02193 break;
02194 case 5:
02195 logWarnMsg(UNSUPPORTED_ATTR, wxT("attenuation"));
02196 textParser->GetWxString();
02197 textParser->GetWxString();
02198 textParser->GetWxString();
02199 break;
02200 case 6:
02201 if (textParser->ParseVector(light->diffuse._v, 3,true) != 3)
02202 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02203 break;
02204 case 7:
02205 case 8:
02206 case 9:
02207 logWarnMsg(UNSUPPORTED_ATTR, wxT("intensity|ambientIntensity|on"));
02208 textParser->GetWxString();
02209 break;
02210 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02211 }
02212 }
02213 light->type = Light::SPOTLIGHT;
02214 if ( light->angle < beamWidth)
02215 LOGWARNING(wxT("<VRMLParser>: The spotlight can't be translated exactly."));
02216 else light->exponent = 0;
02217 textParser->GetChar(" \t\n\r,");
02218 return true;
02219 }
02220
02221
02222 bool VRMLParser::Switch(const wxString & parentUid, bool jd_upper){
02223 if ( textParser->GetChar(" \t\n\r,") != '{') {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
02224
02225
02226 static const char *keywords[]={"whichChoice", "choice", ""};
02227 bool just_define = true;
02228 int index;
02229 int which = -1;
02230 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
02231 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
02232 switch(index){
02233 case 0:
02234 if (textParser->NextKeywordIs("-1"))
02235 just_define = true;
02236 else {
02237 just_define = false;
02238 if (!textParser->ParseInt(&which))
02239 return logErrorMsg(UNEXPECTED, textParser->GetWxLine() );
02240 }
02241 break;
02242 case 1:
02243 {
02244 if ( jd_upper ) just_define = true;
02245 if ( textParser->GetChar() != '[')
02246 return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("["));
02247 int counter = 0;
02248 if ( just_define) {
02249 while ( !textParser->NextCharIs(']')){
02250 if ( !node(parentUid, just_define)) return false;
02251 }
02252 } else {
02253 while ( !textParser->NextCharIs(']')){
02254 if ( counter != which ) skip_stack('}', '{');
02255 else
02256 if ( !node(parentUid, just_define)) return false;
02257 }
02258 }
02259 textParser->GetChar(" \t\n\r,");
02260 break;
02261 }
02262 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02263 }
02264 }
02265 textParser->GetChar(" \t\n\r,");
02266 return true;
02267 }
02268
02269
02270 bool VRMLParser::Transform(const wxString & parentUid, bool just_define, ANode* anode){
02271
02272 if ( textParser->GetChar(" \t\n\r,") != '{') {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
02273
02274 static const char *keywords[]={"center", "rotation", "scale", "scaleOrientation", "translation", "bboxCenter", "bboxSize", "children", ""};
02275 VECTOR3 scale(1,1,1);
02276 VECTOR4 scaleOrientation(0,0,1,0);
02277 VECTOR3 center(0,0,0);
02278 VECTOR3 translation(0,0,0);
02279 VECTOR4 rotation(0,0,1,0);
02280
02281 int index;
02282 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
02283 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
02284 switch(index){
02285 case 0:
02286 if ( textParser->ParseVector(center._v, 3, true) != 3 )
02287 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02288 break;
02289 case 1: {
02290 if ( textParser->ParseVector(rotation._v, 4, true) != 4)
02291 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02292 break;
02293 }
02294 case 2:{
02295 if (textParser->ParseVector(scale._v, 3, true) != 3)
02296 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02297 break;
02298 }
02299 case 3:
02300 { if ( textParser->ParseVector(scaleOrientation._v, 4, true) != 4)
02301 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02302 break;
02303 }
02304 case 4:
02305 {
02306 if (textParser->ParseVector(translation._v, 3, true) != 3)
02307 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02308 break;
02309 }
02310 case 5:
02311 case 6:
02312 logWarnMsg(UNSUPPORTED_ATTR, wxT("bboxCenter|bboxSize"));
02313 textParser->GetWxString();
02314 textParser->GetWxString();
02315 textParser->GetWxString();
02316 break;
02317 case 7:
02318 {
02319 if ( textParser->NextCharIs('['," \t\n\r,")) {
02320 textParser->GetChar(" \t\n\r,");
02321 while ( !textParser->NextCharIs(']'," \t\n\r,") )
02322 if ( !node(parentUid, just_define)) return false;
02323 textParser->GetChar(" \t\n\r,");
02324 } else
02325 if ( !node(parentUid, just_define)) return false;
02326 break;
02327 }
02328 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02329 }
02330 }
02331 textParser->GetChar(" \t\n\r,");
02332
02338
02339 MATRIX mat =
02340 MATRIX::RotationAxis(VECTOR3(scaleOrientation[0],scaleOrientation[1],scaleOrientation[2]),scaleOrientation[3])
02341 * MATRIX::ScaleMat(scale)
02342 * MATRIX::RotationAxis(VECTOR3(scaleOrientation[0],scaleOrientation[1],scaleOrientation[2]),-scaleOrientation[3])
02343 * MATRIX::Translation(center)
02344 * MATRIX::RotationAxis(VECTOR3(rotation[0],rotation[1],rotation[2]),-rotation[3])
02345 * MATRIX::Translation(-center)
02346 * MATRIX::Translation(translation);
02347
02348 if ( !just_define){
02349 wxCommandEvent ev3 = Event::GET_EVT_SCENE_NODE_TRANSFORM(sceneID, parentUid, mat);
02350 module->PostToKernel(ev3);
02351
02352 } else {
02353 if (anode != NULL) {
02354 anode -> setParam(mat);
02355 }
02356 }
02357 return true;
02358 }
02359
02360 bool VRMLParser::Viewpoint(MATRIX& mat, float & field){
02361 if ( !textParser->NextCharIs('{'," \t\n\r,")) {return logErrorMsg(EXPECTED, textParser->GetWxLine() , wxT("{"));}
02362 else textParser->GetChar(" \t\n\r,");
02363
02364 static const char *keywords[]={"fieldOfView", "position", "orientation", "jump", "description", ""};
02365 int index;
02366 field = 0.785398f;
02367 VECTOR3 position(0,0,10);
02368 VECTOR4 orientation(0,0,1,0);
02369
02370 while ( !textParser->NextCharIs('}'," \t\n\r,") ){
02371 index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
02372 switch(index){
02373 case 0:
02374 if (!textParser->ParseFloat(&field))
02375 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02376 break;
02377 case 1:
02378 if (textParser->ParseVector(position._v, 3, true) != 3)
02379 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02380 break;
02381 case 2:
02382 if ( textParser->ParseVector(orientation._v, 4, true) != 4)
02383 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02384 break;
02385 case 3:
02386 logWarnMsg(UNSUPPORTED_ATTR, wxT("jump"));
02387 textParser->GetWxString();
02388 break;
02389 case 4:
02390 logWarnMsg(UNSUPPORTED_ATTR, wxT("description"));
02391 skip('"'); skip('"');
02392 break;
02393 default: return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02394 }
02395 }
02396 mat = mat * MATRIX::Translation(position);
02397 mat = MATRIX::RotationAxis(VECTOR3(orientation[0],orientation[1],orientation[2]),orientation[3]) * mat;
02398
02399 textParser->GetChar(" \t\n\r,");
02400
02401 return true;
02402 }
02403
02404
02405 bool VRMLParser::proto(){
02406
02407 logWarnMsg(UNSUPPORTED, wxT("PROTO"));
02408 textParser->GetWxString();
02409 textParser->GetChar();
02410 skip(']');
02411 if (textParser->GetChar(" \t\n\r,") == '{') return skip_stack('}','{');
02412 else return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02413
02414 }
02415
02416
02417 bool VRMLParser::routeStatement(){
02418 logWarnMsg(UNSUPPORTED, wxT("ROUTE"));
02419
02420 textParser->GetWxString();
02421 textParser->GetWxString();
02422 textParser->GetWxString();
02423 return true;
02424 }
02425
02426
02427
02428 bool VRMLParser::statement(const wxString & parentUid){
02429 static const char *keywords[]={"EXTERNPROTO", "PROTO", "ROUTE", ""};
02430 int index = textParser->KeywordsSwitch(keywords, " \t\n\r,", " \t\n\r,{}[]");
02431 switch(index){
02432 case 0:
02433 case 1:
02434 return proto();
02435 case 2:
02436 return routeStatement();
02437 default:
02438 return node(parentUid, false);
02439 }
02440 }
02441
02442 bool VRMLParser::URLList(){
02443 wxString word = textParser->GetWxString();
02444
02445 if ( word == wxString::FromAscii("[") ) skip(']');
02446
02447
02448 return true;
02449 }
02450
02451 bool VRMLParser::parseModel(const wxString & rootUid)
02452 {
02453
02454 if (textParser->GetChar(NULL, false) != '#')
02455 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02456 if ( !textParser->NextKeywordIs("VRML") )
02457 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02458 if ( !textParser->NextKeywordIs("V2.0") )
02459 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02460 if ( !textParser->NextKeywordIs("utf8") )
02461 return logErrorMsg(UNEXPECTED, textParser->GetWxLine());
02462 if ( !textParser->NextCharIs('\n', " \t\r")){
02463 if ( textParser->NextKeywordIs("VRUTexporter"))
02464 fromVRUT = true;
02465 else textParser->GetWxLine();
02466 }
02467
02468 if ( textParser->IsEmpty())
02469 return true;
02470
02471
02472 while ( !textParser->IsEmpty()){
02473 if ( !statement(rootUid) )
02474 return false;
02475 }
02476 return true;
02477 }
02478
02479
02480 bool VRMLParser::Parse(const wxString & rootUid, bool teselate, NodeUidsList* nnl){
02481 if (nnl != NULL)
02482 nodeUidsList = NodeUidsList(*nnl);
02483 if ( teselate)
02484 LOGWARNING(wxT("<VRMLParser>Teselation enabled"));
02485 else
02486 LOGWARNING(wxT("<VRMLParser>Teselation disabled"));
02487 if (!parseModel(rootUid)){
02488 LOGERROR(wxT("<VRMLParser>Scene not loaded properly"));
02489 return false;
02490 }
02491 return true;
02492 }
02493
02494