diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index c922a6ada0..890c238e8f 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -275,14 +275,12 @@ setup_scene(const NodePath &camera, GraphicsStateGuardian *gsg) { // The render transform is the same as the world transform, except // it is converted into the GSG's internal coordinate system. This // is the transform that the GSG will apply to all of its vertices. - CPT(TransformState) render_transform = world_transform; - + CPT(TransformState) cs_transform = TransformState::make_identity(); 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 = + cs_transform = TransformState::make_mat(LMatrix4f::convert_mat(external_cs, internal_cs)); - render_transform = cs_transform->compose(render_transform); } scene_setup->set_scene_root(scene_root); @@ -291,7 +289,7 @@ setup_scene(const NodePath &camera, GraphicsStateGuardian *gsg) { scene_setup->set_lens(lens); scene_setup->set_camera_transform(camera_transform); scene_setup->set_world_transform(world_transform); - scene_setup->set_render_transform(render_transform); + scene_setup->set_cs_transform(cs_transform); return scene_setup; } diff --git a/panda/src/pgraph/Sources.pp b/panda/src/pgraph/Sources.pp index 25391a4998..de1ce4f1aa 100644 --- a/panda/src/pgraph/Sources.pp +++ b/panda/src/pgraph/Sources.pp @@ -19,6 +19,7 @@ colorBlendAttrib.I colorBlendAttrib.h \ colorScaleAttrib.I colorScaleAttrib.h \ colorWriteAttrib.I colorWriteAttrib.h \ + compassEffect.I compassEffect.h \ config_pgraph.h \ cullBin.I cullBin.h \ cullBinAttrib.I cullBinAttrib.h \ @@ -100,6 +101,7 @@ colorBlendAttrib.cxx \ colorScaleAttrib.cxx \ colorWriteAttrib.cxx \ + compassEffect.cxx \ config_pgraph.cxx \ cullBin.cxx \ cullBinAttrib.cxx \ @@ -180,6 +182,7 @@ colorBlendAttrib.I colorBlendAttrib.h \ colorScaleAttrib.I colorScaleAttrib.h \ colorWriteAttrib.I colorWriteAttrib.h \ + compassEffect.I compassEffect.h \ config_pgraph.h \ cullBin.I cullBin.h \ cullBinAttrib.I cullBinAttrib.h \ diff --git a/panda/src/pgraph/billboardEffect.cxx b/panda/src/pgraph/billboardEffect.cxx index 762db81406..73c9720d2a 100644 --- a/panda/src/pgraph/billboardEffect.cxx +++ b/panda/src/pgraph/billboardEffect.cxx @@ -17,6 +17,7 @@ //////////////////////////////////////////////////////////////////// #include "billboardEffect.h" +#include "nodePath.h" #include "look_at.h" #include "bamReader.h" #include "bamWriter.h" @@ -105,6 +106,10 @@ do_billboard(const TransformState *net_transform, const TransformState *camera_transform) const { // Determine the relative transform to our camera (or other look_at // coordinate space). + if (!_look_at.is_empty()) { + camera_transform = _look_at.get_net_transform(); + } + CPT(TransformState) rel_transform = net_transform->invert_compose(camera_transform); const LMatrix4f &rel_mat = rel_transform->get_mat(); @@ -123,13 +128,8 @@ do_billboard(const TransformState *net_transform, camera_pos = LVector3f::forward() * rel_mat; } else { -// camera_pos= -rel_mat.get_row3(3); - - camera_pos[0] = -rel_mat(3,0); - camera_pos[1] = -rel_mat(3,1); - camera_pos[2] = -rel_mat(3,2); - up = _up_vector; + camera_pos = -(_look_at_point * rel_mat); } // Now determine the rotation matrix for the Billboard. diff --git a/panda/src/pgraph/compassEffect.I b/panda/src/pgraph/compassEffect.I new file mode 100644 index 0000000000..afa66b95c3 --- /dev/null +++ b/panda/src/pgraph/compassEffect.I @@ -0,0 +1,28 @@ +// Filename: compassEffect.I +// Created by: drose (16Jul02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, 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://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::Constructor +// Access: Private +// Description: Use CompassEffect::make() to construct a new +// CompassEffect object. +//////////////////////////////////////////////////////////////////// +INLINE CompassEffect:: +CompassEffect() { +} diff --git a/panda/src/pgraph/compassEffect.cxx b/panda/src/pgraph/compassEffect.cxx new file mode 100644 index 0000000000..b8be381562 --- /dev/null +++ b/panda/src/pgraph/compassEffect.cxx @@ -0,0 +1,210 @@ +// Filename: compassEffect.cxx +// Created by: drose (16Jul02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, 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://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "compassEffect.h" +#include "config_pgraph.h" +#include "nodePath.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "datagram.h" +#include "datagramIterator.h" + +TypeHandle CompassEffect::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::make +// Access: Published, Static +// Description: Constructs a new CompassEffect object. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffect) CompassEffect:: +make(const NodePath &reference) { + CompassEffect *effect = new CompassEffect; + effect->_reference = reference; + return return_new(effect); +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::safe_to_transform +// Access: Public, Virtual +// Description: Returns true if it is generally safe to transform +// this particular kind of RenderEffect by calling the +// xform() method, false otherwise. +//////////////////////////////////////////////////////////////////// +bool CompassEffect:: +safe_to_transform() const { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::output +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void CompassEffect:: +output(ostream &out) const { + if (!_reference.is_empty()) { + RenderEffect::output(out); + } else { + out << get_type() << ":"; + if (!_reference.is_empty()) { + out << " reference " << _reference; + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::do_compass +// Access: Public +// Description: Computes the appropriate transform to rotate the node +// according to the reference node, or to the root +// transform if there is no reference node. +//////////////////////////////////////////////////////////////////// +CPT(TransformState) CompassEffect:: +do_compass(const TransformState *net_transform, + const TransformState *node_transform) const { + if (!net_transform->has_components() || !node_transform->has_quat()) { + // If we don't have a decomposable transform, we can't do anything here. + pgraph_cat.warning() + << "CompassEffect unable to adjust non-decomposable transform\n"; + return TransformState::make_identity(); + } + + // Compute just the rotation part of the transform we want. + CPT(TransformState) want_rot = TransformState::make_identity(); + if (!_reference.is_empty()) { + CPT(TransformState) rel_transform = _reference.get_net_transform(); + if (!rel_transform->has_quat()) { + pgraph_cat.warning() + << "CompassEffect unable to reference non-decomposable transform\n"; + } else { + want_rot = TransformState::make_quat(rel_transform->get_quat()); + } + } + + want_rot = + want_rot->compose(TransformState::make_quat(node_transform->get_quat())); + + // Now compute the net transform we want to achieve. This is the + // same as the net transform we were given, except the rotation + // component is replaced by our desired rotation. + CPT(TransformState) want_transform = + TransformState::make_pos_quat_scale(net_transform->get_pos(), + want_rot->get_quat(), + net_transform->get_scale()); + + // Now compute the transform that will convert net_transform to + // want_transform. This is inv(net_transform) * want_transform. + return net_transform->invert_compose(want_transform); +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::compare_to_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived CompassEffect +// types to return a unique number indicating whether +// this CompassEffect is equivalent to the other one. +// +// This should return 0 if the two CompassEffect 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 CompassEffect +// objects whose get_type() functions return the same. +//////////////////////////////////////////////////////////////////// +int CompassEffect:: +compare_to_impl(const RenderEffect *other) const { + const CompassEffect *ta; + DCAST_INTO_R(ta, other, 0); + + int compare = _reference.compare_to(ta->_reference); + if (compare != 0) { + return compare; + } + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::make_default_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived CompassEffect +// types to specify what the default property for a +// CompassEffect of this type should be. +// +// This should return a newly-allocated CompassEffect of +// the same type that corresponds to whatever the +// standard default for this kind of CompassEffect is. +//////////////////////////////////////////////////////////////////// +RenderEffect *CompassEffect:: +make_default_impl() const { + return new CompassEffect; +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// CompassEffect. +//////////////////////////////////////////////////////////////////// +void CompassEffect:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void CompassEffect:: +write_datagram(BamWriter *manager, Datagram &dg) { + RenderEffect::write_datagram(manager, dg); +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type CompassEffect is encountered +// in the Bam file. It should create the CompassEffect +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *CompassEffect:: +make_from_bam(const FactoryParams ¶ms) { + CompassEffect *effect = new CompassEffect; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + effect->fillin(scan, manager); + + return effect; +} + +//////////////////////////////////////////////////////////////////// +// Function: CompassEffect::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 CompassEffect. +//////////////////////////////////////////////////////////////////// +void CompassEffect:: +fillin(DatagramIterator &scan, BamReader *manager) { + RenderEffect::fillin(scan, manager); +} diff --git a/panda/src/pgraph/compassEffect.h b/panda/src/pgraph/compassEffect.h new file mode 100644 index 0000000000..1f78e03a98 --- /dev/null +++ b/panda/src/pgraph/compassEffect.h @@ -0,0 +1,85 @@ +// Filename: compassEffect.h +// Created by: drose (16Jul02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, 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://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef COMPASSEFFECT_H +#define COMPASSEFFECT_H + +#include "pandabase.h" + +#include "renderEffect.h" +#include "luse.h" +#include "nodePath.h" + +//////////////////////////////////////////////////////////////////// +// Class : CompassEffect +// Description : Indicates that geometry at this node should +// automatically rotate to face the camera, or any other +// arbitrary node. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA CompassEffect : public RenderEffect { +private: + INLINE CompassEffect(); + +PUBLISHED: + static CPT(RenderEffect) make(const NodePath &reference); + +public: + virtual bool safe_to_transform() const; + virtual void output(ostream &out) const; + + CPT(TransformState) CompassEffect:: + do_compass(const TransformState *net_transform, + const TransformState *node_transform) const; + +protected: + virtual int compare_to_impl(const RenderEffect *other) const; + virtual RenderEffect *make_default_impl() const; + +private: + NodePath _reference; + +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() { + RenderEffect::init_type(); + register_type(_type_handle, "CompassEffect", + RenderEffect::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 "compassEffect.I" + +#endif + diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index e6ee9bd502..3ad17cca04 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -27,6 +27,7 @@ #include "colorBlendAttrib.h" #include "colorScaleAttrib.h" #include "colorWriteAttrib.h" +#include "compassEffect.h" #include "cullFaceAttrib.h" #include "cullBin.h" #include "cullBinAttrib.h" @@ -167,6 +168,7 @@ init_libpgraph() { ColorBlendAttrib::init_type(); ColorScaleAttrib::init_type(); ColorWriteAttrib::init_type(); + CompassEffect::init_type(); CullFaceAttrib::init_type(); CullBin::init_type(); CullBinAttrib::init_type(); @@ -230,6 +232,7 @@ init_libpgraph() { BillboardEffect::register_with_read_factory(); Camera::register_with_read_factory(); ClipPlaneAttrib::register_with_read_factory(); + CompassEffect::register_with_read_factory(); ColorAttrib::register_with_read_factory(); ColorBlendAttrib::register_with_read_factory(); ColorScaleAttrib::register_with_read_factory(); diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx index e2e07f8fa1..89aa76fa4a 100644 --- a/panda/src/pgraph/cullTraverserData.cxx +++ b/panda/src/pgraph/cullTraverserData.cxx @@ -24,6 +24,7 @@ #include "textureAttrib.h" #include "renderModeAttrib.h" #include "billboardEffect.h" +#include "compassEffect.h" //////////////////////////////////////////////////////////////////// // Function: CullTraverserData::apply_transform_and_state @@ -73,6 +74,21 @@ apply_transform_and_state(CullTraverser *trav) { _state = _state->compose(node_state); const RenderEffects *node_effects = node()->get_effects(); + + const CompassEffect *compass = node_effects->get_compass(); + if (compass != (const CompassEffect *)NULL) { + // Got to apply a compass transform here. + CPT(TransformState) compass_transform = + compass->do_compass(_net_transform, node_transform); + _render_transform = _render_transform->compose(compass_transform); + _net_transform = _net_transform->compose(compass_transform); + + // We can't reliably cull within a compass, because the geometry + // might get rotated out of its bounding volume. So once we get + // within a compass, we consider it all visible. + _view_frustum = (GeometricBoundingVolume *)NULL; + } + const BillboardEffect *billboard = node_effects->get_billboard(); if (billboard != (const BillboardEffect *)NULL) { // Got to apply a billboard transform here. diff --git a/panda/src/pgraph/nodePath.I b/panda/src/pgraph/nodePath.I index 435bcef633..c4d8045cf7 100644 --- a/panda/src/pgraph/nodePath.I +++ b/panda/src/pgraph/nodePath.I @@ -885,6 +885,42 @@ get_distance(const NodePath &other) const { return length(LVector3f(pos)); } +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_billboard_axis +// Access: Published +// Description: Puts a billboard transition on the node such that it +// will rotate in two dimensions around the up axis. +//////////////////////////////////////////////////////////////////// +INLINE void NodePath:: +set_billboard_axis(float offset) { + set_billboard_axis(NodePath(), offset); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_billboard_point_eye +// Access: Published +// Description: Puts a billboard transition on the node such that it +// will rotate in three dimensions about the origin, +// keeping its up vector oriented to the top of the +// camera. +//////////////////////////////////////////////////////////////////// +INLINE void NodePath:: +set_billboard_point_eye(float offset) { + set_billboard_point_eye(NodePath(), offset); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_billboard_point_world +// Access: Published +// Description: Puts a billboard transition on the node such that it +// will rotate in three dimensions about the origin, +// keeping its up vector oriented to the sky. +//////////////////////////////////////////////////////////////////// +INLINE void NodePath:: +set_billboard_point_world(float offset) { + set_billboard_point_world(NodePath(), offset); +} + //////////////////////////////////////////////////////////////////// // Function: NodePath::adjust_all_priorities // Access: Published diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 5aae72b268..d71cee8dbf 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -34,6 +34,7 @@ #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "billboardEffect.h" +#include "compassEffect.h" #include "showBoundsEffect.h" #include "transparencyAttrib.h" #include "materialPool.h" @@ -2376,14 +2377,16 @@ do_billboard_point_world(const NodePath &camera, float offset) { // Function: NodePath::set_billboard_axis // Access: Published // Description: Puts a billboard transition on the node such that it -// will rotate in two dimensions around the up axis. +// will rotate in two dimensions around the up axis, +// towards a specified "camera" instead of to the +// viewing camera. //////////////////////////////////////////////////////////////////// void NodePath:: -set_billboard_axis(float offset) { +set_billboard_axis(const NodePath &camera, float offset) { nassertv_always(!is_empty()); CPT(RenderEffect) billboard = BillboardEffect::make (LVector3f::up(), false, true, - offset, NodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); + offset, camera, LPoint3f(0.0f, 0.0f, 0.0f)); node()->set_effect(billboard); } @@ -2393,14 +2396,15 @@ set_billboard_axis(float offset) { // Description: Puts a billboard transition on the node such that it // will rotate in three dimensions about the origin, // keeping its up vector oriented to the top of the -// camera. +// camera, towards a specified "camera" instead of to +// the viewing camera. //////////////////////////////////////////////////////////////////// void NodePath:: -set_billboard_point_eye(float offset) { +set_billboard_point_eye(const NodePath &camera, float offset) { nassertv_always(!is_empty()); CPT(RenderEffect) billboard = BillboardEffect::make (LVector3f::up(), true, false, - offset, NodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); + offset, camera, LPoint3f(0.0f, 0.0f, 0.0f)); node()->set_effect(billboard); } @@ -2409,14 +2413,15 @@ set_billboard_point_eye(float offset) { // Access: Published // Description: Puts a billboard transition on the node such that it // will rotate in three dimensions about the origin, -// keeping its up vector oriented to the sky. +// keeping its up vector oriented to the sky, towards a +// specified "camera" instead of to the viewing camera. //////////////////////////////////////////////////////////////////// void NodePath:: -set_billboard_point_world(float offset) { +set_billboard_point_world(const NodePath &camera, float offset) { nassertv_always(!is_empty()); CPT(RenderEffect) billboard = BillboardEffect::make (LVector3f::up(), false, false, - offset, NodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); + offset, camera, LPoint3f(0.0f, 0.0f, 0.0f)); node()->set_effect(billboard); } @@ -2443,6 +2448,43 @@ has_billboard() const { return node()->has_effect(BillboardEffect::get_class_type()); } +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_compass +// Access: Published +// Description: Puts a compass effect on the node, so that it will +// retain a fixed rotation relative to the reference +// node (or render if the reference node is empty) +// regardless of the transforms above it. +//////////////////////////////////////////////////////////////////// +void NodePath:: +set_compass(const NodePath &reference) { + nassertv_always(!is_empty()); + node()->set_effect(CompassEffect::make(reference)); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::clear_compass +// Access: Published +// Description: Removes any compass effect from the node. +//////////////////////////////////////////////////////////////////// +void NodePath:: +clear_compass() { + nassertv_always(!is_empty()); + node()->clear_effect(CompassEffect::get_class_type()); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::has_compass +// Access: Published +// Description: Returns true if there is any compass effect on +// the node. +//////////////////////////////////////////////////////////////////// +bool NodePath:: +has_compass() const { + nassertr_always(!is_empty(), false); + return node()->has_effect(CompassEffect::get_class_type()); +} + //////////////////////////////////////////////////////////////////// // Function: NodePath::set_transparency // Access: Published diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 4191516c4e..49a73e5665 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -462,12 +462,19 @@ PUBLISHED: void do_billboard_axis(const NodePath &camera, float offset); void do_billboard_point_eye(const NodePath &camera, float offset); void do_billboard_point_world(const NodePath &camera, float offset); - void set_billboard_axis(float offset = 0.0); - void set_billboard_point_eye(float offset = 0.0); - void set_billboard_point_world(float offset = 0.0); + INLINE void set_billboard_axis(float offset = 0.0); + INLINE void set_billboard_point_eye(float offset = 0.0); + INLINE void set_billboard_point_world(float offset = 0.0); + void set_billboard_axis(const NodePath &camera, float offset); + void set_billboard_point_eye(const NodePath &camera, float offset); + void set_billboard_point_world(const NodePath &camera, float offset); void clear_billboard(); bool has_billboard() const; + void set_compass(const NodePath &reference = NodePath()); + void clear_compass(); + bool has_compass() const; + void set_transparency(bool transparency, int priority = 0); void clear_transparency(); bool has_transparency() const; diff --git a/panda/src/pgraph/pgraph_composite1.cxx b/panda/src/pgraph/pgraph_composite1.cxx index 8be701a9d6..5ea507592d 100644 --- a/panda/src/pgraph/pgraph_composite1.cxx +++ b/panda/src/pgraph/pgraph_composite1.cxx @@ -8,6 +8,7 @@ #include "colorBlendAttrib.cxx" #include "colorScaleAttrib.cxx" #include "colorWriteAttrib.cxx" +#include "compassEffect.cxx" #include "config_pgraph.cxx" #include "cullBin.cxx" #include "cullBinAttrib.cxx" diff --git a/panda/src/pgraph/renderEffects.I b/panda/src/pgraph/renderEffects.I index 0be1e528cb..89308bc57e 100644 --- a/panda/src/pgraph/renderEffects.I +++ b/panda/src/pgraph/renderEffects.I @@ -181,6 +181,25 @@ has_decal() const { return ((_flags & F_has_decal) != 0); } +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::get_compass +// Access: Public +// Description: This function is provided as an optimization, to +// speed up the render-time checking for the existance +// of a CompassEffect on this state. It returns a +// pointer to the CompassEffect, if there is one, or +// NULL if there is not. +//////////////////////////////////////////////////////////////////// +INLINE const CompassEffect *RenderEffects:: +get_compass() const { + if ((_flags & F_checked_compass) == 0) { + // We pretend this function is const, even though it transparently + // modifies the internal compass cache. + ((RenderEffects *)this)->determine_compass(); + } + return _compass; +} + //////////////////////////////////////////////////////////////////// // Function: RenderEffects::has_show_bounds // Access: Public diff --git a/panda/src/pgraph/renderEffects.cxx b/panda/src/pgraph/renderEffects.cxx index c10c93f712..9422c2b831 100644 --- a/panda/src/pgraph/renderEffects.cxx +++ b/panda/src/pgraph/renderEffects.cxx @@ -19,6 +19,7 @@ #include "renderEffects.h" #include "billboardEffect.h" #include "decalEffect.h" +#include "compassEffect.h" #include "showBoundsEffect.h" #include "config_pgraph.h" #include "bamReader.h" @@ -460,6 +461,21 @@ determine_decal() { _flags |= F_checked_decal; } +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::determine_compass +// Access: Private +// Description: This is the private implementation of has_compass(). +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +determine_compass() { + const RenderEffect *effect = get_effect(CompassEffect::get_class_type()); + _compass = (const CompassEffect *)NULL; + if (effect != (const RenderEffect *)NULL) { + _compass = DCAST(CompassEffect, effect); + } + _flags |= F_checked_compass; +} + //////////////////////////////////////////////////////////////////// // Function: RenderEffects::determine_show_bounds // Access: Private diff --git a/panda/src/pgraph/renderEffects.h b/panda/src/pgraph/renderEffects.h index 22ab9201f9..5f9063275b 100644 --- a/panda/src/pgraph/renderEffects.h +++ b/panda/src/pgraph/renderEffects.h @@ -28,6 +28,7 @@ #include "ordered_vector.h" class BillboardEffect; +class CompassEffect; class FactoryParams; //////////////////////////////////////////////////////////////////// @@ -89,12 +90,14 @@ PUBLISHED: public: INLINE const BillboardEffect *get_billboard() const; INLINE bool has_decal() const; + INLINE const CompassEffect *get_compass() const; INLINE bool has_show_bounds() const; private: static CPT(RenderEffects) return_new(RenderEffects *state); void determine_billboard(); void determine_decal(); + void determine_compass(); void determine_show_bounds(); private: @@ -129,6 +132,7 @@ private: // We cache the pointer to some critical effects stored in the // state, if they exist. const BillboardEffect *_billboard; + const CompassEffect *_compass; enum Flags { F_checked_billboard = 0x0001, @@ -136,6 +140,7 @@ private: F_has_decal = 0x0004, F_checked_show_bounds = 0x0008, F_has_show_bounds = 0x0010, + F_checked_compass = 0x0020, }; short _flags; diff --git a/panda/src/pgraph/sceneSetup.I b/panda/src/pgraph/sceneSetup.I index d9c9c23bae..b905acfa33 100644 --- a/panda/src/pgraph/sceneSetup.I +++ b/panda/src/pgraph/sceneSetup.I @@ -26,7 +26,7 @@ INLINE SceneSetup:: SceneSetup() { _camera_transform = TransformState::make_identity(); _world_transform = TransformState::make_identity(); - _render_transform = TransformState::make_identity(); + _cs_transform = TransformState::make_identity(); } //////////////////////////////////////////////////////////////////// @@ -145,6 +145,7 @@ get_camera_transform() const { INLINE void SceneSetup:: set_world_transform(const TransformState *world_transform) { _world_transform = world_transform; + _render_transform = _cs_transform->compose(_world_transform); } //////////////////////////////////////////////////////////////////// @@ -160,16 +161,29 @@ get_world_transform() const { } //////////////////////////////////////////////////////////////////// -// Function: SceneSetup::set_render_transform +// Function: SceneSetup::set_cs_transform // Access: Public -// Description: Specifies the position of the starting node relative -// to the camera, pretransformed as appropriate for -// rendering. This is the same as the world transform, -// with a possible coordinate-system conversion applied. +// Description: Specifies the pretransformation to apply to the world +// transform to produce the appropriate transformation +// for rendering. This is usually the appropriate +// coordinate-system conversion for the current GSG. //////////////////////////////////////////////////////////////////// INLINE void SceneSetup:: -set_render_transform(const TransformState *render_transform) { - _render_transform = render_transform; +set_cs_transform(const TransformState *cs_transform) { + _cs_transform = cs_transform; + _render_transform = _cs_transform->compose(_world_transform); +} + +//////////////////////////////////////////////////////////////////// +// Function: SceneSetup::get_cs_transform +// Access: Public +// Description: Returns the pretransformation to apply to the world +// transform to produce the appropriate transformation +// for rendering. +//////////////////////////////////////////////////////////////////// +INLINE const TransformState *SceneSetup:: +get_cs_transform() const { + return _cs_transform; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/sceneSetup.h b/panda/src/pgraph/sceneSetup.h index 8896f346f8..eeba4f02f7 100644 --- a/panda/src/pgraph/sceneSetup.h +++ b/panda/src/pgraph/sceneSetup.h @@ -56,7 +56,9 @@ public: INLINE void set_world_transform(const TransformState *world_transform); INLINE const TransformState *get_world_transform() const; - INLINE void set_render_transform(const TransformState *render_transform); + INLINE void set_cs_transform(const TransformState *cs_transform); + INLINE const TransformState *get_cs_transform() const; + INLINE const TransformState *get_render_transform() const; private: @@ -66,6 +68,7 @@ private: CPT(Lens) _lens; CPT(TransformState) _camera_transform; CPT(TransformState) _world_transform; + CPT(TransformState) _cs_transform; CPT(TransformState) _render_transform; };