Logo Search packages:      
Sourcecode: whitedune version File versions  Download package

Node.h

/*
 * 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 <stdio.h>
#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<Socket> 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<Parent> 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

Generated by  Doxygen 1.6.0   Back to index