Panda3D
|
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 }