mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-17 12:12:10 -04:00
unify()
This commit is contained in:
parent
52dd2fa615
commit
4eb9de4b8e
@ -17,6 +17,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "qpgeom.h"
|
#include "qpgeom.h"
|
||||||
|
#include "qpgeomPoints.h"
|
||||||
#include "qpgeomVertexReader.h"
|
#include "qpgeomVertexReader.h"
|
||||||
#include "qpgeomVertexRewriter.h"
|
#include "qpgeomVertexRewriter.h"
|
||||||
#include "pStatTimer.h"
|
#include "pStatTimer.h"
|
||||||
@ -232,8 +233,14 @@ make_nonindexed(bool composite_only) {
|
|||||||
PT(qpGeomPrimitive) primitive = (*pi)->make_copy();
|
PT(qpGeomPrimitive) primitive = (*pi)->make_copy();
|
||||||
new_prims.push_back(primitive);
|
new_prims.push_back(primitive);
|
||||||
|
|
||||||
|
// GeomPoints are considered "composite" for the purposes of
|
||||||
|
// making nonindexed, since there's no particular advantage to
|
||||||
|
// having indexed points (as opposed to, say, indexed triangles or
|
||||||
|
// indexed lines).
|
||||||
if (primitive->is_indexed() &&
|
if (primitive->is_indexed() &&
|
||||||
(primitive->is_composite() || !composite_only)) {
|
(primitive->is_composite() ||
|
||||||
|
primitive->is_exact_type(qpGeomPoints::get_class_type()) ||
|
||||||
|
!composite_only)) {
|
||||||
primitive->make_nonindexed(new_data, orig_data);
|
primitive->make_nonindexed(new_data, orig_data);
|
||||||
++num_changed;
|
++num_changed;
|
||||||
} else {
|
} else {
|
||||||
@ -281,18 +288,16 @@ set_primitive(int i, const qpGeomPrimitive *primitive) {
|
|||||||
nassertv(cdata->_primitive_type == PT_none ||
|
nassertv(cdata->_primitive_type == PT_none ||
|
||||||
cdata->_primitive_type == primitive->get_primitive_type());
|
cdata->_primitive_type == primitive->get_primitive_type());
|
||||||
|
|
||||||
// They also should have the same fundamental shade model, but
|
// They also should have the a compatible shade model.
|
||||||
// SM_uniform is compatible with anything.
|
CPT(qpGeomPrimitive) compat = primitive->match_shade_model(cdata->_shade_model);
|
||||||
nassertv(cdata->_shade_model == SM_uniform ||
|
nassertv_always(compat != (qpGeomPrimitive *)NULL);
|
||||||
primitive->get_shade_model() == SM_uniform ||
|
|
||||||
cdata->_shade_model == primitive->get_shade_model());
|
|
||||||
|
|
||||||
cdata->_primitives[i] = (qpGeomPrimitive *)primitive;
|
cdata->_primitives[i] = (qpGeomPrimitive *)compat.p();
|
||||||
PrimitiveType new_primitive_type = primitive->get_primitive_type();
|
PrimitiveType new_primitive_type = compat->get_primitive_type();
|
||||||
if (new_primitive_type != cdata->_primitive_type) {
|
if (new_primitive_type != cdata->_primitive_type) {
|
||||||
cdata->_primitive_type = new_primitive_type;
|
cdata->_primitive_type = new_primitive_type;
|
||||||
}
|
}
|
||||||
ShadeModel new_shade_model = primitive->get_shade_model();
|
ShadeModel new_shade_model = compat->get_shade_model();
|
||||||
if (new_shade_model != cdata->_shade_model &&
|
if (new_shade_model != cdata->_shade_model &&
|
||||||
new_shade_model != SM_uniform) {
|
new_shade_model != SM_uniform) {
|
||||||
cdata->_shade_model = new_shade_model;
|
cdata->_shade_model = new_shade_model;
|
||||||
@ -323,18 +328,16 @@ add_primitive(const qpGeomPrimitive *primitive) {
|
|||||||
nassertv(cdata->_primitive_type == PT_none ||
|
nassertv(cdata->_primitive_type == PT_none ||
|
||||||
cdata->_primitive_type == primitive->get_primitive_type());
|
cdata->_primitive_type == primitive->get_primitive_type());
|
||||||
|
|
||||||
// They also should have the same fundamental shade model, but
|
// They also should have the a compatible shade model.
|
||||||
// SM_uniform is compatible with anything.
|
CPT(qpGeomPrimitive) compat = primitive->match_shade_model(cdata->_shade_model);
|
||||||
nassertv(cdata->_shade_model == SM_uniform ||
|
nassertv_always(compat != (qpGeomPrimitive *)NULL);
|
||||||
primitive->get_shade_model() == SM_uniform ||
|
|
||||||
cdata->_shade_model == primitive->get_shade_model());
|
|
||||||
|
|
||||||
cdata->_primitives.push_back((qpGeomPrimitive *)primitive);
|
cdata->_primitives.push_back((qpGeomPrimitive *)compat.p());
|
||||||
PrimitiveType new_primitive_type = primitive->get_primitive_type();
|
PrimitiveType new_primitive_type = compat->get_primitive_type();
|
||||||
if (new_primitive_type != cdata->_primitive_type) {
|
if (new_primitive_type != cdata->_primitive_type) {
|
||||||
cdata->_primitive_type = new_primitive_type;
|
cdata->_primitive_type = new_primitive_type;
|
||||||
}
|
}
|
||||||
ShadeModel new_shade_model = primitive->get_shade_model();
|
ShadeModel new_shade_model = compat->get_shade_model();
|
||||||
if (new_shade_model != cdata->_shade_model &&
|
if (new_shade_model != cdata->_shade_model &&
|
||||||
new_shade_model != SM_uniform) {
|
new_shade_model != SM_uniform) {
|
||||||
cdata->_shade_model = new_shade_model;
|
cdata->_shade_model = new_shade_model;
|
||||||
@ -515,6 +518,51 @@ unify_in_place() {
|
|||||||
reset_geom_rendering(cdata);
|
reset_geom_rendering(cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeom::copy_primitives_from
|
||||||
|
// Access: Published
|
||||||
|
// Description: Copies the primitives from the indicated Geom into
|
||||||
|
// this one. This does require that both Geoms contain
|
||||||
|
// the same fundamental type primitives, both have a
|
||||||
|
// compatible shade model, and both use the same
|
||||||
|
// GeomVertexData.
|
||||||
|
//
|
||||||
|
// Returns true if the copy is successful, or false
|
||||||
|
// otherwise (because the Geoms were mismatched).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool qpGeom::
|
||||||
|
copy_primitives_from(const qpGeom *other) {
|
||||||
|
if (get_primitive_type() != PT_none &&
|
||||||
|
other->get_primitive_type() != get_primitive_type()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (get_vertex_data() != other->get_vertex_data()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShadeModel this_shade_model = get_shade_model();
|
||||||
|
ShadeModel other_shade_model = other->get_shade_model();
|
||||||
|
if (this_shade_model != SM_uniform && other_shade_model != SM_uniform &&
|
||||||
|
this_shade_model != other_shade_model) {
|
||||||
|
if ((this_shade_model == SM_flat_first_vertex && other_shade_model == SM_flat_last_vertex) ||
|
||||||
|
(this_shade_model == SM_flat_last_vertex && other_shade_model == SM_flat_first_vertex)) {
|
||||||
|
// This is acceptable; we can rotate the primitives to match.
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Otherwise, we have incompatible shade models.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_primitives = other->get_num_primitives();
|
||||||
|
for (int i = 0; i < num_primitives; i++) {
|
||||||
|
add_primitive(other->get_primitive(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeom::get_num_bytes
|
// Function: qpGeom::get_num_bytes
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -682,11 +730,13 @@ output(ostream &out) const {
|
|||||||
CDReader cdata(_cycler);
|
CDReader cdata(_cycler);
|
||||||
|
|
||||||
// Get a list of the primitive types contained within this object.
|
// Get a list of the primitive types contained within this object.
|
||||||
|
int num_faces = 0;
|
||||||
pset<TypeHandle> types;
|
pset<TypeHandle> types;
|
||||||
Primitives::const_iterator pi;
|
Primitives::const_iterator pi;
|
||||||
for (pi = cdata->_primitives.begin();
|
for (pi = cdata->_primitives.begin();
|
||||||
pi != cdata->_primitives.end();
|
pi != cdata->_primitives.end();
|
||||||
++pi) {
|
++pi) {
|
||||||
|
num_faces += (*pi)->get_num_faces();
|
||||||
types.insert((*pi)->get_type());
|
types.insert((*pi)->get_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,7 +745,7 @@ output(ostream &out) const {
|
|||||||
for (ti = types.begin(); ti != types.end(); ++ti) {
|
for (ti = types.begin(); ti != types.end(); ++ti) {
|
||||||
out << " " << (*ti);
|
out << " " << (*ti);
|
||||||
}
|
}
|
||||||
out << " ], " << cdata->_data->get_num_rows() << " vertices";
|
out << " ], " << num_faces << " faces";
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -96,6 +96,8 @@ PUBLISHED:
|
|||||||
void rotate_in_place();
|
void rotate_in_place();
|
||||||
void unify_in_place();
|
void unify_in_place();
|
||||||
|
|
||||||
|
bool copy_primitives_from(const qpGeom *other);
|
||||||
|
|
||||||
int get_num_bytes() const;
|
int get_num_bytes() const;
|
||||||
INLINE UpdateSeq get_modified() const;
|
INLINE UpdateSeq get_modified() const;
|
||||||
|
|
||||||
|
@ -675,7 +675,9 @@ decompose() const {
|
|||||||
// Function: qpGeomPrimitive::rotate
|
// Function: qpGeomPrimitive::rotate
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns a new primitive with the shade_model reversed
|
// Description: Returns a new primitive with the shade_model reversed
|
||||||
// (if it is flat shaded).
|
// (if it is flat shaded), if possible. If the
|
||||||
|
// primitive type cannot be rotated, returns the
|
||||||
|
// original primitive, unrotated.
|
||||||
//
|
//
|
||||||
// If the current shade_model indicates
|
// If the current shade_model indicates
|
||||||
// flat_vertex_last, this should bring the last vertex
|
// flat_vertex_last, this should bring the last vertex
|
||||||
@ -694,14 +696,70 @@ rotate() const {
|
|||||||
CPT(qpGeomVertexArrayData) rotated_vertices = rotate_impl();
|
CPT(qpGeomVertexArrayData) rotated_vertices = rotate_impl();
|
||||||
|
|
||||||
if (rotated_vertices == (qpGeomVertexArrayData *)NULL) {
|
if (rotated_vertices == (qpGeomVertexArrayData *)NULL) {
|
||||||
|
// This primitive type can't be rotated.
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
PT(qpGeomPrimitive) new_prim = make_copy();
|
PT(qpGeomPrimitive) new_prim = make_copy();
|
||||||
new_prim->set_vertices(rotated_vertices);
|
new_prim->set_vertices(rotated_vertices);
|
||||||
|
|
||||||
|
switch (get_shade_model()) {
|
||||||
|
case SM_flat_first_vertex:
|
||||||
|
new_prim->set_shade_model(SM_flat_last_vertex);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SM_flat_last_vertex:
|
||||||
|
new_prim->set_shade_model(SM_flat_first_vertex);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return new_prim;
|
return new_prim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomPrimitive::match_shade_model
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a new primitive that is compatible with the
|
||||||
|
// indicated shade model, if possible, or NULL if this
|
||||||
|
// is not possible.
|
||||||
|
//
|
||||||
|
// In most cases, this will return either NULL or the
|
||||||
|
// original primitive. In the case of a
|
||||||
|
// SM_flat_first_vertex vs. a SM_flat_last_vertex (or
|
||||||
|
// vice-versa), however, it will return a rotated
|
||||||
|
// primitive.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CPT(qpGeomPrimitive) qpGeomPrimitive::
|
||||||
|
match_shade_model(qpGeomPrimitive::ShadeModel shade_model) const {
|
||||||
|
ShadeModel this_shade_model = get_shade_model();
|
||||||
|
if (this_shade_model == shade_model) {
|
||||||
|
// Trivially compatible.
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this_shade_model == SM_uniform || shade_model == SM_uniform) {
|
||||||
|
// SM_uniform is compatible with anything.
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this_shade_model == SM_flat_first_vertex && shade_model == SM_flat_last_vertex) ||
|
||||||
|
(this_shade_model == SM_flat_last_vertex && shade_model == SM_flat_first_vertex)) {
|
||||||
|
// Needs to be rotated.
|
||||||
|
CPT(qpGeomPrimitive) rotated = rotate();
|
||||||
|
if (rotated == this) {
|
||||||
|
// Oops, can't be rotated, sorry.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return rotated;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not compatible, sorry.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomPrimitive::get_num_bytes
|
// Function: qpGeomPrimitive::get_num_bytes
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -122,6 +122,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
CPT(qpGeomPrimitive) decompose() const;
|
CPT(qpGeomPrimitive) decompose() const;
|
||||||
CPT(qpGeomPrimitive) rotate() const;
|
CPT(qpGeomPrimitive) rotate() const;
|
||||||
|
CPT(qpGeomPrimitive) match_shade_model(ShadeModel shade_model) const;
|
||||||
|
|
||||||
int get_num_bytes() const;
|
int get_num_bytes() const;
|
||||||
INLINE int get_data_size_bytes() const;
|
INLINE int get_data_size_bytes() const;
|
||||||
|
@ -449,6 +449,75 @@ add_geoms_from(const GeomNode *other) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GeomNode::unify
|
||||||
|
// Access: Published
|
||||||
|
// Description: Attempts to unify all of the Geoms contained within
|
||||||
|
// this node into a single Geom, or at least as few
|
||||||
|
// Geoms as possible. In turn, the individual
|
||||||
|
// GeomPrimitives contained within each resulting Geom
|
||||||
|
// are also unified. The goal is to reduce the number
|
||||||
|
// of GeomPrimitives within the node as far as possible.
|
||||||
|
// This may result in composite primitives, such as
|
||||||
|
// triangle strips and triangle fans, being decomposed
|
||||||
|
// into triangles. See also Geom::unify().
|
||||||
|
//
|
||||||
|
// In order for this to be successful, the primitives
|
||||||
|
// must reference the same GeomVertexData, have the same
|
||||||
|
// fundamental primitive type, and have compatible shade
|
||||||
|
// models.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void GeomNode::
|
||||||
|
unify() {
|
||||||
|
CDWriter cdata(_cycler);
|
||||||
|
|
||||||
|
Geoms new_geoms;
|
||||||
|
|
||||||
|
// Try to unify each Geom with each preceding Geom. This is an n^2
|
||||||
|
// operation, but usually there are only a handful of Geoms to
|
||||||
|
// consider, so that's not a big deal.
|
||||||
|
Geoms::iterator gi;
|
||||||
|
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||||
|
const GeomEntry &entry = (*gi);
|
||||||
|
|
||||||
|
bool unified = false;
|
||||||
|
if (entry._geom->is_of_type(qpGeom::get_class_type())) {
|
||||||
|
Geoms::iterator gj;
|
||||||
|
for (gj = new_geoms.begin(); gj != new_geoms.end() && !unified; ++gj) {
|
||||||
|
GeomEntry &new_entry = (*gj);
|
||||||
|
if (new_entry._geom->is_of_type(qpGeom::get_class_type())) {
|
||||||
|
if (entry._state == new_entry._state) {
|
||||||
|
// Both states match, so try to combine the primitives.
|
||||||
|
if (DCAST(qpGeom, new_entry._geom)->copy_primitives_from
|
||||||
|
(DCAST(qpGeom, entry._geom))) {
|
||||||
|
// Successfully combined!
|
||||||
|
unified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unified) {
|
||||||
|
// Couldn't unify this Geom with anything, so just add it to the
|
||||||
|
// output list.
|
||||||
|
new_geoms.push_back(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done! We'll keep whatever's left in the output list.
|
||||||
|
cdata->_geoms.swap(new_geoms);
|
||||||
|
new_geoms.clear();
|
||||||
|
|
||||||
|
// Finally, go back through and unify the resulting geom(s).
|
||||||
|
for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
|
||||||
|
const GeomEntry &entry = (*gi);
|
||||||
|
if (entry._geom->is_of_type(qpGeom::get_class_type())) {
|
||||||
|
DCAST(qpGeom, entry._geom)->unify_in_place();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GeomNode::write_geoms
|
// Function: GeomNode::write_geoms
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -68,6 +68,8 @@ PUBLISHED:
|
|||||||
INLINE void remove_geom(int n);
|
INLINE void remove_geom(int n);
|
||||||
INLINE void remove_all_geoms();
|
INLINE void remove_all_geoms();
|
||||||
|
|
||||||
|
void unify();
|
||||||
|
|
||||||
void write_geoms(ostream &out, int indent_level) const;
|
void write_geoms(ostream &out, int indent_level) const;
|
||||||
void write_verbose(ostream &out, int indent_level) const;
|
void write_verbose(ostream &out, int indent_level) const;
|
||||||
|
|
||||||
|
@ -617,7 +617,7 @@ collect_vertex_data(qpGeom *geom, int collect_bits) {
|
|||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Collects together individual GeomVertexData
|
// Description: Collects together individual GeomVertexData
|
||||||
// structures that share the same format into one big
|
// structures that share the same format into one big
|
||||||
// GeomVertexData structure. This is designed to
|
// GeomVertexData structure. This is intended to
|
||||||
// minimize context switches on the graphics card.
|
// minimize context switches on the graphics card.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int GeomTransformer::
|
int GeomTransformer::
|
||||||
|
@ -133,3 +133,14 @@ INLINE int SceneGraphReducer::
|
|||||||
make_nonindexed(PandaNode *root, int nonindexed_bits) {
|
make_nonindexed(PandaNode *root, int nonindexed_bits) {
|
||||||
return r_make_nonindexed(root, nonindexed_bits);
|
return r_make_nonindexed(root, nonindexed_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SceneGraphReducer::unify
|
||||||
|
// Access: Published
|
||||||
|
// Description: Calls unify() on every GeomNode at this level and
|
||||||
|
// below.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void SceneGraphReducer::
|
||||||
|
unify(PandaNode *root) {
|
||||||
|
r_unify(root);
|
||||||
|
}
|
||||||
|
@ -674,3 +674,22 @@ r_make_nonindexed(PandaNode *node, int nonindexed_bits) {
|
|||||||
|
|
||||||
return num_changed;
|
return num_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SceneGraphReducer::r_unify
|
||||||
|
// Access: Private
|
||||||
|
// Description: The recursive implementation of unify().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void SceneGraphReducer::
|
||||||
|
r_unify(PandaNode *node) {
|
||||||
|
if (node->is_geom_node()) {
|
||||||
|
GeomNode *geom_node = DCAST(GeomNode, node);
|
||||||
|
geom_node->unify();
|
||||||
|
}
|
||||||
|
|
||||||
|
PandaNode::Children children = node->get_children();
|
||||||
|
int num_children = children.get_num_children();
|
||||||
|
for (int i = 0; i < num_children; ++i) {
|
||||||
|
r_unify(children.get_child(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -114,6 +114,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
INLINE int collect_vertex_data(PandaNode *root, int collect_bits = ~0);
|
INLINE int collect_vertex_data(PandaNode *root, int collect_bits = ~0);
|
||||||
INLINE int make_nonindexed(PandaNode *root, int nonindexed_bits = ~0);
|
INLINE int make_nonindexed(PandaNode *root, int nonindexed_bits = ~0);
|
||||||
|
INLINE void unify(PandaNode *root);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
void r_apply_attribs(PandaNode *node, const AccumulatedAttribs &attribs,
|
||||||
@ -143,6 +144,7 @@ protected:
|
|||||||
int r_collect_vertex_data(PandaNode *node, int collect_bits,
|
int r_collect_vertex_data(PandaNode *node, int collect_bits,
|
||||||
GeomTransformer &transformer);
|
GeomTransformer &transformer);
|
||||||
int r_make_nonindexed(PandaNode *node, int collect_bits);
|
int r_make_nonindexed(PandaNode *node, int collect_bits);
|
||||||
|
void r_unify(PandaNode *node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GeomTransformer _transformer;
|
GeomTransformer _transformer;
|
||||||
|
@ -82,6 +82,12 @@ event_W(CPT_Event, void *) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
event_F(CPT_Event, void *) {
|
||||||
|
// shift-F: flatten the model hierarchy.
|
||||||
|
framework.get_models().flatten_strong();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
event_Enter(CPT_Event, void *) {
|
event_Enter(CPT_Event, void *) {
|
||||||
// alt-enter: toggle between window/fullscreen in the same scene.
|
// alt-enter: toggle between window/fullscreen in the same scene.
|
||||||
@ -133,8 +139,9 @@ event_0(CPT_Event event, void *) {
|
|||||||
// 0: run hacky test.
|
// 0: run hacky test.
|
||||||
|
|
||||||
SceneGraphReducer gr;
|
SceneGraphReducer gr;
|
||||||
gr.make_nonindexed(framework.get_models().node());
|
|
||||||
gr.collect_vertex_data(framework.get_models().node());
|
gr.collect_vertex_data(framework.get_models().node());
|
||||||
|
gr.unify(framework.get_models().node());
|
||||||
|
gr.make_nonindexed(framework.get_models().node());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
@ -312,6 +319,7 @@ main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
framework.enable_default_keys();
|
framework.enable_default_keys();
|
||||||
framework.define_key("shift-w", "open a new window", event_W, NULL);
|
framework.define_key("shift-w", "open a new window", event_W, NULL);
|
||||||
|
framework.define_key("shift-f", "flatten hierarchy", event_F, NULL);
|
||||||
framework.define_key("alt-enter", "toggle between window/fullscreen", event_Enter, NULL);
|
framework.define_key("alt-enter", "toggle between window/fullscreen", event_Enter, NULL);
|
||||||
framework.define_key("2", "split the window", event_2, NULL);
|
framework.define_key("2", "split the window", event_2, NULL);
|
||||||
if (pview_test_hack) {
|
if (pview_test_hack) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user