/* * Node.h * * Copyright (C) 1999 Stephen F. White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file "COPYING" for details); if * not, write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. */ #ifndef _NODE_H #define _NODE_H #ifndef _STDIO_H #include #endif #ifndef _ARRAY_H #include "Array.h" #endif #ifndef _LIST_H #include "List.h" #endif #ifndef _VEC3F_H #include "Vec3f.h" #endif #ifndef _DUNE_STRING_H #include "MyString.h" #endif class FieldValue; class Node; class Scene; class Proto; class Path; class NodeList; class Socket { public: Socket() { _node = NULL; _index = -1; } Socket(Node *node, int index) { _node = node; _index = index; } int operator==(const Socket &t) { return t._node == _node && t._index == _index; } int operator!=(const Socket &t) { return t._node != _node || t._index != _index; } Node *_node; int _index; }; typedef List SocketList; enum parentFlag { PARENT_NOT_TOUCHED, PARENT_TOUCHED, PARENT_RECURSIVE }; class Parent { public: Parent(Node *node, int index, Node *self) { _node = node; _index = index; _self = self; _parentFlag = PARENT_NOT_TOUCHED; } int operator==(const Parent &t) { return t._self == _self; } int operator!=(const Parent &t) { return t._self != _self; } Node *_node; int _index; Node *_self; parentFlag _parentFlag; }; typedef List ParentList; typedef ParentList::Iterator *ParentIter; enum flags { NODE_FLAG_SELECTED, NODE_FLAG_TOUCHED, NODE_FLAG_COLLAPSED, NODE_FLAG_DEFED }; enum Constraint { CONSTRAIN_NONE = 0, CONSTRAIN_X, CONSTRAIN_Y, CONSTRAIN_Z, CONSTRAIN_XY, CONSTRAIN_YZ, CONSTRAIN_ZX, CONSTRAIN_SPHERE }; #ifdef WIN32 # undef NODE_COMMENT # undef NODE_TEXT #endif enum NodeEnum { NODE_ANCHOR, NODE_APPEARANCE, NODE_AUDIO_CLIP, NODE_BACKGROUND, NODE_BILLBOARD, NODE_BOX, NODE_COLLISION, NODE_COLOR, NODE_COLOR_INTERPOLATOR, NODE_CONE, NODE_CONTOUR_2D, NODE_COORDINATE, NODE_COORDINATE_DEFORMER, NODE_COORDINATE_INTERPOLATOR, NODE_CYLINDER, NODE_CYLINDER_SENSOR, NODE_DIRECTIONAL_LIGHT, NODE_ELEVATION_GRID, NODE_EXTRUSION, NODE_FOG, NODE_FONT_STYLE, // NODE_GEO_COORDINATE, // NODE_GEO_ELEVATION_GRID, // NODE_GEO_LOCATION, // NODE_GEO_LOD, // NODE_GEO_METADATA, // NODE_GEO_ORIGIN, // NODE_GEO_POSITION_INTERPOLATOR, // NODE_GEO_TOUCH_SENSOR, // NODE_GEO_VIEWPOINT, NODE_GROUP, NODE_IMAGE_TEXTURE, NODE_INDEXED_FACE_SET, NODE_INDEXED_LINE_SET, NODE_INLINE, NODE_INLINE_LOAD_CONTROL, NODE_LOAD_SENSOR, NODE_LOD, NODE_MATERIAL, NODE_MOVIE_TEXTURE, NODE_NAVIGATION_INFO, NODE_NORMAL, NODE_NORMAL_INTERPOLATOR, NODE_NURBS_CURVE, NODE_NURBS_CURVE_2D, NODE_NURBS_GROUP, NODE_NURBS_POSITION_INTERPOLATOR, NODE_NURBS_SURFACE, NODE_NURBS_TEXTURE_SURFACE, NODE_ORIENTATION_INTERPOLATOR, NODE_PIXEL_TEXTURE, NODE_PLANE_SENSOR, NODE_POINT_LIGHT, NODE_POINT_SET, NODE_POLYLINE_2D, NODE_POSITION_INTERPOLATOR, NODE_PROXIMITY_SENSOR, NODE_SCALAR_INTERPOLATOR, NODE_SCRIPT, NODE_SHAPE, NODE_SOUND, NODE_SPHERE, NODE_SPHERE_SENSOR, NODE_SPOT_LIGHT, NODE_SUPER_ELLIPSOID, NODE_SUPER_EXTRUSION, NODE_SUPER_SHAPE, NODE_SWITCH, NODE_TEXT, NODE_TEXTURE_COORDINATE, NODE_TEXTURE_TRANSFORM, NODE_TIME_SENSOR, NODE_TOUCH_SENSOR, NODE_TRANSFORM, NODE_TRIMMED_SURFACE, NODE_VIEWPOINT, NODE_VISIBILITY_SENSOR, NODE_WORLD_INFO, NODE_COMMENT }; // the following are node "classes", used to validate the // scene graph hierarchy enum { ANY_NODE = 1<<20, CHILD_NODE = 1<<21, GEOMETRY_NODE = 1<<22, PARAMETRIC_GEOMETRY_NODE = 1<<23, NURBS_CONTROL_CURVE_NODE = 1<<24, NURBS_TEXTURE_SURFACE_NODE = 1<<25, TEXTURE_COORDINATE_NODE = 1<<26, TEXTURE_NODE = 1<<27, SOUND_SOURCE_NODE = 1<<28, URL_NODE = 1<<29, INTERPOLATOR_NODE = 1<<30 // do not use sign bit 31 }; class NodeData { public: NodeData(Scene *scene, Proto *proto); NodeData(const Node &node); bool isClassType(int type) { return type >= ANY_NODE; } virtual int write(int filedes, int indent); virtual bool writeEXTERNPROTO(int filedes); Scene *getScene() const { return _scene; } FieldValue *getField(int index, bool ignoreproto=false) const; virtual void setField(int index, FieldValue *value); // setName should only be called from Scene::def void setName(const char *name) { _name = name; } const MyString &getName(void); bool hasName(void); void getGraphPosition(float *x, float *y) const { *x = _graphX; *y = _graphY; } void setGraphPosition(float x, float y) { _graphX = x; _graphY = y; } void getGraphSize(int *width, int *height) const { *width = _graphWidth; *height = _graphHeight; } void setGraphSize(int width, int height) { _graphWidth = width; _graphHeight = height; } void ref() { _refs++; } void unref() { if (--_refs == 0) delete this; } int getRefs() { return _refs; } virtual int getType() const = 0; virtual Node *copy() const = 0; int findChild(Node *child, int field) const; int lookupEventIn(const MyString &name) const; int lookupEventOut(const MyString &name) const; Proto *getProto() const { return _proto; } virtual int getNodeClass() const { return CHILD_NODE; } void addInput(int eventIn, Node *src, int eventOut); void addOutput(int eventOut, Node *dst, int eventIn); void removeInput(int eventIn, Node *src, int eventOut); void removeOutput(int eventOut, Node *dst, int eventIn); const SocketList &getInput(int i) { return _inputs[i]; } const SocketList &getOutput(int i) { return _outputs[i]; } virtual void update(); virtual void reInit(); Node *getParent(ParentIter iter) const { return iter->item()._node; } int getParentField(ParentIter iter) const { return iter->item()._index; } int getNumParents() const { return _parents.size(); } parentFlag getParentFlag(int index) const { return _parents.get(index)->item()._parentFlag; } void setParentFlag(int index, parentFlag flag) { Parent parent=_parents.get(index)->item(); parent._parentFlag = flag; _parents.get(index)->setItem(parent); } bool validChild(int field, Node *child); bool validChildType(int field, int childType); int findValidField(Node *child); int findValidFieldType(int childType); Path *getPrimaryPath() const; FieldValue *rewriteField(FieldValue *value, const char *oldBase, const char *newBase); bool needsDEF() const; bool getFlag(int flag) const { return (_flags & (1 << flag)) != 0; } void setFlag(int flag) { _flags |= (1 << flag); } int getNumberUse() { return _numberUse; } void setNumberUse(int use) { _numberUse = use; } void setFlagRec(int flag); void clearFlag(int flag) { _flags &= ~(1 << flag); } void clearFlagRec(int flag); bool isSelected() const { return getFlag(NODE_FLAG_SELECTED); } bool isCollapsed() const { return getFlag(NODE_FLAG_COLLAPSED); } virtual void preDraw() {} virtual void transform() {} virtual void transformForHandle(int /* handle */) {} virtual void draw() {} virtual void bind() {} virtual void unbind() {} virtual void drawHandles() {} virtual int countPolygons(void) {return 0;} virtual int countPrimitives(void) {return 0;} virtual Vec3f getHandle(int handle, int *constraint, int *field) { *field=-1;return Vec3f(0.0f, 0.0f, 0.0f); } virtual void setHandle(int /* handle */, const Vec3f & /* v */) {} void sendEvent(int eventOut, double timestamp, FieldValue *value); virtual void receiveEvent(int eventIn, double timestamp, FieldValue *value); virtual bool isInterpolator() { return false; } //nurbs conversion virtual virtual Node *toNurbs() {return NULL;} virtual Node *toNurbs(int nshell, int narea, int narcs, int uDegree, int vDegree) {return NULL;} virtual Node *toNurbs(int narcslong, int narcslat, int uDegree, int vDegree) {return NULL;} virtual Node *toNurbs(int nAreaPoints, int Degree) {return NULL;} virtual Node *toNurbs(int narcs, int pDegree, float rDegree, int axis) {return NULL;} virtual Node *toNurbs(int narcs, int pDegree, float uDegree, Vec3f &P1, Vec3f &P2) {return NULL;} virtual Node *degreeElevate(int newDegree) {return NULL;} virtual Node *degreeElevate(int newUDegree, int newVDegree) {return NULL;} // mesh conversion virtual virtual Node *toIndexedFaceSet(bool wantNormal = true) { return NULL; } virtual bool canConvertToIndexedFaceSet(void) { return false; } // extrusion conversion virtual virtual Node *toExtrusion(void) { return NULL; } virtual bool canConvertToExtrusion(void) { return false; } /// compare content bool isEqual(Node* Node); friend bool isEqual(Node* Node); MyString newEventName(int typeEnum, bool out); bool hasFieldFlag(int flag); virtual bool isInvalidChildNode(void) { // true if node may not be part of a MFNode field // of a other node (or at root of scenegraph) return false; } protected: int writeFields(int f, int indent); int writeRoutes(int f, int indent) const; protected: Scene *_scene; MyString _name; int _refs; int _numberUse; int _flags; Proto *_proto; ParentList _parents; FieldValue **_fields; int _numFields; int _numEventIns; int _numEventOuts; SocketList *_inputs; SocketList *_outputs; float _graphX, _graphY; int _graphWidth, _graphHeight; unsigned long _identifier; }; class Node : public NodeData { public: Node(Scene *scene, Proto *proto); Node(const Node &node); Node(const Node &node, Proto *proto); void addParent(Node *parent, int field); bool hasParent(void) const { if (getNumParents()<=0) return false; return true; } Node *getParent(void) const { return NodeData::getParent(_geometricParentIter); } int getParentField(void) const { return NodeData::getParentField(_geometricParentIter); } bool isInScene(Scene* scene) const; virtual void addFieldNodeList(int index, NodeList *value); void removeParent(Node *parent, int field); // void removeUpdateParents(SocketList::Iterator *i); bool hasAncestor(Node *node) const; bool isAnimateable(void); virtual int getAnmationCommentID(void) { return -1; } virtual bool isInvalidChild(void); virtual bool hasBoundingBox(void) { return false; } virtual Vec3f getMinBoundingBox(void); virtual Vec3f getMaxBoundingBox(void); virtual void flip(int index) {} virtual bool showFields() { return false; } void appendTo(NodeList* nodelist); void appendComment(Node *node); protected: virtual ~Node(); ParentIter getGeometricParentIter(void) { return _geometricParentIter; } protected: ParentIter _geometricParentIter; NodeList *_commentsList; }; bool hasRoute(SocketList socketlist); #endif // _NODE_H