1 /* 2 * Proto.h 3 * 4 * Copyright (C) 1999 Stephen F. White, 2005 J. "MUFTI" Scheurich 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program (see the file "COPYING" for details); if 18 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 19 * Cambridge, MA 02139, USA. 20 */ 21 22 #pragma once 23 24 # include "Array.h" 25 # include "Map.h" 26 # include "MyString.h" 27 # include "Node.h" 28 29 #define INVALID_INDEX (-1) 30 31 class Element; 32 class EventIn; 33 class EventOut; 34 class Field; 35 class ExposedField; 36 class FieldValue; 37 class Scene; 38 class Node; 39 40 #include "ProtoMacros.h" 41 #include "StringArray.h" 42 #include "NodeList.h" 43 #include "InterfaceArray.h" 44 45 class NodeScript; 46 class ScriptDialog; 47 48 enum UrlSchemas { 49 URL_NULL, 50 URL_VRML97_AMENDMENT1, 51 URL_X3D, 52 URL_SCRIPTED_NODES, 53 URL_COVER, 54 URL_KAMBI, 55 URL_EXPORT_CONTAINER 56 }; 57 58 class RouteInfo { 59 public: RouteInfo(Node * s,int out,Node * d,int in)60 RouteInfo(Node *s, int out, Node *d, int in) 61 { src = s; eventOut = out; dest = d; eventIn = in; } RouteInfo()62 RouteInfo() 63 { src = NULL; eventOut = -1; dest = NULL; eventIn = -1; } 64 65 Node *src; 66 Node *dest; 67 int eventOut; 68 int eventIn; 69 }; 70 71 72 class Proto { 73 public: 74 75 // unlike other nodes, script nodes need to change their Proto dynamically 76 friend class DynamicFieldsNode; 77 78 Proto(Scene *scene, const MyString &name); 79 // create a Proto as a X3D/Cover extension 80 Proto(Scene *scene, Proto *proto, int extensionFlag); Proto()81 Proto() {} 82 virtual ~Proto(); 83 84 FieldIndex metadata; 85 metadata_Field(void)86 int metadata_Field(void) const { return metadata; } 87 88 void protoInitializer(Scene *scene, const MyString &name); 89 isDynamicFieldsProto(void)90 virtual bool isDynamicFieldsProto(void) { return false; } 91 92 void finishEvents(void); 93 94 bool avoidElement(Element *element, bool x3d); 95 bool avoidElement(Element *element, int flag); 96 getType()97 virtual int getType() const { return -1; } getNodeClass()98 virtual int getNodeClass() const { return CHILD_NODE; } 99 100 bool matchNodeClass(int childType) const; 101 102 virtual Node *create(Scene *scene); needUpdate(void)103 virtual bool needUpdate(void) { return false; } 104 getEventIn(int index)105 EventIn *getEventIn(int index) const 106 { return m_eventIns[index]; } getEventOut(int index)107 EventOut *getEventOut(int index) const 108 { return m_eventOuts[index]; } getField(int index)109 Field *getField(int index) const { return m_fields[index]; } getExposedField(int index)110 ExposedField *getExposedField(int index) const 111 { return m_exposedFields[index]; } 112 Element *getElement(int elementType, int index) const; 113 getNumFields()114 int getNumFields() const { return m_fields.size(); } getNumEventIns()115 int getNumEventIns() const { return m_eventIns.size(); } getNumEventOuts()116 int getNumEventOuts() const { return m_eventOuts.size(); } getNumExposedFields()117 int getNumExposedFields() const 118 { return m_exposedFields.size(); } 119 120 int getExposedOfField(Field *field); 121 int getFieldOfExposed(ExposedField *field); 122 123 int lookupEventIn(const MyString &name, 124 bool x3d = false) const; 125 int lookupEventOut(const MyString &name, 126 bool x3d = false) const; 127 int lookupField(const MyString &name, 128 bool x3d = false) const; 129 int lookupExposedField(const MyString &name, 130 bool x3d = false) const; 131 132 int lookupIsEventIn(const char *name, 133 int elementType = -1) const; 134 int lookupIsExposedField(const char *name, 135 int elementType = -1) const; 136 137 int lookupIsEventIn(Node *node, int eventIn, 138 int elementType = -1) const; 139 int lookupIsEventOut(Node *node, int eventOut, 140 int elementType = -1) const; 141 int lookupIsField(Node *node, int field) const; 142 int lookupIsExposedField(Node *node, int field) const; 143 144 int getNumIsMSNodes(void) const; 145 Node *getIsMSNode(int numNode) const; 146 int getIsMSNodeField(int numNode) const; 147 getName(bool x3d)148 virtual const MyString &getName(bool x3d) const { return m_name; } 149 150 bool canWriteElement(Element *element, bool x3d) const; 151 int write(int filedes, int indent, int flags) const; 152 int writeEvents(int filedes, int indent, int flags) const; 153 154 virtual int writeCDeclaration(int filedes, int languageFlag); 155 int writeCDeclarationEventIn(int f, int i, 156 int languageFlag); 157 int writeCDeclarationEventOut(int f, int i, 158 int languageFlag); 159 int writeCDeclarationField(int f, int i, 160 int languageFlag); 161 virtual int writeCExtraFields(int f, int languageFlag); 162 int writeCConstructorField(int f, int i, 163 int languageFlag); 164 int writeCCallTreeField(int f, int i, 165 const char *treeFunctionName, 166 int languageFlag, 167 const char *functionName = NULL, 168 bool useObject = false); 169 170 void buildExportNames(const char *nodeName = NULL); getClassName(void)171 const char *getClassName(void) 172 { return m_className; } 173 174 MyString buildCallbackClass(const char* name); 175 MyString buildCallbackName(const char* name); 176 getRenderCallbackClass(void)177 const char *getRenderCallbackClass(void) 178 { return m_renderCallbackClass; } getRenderCallbackName(void)179 const char *getRenderCallbackName(void) 180 { return m_renderCallbackName; } 181 getTreeRenderCallbackClass(void)182 const char *getTreeRenderCallbackClass(void) 183 { return m_treeRenderCallbackClass; } getTreeRenderCallbackName(void)184 const char *getTreeRenderCallbackName(void) 185 { return m_treeRenderCallbackName; } 186 getCreateNormalsCallbackClass(void)187 const char *getCreateNormalsCallbackClass(void) 188 { return m_createNormalsCallbackClass; } getCreateNormalsCallbackName(void)189 const char *getCreateNormalsCallbackName(void) 190 { return m_createNormalsCallbackName; } 191 getDoWithDataCallbackClass(void)192 const char *getDoWithDataCallbackClass(void) 193 { return m_doWithDataCallbackClass; } getDoWithDataCallbackName(void)194 const char *getDoWithDataCallbackName(void) 195 { return m_doWithDataCallbackName; } 196 getTreeDoWithDataCallbackClass(void)197 const char *getTreeDoWithDataCallbackClass(void) 198 { return m_treeDoWithDataCallbackClass; } getTreeDoWithDataCallbackName(void)199 const char *getTreeDoWithDataCallbackName(void) 200 { return m_treeDoWithDataCallbackName; } 201 getProcessEventCallbackClass(void)202 const char *getProcessEventCallbackClass(void) 203 { return m_processEventCallbackClass; } getProcessEventCallbackName(void)204 const char *getProcessEventCallbackName(void) 205 { return m_processEventCallbackName; } 206 translateField(int field)207 virtual int translateField(int field) const { return field; } 208 getCName(bool x3d)209 virtual const MyString &getCName(bool x3d) const { return m_cName; } 210 211 int addElement(Element *element); 212 int addOrUpdateElement(Element *element); 213 int addField(Field *field); 214 int addExposedField(ExposedField *exposedField); 215 216 void deleteElements(void); 217 218 void define(Node *primaryNode, NodeList *nodes); getNumNodes(void)219 int getNumNodes(void) { return m_protoNodes.size(); } getNode(long i)220 Node *getNode(long i) 221 { 222 if (i >= m_protoNodes.size()) 223 return NULL; 224 return m_protoNodes[i]; 225 } addNode(Node * node)226 void addNode(Node *node) 227 { 228 m_protoNodes.append(node); 229 } 230 void removeNode(int i); 231 void removeFromIs(Node *node); 232 void compareToIsNodes(Node *node); 233 void addURLs(FieldValue *urls); 234 void addURLs(int urlSchema); getURLs(void)235 FieldValue * getURLs(void) { return m_urls; } isInternUrl(void)236 bool isInternUrl(void) { return m_isInternUrl; } 237 isX3dExtensionProto(void)238 bool isX3dExtensionProto(void) 239 { return isExtensionProto(FF_X3D_ONLY); } isCoverExtensionProto(void)240 bool isCoverExtensionProto(void) 241 { return isExtensionProto(FF_COVER_ONLY); } isKambiExtensionProto(void)242 bool isKambiExtensionProto(void) 243 { return isExtensionProto(FF_KAMBI_ONLY); } isX3domExtensionProto(void)244 bool isX3domExtensionProto(void) 245 { return isExtensionProto(FF_X3DOM_ONLY); } 246 bool isExtensionProto(int flag); 247 bool isMismatchingProto(void); getUrls(void)248 FieldValue *getUrls(void) { return m_urls; } isExternProto(void)249 bool isExternProto(void) { return m_urls != NULL; } 250 bool checkIsExtension(Element *element, int flag); 251 isCoverProto(void)252 virtual bool isCoverProto(void) { return false; } isKambiProto(void)253 virtual bool isKambiProto(void) { return false; } isX3domProto(void)254 virtual bool isX3domProto(void) { return false; } isScriptedProto(void)255 virtual bool isScriptedProto(void) { return false; } isScriptedExternProto(void)256 virtual bool isScriptedExternProto(void) { return false; } isX3dInternalProto(void)257 virtual bool isX3dInternalProto(void) { return false; } 258 setScene(Scene * scene)259 void setScene(Scene *scene) { m_scene = scene; } getScene(void)260 Scene *getScene(void) { return m_scene; } 261 262 void convert2X3d(void); 263 void convert2Vrml(void); 264 isLoading(void)265 bool isLoading(void) { return m_loading; } setLoading(bool flag)266 void setLoading(bool flag) { m_loading = flag; } isLoaded(void)267 bool isLoaded(void) 268 { return m_loaded && (m_protoNodes.size() > 0); } setLoaded(bool flag)269 void setLoaded(bool flag) { m_loaded = flag; } 270 isDefined(void)271 bool isDefined(void) { return m_defined; } 272 setAppinfo(const MyString & appinfo)273 void setAppinfo(const MyString& appinfo) 274 { m_appinfo = appinfo; } getAppinfo()275 MyString getAppinfo() const 276 { return m_appinfo; } setDocumentation(const MyString & documentation)277 void setDocumentation(const MyString& documentation) 278 { m_documentation = documentation; } getDocumentation()279 MyString getDocumentation() const 280 { return m_documentation; } 281 isDynamicProto(void)282 bool isDynamicProto(void) { return m_dynamicProto; } setDynamicProto(void)283 void setDynamicProto(void) { m_dynamicProto = true; } 284 isMesh(void)285 virtual bool isMesh(void) { return false; } isExportTargetMesh(void)286 virtual bool isExportTargetMesh(void) { return false; } isWonderlandExported(void)287 virtual bool isWonderlandExported(void) 288 { 289 if (isMesh()) 290 return true; 291 return false; 292 } 293 isWriteCDeclarationWritten()294 bool isWriteCDeclarationWritten() 295 { return m_writeCDeclarationWritten; } setWriteCDeclarationWritten(bool flag)296 void setWriteCDeclarationWritten(bool flag) 297 { m_writeCDeclarationWritten = flag; } 298 isInScene()299 bool isInScene() 300 { 301 #ifdef HAVE_NULL_COMPARE 302 if (this == NULL) 303 return false; 304 #endif 305 return m_isInScene; 306 } setIsInScene(bool flag)307 void setIsInScene(bool flag) { m_isInScene = flag; } 308 isDeclaredInRwd_h()309 virtual bool isDeclaredInRwd_h() { return false; } 310 isInUse(void)311 bool isInUse(void) { return m_inUse; } setInUse(bool flag)312 void setInUse(bool flag) { m_inUse = flag; } 313 fromProtoLibrary()314 bool fromProtoLibrary() { return m_fromProtoLibrary; } setFromProtoLibrary()315 void setFromProtoLibrary() { m_fromProtoLibrary = true; } 316 317 bool showFields(bool x3d); showFields()318 virtual bool showFields() { return false; } 319 bool hasNumbers4kids(void); 320 getInterfaceData(void)321 InterfaceArray *getInterfaceData(void) 322 { 323 return &m_interface; 324 } getInterfaceData(bool protoFlag)325 InterfaceArray *getInterfaceData(bool protoFlag) 326 { 327 buildInterfaceData(protoFlag); 328 return &m_interface; 329 } 330 void buildInterfaceData(bool protoFlag); 331 332 int addField(int fieldType, const MyString &name, 333 FieldValue *defaultValue = NULL, 334 FieldValue *min = NULL, 335 FieldValue *max = NULL); 336 int addExposedField(int fieldType, const MyString &name, 337 FieldValue *defaultValue = NULL, 338 FieldValue *min = NULL, 339 FieldValue *max = NULL, 340 const MyString &x3dName = ""); 341 int addEventIn(int fieldType, const MyString &name); 342 int addEventOut(int fieldType, const MyString &name); 343 getGraphPosition(float * x,float * y)344 void getGraphPosition(float *x, float *y) const 345 { *x = m_graphX; *y = m_graphY; } setGraphPosition(float x,float y)346 void setGraphPosition(float x, float y) 347 { m_graphX = x; m_graphY = y; } 348 getGraphSize(int * width,int * height)349 void getGraphSize(int *width, int *height) const 350 { *width = m_graphWidth; *height = m_graphHeight; } setGraphSize(int width,int height)351 void setGraphSize(int width, int height) 352 { m_graphWidth = width; m_graphHeight = height; } 353 void deleteField(int i); 354 void deleteEventIn(int i); 355 void deleteEventOut(int i); 356 void deleteExposedField(int i); 357 void setIsNodeIndex(void); 358 getUnitLength(void)359 double getUnitLength(void) { return m_unitLength; } getUnitAngle(void)360 double getUnitAngle(void) { return m_unitAngle; } 361 setUnitLength(double u)362 void setUnitLength(double u) { m_unitLength = u; } setUnitAngle(double u)363 void setUnitAngle(double u) { m_unitAngle = u; } 364 isCRouteSource(void)365 virtual bool isCRouteSource(void) { return false; } 366 hasTimeSensor(void)367 bool hasTimeSensor(void) 368 { return m_hasTimeSensor; } 369 specialInit(void)370 bool specialInit(void) 371 { 372 static bool init = true; 373 if (init) { 374 init = false; 375 return true; 376 } 377 return false; 378 } 379 380 protected: copy()381 Proto *copy() const { return new Proto(*this); } 382 int addField(int fieldType, const MyString &name, 383 FieldValue *defaultValue, int nodeType); 384 int addField(int fieldType, const MyString &name, 385 FieldValue *defaultValue, int flags, 386 const char **strings); 387 int addEventIn(int fieldType, const MyString &name, 388 int flags); 389 int addEventIn(int fieldType, const MyString &name, 390 int flags, int field); 391 int addEventOut(int fieldType, const MyString &name, 392 int flags); 393 int addExposedField(int fieldType, const MyString &name, 394 FieldValue *defaultValue, 395 int nodeType, 396 const MyString &x3dName = ""); 397 int addExposedField(int fieldType, const MyString &name, 398 FieldValue *defaultValue, int flags, 399 const char **strings); 400 int addExposedField(int fieldType, const MyString &name, 401 FieldValue *defaultValue, 402 FieldValue *min, FieldValue *max, 403 int nodeType, int flags, 404 const char **strings, 405 const MyString &x3dName); 406 int lookupSimpleEventIn(const MyString &name, 407 bool x3d) const; 408 int lookupSimpleEventOut(const MyString &name, 409 bool x3d) const; 410 void setFieldFlags(int index, int flags); 411 412 protected: 413 Scene *m_scene; 414 MyString m_name; 415 MyArray<EventIn *> m_eventIns; 416 MyArray<EventOut *> m_eventOuts; 417 MyArray<Field *> m_fields; 418 MyArray<ExposedField *> m_exposedFields; 419 420 MyString m_appinfo; 421 MyString m_documentation; 422 423 InterfaceArray m_interface; 424 425 bool m_writeCDeclarationWritten; 426 bool m_isInScene; 427 428 bool m_showFieldsInit; 429 bool m_showFields; 430 431 bool m_numbers4Kids; 432 bool m_numbers4KidsInit; 433 434 // for PROTO's: 435 MyArray<Node *> m_protoNodes; 436 int m_nodeIndex; 437 FieldValue *m_urls; 438 bool m_isInternUrl; 439 bool m_loaded; 440 bool m_loading; 441 bool m_defined; 442 StringArray m_nameOfFieldsWithDefaultValue; 443 444 float m_graphX, m_graphY; 445 int m_graphWidth, m_graphHeight; 446 447 MyString m_cName; 448 MyString m_className; 449 450 MyString m_renderCallbackClass; 451 MyString m_renderCallbackName; 452 453 MyString m_treeRenderCallbackClass; 454 MyString m_treeRenderCallbackName; 455 456 MyString m_createNormalsCallbackClass; 457 MyString m_createNormalsCallbackName; 458 459 MyString m_doWithDataCallbackClass; 460 MyString m_doWithDataCallbackName; 461 462 MyString m_treeDoWithDataCallbackClass; 463 MyString m_treeDoWithDataCallbackName; 464 465 MyString m_processEventCallbackClass; 466 MyString m_processEventCallbackName; 467 468 bool m_dynamicProto; 469 bool m_inUse; 470 471 bool m_fromProtoLibrary; 472 double m_unitLength; 473 double m_unitAngle; 474 475 bool m_hasTimeSensor; 476 }; 477 478 #include "DynamicFieldsNode.h" 479 480 class NodePROTO : public DynamicFieldsNode 481 { 482 public: 483 NodePROTO(Scene *scene, Proto *proto); 484 void createPROTO(bool copy = true); 485 getX3dVersion(void)486 virtual int getX3dVersion(void) const { return 0; } 487 isPROTO(void)488 virtual bool isPROTO(void) const { return true; } 489 490 virtual int write(int filedes, int indent, bool avoidUse); 491 492 virtual int writeXml(int filedes, int indent, 493 int containerField = -1, 494 bool avoidUse = false); 495 writeFields(int filedes,int indent)496 virtual int writeFields(int filedes, int indent) 497 { return Node::writeFields(filedes, indent); } 498 writeProto(int f)499 virtual int writeProto(int f) { return Node::writeProto(f); } 500 writeCDynamicNodeCallback(int f,int languageFlag)501 virtual int writeCDynamicNodeCallback(int f, int languageFlag) 502 { 503 return Node::writeCDynamicNodeCallback(f, 504 languageFlag); 505 } 506 507 virtual int getType() const; 508 virtual int getNodeClass() const; 509 virtual int getProfile(void) const; copy()510 virtual Node *copy() const { return new NodePROTO(*this); } 511 getPrimaryProto()512 virtual Proto *getPrimaryProto() const 513 { return m_indexedNodes[0]->getProto(); } 514 515 virtual void preDraw(); 516 virtual void draw(); 517 virtual void draw(int pass); 518 519 virtual void update(); 520 virtual void reInit(void); 521 522 virtual FieldValue *getField(int index) const; 523 virtual void setField(int index, FieldValue *value, int cf = -1); 524 void receiveProtoEvent(int eventOut, double timestamp, 525 FieldValue *value); 526 virtual void sendEvent(int eventOut, double timestamp, 527 FieldValue *value); 528 virtual void receiveEvent(int eventIn, double timestamp, 529 FieldValue *value); 530 Node *getIsNode(int nodeIndex); 531 void appendToIndexedNodes(Node *node); getNumIndexedNodes(void)532 int getNumIndexedNodes(void) 533 { return m_indexedNodes.size(); } getIndexedNode(int i)534 Node *getIndexedNode(int i) { return m_indexedNodes[i]; } isJoint(void)535 virtual bool isJoint(void) { return m_jointRotationField != -1; } isHumanoid(void)536 virtual bool isHumanoid(void) { return m_isHumanoid; } 537 virtual void drawHandles(void); 538 virtual int countPolygons(void); 539 virtual int countPrimitives(void); 540 virtual int countPolygons1Sided(void); 541 virtual int countPolygons2Sided(void); 542 virtual Vec3f getHandle(int handle, int *constraint, int *field); 543 virtual void setHandle(int handle, const Vec3f &v); 544 virtual void transform(); 545 virtual bool isEXTERNPROTO(void); 546 void getComponentsInBranch(DoWithNodeCallback callback, 547 void *data); 548 virtual bool canWriteAc3d(); 549 virtual int writeAc3d(int filedes, int indent); 550 virtual void handleAc3dMaterial(ac3dMaterialCallback callback, 551 Scene* scene); 552 virtual int writeRib(int filedes, int indent); 553 554 virtual bool canWriteCattGeo(); 555 virtual int writeCattGeo(int filedes, int indent); 556 hasProtoNodes(void)557 virtual bool hasProtoNodes(void) 558 { return m_indexedNodes.size() > 0; } 559 Node *getProtoRoot(void); 560 getProtoNode(int i)561 Node *getProtoNode(int i) { return m_nodes.get(i); } getNumProtoNodes(void)562 int getNumProtoNodes(void) { return m_nodes.size(); } 563 isLoaded(void)564 bool isLoaded(void) 565 { return getProto()->isLoaded() && 566 (m_indexedNodes.size() > 0); } 567 showFields()568 virtual bool showFields() { return true; } 569 570 protected: 571 NodeList m_nodes; 572 MyArray<Node *> m_indexedNodes; 573 int m_jointRotationField; 574 bool m_isHumanoid; 575 }; 576 577 typedef MyArray<Proto *> ProtoArray; 578 int getMaskedNodeClass(int nodeClass); 579 bool matchNodeClass(int nodeType, int childType, bool repeat = true); 580 581 class WonderlandExportProto : public Proto { 582 public: WonderlandExportProto(Scene * scene,const char * name)583 WonderlandExportProto(Scene *scene, const char *name) : 584 Proto(scene, name) {} 585 isWonderlandExported(void)586 virtual bool isWonderlandExported(void) { return true; } 587 }; 588 589