mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
fix flatten TT_cull_face
This commit is contained in:
parent
0aaf110ea2
commit
b764c3aa2e
@ -105,7 +105,8 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||||||
GeomTransformer &transformer) {
|
GeomTransformer &transformer) {
|
||||||
if (pgraph_cat.is_debug()) {
|
if (pgraph_cat.is_debug()) {
|
||||||
pgraph_cat.debug()
|
pgraph_cat.debug()
|
||||||
<< "Transforming geometry.\n";
|
<< "Transforming geometry:\n";
|
||||||
|
attribs.write(pgraph_cat.debug(false), attrib_types, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
|
if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
|
||||||
@ -114,34 +115,19 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) {
|
|
||||||
if (attribs._cull_face != (const RenderAttrib *)NULL) {
|
|
||||||
const CullFaceAttrib *cfa = DCAST(CullFaceAttrib, attribs._cull_face);
|
|
||||||
CullFaceAttrib::Mode mode = cfa->get_effective_mode();
|
|
||||||
switch (mode) {
|
|
||||||
case CullFaceAttrib::M_cull_none:
|
|
||||||
// Doublesided polys. Duplicate them.
|
|
||||||
transformer.doubleside(this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CullFaceAttrib::M_cull_counter_clockwise:
|
|
||||||
// Reverse winding order.
|
|
||||||
transformer.reverse(this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread *current_thread = Thread::get_current_thread();
|
Thread *current_thread = Thread::get_current_thread();
|
||||||
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
|
OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) {
|
||||||
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
|
CDStageWriter cdata(_cycler, pipeline_stage, current_thread);
|
||||||
GeomList::iterator gi;
|
GeomList::iterator gi;
|
||||||
PT(GeomList) geoms = cdata->modify_geoms();
|
PT(GeomList) geoms = cdata->modify_geoms();
|
||||||
for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
|
|
||||||
GeomEntry &entry = (*gi);
|
// Iterate based on the number of geoms, not using STL iterators.
|
||||||
|
// This allows us to append to the list in the code below (which
|
||||||
|
// we might do when doublesiding polys) without visiting those new
|
||||||
|
// nodes during the traversal.
|
||||||
|
size_t num_geoms = geoms->size();
|
||||||
|
for (size_t i = 0; i < num_geoms; ++i) {
|
||||||
|
GeomEntry &entry = (*geoms)[i];
|
||||||
PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
|
PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
|
||||||
|
|
||||||
AccumulatedAttribs geom_attribs = attribs;
|
AccumulatedAttribs geom_attribs = attribs;
|
||||||
@ -218,13 +204,55 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (any_changed) {
|
|
||||||
entry._geom = new_geom;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
|
if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
|
||||||
entry._state = geom_attribs._other->compose(entry._state);
|
entry._state = geom_attribs._other->compose(entry._state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We handle cull_face last, since that might involve
|
||||||
|
// duplicating the geom, and we'd also like to duplicate all of
|
||||||
|
// the changes we may have applied in the above.
|
||||||
|
|
||||||
|
if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) {
|
||||||
|
if (geom_attribs._cull_face != (const RenderAttrib *)NULL) {
|
||||||
|
const CullFaceAttrib *cfa = DCAST(CullFaceAttrib, geom_attribs._cull_face);
|
||||||
|
CullFaceAttrib::Mode mode = cfa->get_effective_mode();
|
||||||
|
switch (mode) {
|
||||||
|
case CullFaceAttrib::M_cull_none:
|
||||||
|
// Doublesided polys. Duplicate them.
|
||||||
|
{
|
||||||
|
bool has_normals = (new_geom->get_vertex_data()->has_column(InternalName::get_normal()));
|
||||||
|
if (has_normals) {
|
||||||
|
// If the geometry has normals, we have to duplicate
|
||||||
|
// it to reverse the normals on the duplicate copy.
|
||||||
|
PT(Geom) dup_geom = new_geom->reverse();
|
||||||
|
transformer.reverse_normals(dup_geom);
|
||||||
|
geoms->push_back(GeomEntry(dup_geom, entry._state));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If there are no normals, we can just doubleside it in
|
||||||
|
// place. This is preferable because we can share vertices.
|
||||||
|
new_geom->doubleside_in_place();
|
||||||
|
any_changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CullFaceAttrib::M_cull_counter_clockwise:
|
||||||
|
// Reverse winding order.
|
||||||
|
new_geom->reverse_in_place();
|
||||||
|
transformer.reverse_normals(new_geom);
|
||||||
|
any_changed = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (any_changed) {
|
||||||
|
entry._geom = new_geom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
|
CLOSE_ITERATE_CURRENT_AND_UPSTREAM(_cycler);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user