mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
more new geom work
This commit is contained in:
parent
1058f0fa68
commit
d4401c9c43
@ -104,3 +104,20 @@ set_component(int i, const EggAttributes *attrib) {
|
||||
nassertv(i >= 0 && i < (int)_components.size());
|
||||
_components[i] = new EggAttributes(*attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::triangulate_into
|
||||
// Access: Published
|
||||
// Description: Subdivides the composite primitive into triangles and
|
||||
// adds those triangles to the indicated container.
|
||||
// Does not remove the primitive from its existing
|
||||
// parent or modify it in any way.
|
||||
//
|
||||
// Returns true if the triangulation is successful, or
|
||||
// false if there was some error (in which case the
|
||||
// container may contain some partial triangulation).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggCompositePrimitive::
|
||||
triangulate_into(EggGroupNode *container) const {
|
||||
return do_triangulate(container);
|
||||
}
|
||||
|
@ -42,13 +42,14 @@ PUBLISHED:
|
||||
INLINE EggAttributes *get_component(int i);
|
||||
INLINE void set_component(int i, const EggAttributes *attrib);
|
||||
|
||||
INLINE bool triangulate_into(EggGroupNode *container) const;
|
||||
PT(EggCompositePrimitive) triangulate_in_place();
|
||||
|
||||
protected:
|
||||
virtual void prepare_add_vertex(EggVertex *vertex, int i, int n);
|
||||
virtual void prepare_remove_vertex(EggVertex *vertex, int i, int n);
|
||||
|
||||
virtual void do_triangulate(EggGroupNode *container)=0;
|
||||
virtual bool do_triangulate(EggGroupNode *container) const=0;
|
||||
|
||||
void write_body(ostream &out, int indent_level) const;
|
||||
|
||||
|
@ -1253,6 +1253,8 @@ r_load_externals(const DSearchPath &searchpath, CoordinateSystem coordsys) {
|
||||
void EggGroupNode::
|
||||
prepare_add_child(EggNode *node) {
|
||||
nassertv(node != (EggNode *)NULL);
|
||||
test_ref_count_integrity();
|
||||
node->test_ref_count_integrity();
|
||||
// Make sure the node is not already a child of some other group.
|
||||
nassertv(node->get_parent() == NULL);
|
||||
nassertv(node->get_depth() == 0);
|
||||
|
@ -42,54 +42,74 @@ EggMesher() {
|
||||
// Access: Public
|
||||
// Description: Accepts an EggGroupNode, which contains a set of
|
||||
// EggPrimitives--typically, triangles and quads--as
|
||||
// children. All of the EggPrimitives must reference
|
||||
// the same vertex pool.
|
||||
//
|
||||
// At the completion of this function, the triangles in
|
||||
// the group will have been replaced with
|
||||
// EggTriangleStrips as appropriate.
|
||||
// children. Removes these primitives and replaces them
|
||||
// with (mostly) equivalent EggTriangleStrips and
|
||||
// EggTriangleFans where possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
mesh(EggGroupNode *group) {
|
||||
_vertex_pool = NULL;
|
||||
_strip_index = 0;
|
||||
// Create a temporary node to hold the children of group that aren't
|
||||
// involved in the meshing, as well as the newly-generate triangle
|
||||
// strips.
|
||||
PT(EggGroupNode) output_children = new EggGroupNode;
|
||||
|
||||
// Create a temporary node to hold the children of groupthat aren't
|
||||
// involved in the meshing.
|
||||
PT(EggGroupNode) saved_children = new EggGroupNode;
|
||||
// And another to hold the children that will be processed next
|
||||
// time.
|
||||
PT(EggGroupNode) next_children = new EggGroupNode;
|
||||
PT(EggGroupNode) this_children = group;
|
||||
|
||||
// Add each primitive in the group to the mesh pool.
|
||||
EggGroupNode::iterator ci = group->begin();
|
||||
while (ci != group->end()) {
|
||||
EggGroupNode::iterator cnext = ci;
|
||||
++cnext;
|
||||
// Only primitives that share a common vertex pool can be meshed
|
||||
// together. Thus, pull out the primitives with the same vertex
|
||||
// pool in groups.
|
||||
while (this_children->size() != 0) {
|
||||
clear();
|
||||
|
||||
if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
|
||||
add_polygon(DCAST(EggPolygon, *ci), EggMesherStrip::MO_user);
|
||||
} else {
|
||||
// If it's not a polygon, preserve it.
|
||||
saved_children->add_child(*ci);
|
||||
// Add each polygon in the group to the mesh pool.
|
||||
while (!this_children->empty()) {
|
||||
PT(EggNode) child = this_children->get_first_child();
|
||||
this_children->remove_child(child);
|
||||
|
||||
if (child->is_of_type(EggPolygon::get_class_type())) {
|
||||
EggPolygon *poly = DCAST(EggPolygon, child);
|
||||
|
||||
if (_vertex_pool == (EggVertexPool *)NULL) {
|
||||
_vertex_pool = poly->get_pool();
|
||||
add_polygon(poly, EggMesherStrip::MO_user);
|
||||
|
||||
} else if (_vertex_pool == poly->get_pool()) {
|
||||
add_polygon(poly, EggMesherStrip::MO_user);
|
||||
|
||||
} else {
|
||||
// A different vertex pool; save this one for next pass.
|
||||
next_children->add_child(poly);
|
||||
}
|
||||
|
||||
} else {
|
||||
// If it's not a polygon of any kind, just output it
|
||||
// unchanged.
|
||||
output_children->add_child(child);
|
||||
}
|
||||
}
|
||||
|
||||
do_mesh();
|
||||
|
||||
Strips::iterator si;
|
||||
for (si = _done.begin(); si != _done.end(); ++si) {
|
||||
PT(EggPrimitive) egg_prim = get_prim(*si);
|
||||
if (egg_prim != (EggPrimitive *)NULL) {
|
||||
output_children->add_child(egg_prim);
|
||||
}
|
||||
}
|
||||
ci = cnext;
|
||||
}
|
||||
|
||||
do_mesh();
|
||||
this_children = next_children;
|
||||
next_children = new EggGroupNode;
|
||||
}
|
||||
|
||||
// Now copy the newly-meshed primitives back to the group.
|
||||
group->clear();
|
||||
group->steal_children(*saved_children);
|
||||
group->steal_children(*output_children);
|
||||
|
||||
Strips::iterator si;
|
||||
for (si = _done.begin(); si != _done.end(); ++si) {
|
||||
PT(EggPrimitive) egg_prim = get_prim(*si);
|
||||
if (egg_prim != (EggPrimitive *)NULL) {
|
||||
group->add_child(egg_prim);
|
||||
}
|
||||
}
|
||||
|
||||
_vertex_pool = NULL;
|
||||
_strip_index = 0;
|
||||
_color_sheets.clear();
|
||||
clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -136,6 +156,26 @@ write(ostream &out) const {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::clear
|
||||
// Access: Private
|
||||
// Description: Empties the pool of meshable primitives and resets to
|
||||
// an initial state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
clear() {
|
||||
_tris.clear();
|
||||
_quads.clear();
|
||||
_strips.clear();
|
||||
_dead.clear();
|
||||
_done.clear();
|
||||
_verts.clear();
|
||||
_edges.clear();
|
||||
_strip_index = 0;
|
||||
_vertex_pool = NULL;
|
||||
_color_sheets.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::add_polygon
|
||||
// Access: Private
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
bool _show_qsheets;
|
||||
|
||||
private:
|
||||
void clear();
|
||||
bool add_polygon(const EggPolygon *egg_poly,
|
||||
EggMesherStrip::MesherOrigin origin);
|
||||
void do_mesh();
|
||||
|
@ -65,13 +65,17 @@ write(ostream &out, int indent_level) const {
|
||||
// It is assumed that the EggTriangleStrip is not
|
||||
// already a child of any other group when this function
|
||||
// is called.
|
||||
//
|
||||
// Returns true if the triangulation is successful, or
|
||||
// false if there was some error (in which case the
|
||||
// container may contain some partial triangulation).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTriangleStrip::
|
||||
do_triangulate(EggGroupNode *container) {
|
||||
bool EggTriangleStrip::
|
||||
do_triangulate(EggGroupNode *container) const {
|
||||
if (size() < 3) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
iterator vi = begin();
|
||||
const_iterator vi = begin();
|
||||
EggVertex *v0 = (*vi);
|
||||
++vi;
|
||||
EggVertex *v1 = (*vi);
|
||||
@ -104,4 +108,6 @@ do_triangulate(EggGroupNode *container) {
|
||||
container->add_child(poly);
|
||||
++vi;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ PUBLISHED:
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
protected:
|
||||
virtual void do_triangulate(EggGroupNode *container);
|
||||
virtual bool do_triangulate(EggGroupNode *container) const;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -134,11 +134,12 @@ EggLoader() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: The EggLoader constructor makes a copy of the EggData
|
||||
// passed in.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggLoader::
|
||||
EggLoader(const EggData &data) :
|
||||
_data(new EggData(data))
|
||||
EggLoader(const EggData *data) :
|
||||
_data(new EggData(*data))
|
||||
{
|
||||
_error = false;
|
||||
}
|
||||
@ -1595,8 +1596,8 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
|
||||
if (pnode->get_num_vertices() == 0) {
|
||||
egg2pg_cat.warning()
|
||||
<< "Portal " << egg_group->get_name() << " has no vertices!\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (egg_group->get_polylight_flag()) {
|
||||
// Create a polylight instead of a regular polyset.
|
||||
// use make_sphere to get the center, radius and color
|
||||
@ -1987,7 +1988,7 @@ void EggLoader::
|
||||
set_portal_polygon(EggGroup *egg_group, PortalNode *pnode) {
|
||||
pnode->clear_vertices();
|
||||
|
||||
EggPolygon *poly = find_first_polygon(egg_group);
|
||||
PT(EggPolygon) poly = find_first_polygon(egg_group);
|
||||
if (poly != (EggPolygon *)NULL) {
|
||||
LMatrix4d mat = poly->get_vertex_to_node();
|
||||
|
||||
@ -2005,7 +2006,7 @@ set_portal_polygon(EggGroup *egg_group, PortalNode *pnode) {
|
||||
// Description: Returns the first EggPolygon found at or below the
|
||||
// indicated node.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggPolygon *EggLoader::
|
||||
PT(EggPolygon) EggLoader::
|
||||
find_first_polygon(EggGroup *egg_group) {
|
||||
// Does this group have any polygons?
|
||||
EggGroup::const_iterator ci;
|
||||
@ -2021,8 +2022,8 @@ find_first_polygon(EggGroup *egg_group) {
|
||||
for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
|
||||
if ((*ci)->is_of_type(EggGroup::get_class_type())) {
|
||||
EggGroup *child_group = DCAST(EggGroup, *ci);
|
||||
EggPolygon *found = find_first_polygon(child_group);
|
||||
if (found != NULL) {
|
||||
PT(EggPolygon) found = find_first_polygon(child_group);
|
||||
if (found != (EggPolygon *)NULL) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
@ -2181,6 +2182,13 @@ make_collision_plane(EggGroup *egg_group, CollisionNode *cnode,
|
||||
cnode->add_solid(csplane);
|
||||
return;
|
||||
}
|
||||
} else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
|
||||
EggCompositePrimitive *comp = DCAST(EggCompositePrimitive, *ci);
|
||||
PT(EggGroup) temp_group = new EggGroup;
|
||||
if (comp->triangulate_into(temp_group)) {
|
||||
make_collision_plane(temp_group, cnode, flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2203,6 +2211,13 @@ make_collision_polygon(EggGroup *egg_group, CollisionNode *cnode,
|
||||
if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
|
||||
create_collision_polygons(cnode, DCAST(EggPolygon, *ci),
|
||||
egg_group, flags);
|
||||
} else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
|
||||
EggCompositePrimitive *comp = DCAST(EggCompositePrimitive, *ci);
|
||||
PT(EggGroup) temp_group = new EggGroup;
|
||||
if (comp->triangulate_into(temp_group)) {
|
||||
make_collision_polygon(temp_group, cnode, flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2224,6 +2239,12 @@ make_collision_polyset(EggGroup *egg_group, CollisionNode *cnode,
|
||||
if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
|
||||
create_collision_polygons(cnode, DCAST(EggPolygon, *ci),
|
||||
egg_group, flags);
|
||||
} else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
|
||||
EggCompositePrimitive *comp = DCAST(EggCompositePrimitive, *ci);
|
||||
PT(EggGroup) temp_group = new EggGroup;
|
||||
if (comp->triangulate_into(temp_group)) {
|
||||
make_collision_polyset(temp_group, cnode, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class PolylightNode;
|
||||
class EggLoader {
|
||||
public:
|
||||
EggLoader();
|
||||
EggLoader(const EggData &data);
|
||||
EggLoader(const EggData *data);
|
||||
|
||||
void build_graph();
|
||||
void reparent_decals();
|
||||
@ -133,7 +133,7 @@ private:
|
||||
void make_primitive(EggPrimitive *egg_prim, Primitives &primitives);
|
||||
|
||||
void set_portal_polygon(EggGroup *egg_group, PortalNode *pnode);
|
||||
EggPolygon *find_first_polygon(EggGroup *egg_group);
|
||||
PT(EggPolygon) find_first_polygon(EggGroup *egg_group);
|
||||
|
||||
bool make_sphere(EggGroup *start_group, EggGroup::CollideFlags flags,
|
||||
LPoint3f ¢er, float &radius, Colorf &color);
|
||||
|
@ -117,11 +117,11 @@ load_egg_file(const string &filename, CoordinateSystem cs) {
|
||||
// loading.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(PandaNode)
|
||||
load_egg_data(EggData &data, CoordinateSystem cs) {
|
||||
load_egg_data(EggData *data, CoordinateSystem cs) {
|
||||
// We temporarily shuttle the children to a holding node so we can
|
||||
// copy them into the EggLoader's structure without it complaining.
|
||||
EggGroupNode children_holder;
|
||||
children_holder.steal_children(data);
|
||||
children_holder.steal_children(*data);
|
||||
|
||||
EggLoader loader(data);
|
||||
loader._data->steal_children(children_holder);
|
||||
|
@ -48,7 +48,7 @@ load_egg_file(const string &filename, CoordinateSystem cs = CS_default);
|
||||
// loading.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EXPCL_PANDAEGG PT(PandaNode)
|
||||
load_egg_data(EggData &data, CoordinateSystem cs = CS_default);
|
||||
load_egg_data(EggData *data, CoordinateSystem cs = CS_default);
|
||||
END_PUBLISH
|
||||
|
||||
#endif
|
||||
|
@ -58,19 +58,19 @@ get_vertices() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_vertices
|
||||
// Access: Published
|
||||
// Description: Returns a const pointer to the primitive lengths
|
||||
// Description: Returns a const pointer to the primitive ends
|
||||
// array so application code can read it directly. Do
|
||||
// not attempt to modify the returned array; use
|
||||
// modify_lengths() or set_lengths() for this.
|
||||
// modify_ends() or set_ends() for this.
|
||||
//
|
||||
// Note that simple primitive types, like triangles, do
|
||||
// not have a lengths array: since all the primitives
|
||||
// not have a ends array: since all the primitives
|
||||
// have the same number of vertices, it is not needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_int qpGeomPrimitive::
|
||||
get_lengths() const {
|
||||
get_ends() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_lengths;
|
||||
return cdata->_ends;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -124,7 +124,7 @@ CData() :
|
||||
INLINE qpGeomPrimitive::CData::
|
||||
CData(const qpGeomPrimitive::CData ©) :
|
||||
_vertices(copy._vertices),
|
||||
_lengths(copy._lengths),
|
||||
_ends(copy._ends),
|
||||
_got_minmax(copy._got_minmax),
|
||||
_min_vertex(copy._min_vertex),
|
||||
_max_vertex(copy._max_vertex)
|
||||
|
@ -141,11 +141,16 @@ close_primitive() {
|
||||
if (num_vertices_per_primitive == 0) {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
if (cdata->_lengths.empty()) {
|
||||
cdata->_lengths.push_back((int)cdata->_vertices.size());
|
||||
} else if (cdata->_lengths.back() != (int)cdata->_vertices.size()) {
|
||||
cdata->_lengths.push_back((int)cdata->_vertices.size() - cdata->_lengths.back());
|
||||
#ifndef NDEBUG
|
||||
int num_added;
|
||||
if (cdata->_ends.empty()) {
|
||||
num_added = (int)cdata->_vertices.size();
|
||||
} else {
|
||||
num_added = (int)cdata->_vertices.size() - cdata->_ends.back();
|
||||
}
|
||||
nassertv(num_added >= get_min_num_vertices_per_primitive());
|
||||
#endif
|
||||
cdata->_ends.push_back((int)cdata->_vertices.size());
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
@ -166,7 +171,7 @@ clear_vertices() {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_vertices.clear();
|
||||
cdata->_lengths.clear();
|
||||
cdata->_ends.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -189,7 +194,7 @@ modify_vertices() {
|
||||
// Access: Published
|
||||
// Description: Completely replaces the vertex index list with a new
|
||||
// table. Chances are good that you should also replace
|
||||
// the lengths list with set_lengths() at the same time.
|
||||
// the ends list with set_ends() at the same time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
set_vertices(PTA_ushort vertices) {
|
||||
@ -199,41 +204,41 @@ set_vertices(PTA_ushort vertices) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::modify_lengths
|
||||
// Function: qpGeomPrimitive::modify_ends
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the primitive lengths
|
||||
// Description: Returns a modifiable pointer to the primitive ends
|
||||
// array, so application code can directly fiddle with
|
||||
// this data. Use with caution, since there are no
|
||||
// checks that the data will be left in a stable state.
|
||||
//
|
||||
// Note that simple primitive types, like triangles, do
|
||||
// not have a lengths array: since all the primitives
|
||||
// not have a ends array: since all the primitives
|
||||
// have the same number of vertices, it is not needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_int qpGeomPrimitive::
|
||||
modify_lengths() {
|
||||
modify_ends() {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
return cdata->_lengths;
|
||||
return cdata->_ends;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::set_lengths
|
||||
// Function: qpGeomPrimitive::set_ends
|
||||
// Access: Published
|
||||
// Description: Completely replaces the primitive lengths array with
|
||||
// Description: Completely replaces the primitive ends array with
|
||||
// a new table. Chances are good that you should also
|
||||
// replace the vertices list with set_vertices() at the
|
||||
// same time.
|
||||
//
|
||||
// Note that simple primitive types, like triangles, do
|
||||
// not have a lengths array: since all the primitives
|
||||
// not have a ends array: since all the primitives
|
||||
// have the same number of vertices, it is not needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
set_lengths(PTA_int lengths) {
|
||||
set_ends(PTA_int ends) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lengths = lengths;
|
||||
cdata->_ends = ends;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -246,7 +251,7 @@ int qpGeomPrimitive::
|
||||
get_num_bytes() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_vertices.size() * sizeof(short) +
|
||||
cdata->_lengths.size() * sizeof(int);
|
||||
cdata->_ends.size() * sizeof(int);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -265,6 +270,17 @@ get_num_vertices_per_primitive() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_min_num_vertices_per_primitive
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the minimum number of vertices that must be
|
||||
// added before close_primitive() may legally be called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPrimitive::
|
||||
get_min_num_vertices_per_primitive() const {
|
||||
return 3;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_num_primitives
|
||||
// Access: Published
|
||||
@ -280,7 +296,7 @@ get_num_primitives() const {
|
||||
if (num_vertices_per_primitive == 0) {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
return cdata->_lengths.size();
|
||||
return cdata->_ends.size();
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
@ -293,7 +309,7 @@ get_num_primitives() const {
|
||||
// Function: qpGeomPrimitive::get_primitive_start
|
||||
// Access: Published
|
||||
// Description: Returns the element within the _vertices list at which
|
||||
// the ith primitive starts.
|
||||
// the ith primitive ends.
|
||||
//
|
||||
// If i is one more than the highest valid primitive
|
||||
// vertex, the return value will be one more than the
|
||||
@ -310,11 +326,11 @@ get_primitive_start(int i) const {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(i >= 0 && i <= (int)cdata->_lengths.size(), -1);
|
||||
nassertr(i >= 0 && i <= (int)cdata->_ends.size(), -1);
|
||||
if (i == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return cdata->_lengths[i - 1];
|
||||
return cdata->_ends[i - 1];
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -338,8 +354,12 @@ get_primitive_num_vertices(int i) const {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(i >= 0 && i < (int)cdata->_lengths.size(), 0);
|
||||
return cdata->_lengths[i];
|
||||
nassertr(i >= 0 && i < (int)cdata->_ends.size(), 0);
|
||||
if (i == 0) {
|
||||
return cdata->_ends[0];
|
||||
} else {
|
||||
return cdata->_ends[i] - cdata->_ends[i - 1];
|
||||
}
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
|
@ -75,9 +75,9 @@ PUBLISHED:
|
||||
PTA_ushort modify_vertices();
|
||||
void set_vertices(PTA_ushort vertices);
|
||||
|
||||
INLINE CPTA_int get_lengths() const;
|
||||
PTA_int modify_lengths();
|
||||
void set_lengths(PTA_int lengths);
|
||||
INLINE CPTA_int get_ends() const;
|
||||
PTA_int modify_ends();
|
||||
void set_ends(PTA_int ends);
|
||||
|
||||
int get_num_bytes() const;
|
||||
|
||||
@ -85,6 +85,7 @@ PUBLISHED:
|
||||
INLINE int get_max_vertex() const;
|
||||
|
||||
virtual int get_num_vertices_per_primitive() const;
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
int get_num_primitives() const;
|
||||
int get_primitive_start(int i) const;
|
||||
int get_primitive_num_vertices(int i) const;
|
||||
@ -121,7 +122,7 @@ private:
|
||||
virtual void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
PTA_ushort _vertices;
|
||||
PTA_int _lengths;
|
||||
PTA_int _ends;
|
||||
|
||||
bool _got_minmax;
|
||||
unsigned short _min_vertex;
|
||||
|
@ -81,28 +81,31 @@ PT(qpGeomPrimitive) qpGeomTrifans::
|
||||
decompose_impl() {
|
||||
PT(qpGeomTriangles) triangles = new qpGeomTriangles;
|
||||
CPTA_ushort vertices = get_vertices();
|
||||
CPTA_int lengths = get_lengths();
|
||||
CPTA_int ends = get_ends();
|
||||
|
||||
CPTA_ushort::const_iterator vi;
|
||||
vi = vertices.begin();
|
||||
|
||||
CPTA_int::const_iterator li;
|
||||
for (li = lengths.begin(); li != lengths.end(); ++li) {
|
||||
int length = (*li);
|
||||
nassertr(length >= 2, triangles.p());
|
||||
int v0 = (*vi);
|
||||
int vi = 0;
|
||||
int li = 0;
|
||||
while (li < (int)ends.size()) {
|
||||
int end = ends[li];
|
||||
nassertr(vi + 2 <= end, triangles.p());
|
||||
nassertr(vi < (int)vertices.size(), this);
|
||||
int v0 = vertices[vi];
|
||||
++vi;
|
||||
int v1 = (*vi);
|
||||
nassertr(vi < (int)vertices.size(), this);
|
||||
int v1 = vertices[vi];
|
||||
++vi;
|
||||
for (int i = 2; i < length; i++) {
|
||||
while (vi < end) {
|
||||
triangles->add_vertex(v0);
|
||||
triangles->add_vertex(v1);
|
||||
triangles->add_vertex(*vi);
|
||||
triangles->add_vertex(vertices[vi]);
|
||||
triangles->close_primitive();
|
||||
++vi;
|
||||
}
|
||||
++li;
|
||||
}
|
||||
|
||||
nassertr(vi == (int)vertices.size(), triangles.p());
|
||||
|
||||
return triangles.p();
|
||||
}
|
||||
|
||||
|
@ -81,26 +81,21 @@ PT(qpGeomPrimitive) qpGeomTristrips::
|
||||
decompose_impl() {
|
||||
PT(qpGeomTriangles) triangles = new qpGeomTriangles;
|
||||
CPTA_ushort vertices = get_vertices();
|
||||
CPTA_int lengths = get_lengths();
|
||||
CPTA_int ends = get_ends();
|
||||
|
||||
CPTA_ushort::const_iterator vi;
|
||||
vi = vertices.begin();
|
||||
|
||||
cerr << "starting vertices, size = " << vertices.size() << "\n";
|
||||
|
||||
CPTA_int::const_iterator li;
|
||||
for (li = lengths.begin(); li != lengths.end(); ++li) {
|
||||
int length = (*li);
|
||||
cerr << "length = " << length << "\n";
|
||||
nassertr(length >= 2, triangles.p());
|
||||
nassertr(vi != vertices.end(), this);
|
||||
int v0 = (*vi);
|
||||
int vi = 0;
|
||||
int li = 0;
|
||||
while (li < (int)ends.size()) {
|
||||
int end = ends[li];
|
||||
nassertr(vi + 2 <= end, triangles.p());
|
||||
nassertr(vi < (int)vertices.size(), this);
|
||||
int v0 = vertices[vi];
|
||||
++vi;
|
||||
nassertr(vi != vertices.end(), this);
|
||||
int v1 = (*vi);
|
||||
nassertr(vi < (int)vertices.size(), this);
|
||||
int v1 = vertices[vi];
|
||||
++vi;
|
||||
bool reversed = false;
|
||||
for (int i = 2; i < length; i++) {
|
||||
while (vi < end) {
|
||||
if (reversed) {
|
||||
triangles->add_vertex(v1);
|
||||
triangles->add_vertex(v0);
|
||||
@ -110,16 +105,17 @@ decompose_impl() {
|
||||
triangles->add_vertex(v1);
|
||||
reversed = true;
|
||||
}
|
||||
triangles->add_vertex(*vi);
|
||||
triangles->add_vertex(vertices[vi]);
|
||||
v0 = v1;
|
||||
nassertr(vi != vertices.end(), this);
|
||||
v1 = *vi;
|
||||
nassertr(vi < (int)vertices.size(), this);
|
||||
v1 = vertices[vi];
|
||||
triangles->close_primitive();
|
||||
++vi;
|
||||
}
|
||||
++li;
|
||||
}
|
||||
|
||||
triangles->write(cerr, 0);
|
||||
nassertr(vi == (int)vertices.size(), triangles.p());
|
||||
|
||||
return triangles.p();
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ class CgShaderAttrib;
|
||||
class CullFaceAttrib;
|
||||
class StencilAttrib;
|
||||
class ClipPlaneAttrib;
|
||||
class ShadeModelAttrib;
|
||||
class TransparencyAttrib;
|
||||
class FogAttrib;
|
||||
class LinesmoothAttrib;
|
||||
@ -212,6 +213,7 @@ public:
|
||||
virtual void issue_cg_shader_bind(const CgShaderAttrib *){}
|
||||
virtual void issue_stencil(const StencilAttrib *) { }
|
||||
virtual void issue_clip_plane(const ClipPlaneAttrib *) { }
|
||||
virtual void issue_shade_model(const ShadeModelAttrib *) { }
|
||||
|
||||
virtual void bind_light(PointLight *light_obj, const NodePath &light,
|
||||
int light_id) { }
|
||||
|
@ -87,6 +87,7 @@
|
||||
sceneSetup.I sceneSetup.h \
|
||||
selectiveChildNode.I selectiveChildNode.h \
|
||||
sequenceNode.I sequenceNode.h \
|
||||
shadeModelAttrib.I shadeModelAttrib.h \
|
||||
showBoundsEffect.I showBoundsEffect.h \
|
||||
spotlight.I spotlight.h \
|
||||
switchNode.I switchNode.h \
|
||||
@ -181,6 +182,7 @@
|
||||
sceneSetup.cxx \
|
||||
selectiveChildNode.cxx \
|
||||
sequenceNode.cxx \
|
||||
shadeModelAttrib.cxx \
|
||||
showBoundsEffect.cxx \
|
||||
spotlight.cxx \
|
||||
switchNode.cxx \
|
||||
@ -273,6 +275,7 @@
|
||||
sceneSetup.I sceneSetup.h \
|
||||
selectiveChildNode.I selectiveChildNode.h \
|
||||
sequenceNode.I sequenceNode.h \
|
||||
shadeModelAttrib.I shadeModelAttrib.h \
|
||||
showBoundsEffect.I showBoundsEffect.h \
|
||||
spotlight.I spotlight.h \
|
||||
switchNode.I switchNode.h \
|
||||
|
@ -78,6 +78,7 @@
|
||||
#include "rescaleNormalAttrib.h"
|
||||
#include "selectiveChildNode.h"
|
||||
#include "sequenceNode.h"
|
||||
#include "shadeModelAttrib.h"
|
||||
#include "showBoundsEffect.h"
|
||||
#include "spotlight.h"
|
||||
#include "switchNode.h"
|
||||
@ -277,6 +278,7 @@ init_libpgraph() {
|
||||
RescaleNormalAttrib::init_type();
|
||||
SelectiveChildNode::init_type();
|
||||
SequenceNode::init_type();
|
||||
ShadeModelAttrib::init_type();
|
||||
ShowBoundsEffect::init_type();
|
||||
Spotlight::init_type();
|
||||
SwitchNode::init_type();
|
||||
@ -332,6 +334,7 @@ init_libpgraph() {
|
||||
RenderModeAttrib::register_with_read_factory();
|
||||
RenderState::register_with_read_factory();
|
||||
SequenceNode::register_with_read_factory();
|
||||
ShadeModelAttrib::register_with_read_factory();
|
||||
ShowBoundsEffect::register_with_read_factory();
|
||||
Spotlight::register_with_read_factory();
|
||||
SwitchNode::register_with_read_factory();
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "sceneGraphReducer.cxx"
|
||||
#include "selectiveChildNode.cxx"
|
||||
#include "sequenceNode.cxx"
|
||||
#include "shadeModelAttrib.cxx"
|
||||
#include "showBoundsEffect.cxx"
|
||||
#include "spotlight.cxx"
|
||||
#include "switchNode.cxx"
|
||||
|
40
panda/src/pgraph/shadeModelAttrib.I
Normal file
40
panda/src/pgraph/shadeModelAttrib.I
Normal file
@ -0,0 +1,40 @@
|
||||
// Filename: shadeModelAttrib.I
|
||||
// Created by: drose (14Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::Constructor
|
||||
// Access: Private
|
||||
// Description: Use ShadeModelAttrib::make() to construct a new
|
||||
// ShadeModelAttrib object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ShadeModelAttrib::
|
||||
ShadeModelAttrib(ShadeModelAttrib::Mode mode) :
|
||||
_mode(mode)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::get_mode
|
||||
// Access: Published
|
||||
// Description: Returns the shade mode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ShadeModelAttrib::Mode ShadeModelAttrib::
|
||||
get_mode() const {
|
||||
return _mode;
|
||||
}
|
194
panda/src/pgraph/shadeModelAttrib.cxx
Normal file
194
panda/src/pgraph/shadeModelAttrib.cxx
Normal file
@ -0,0 +1,194 @@
|
||||
// Filename: shadeModelAttrib.cxx
|
||||
// Created by: drose (14Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "shadeModelAttrib.h"
|
||||
#include "graphicsStateGuardianBase.h"
|
||||
#include "dcast.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
TypeHandle ShadeModelAttrib::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::make
|
||||
// Access: Published, Static
|
||||
// Description: Constructs a new ShadeModelAttrib object that specifies
|
||||
// whether to draw polygons with flat shading or with
|
||||
// per-vertex (smooth) shading.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ShadeModelAttrib::
|
||||
make(ShadeModelAttrib::Mode mode) {
|
||||
ShadeModelAttrib *attrib = new ShadeModelAttrib(mode);
|
||||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::issue
|
||||
// Access: Public, Virtual
|
||||
// Description: Calls the appropriate method on the indicated GSG
|
||||
// to issue the graphics commands appropriate to the
|
||||
// given attribute. This is normally called
|
||||
// (indirectly) only from
|
||||
// GraphicsStateGuardian::set_state() or modify_state().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShadeModelAttrib::
|
||||
issue(GraphicsStateGuardianBase *gsg) const {
|
||||
gsg->issue_shade_model(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShadeModelAttrib::
|
||||
output(ostream &out) const {
|
||||
out << get_type() << ":";
|
||||
switch (get_mode()) {
|
||||
case M_flat:
|
||||
out << "flat";
|
||||
|
||||
case M_smooth:
|
||||
out << "smooth";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::compare_to_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Intended to be overridden by derived ShadeModelAttrib
|
||||
// types to return a unique number indicating whether
|
||||
// this ShadeModelAttrib is equivalent to the other one.
|
||||
//
|
||||
// This should return 0 if the two ShadeModelAttrib objects
|
||||
// are equivalent, a number less than zero if this one
|
||||
// should be sorted before the other one, and a number
|
||||
// greater than zero otherwise.
|
||||
//
|
||||
// This will only be called with two ShadeModelAttrib
|
||||
// objects whose get_type() functions return the same.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ShadeModelAttrib::
|
||||
compare_to_impl(const RenderAttrib *other) const {
|
||||
const ShadeModelAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
return (int)_mode - (int)ta->_mode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::compose_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Intended to be overridden by derived RenderAttrib
|
||||
// types to specify how two consecutive RenderAttrib
|
||||
// objects of the same type interact.
|
||||
//
|
||||
// This should return the result of applying the other
|
||||
// RenderAttrib to a node in the scene graph below this
|
||||
// RenderAttrib, which was already applied. In most
|
||||
// cases, the result is the same as the other
|
||||
// RenderAttrib (that is, a subsequent RenderAttrib
|
||||
// completely replaces the preceding one). On the other
|
||||
// hand, some kinds of RenderAttrib (for instance,
|
||||
// ColorTransformAttrib) might combine in meaningful
|
||||
// ways.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderAttrib) ShadeModelAttrib::
|
||||
compose_impl(const RenderAttrib *other) const {
|
||||
const ShadeModelAttrib *ta;
|
||||
DCAST_INTO_R(ta, other, 0);
|
||||
|
||||
Mode mode = ta->get_mode();
|
||||
return make(mode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::make_default_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Intended to be overridden by derived ShadeModelAttrib
|
||||
// types to specify what the default property for a
|
||||
// ShadeModelAttrib of this type should be.
|
||||
//
|
||||
// This should return a newly-allocated ShadeModelAttrib of
|
||||
// the same type that corresponds to whatever the
|
||||
// standard default for this kind of ShadeModelAttrib is.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
RenderAttrib *ShadeModelAttrib::
|
||||
make_default_impl() const {
|
||||
return new ShadeModelAttrib(M_smooth);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// ShadeModelAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShadeModelAttrib::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShadeModelAttrib::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
RenderAttrib::write_datagram(manager, dg);
|
||||
|
||||
dg.add_int8(_mode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type ShadeModelAttrib is encountered
|
||||
// in the Bam file. It should create the ShadeModelAttrib
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *ShadeModelAttrib::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
ShadeModelAttrib *attrib = new ShadeModelAttrib(M_smooth);
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
attrib->fillin(scan, manager);
|
||||
|
||||
return attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShadeModelAttrib::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new ShadeModelAttrib.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShadeModelAttrib::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
RenderAttrib::fillin(scan, manager);
|
||||
|
||||
_mode = (Mode)scan.get_int8();
|
||||
}
|
89
panda/src/pgraph/shadeModelAttrib.h
Normal file
89
panda/src/pgraph/shadeModelAttrib.h
Normal file
@ -0,0 +1,89 @@
|
||||
// Filename: shadeModelAttrib.h
|
||||
// Created by: drose (14Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SHADEMODELATTRIB_H
|
||||
#define SHADEMODELATTRIB_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "renderAttrib.h"
|
||||
|
||||
class FactoryParams;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ShadeModelAttrib
|
||||
// Description : Specifies whether flat shading (per-polygon) or
|
||||
// smooth shading (per-vertex) is in effect.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA ShadeModelAttrib : public RenderAttrib {
|
||||
PUBLISHED:
|
||||
enum Mode {
|
||||
M_flat,
|
||||
M_smooth,
|
||||
};
|
||||
|
||||
private:
|
||||
INLINE ShadeModelAttrib(Mode mode);
|
||||
|
||||
PUBLISHED:
|
||||
static CPT(RenderAttrib) make(Mode mode);
|
||||
|
||||
INLINE Mode get_mode() const;
|
||||
|
||||
public:
|
||||
virtual void issue(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
protected:
|
||||
virtual int compare_to_impl(const RenderAttrib *other) const;
|
||||
virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
|
||||
virtual RenderAttrib *make_default_impl() const;
|
||||
|
||||
private:
|
||||
Mode _mode;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
RenderAttrib::init_type();
|
||||
register_type(_type_handle, "ShadeModelAttrib",
|
||||
RenderAttrib::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "shadeModelAttrib.I"
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user