Panda3D
 All Classes Functions Variables Enumerations
eggBinner.cxx
1 // Filename: eggBinner.cxx
2 // Created by: drose (17Feb00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "eggBinner.h"
16 #include "eggRenderState.h"
17 #include "eggPrimitive.h"
18 #include "eggNurbsSurface.h"
19 #include "eggNurbsCurve.h"
20 #include "eggPatch.h"
21 #include "eggSwitchCondition.h"
22 #include "eggGroup.h"
23 #include "dcast.h"
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function: EggBinner::Constructor
27 // Access: Public
28 // Description:
29 ////////////////////////////////////////////////////////////////////
30 EggBinner::
31 EggBinner(EggLoader &loader) :
32  _loader(loader)
33 {
34 }
35 
36 ////////////////////////////////////////////////////////////////////
37 // Function: EggBinner::prepare_node
38 // Access: Public, Virtual
39 // Description: May be overridden in derived classes to perform some
40 // setup work as each node is encountered. This will be
41 // called once for each node in the egg hierarchy.
42 ////////////////////////////////////////////////////////////////////
43 void EggBinner::
45  if (node->is_of_type(EggPrimitive::get_class_type())) {
46  EggPrimitive *egg_prim = DCAST(EggPrimitive, node);
47  PT(EggRenderState) render_state = new EggRenderState(_loader);
48  render_state->fill_state(egg_prim);
49  egg_prim->set_user_data(render_state);
50  }
51 }
52 
53 ////////////////////////////////////////////////////////////////////
54 // Function: EggBinner::get_bin_number
55 // Access: Public, Virtual
56 // Description:
57 ////////////////////////////////////////////////////////////////////
58 int EggBinner::
59 get_bin_number(const EggNode *node) {
60  if (node->is_of_type(EggNurbsSurface::get_class_type())) {
61  return (int)BN_nurbs_surface;
62 
63  } else if (node->is_of_type(EggNurbsCurve::get_class_type())) {
64  return (int)BN_nurbs_curve;
65 
66  } else if (node->is_of_type(EggPatch::get_class_type())) {
67  return (int)BN_patches;
68 
69  } else if (node->is_of_type(EggPrimitive::get_class_type())) {
70  return (int)BN_polyset;
71 
72  } else if (node->is_of_type(EggGroup::get_class_type())) {
73  const EggGroup *group = DCAST(EggGroup, node);
74  if (group->has_lod()) {
75  return (int)BN_lod;
76  }
77  }
78 
79  return (int)BN_none;
80 }
81 
82 ////////////////////////////////////////////////////////////////////
83 // Function: EggBinner::get_bin_name
84 // Access: Public, Virtual
85 // Description: May be overridden in derived classes to define a name
86 // for each new bin, based on its bin number, and a
87 // sample child.
88 ////////////////////////////////////////////////////////////////////
89 string EggBinner::
90 get_bin_name(int bin_number, const EggNode *child) {
91  if (bin_number == BN_polyset || bin_number == BN_patches) {
92  return DCAST(EggPrimitive, child)->get_sort_name();
93  }
94 
95  return string();
96 }
97 
98 ////////////////////////////////////////////////////////////////////
99 // Function: EggBinner::sorts_less
100 // Access: Public, Virtual
101 // Description:
102 ////////////////////////////////////////////////////////////////////
103 bool EggBinner::
104 sorts_less(int bin_number, const EggNode *a, const EggNode *b) {
105  switch (bin_number) {
106  case BN_polyset:
107  case BN_patches:
108  {
109  const EggPrimitive *pa, *pb;
110  DCAST_INTO_R(pa, a, false);
111  DCAST_INTO_R(pb, b, false);
112 
113  // Different render states are binned separately.
114  const EggRenderState *rsa, *rsb;
115  DCAST_INTO_R(rsa, pa->get_user_data(EggRenderState::get_class_type()), false);
116  DCAST_INTO_R(rsb, pb->get_user_data(EggRenderState::get_class_type()), false);
117  int compare = rsa->compare_to(*rsb);
118  if (compare != 0) {
119  return (compare < 0);
120  }
121 
122  if (bin_number == BN_patches) {
123  // For patches only, we group together patches of similar size.
124  const EggPatch *patch_a, *patch_b;
125  DCAST_INTO_R(patch_a, a, false);
126  DCAST_INTO_R(patch_b, b, false);
127  if (patch_a->size() != patch_b->size()) {
128  return patch_a->size() < patch_b->size();
129  }
130  }
131 
132  // Also, if the primitive was given a name (that does not begin
133  // with a digit), it gets binned with similar-named primitives.
134  return pa->get_sort_name() < pb->get_sort_name();
135  }
136 
137  case BN_lod:
138  {
139  const EggGroup *ga = DCAST(EggGroup, a);
140  const EggGroup *gb = DCAST(EggGroup, b);
141 
142  const EggSwitchCondition &swa = ga->get_lod();
143  const EggSwitchCondition &swb = gb->get_lod();
144 
145  // For now, this is the only kind of switch condition there is.
146  const EggSwitchConditionDistance &swda =
147  *DCAST(EggSwitchConditionDistance, &swa);
148  const EggSwitchConditionDistance &swdb =
149  *DCAST(EggSwitchConditionDistance, &swb);
150 
151  // Group LOD nodes in order by switching center.
152  return (swda._center.compare_to(swdb._center) < 0);
153  }
154 
155  case BN_nurbs_surface:
156  case BN_nurbs_curve:
157  // Nurbs curves and surfaces are always binned individually.
158  return a < b;
159 
160  case BN_none:
161  break;
162  }
163 
164  // Shouldn't get here.
165  return false;
166 }
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
Definition: eggPrimitive.h:51
EggUserData * get_user_data() const
Returns the user data pointer most recently stored on this object, or NULL if nothing was previously ...
Definition: eggObject.cxx:102
virtual bool sorts_less(int bin_number, const EggNode *a, const EggNode *b)
May be overridden in derived classes to create additional bins within a particular bin number...
Definition: eggBinner.cxx:104
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:63
This class is used within this package only to record the render state that should be assigned to eac...
The main glue of the egg hierarchy, this corresponds to the &lt;Group&gt;, &lt;Instance&gt;, and &lt;Joint&gt; type nod...
Definition: eggGroup.h:36
A single &quot;patch&quot;, a special primitive to be rendered only with a tessellation shader.
Definition: eggPatch.h:27
string get_sort_name() const
Returns the name of the primitive for the purposes of sorting primitives into different groups...
Definition: eggPrimitive.I:82
void set_user_data(EggUserData *user_data)
Sets the user data associated with this object.
Definition: eggObject.cxx:89
int compare_to(const EggRenderState &other) const
Provides a unique ordering for different EggRenderState objects, so that primitives of similar state ...
virtual void prepare_node(EggNode *node)
May be overridden in derived classes to perform some setup work as each node is encountered.
Definition: eggBinner.cxx:44
int compare_to(const LVecBase3d &other) const
This flavor of compare_to uses a default threshold value based on the numeric type.
Definition: lvecBase3.h:2273
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:38
This corresponds to a &lt;SwitchCondition&gt; entry within a group.
virtual string get_bin_name(int bin_number, const EggNode *child)
May be overridden in derived classes to define a name for each new bin, based on its bin number...
Definition: eggBinner.cxx:90
A SwitchCondition that switches the levels-of-detail based on distance from the camera&#39;s eyepoint...
Converts an egg data structure, possibly read from an egg file but not necessarily, into a scene graph suitable for rendering.
Definition: eggLoader.h:70