00001 #ifndef GSGL_SG_NODE_H 00002 #define GSGL_SG_NODE_H 00003 00004 // 00005 // $Id: node.hpp 2 2008-03-01 20:58:50Z kulibali $ 00006 // 00007 // Copyright (c) 2008, The Periapsis Project. All rights reserved. 00008 // 00009 // Redistribution and use in source and binary forms, with or without 00010 // modification, are permitted provided that the following conditions are 00011 // met: 00012 // 00013 // * Redistributions of source code must retain the above copyright notice, 00014 // this list of conditions and the following disclaimer. 00015 // 00016 // * Redistributions in binary form must reproduce the above copyright 00017 // notice, this list of conditions and the following disclaimer in the 00018 // documentation and/or other materials provided with the distribution. 00019 // 00020 // * Neither the name of the The Periapsis Project nor the names of its 00021 // contributors may be used to endorse or promote products derived from 00022 // this software without specific prior written permission. 00023 // 00024 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00025 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00026 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00027 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00028 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00029 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00030 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00031 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00032 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00033 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00034 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 // 00036 00037 #include "scenegraph/scenegraph.hpp" 00038 #include "scenegraph/context.hpp" 00039 #include "scenegraph/event.hpp" 00040 00041 #include "data/array.hpp" 00042 #include "data/list.hpp" 00043 #include "data/string.hpp" 00044 #include "data/pqueue.hpp" 00045 #include "data/config.hpp" 00046 #include "data/broker.hpp" 00047 00048 #include "math/vector.hpp" 00049 #include "math/transform.hpp" 00050 00051 namespace gsgl 00052 { 00053 00054 namespace scenegraph 00055 { 00056 00057 class light; 00058 class node; 00059 00060 /// Stores the nodes in the scene graph needed to calculate the transform from src's frame to dest's. 00061 class SCENEGRAPH_API node_relative_path 00062 { 00063 data::simple_array<node *> to_cur; 00064 data::simple_array<node *> from_ref; 00065 00066 math::transform relative_transform; 00067 00068 public: 00069 node_relative_path(node *reference, node *cur); 00070 00071 const math::transform & get_relative_transform() const { return relative_transform; } 00072 00073 void initialize(node *reference, node *cur); 00074 const math::transform & calc_relative_transform(bool include_translation); 00075 }; // class node_relative_path 00076 00077 00078 /// Base class for nodes in the scene graph. 00079 class SCENEGRAPH_API node 00080 : public scenegraph_object, public data::brokered_object 00081 { 00082 node *parent; 00083 data::simple_array<node *> children; 00084 00085 string name, parent_name; 00086 00087 gsgl::real_t scale; ///< The scale of the node in meters per unit. 00088 00089 math::vector translation; ///< The translation of the node's frame in its parent's frame and scale. 00090 math::transform orientation; ///< Multiply this by a position in the node's frame to yield the position in the parent's frame. Should never contain a translation component! 00091 00092 math::transform modelview; ///< The modelview matrix the node should be drawn with. 00093 00094 gsgl::flags_t draw_flags; ///< Flags that control how the node should be drawn (these stay fairly constant). 00095 gsgl::flags_t draw_results; ///< Flags that indicate what happened to the node when it was drawn (these may change frame to frame). 00096 00097 public: 00098 00099 /// Creates a node with a given name and parent. 00100 node(const gsgl::string & name, node *parent); 00101 00102 /// Creates a node from a config_record record. 00103 node(const data::config_record & conf); 00104 00105 virtual ~node(); 00106 00107 /// \name Accessors. 00108 /// @{ 00109 00110 const node *get_parent() const; 00111 node * & get_parent(); 00112 data::simple_array<node *> & get_children(); 00113 00114 const string & get_name() const; 00115 string & get_name(); 00116 string & get_parent_name(); 00117 00118 gsgl::real_t & get_scale(); 00119 00120 math::vector & get_translation(); 00121 math::transform & get_orientation(); 00122 00123 math::transform & get_modelview(); 00124 00125 /// @} 00126 00127 /// \name Scene Graph Functionality. 00128 /// @{ 00129 00130 /// Add a child node. Also sets the child's parent to \c this. 00131 void add_child(node *child); 00132 00133 /// Removes the node from the scene graph (does not delete it!). 00134 void detach(); 00135 00136 /// If this is called on the root of a scene graph, it will insert the branch node in the appropriate place in the graph, or return false. 00137 bool connect(node *branch); 00138 00139 00140 /// Flags that control node drawing. 00141 enum node_draw_flags 00142 { 00143 NODE_NO_DRAW_FLAGS = 0, 00144 NODE_NO_FRUSTUM_CHECK = 1 << 0, ///< Don't perform a frustum check when drawing this node. 00145 NODE_DUMMY_OBJECT = 1 << 2, ///< This node should never be drawn. 00146 NODE_DRAW_UNLIT = 1 << 3 ///< This node should not be lit. 00147 }; 00148 00149 /// \return The node's draw flags (a bitset using node_draw_flags). 00150 const gsgl::flags_t & get_draw_flags() const { return draw_flags; } 00151 00152 /// \return The node's draw flags (a bitset using node_draw_flags). 00153 gsgl::flags_t & get_draw_flags() { return draw_flags; } 00154 00155 00156 /// Flags that indicate what happened when the node was drawn. 00157 enum node_draw_results 00158 { 00159 NODE_NO_DRAW_RESULTS = 0, 00160 NODE_OFF_SCREEN = 1 << 0, ///< The node was not drawn because it was out-of-frame. 00161 NODE_DREW_POINT = 1 << 1, ///< The node was drawn as a point. 00162 NODE_DISTANCE_CULLED = 1 << 2 ///< The node was not drawn due to distance. 00163 }; 00164 00165 /// \return The node's draw results (a bitset using node_draw_results). 00166 const gsgl::flags_t & get_draw_results() const { return draw_results; } 00167 00168 /// \return The node's draw results (a bitset using node_draw_results). 00169 gsgl::flags_t & get_draw_results() { return draw_results; } 00170 00171 00172 /// Contains information about the current drawing pass. 00173 struct pre_draw_rec 00174 { 00175 data::pqueue<light *, gsgl::real_t> light_queue; 00176 data::pqueue<node *, gsgl::real_t> paint_queue; 00177 data::simple_array<node *> solids; 00178 data::simple_array<node *> translucents; 00179 }; // struct pre_draw_rec 00180 00181 /// Collect information about the scene to draw. Unsafe to call while update is being called in the tree. 00182 static void pre_draw_scene(gsgl::scenegraph::context *c, pre_draw_rec & rec); 00183 00184 /// Draws a scene. Safe to call while update is also being called in the tree. 00185 static void draw_scene(gsgl::scenegraph::context *c, pre_draw_rec & rec); 00186 00187 /// @} 00188 00189 /// \name Node Life Cycle. 00190 /// @{ 00191 00192 /// Called when the simulation is created. The node's modelview matrix is invalid at this point. 00193 virtual void init(gsgl::scenegraph::context *c); 00194 00195 /// Called to draw the node. The node's modelview matrix is in the correct state for drawing, and already loaded into the OpenGL modelview matrix. 00196 virtual void draw(gsgl::scenegraph::context *c); 00197 00198 /// Called from the root of the world-tree up to update the node's state. The node's modelview matrix is that of the previously-drawn frame. 00199 virtual void update(gsgl::scenegraph::context *c); 00200 00201 /// Called when the simulation is done. 00202 virtual void cleanup(gsgl::scenegraph::context *c); 00203 00204 /// Called with events. 00205 virtual bool handle_event(gsgl::scenegraph::context *c, sg_event & e); 00206 00207 /// Called to save the node to a config_record structure. 00208 virtual data::config_record *save() const; 00209 00210 /// @} 00211 00212 /// \name Drawing Information Functions. 00213 /// @{ 00214 00215 static const gsgl::real_t NODE_DRAW_IGNORE; 00216 static const gsgl::real_t NODE_DRAW_SOLID; 00217 static const gsgl::real_t NODE_DRAW_TRANSLUCENT; 00218 static const gsgl::real_t NODE_DRAW_FIRST; 00219 00220 /// Called to determine the draw priority of the node. 00221 /// A value of NODE_DRAW_IGNORE means don't draw (invisible nodes or nodes that are drawn by their parents -- the modelview matrix is still built). 00222 /// A value of NODE_DRAW_SOLID means the object is solid and should be drawn after the painter's algorithm. 00223 /// A value of NODE_DRAW_TRANSLUCENT means the object is translucent and should be drawn after solid objects. 00224 /// A value > NODE_DRAW_TRANSLUCENT is interpreted as the distance to the object. Objects that return > 2.0 are drawn with a painter's algorithm. 00225 virtual gsgl::real_t get_priority(gsgl::scenegraph::context *); 00226 00227 /// Should return the maximum extent of the object (in the node's coordinates, i.e. not scaled to meters). 00228 virtual gsgl::real_t max_extent() const; 00229 00230 virtual gsgl::real_t default_view_distance() const; 00231 virtual gsgl::real_t minimum_view_distance() const; 00232 /// @} 00233 00234 private: 00235 static void build_draw_list(node *cur, node *prev, context *c, const math::transform & modelview, pre_draw_rec &); 00236 }; // class node 00237 00238 } // namespace scenegraph 00239 00240 } // namespace gsgl 00241 00242 #endif