Panda3D
 All Classes Functions Variables Enumerations
accumulatedAttribs.cxx
00001 // Filename: accumulatedAttribs.cxx
00002 // Created by:  drose (30Jan03)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "accumulatedAttribs.h"
00016 #include "sceneGraphReducer.h"
00017 #include "pandaNode.h"
00018 #include "colorAttrib.h"
00019 #include "colorScaleAttrib.h"
00020 #include "texMatrixAttrib.h"
00021 #include "textureAttrib.h"
00022 #include "clipPlaneAttrib.h"
00023 #include "cullFaceAttrib.h"
00024 #include "config_pgraph.h"
00025 
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //     Function: AccumulatedAttribs::Constructor
00029 //       Access: Public
00030 //  Description:
00031 ////////////////////////////////////////////////////////////////////
00032 AccumulatedAttribs::
00033 AccumulatedAttribs() {
00034   _transform = TransformState::make_identity();
00035   _color_override = 0;
00036   _color_scale_override = 0;
00037   _tex_matrix_override = 0;
00038   _texture_override = 0;
00039   _clip_plane_override = 0;
00040   _cull_face_override = 0;
00041   _other = RenderState::make_empty();
00042 }
00043 
00044 ////////////////////////////////////////////////////////////////////
00045 //     Function: AccumulatedAttribs::Copy Constructor
00046 //       Access: Public
00047 //  Description:
00048 ////////////////////////////////////////////////////////////////////
00049 AccumulatedAttribs::
00050 AccumulatedAttribs(const AccumulatedAttribs &copy) :
00051   _transform(copy._transform),
00052   _color(copy._color),
00053   _color_override(copy._color_override),
00054   _color_scale(copy._color_scale),
00055   _color_scale_override(copy._color_scale_override),
00056   _tex_matrix(copy._tex_matrix),
00057   _tex_matrix_override(copy._tex_matrix_override),
00058   _texture(copy._texture),
00059   _texture_override(copy._texture_override),
00060   _clip_plane(copy._clip_plane),
00061   _clip_plane_override(copy._clip_plane_override),
00062   _cull_face(copy._cull_face),
00063   _cull_face_override(copy._cull_face_override),
00064   _other(copy._other)
00065 {
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: AccumulatedAttribs::Copy Assignment
00070 //       Access: Public
00071 //  Description:
00072 ////////////////////////////////////////////////////////////////////
00073 void AccumulatedAttribs::
00074 operator = (const AccumulatedAttribs &copy) {
00075   _transform = copy._transform;
00076   _color = copy._color;
00077   _color_override = copy._color_override;
00078   _color_scale = copy._color_scale;
00079   _color_scale_override = copy._color_scale_override;
00080   _tex_matrix = copy._tex_matrix;
00081   _tex_matrix_override = copy._tex_matrix_override;
00082   _texture = copy._texture;
00083   _texture_override = copy._texture_override;
00084   _clip_plane = copy._clip_plane;
00085   _clip_plane_override = copy._clip_plane_override;
00086   _cull_face = copy._cull_face;
00087   _cull_face_override = copy._cull_face_override;
00088   _other = copy._other;
00089 }
00090 
00091 ////////////////////////////////////////////////////////////////////
00092 //     Function: AccumulatedAttribs::write
00093 //       Access: Public
00094 //  Description:
00095 ////////////////////////////////////////////////////////////////////
00096 void AccumulatedAttribs::
00097 write(ostream &out, int attrib_types, int indent_level) const {
00098   if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
00099     _transform->write(out, indent_level);
00100   }
00101   if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
00102     if (_color == (const RenderAttrib *)NULL) {
00103       indent(out, indent_level) << "no color\n";
00104     } else {
00105       _color->write(out, indent_level);
00106     }
00107   }
00108   if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) {
00109     if (_color_scale == (const RenderAttrib *)NULL) {
00110       indent(out, indent_level) << "no color scale\n";
00111     } else {
00112       _color_scale->write(out, indent_level);
00113     }
00114   }
00115   if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) {
00116     if (_tex_matrix == (const RenderAttrib *)NULL) {
00117       indent(out, indent_level) << "no tex matrix\n";
00118     } else {
00119       _tex_matrix->write(out, indent_level);
00120     }
00121   }
00122   if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) {
00123     if (_clip_plane == (const RenderAttrib *)NULL) {
00124       indent(out, indent_level) << "no clip plane\n";
00125     } else {
00126       _clip_plane->write(out, indent_level);
00127     }
00128   }
00129   if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) {
00130     if (_cull_face == (const RenderAttrib *)NULL) {
00131       indent(out, indent_level) << "no cull face\n";
00132     } else {
00133       _cull_face->write(out, indent_level);
00134     }
00135   }
00136   if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
00137     _other->write(out, indent_level);
00138   }
00139 }
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: AccumulatedAttribs::collect
00143 //       Access: Public
00144 //  Description: Collects the state and transform from the indicated
00145 //               node and adds it to the accumulator, removing it from
00146 //               the node.
00147 ////////////////////////////////////////////////////////////////////
00148 void AccumulatedAttribs::
00149 collect(PandaNode *node, int attrib_types) {
00150   if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
00151     // Collect the node's transform.
00152     nassertv(_transform != (TransformState *)NULL);
00153     _transform = _transform->compose(node->get_transform());
00154     node->set_transform(TransformState::make_identity());
00155     node->set_prev_transform(TransformState::make_identity());
00156   }
00157 
00158   CPT(RenderState) new_state = collect(node->get_state(), attrib_types);
00159   node->set_state(new_state);
00160 }
00161 
00162 ////////////////////////////////////////////////////////////////////
00163 //     Function: AccumulatedAttribs::collect
00164 //       Access: Public
00165 //  Description: Collects the state and transform from the indicated
00166 //               node and adds it to the accumulator, removing it from
00167 //               the state (and returning a new state).
00168 ////////////////////////////////////////////////////////////////////
00169 CPT(RenderState) AccumulatedAttribs::
00170 collect(const RenderState *state, int attrib_types) {
00171   CPT(RenderState) new_state = state;
00172 
00173   if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
00174     const RenderAttrib *node_attrib = 
00175       new_state->get_attrib(ColorAttrib::get_class_slot());
00176     if (node_attrib != (const RenderAttrib *)NULL) {
00177       int color_override = new_state->get_override(ColorAttrib::get_class_slot());
00178       if (color_override >= _color_override || 
00179           _color == (const RenderAttrib *)NULL) {
00180         // The node has a color attribute; apply it.
00181         if (_color == (const RenderAttrib *)NULL) {
00182           _color = node_attrib;
00183         } else {
00184           _color = _color->compose(node_attrib);
00185         }
00186         _color_override = color_override;
00187       }
00188       new_state = new_state->remove_attrib(ColorAttrib::get_class_slot());
00189     }
00190   }
00191 
00192   if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) {
00193     const RenderAttrib *node_attrib = 
00194       new_state->get_attrib(ColorScaleAttrib::get_class_slot());
00195     if (node_attrib != (const RenderAttrib *)NULL) {
00196       int color_scale_override = new_state->get_override(ColorScaleAttrib::get_class_slot());
00197       if (color_scale_override >= _color_scale_override ||
00198           _color_scale == (const RenderAttrib *)NULL) {
00199         if (_color_scale == (const RenderAttrib *)NULL) {
00200           _color_scale = node_attrib;
00201         } else {
00202           _color_scale = _color_scale->compose(node_attrib);
00203         }
00204         _color_scale_override = color_scale_override;
00205       }
00206       new_state = new_state->remove_attrib(ColorScaleAttrib::get_class_slot());
00207     }
00208   }
00209 
00210   if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) {
00211     const RenderAttrib *node_attrib = 
00212       new_state->get_attrib(TexMatrixAttrib::get_class_slot());
00213     if (node_attrib != (const RenderAttrib *)NULL) {
00214       int tex_matrix_override = new_state->get_override(TexMatrixAttrib::get_class_slot());
00215       if (tex_matrix_override >= _tex_matrix_override ||
00216           _tex_matrix == (const RenderAttrib *)NULL) {
00217         if (_tex_matrix == (const RenderAttrib *)NULL) {
00218           _tex_matrix = node_attrib;
00219         } else {
00220           _tex_matrix = _tex_matrix->compose(node_attrib);
00221         }
00222         _tex_matrix_override = tex_matrix_override;
00223       }
00224       new_state = new_state->remove_attrib(TexMatrixAttrib::get_class_slot());
00225     }
00226 
00227     // We also need to accumulate the texture state if we are
00228     // accumulating texture matrix.
00229     const RenderAttrib *tex_attrib = 
00230       new_state->get_attrib(TextureAttrib::get_class_slot());
00231     if (tex_attrib != (const RenderAttrib *)NULL) {
00232       int texture_override = new_state->get_override(TextureAttrib::get_class_slot());
00233       if (texture_override >= _texture_override || 
00234           _texture == (const RenderAttrib *)NULL) {
00235         if (_texture == (const RenderAttrib *)NULL) {
00236           _texture = tex_attrib;
00237         } else {
00238           _texture = _texture->compose(tex_attrib);
00239         }
00240         _texture_override = texture_override;
00241       }
00242 
00243       // However, we don't remove the texture state from the node.
00244       // We're just accumulating it so we can tell which texture
00245       // coordinates are safe to flatten.
00246     }
00247   }
00248 
00249   if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) {
00250     const RenderAttrib *node_attrib = 
00251       new_state->get_attrib(ClipPlaneAttrib::get_class_slot());
00252     if (node_attrib != (const RenderAttrib *)NULL) {
00253       int clip_plane_override = new_state->get_override(ClipPlaneAttrib::get_class_slot());
00254       if (clip_plane_override >= _clip_plane_override || 
00255           _clip_plane == (const RenderAttrib *)NULL) {
00256         if (_clip_plane == (const RenderAttrib *)NULL) {
00257           _clip_plane = node_attrib;
00258         } else {
00259           _clip_plane = _clip_plane->compose(node_attrib);
00260         }
00261         _clip_plane_override = clip_plane_override;
00262       }
00263       new_state = new_state->remove_attrib(ClipPlaneAttrib::get_class_slot());
00264     }
00265   }
00266 
00267   if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) {
00268     const RenderAttrib *node_attrib = 
00269       new_state->get_attrib(CullFaceAttrib::get_class_slot());
00270     if (node_attrib != (const RenderAttrib *)NULL) {
00271       int cull_face_override = new_state->get_override(CullFaceAttrib::get_class_slot());
00272       if (cull_face_override >= _cull_face_override ||
00273           _cull_face == (const RenderAttrib *)NULL) {
00274         if (_cull_face == (const RenderAttrib *)NULL) {
00275           _cull_face = node_attrib;
00276         } else {
00277           _cull_face = _cull_face->compose(node_attrib);
00278         }
00279         _cull_face_override = cull_face_override;
00280       }
00281       new_state = new_state->remove_attrib(CullFaceAttrib::get_class_slot());
00282     }
00283   }
00284 
00285   if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
00286     // Collect everything else.
00287     nassertr(_other != (RenderState *)NULL, new_state);
00288     _other = _other->compose(new_state);
00289     new_state = RenderState::make_empty();
00290   }
00291 
00292   return new_state;
00293 }
00294 
00295 ////////////////////////////////////////////////////////////////////
00296 //     Function: AccumulatedAttribs::apply_to_node
00297 //       Access: Public
00298 //  Description: Stores the indicated attributes in the node's
00299 //               transform and state information; does not attempt to
00300 //               apply the properties to the vertices.  Clears the
00301 //               attributes from the accumulator for future
00302 //               traversals.
00303 ////////////////////////////////////////////////////////////////////
00304 void AccumulatedAttribs::
00305 apply_to_node(PandaNode *node, int attrib_types) {
00306   if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
00307     node->set_transform(_transform->compose(node->get_transform())->get_unique());
00308     node->reset_prev_transform();
00309     _transform = TransformState::make_identity();
00310   }
00311 
00312   if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
00313     if (_color != (RenderAttrib *)NULL) {
00314       const RenderAttrib *node_attrib =
00315         node->get_attrib(ColorAttrib::get_class_slot());
00316       if (node_attrib != (RenderAttrib *)NULL) {
00317         node->set_attrib(_color->compose(node_attrib)->get_unique());
00318       } else {
00319         node->set_attrib(_color->get_unique());
00320       }
00321       _color = (RenderAttrib *)NULL;
00322     }
00323   }
00324 
00325   if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) {
00326     if (_color_scale != (RenderAttrib *)NULL) {
00327       const RenderAttrib *node_attrib =
00328         node->get_attrib(ColorScaleAttrib::get_class_slot());
00329       if (node_attrib != (RenderAttrib *)NULL) {
00330         node->set_attrib(_color_scale->compose(node_attrib)->get_unique());
00331       } else {
00332         node->set_attrib(_color_scale->get_unique());
00333       }
00334       _color_scale = (RenderAttrib *)NULL;
00335     }
00336   }
00337 
00338   if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) {
00339     if (_tex_matrix != (RenderAttrib *)NULL) {
00340       const RenderAttrib *node_attrib =
00341         node->get_attrib(TexMatrixAttrib::get_class_slot());
00342       if (node_attrib != (RenderAttrib *)NULL) {
00343         node->set_attrib(_tex_matrix->compose(node_attrib)->get_unique());
00344       } else {
00345         node->set_attrib(_tex_matrix->get_unique());
00346       }
00347       _tex_matrix = (RenderAttrib *)NULL;
00348     }
00349   }
00350 
00351   if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) {
00352     if (_clip_plane != (RenderAttrib *)NULL) {
00353       const RenderAttrib *node_attrib =
00354         node->get_attrib(ClipPlaneAttrib::get_class_slot());
00355       if (node_attrib != (RenderAttrib *)NULL) {
00356         node->set_attrib(_clip_plane->compose(node_attrib)->get_unique());
00357       } else {
00358         node->set_attrib(_clip_plane->get_unique());
00359       }
00360       _clip_plane = (RenderAttrib *)NULL;
00361     }
00362   }
00363 
00364   if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) {
00365     if (_cull_face != (RenderAttrib *)NULL) {
00366       const RenderAttrib *node_attrib =
00367         node->get_attrib(CullFaceAttrib::get_class_slot());
00368       if (node_attrib != (RenderAttrib *)NULL) {
00369         node->set_attrib(_cull_face->compose(node_attrib)->get_unique());
00370       } else {
00371         node->set_attrib(_cull_face->get_unique());
00372       }
00373       _cull_face = (RenderAttrib *)NULL;
00374     }
00375   }
00376 
00377   if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
00378     node->set_state(_other->compose(node->get_state())->get_unique());
00379     _other = RenderState::make_empty();
00380   }
00381 }
 All Classes Functions Variables Enumerations