diff --git a/panda/src/builder/builder.cxx b/panda/src/builder/builder.cxx index 3ba20b29e5..b1c14754bc 100644 --- a/panda/src/builder/builder.cxx +++ b/panda/src/builder/builder.cxx @@ -106,7 +106,8 @@ public: if (_bucket->get_name() != other._bucket->get_name()) { return _bucket->get_name() < other._bucket->get_name(); } - return (_bucket->_state < other._bucket->_state); + return 0; + // return (_bucket->_state < other._bucket->_state); } PandaNode *_node; @@ -325,7 +326,6 @@ qpbuild(const string &default_name) { PandaNode *node = nm._node; const string &name = nm._bucket->get_name(); - CPT(RenderState) state = nm._bucket->_state; // Assign the name to the geom, if it doesn't have one already. if (!geom_node->has_name()) { @@ -350,11 +350,6 @@ qpbuild(const string &default_name) { } else { node->add_child(geom_node); - // Now, this is our only opportunity to apply the scene-graph - // state specified in the bucket to the node: we have created - // our own geom_node for these buckets, and we have parented - // it to the scene graph. - geom_node->set_state(state); } } } diff --git a/panda/src/builder/builder.h b/panda/src/builder/builder.h index 93a5d968e2..021efa122e 100644 --- a/panda/src/builder/builder.h +++ b/panda/src/builder/builder.h @@ -202,7 +202,7 @@ public: protected: void add_bucket(const BuilderBucket &bucket); - typedef pset > Buckets; + typedef pset Buckets; Buckets _buckets; Buckets::iterator _bi; diff --git a/panda/src/builder/builderBucket.cxx b/panda/src/builder/builderBucket.cxx index 064deea129..557313a6b2 100644 --- a/panda/src/builder/builderBucket.cxx +++ b/panda/src/builder/builderBucket.cxx @@ -171,8 +171,12 @@ operator < (const BuilderBucket &other) const { return get_name() < other.get_name(); } - if (_node != other._node) + if (_node != other._node) { return _node < other._node; + } + if (_qpnode != other._qpnode) { + return _qpnode < other._qpnode; + } if (_coords != other._coords) return _coords < other._coords; @@ -211,6 +215,9 @@ output(ostream &out) const { if (_node != (NamedNode *)NULL) { out << " attached to " << *_node << "\n"; } + if (_qpnode != (PandaNode *)NULL) { + out << " attached to " << *_qpnode << "\n"; + } out << "\n"; @@ -238,6 +245,10 @@ output(ostream &out) const { out << "_drawOrder = " << _drawOrder << "\n"; } + if (!_state->is_empty()) { + out << *_state << "\n"; + } + BuilderProperties::output(out); } diff --git a/panda/src/builder/builderFuncs.I b/panda/src/builder/builderFuncs.I index edb07ee861..9f53351a49 100644 --- a/panda/src/builder/builderFuncs.I +++ b/panda/src/builder/builderFuncs.I @@ -761,13 +761,12 @@ build_geoms(InputIterator first, InputIterator last, } */ - // geom->setGState((pfGeoState *)bucket.getGState()); // geom->setDrawBin(bucket._drawBin); // geom->setDrawOrder(bucket._drawOrder); Geom *new_geom = bucket.done_geom(geom); if (new_geom != (Geom *)NULL) { - geom_node->add_geom(new_geom); + geom_node->add_geom(new_geom, bucket._state); } return 1; diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index bedee4d0f5..02534b3308 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -157,7 +157,19 @@ cull_and_draw_together(GraphicsWindow *win, DisplayRegion *dr) { DrawCullHandler cull_handler(gsg); qpCullTraverser trav; trav.set_cull_handler(&cull_handler); - trav.set_world_transform(camera.get_rel_transform(NodeChain())); + + // The world transform is computed from the camera's position; we + // then might need to adjust it into the GSG's internal coordinate + // system. + CPT(TransformState) world_transform = camera.get_rel_transform(NodeChain()); + CoordinateSystem external_cs = gsg->get_coordinate_system(); + CoordinateSystem internal_cs = gsg->get_internal_coordinate_system(); + if (internal_cs != CS_default && internal_cs != external_cs) { + CPT(TransformState) cs_transform = + TransformState::make_mat(LMatrix4f::convert_mat(external_cs, internal_cs)); + world_transform = cs_transform->compose(world_transform); + } + trav.set_world_transform(world_transform); DisplayRegionStack old_dr = gsg->push_display_region(dr); gsg->prepare_display_region(); diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 5ef348688f..83c4266a46 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -879,6 +879,24 @@ void GraphicsStateGuardian:: end_decal(GeomNode *) { } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::get_internal_coordinate_system +// Access: Public, Virtual +// Description: Should be overridden by derived classes to return the +// coordinate system used internally by the GSG, if any +// one particular coordinate system is used. The +// default, CS_default, indicates that the GSG can use +// any coordinate system. +// +// If this returns other than CS_default, the +// GraphicsEngine will automatically convert all +// transforms into the indicated coordinate system. +//////////////////////////////////////////////////////////////////// +CoordinateSystem GraphicsStateGuardian:: +get_internal_coordinate_system() const { + return CS_default; +} + //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::issue_transform // Access: Public, Virtual diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 8428c018ff..b07b65181e 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -165,6 +165,7 @@ public: INLINE void set_coordinate_system(CoordinateSystem cs); INLINE CoordinateSystem get_coordinate_system() const; + virtual CoordinateSystem get_internal_coordinate_system() const; // This function may only be called during a render traversal; it // will compute the distance to the indicated point, assumed to be diff --git a/panda/src/glgsg/glGraphicsStateGuardian.cxx b/panda/src/glgsg/glGraphicsStateGuardian.cxx index fb4326f1d1..778a870e84 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.cxx +++ b/panda/src/glgsg/glGraphicsStateGuardian.cxx @@ -3616,6 +3616,24 @@ end_decal(GeomNode *base_geom) { report_errors(); } +//////////////////////////////////////////////////////////////////// +// Function: GLGraphicsStateGuardian::get_internal_coordinate_system +// Access: Public, Virtual +// Description: Should be overridden by derived classes to return the +// coordinate system used internally by the GSG, if any +// one particular coordinate system is used. The +// default, CS_default, indicates that the GSG can use +// any coordinate system. +// +// If this returns other than CS_default, the +// GraphicsEngine will automatically convert all +// transforms into the indicated coordinate system. +//////////////////////////////////////////////////////////////////// +CoordinateSystem GLGraphicsStateGuardian:: +get_internal_coordinate_system() const { + return CS_yup_right; +} + //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::compute_distance_to // Access: Public, Virtual diff --git a/panda/src/glgsg/glGraphicsStateGuardian.h b/panda/src/glgsg/glGraphicsStateGuardian.h index cca731bfc6..37bff6c0cf 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.h +++ b/panda/src/glgsg/glGraphicsStateGuardian.h @@ -165,6 +165,7 @@ public: virtual void begin_decal(GeomNode *base_geom, AllTransitionsWrapper &attrib); virtual void end_decal(GeomNode *base_geom); + virtual CoordinateSystem get_internal_coordinate_system() const; virtual float compute_distance_to(const LPoint3f &point) const; void print_gfx_visual(); diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index 955f12d98b..94ccad0faa 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -346,7 +346,7 @@ write(ostream &out, int indent_level) const { indent(out, indent_level) << *this; CDReader cdata(_cycler); if (!cdata->_transform->is_identity()) { - out << " T"; + out << " " << *cdata->_transform; } if (!cdata->_state->is_empty()) { out << " " << *cdata->_state; diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index da9ff3b10b..12f97f352f 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -473,7 +473,7 @@ remove(TypeHandle type) const { //////////////////////////////////////////////////////////////////// void RenderState:: output(ostream &out) const { - out << get_type() << ":"; + out << "S:"; if (_attributes.empty()) { out << "(empty)"; diff --git a/panda/src/pgraph/transformState.cxx b/panda/src/pgraph/transformState.cxx index 899460380e..2c58c27e93 100644 --- a/panda/src/pgraph/transformState.cxx +++ b/panda/src/pgraph/transformState.cxx @@ -383,22 +383,29 @@ invert_compose(const TransformState *other) const { //////////////////////////////////////////////////////////////////// void TransformState:: output(ostream &out) const { - out << get_type() << ":"; + out << "T:"; if (is_identity()) { out << "(identity)"; } else if (has_components()) { - out << "("; - if (get_pos() != LVecBase3f(0.0f, 0.0f, 0.0f)) { - out << "pos " << get_pos(); + char lead = '('; + if (!get_pos().almost_equal(LVecBase3f(0.0f, 0.0f, 0.0f))) { + out << lead << "pos " << get_pos(); + lead = ' '; } - if (get_hpr() != LVecBase3f(0.0f, 0.0f, 0.0f)) { - out << "hpr " << get_hpr(); + if (!get_hpr().almost_equal(LVecBase3f(0.0f, 0.0f, 0.0f))) { + out << lead << "hpr " << get_hpr(); + lead = ' '; } - if (get_scale() != LVecBase3f(1.0f, 1.0f, 1.0f)) { - out << "scale " << get_scale(); + if (!get_scale().almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f))) { + out << lead << "scale " << get_scale(); + lead = ' '; + } + if (lead == '(') { + out << "(almost identity)"; + } else { + out << ")"; } - out << ")"; } else { out << get_mat(); @@ -462,7 +469,7 @@ return_new(TransformState *state) { //////////////////////////////////////////////////////////////////// CPT(TransformState) TransformState:: do_compose(const TransformState *other) const { - LMatrix4f new_mat = get_mat() * other->get_mat(); + LMatrix4f new_mat = other->get_mat() * get_mat(); return make_mat(new_mat); } @@ -475,7 +482,7 @@ CPT(TransformState) TransformState:: do_invert_compose(const TransformState *other) const { LMatrix4f new_mat; new_mat.invert_from(get_mat()); - new_mat = new_mat * other->get_mat(); + new_mat = other->get_mat() * new_mat; return make_mat(new_mat); } diff --git a/panda/src/sgraph/geomNode.cxx b/panda/src/sgraph/geomNode.cxx index 2e1764b75f..1d441b41e7 100644 --- a/panda/src/sgraph/geomNode.cxx +++ b/panda/src/sgraph/geomNode.cxx @@ -361,7 +361,7 @@ clear() { // new Geom's index number within the node. //////////////////////////////////////////////////////////////////// int GeomNode:: -add_geom(dDrawable *geom) { +add_geom(dDrawable *geom, const RenderState *) { if (_geoms.get_ref_count() == 1) { // The normal case; we own the only pointer to the array. _geoms.push_back(geom); diff --git a/panda/src/sgraph/geomNode.h b/panda/src/sgraph/geomNode.h index 5d7f6972c6..58488a31fe 100644 --- a/panda/src/sgraph/geomNode.h +++ b/panda/src/sgraph/geomNode.h @@ -30,6 +30,7 @@ class GraphicsStateGuardianBase; class GeomNodeContext; +class RenderState; //////////////////////////////////////////////////////////////////// // Class : GeomNode @@ -67,7 +68,8 @@ PUBLISHED: dDrawable *get_geom(int n) const; void remove_geom(int n); void clear(); - int add_geom(dDrawable *geom); + // RenderState pointer here as a temporary builder hack. + int add_geom(dDrawable *geom, const RenderState *ptr = NULL); void add_geoms_from(const GeomNode *other); protected: