open_toontown_panda3d/panda/src/egg2pg/eggBinner.cxx

156 lines
5.0 KiB
C++

// Filename: eggBinner.cxx
// Created by: drose (17Feb00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "eggBinner.h"
#include "eggRenderState.h"
#include "eggPrimitive.h"
#include "eggNurbsSurface.h"
#include "eggNurbsCurve.h"
#include "eggSwitchCondition.h"
#include "eggGroup.h"
#include "dcast.h"
////////////////////////////////////////////////////////////////////
// Function: EggBinner::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggBinner::
EggBinner(EggLoader &loader) :
_loader(loader)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggBinner::prepare_node
// Access: Public, Virtual
// Description: May be overridden in derived classes to perform some
// setup work as each node is encountered. This will be
// called once for each node in the egg hierarchy.
////////////////////////////////////////////////////////////////////
void EggBinner::
prepare_node(EggNode *node) {
if (node->is_of_type(EggPrimitive::get_class_type())) {
EggPrimitive *egg_prim = DCAST(EggPrimitive, node);
PT(EggRenderState) render_state = new EggRenderState(_loader);
render_state->fill_state(egg_prim);
egg_prim->set_user_data(render_state);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggBinner::get_bin_number
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int EggBinner::
get_bin_number(const EggNode *node) {
if (node->is_of_type(EggNurbsSurface::get_class_type())) {
return (int)BN_nurbs_surface;
} else if (node->is_of_type(EggNurbsCurve::get_class_type())) {
return (int)BN_nurbs_curve;
} else if (node->is_of_type(EggPrimitive::get_class_type())) {
return (int)BN_polyset;
} else if (node->is_of_type(EggGroup::get_class_type())) {
const EggGroup *group = DCAST(EggGroup, node);
if (group->has_lod()) {
return (int)BN_lod;
}
}
return (int)BN_none;
}
////////////////////////////////////////////////////////////////////
// Function: EggBinner::get_bin_name
// Access: Public, Virtual
// Description: May be overridden in derived classes to define a name
// for each new bin, based on its bin number, and a
// sample child.
////////////////////////////////////////////////////////////////////
string EggBinner::
get_bin_name(int bin_number, const EggNode *child) {
if (bin_number == BN_polyset) {
return DCAST(EggPrimitive, child)->get_sort_name();
}
return string();
}
////////////////////////////////////////////////////////////////////
// Function: EggBinner::sorts_less
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool EggBinner::
sorts_less(int bin_number, const EggNode *a, const EggNode *b) {
switch (bin_number) {
case BN_polyset:
{
const EggPrimitive *pa, *pb;
DCAST_INTO_R(pa, a, false);
DCAST_INTO_R(pb, b, false);
// Different render states are binned separately.
const EggRenderState *rsa, *rsb;
DCAST_INTO_R(rsa, pa->get_user_data(EggRenderState::get_class_type()), false);
DCAST_INTO_R(rsb, pb->get_user_data(EggRenderState::get_class_type()), false);
int compare = rsa->compare_to(*rsb);
if (compare != 0) {
return (compare < 0);
}
// Also, if the primitive was given a name (that does not begin
// with a digit), it gets binned with similar-named primitives.
return pa->get_sort_name() < pb->get_sort_name();
}
case BN_lod:
{
const EggGroup *ga = DCAST(EggGroup, a);
const EggGroup *gb = DCAST(EggGroup, b);
const EggSwitchCondition &swa = ga->get_lod();
const EggSwitchCondition &swb = gb->get_lod();
// For now, this is the only kind of switch condition there is.
const EggSwitchConditionDistance &swda =
*DCAST(EggSwitchConditionDistance, &swa);
const EggSwitchConditionDistance &swdb =
*DCAST(EggSwitchConditionDistance, &swb);
// Group LOD nodes in order by switching center.
return (swda._center.compare_to(swdb._center) < 0);
}
case BN_nurbs_surface:
case BN_nurbs_curve:
// Nurbs curves and surfaces are always binned individually.
return a < b;
case BN_none:
break;
}
// Shouldn't get here.
return false;
}