Panda3D

eggBinner.cxx

00001 // Filename: eggBinner.cxx
00002 // Created by:  drose (17Feb00)
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 "eggBinner.h"
00016 #include "eggRenderState.h"
00017 #include "eggPrimitive.h"
00018 #include "eggNurbsSurface.h"
00019 #include "eggNurbsCurve.h"
00020 #include "eggSwitchCondition.h"
00021 #include "eggGroup.h"
00022 #include "dcast.h"
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: EggBinner::Constructor
00026 //       Access: Public
00027 //  Description: 
00028 ////////////////////////////////////////////////////////////////////
00029 EggBinner::
00030 EggBinner(EggLoader &loader) :
00031   _loader(loader)
00032 {
00033 }
00034 
00035 ////////////////////////////////////////////////////////////////////
00036 //     Function: EggBinner::prepare_node
00037 //       Access: Public, Virtual
00038 //  Description: May be overridden in derived classes to perform some
00039 //               setup work as each node is encountered.  This will be
00040 //               called once for each node in the egg hierarchy.
00041 ////////////////////////////////////////////////////////////////////
00042 void EggBinner::
00043 prepare_node(EggNode *node) {
00044   if (node->is_of_type(EggPrimitive::get_class_type())) {
00045     EggPrimitive *egg_prim = DCAST(EggPrimitive, node);
00046     PT(EggRenderState) render_state = new EggRenderState(_loader);
00047     render_state->fill_state(egg_prim);
00048     egg_prim->set_user_data(render_state);
00049   }
00050 }
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: EggBinner::get_bin_number
00054 //       Access: Public, Virtual
00055 //  Description:
00056 ////////////////////////////////////////////////////////////////////
00057 int EggBinner::
00058 get_bin_number(const EggNode *node) {
00059   if (node->is_of_type(EggNurbsSurface::get_class_type())) {
00060     return (int)BN_nurbs_surface;
00061 
00062   } else if (node->is_of_type(EggNurbsCurve::get_class_type())) {
00063     return (int)BN_nurbs_curve;
00064 
00065   } else if (node->is_of_type(EggPrimitive::get_class_type())) {
00066     return (int)BN_polyset;
00067 
00068   } else if (node->is_of_type(EggGroup::get_class_type())) {
00069     const EggGroup *group = DCAST(EggGroup, node);
00070     if (group->has_lod()) {
00071       return (int)BN_lod;
00072     }
00073   }
00074 
00075   return (int)BN_none;
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: EggBinner::get_bin_name
00080 //       Access: Public, Virtual
00081 //  Description: May be overridden in derived classes to define a name
00082 //               for each new bin, based on its bin number, and a
00083 //               sample child.
00084 ////////////////////////////////////////////////////////////////////
00085 string EggBinner::
00086 get_bin_name(int bin_number, const EggNode *child) { 
00087   if (bin_number == BN_polyset) {
00088     return DCAST(EggPrimitive, child)->get_sort_name();
00089   }
00090 
00091   return string();
00092 }
00093 
00094 ////////////////////////////////////////////////////////////////////
00095 //     Function: EggBinner::sorts_less
00096 //       Access: Public, Virtual
00097 //  Description:
00098 ////////////////////////////////////////////////////////////////////
00099 bool EggBinner::
00100 sorts_less(int bin_number, const EggNode *a, const EggNode *b) {
00101   switch (bin_number) {
00102   case BN_polyset:
00103     {
00104       const EggPrimitive *pa, *pb;
00105       DCAST_INTO_R(pa, a, false);
00106       DCAST_INTO_R(pb, b, false);
00107 
00108       // Different render states are binned separately.
00109       const EggRenderState *rsa, *rsb;
00110       DCAST_INTO_R(rsa, pa->get_user_data(EggRenderState::get_class_type()), false);
00111       DCAST_INTO_R(rsb, pb->get_user_data(EggRenderState::get_class_type()), false);
00112       int compare = rsa->compare_to(*rsb);
00113       if (compare != 0) {
00114         return (compare < 0);
00115       }
00116 
00117       // Also, if the primitive was given a name (that does not begin
00118       // with a digit), it gets binned with similar-named primitives.
00119       return pa->get_sort_name() < pb->get_sort_name();
00120     }
00121 
00122   case BN_lod:
00123     {
00124       const EggGroup *ga = DCAST(EggGroup, a);
00125       const EggGroup *gb = DCAST(EggGroup, b);
00126       
00127       const EggSwitchCondition &swa = ga->get_lod();
00128       const EggSwitchCondition &swb = gb->get_lod();
00129       
00130       // For now, this is the only kind of switch condition there is.
00131       const EggSwitchConditionDistance &swda =
00132         *DCAST(EggSwitchConditionDistance, &swa);
00133       const EggSwitchConditionDistance &swdb =
00134         *DCAST(EggSwitchConditionDistance, &swb);
00135       
00136       // Group LOD nodes in order by switching center.
00137       return (swda._center.compare_to(swdb._center) < 0);
00138     }
00139 
00140   case BN_nurbs_surface:
00141   case BN_nurbs_curve:
00142     // Nurbs curves and surfaces are always binned individually.
00143     return a < b;
00144       
00145   case BN_none:
00146     break;
00147   }
00148 
00149   // Shouldn't get here.
00150   return false;
00151 }
 All Classes Functions Variables Enumerations