From 85e54125fa688b0ca07cd2eb12fe182392ce2aa6 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 25 May 2001 04:02:20 +0000 Subject: [PATCH] added offset to billboard --- panda/src/sgattrib/billboardTransition.I | 46 ++++++++++++++++++++-- panda/src/sgattrib/billboardTransition.cxx | 27 ++++++++----- panda/src/sgattrib/billboardTransition.h | 10 +++-- 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/panda/src/sgattrib/billboardTransition.I b/panda/src/sgattrib/billboardTransition.I index 729bd2b924..f067076075 100644 --- a/panda/src/sgattrib/billboardTransition.I +++ b/panda/src/sgattrib/billboardTransition.I @@ -13,6 +13,7 @@ BillboardTransition() { _up_vector = LVector3f::up(); _eye_relative = false; _axial_rotate = true; + _offset = 0.0; } //////////////////////////////////////////////////////////////////// @@ -23,11 +24,12 @@ BillboardTransition() { // appropriate to the given coordinate system. //////////////////////////////////////////////////////////////////// INLINE BillboardTransition BillboardTransition:: -axis(CoordinateSystem cs) { +axis(float offset, CoordinateSystem cs) { BillboardTransition t; t.set_up_vector(LVector3f::up(cs)); t.set_eye_relative(false); t.set_axial_rotate(true); + t.set_offset(offset); return t; } @@ -39,11 +41,12 @@ axis(CoordinateSystem cs) { // (camera) coordinates. //////////////////////////////////////////////////////////////////// INLINE BillboardTransition BillboardTransition:: -point_eye(CoordinateSystem cs) { +point_eye(float offset, CoordinateSystem cs) { BillboardTransition t; t.set_up_vector(LVector3f::up(cs)); t.set_eye_relative(true); t.set_axial_rotate(false); + t.set_offset(offset); return t; } @@ -55,11 +58,12 @@ point_eye(CoordinateSystem cs) { // coordinates. //////////////////////////////////////////////////////////////////// INLINE BillboardTransition BillboardTransition:: -point_world(CoordinateSystem cs) { +point_world(float offset, CoordinateSystem cs) { BillboardTransition t; t.set_up_vector(LVector3f::up(cs)); t.set_eye_relative(false); t.set_axial_rotate(false); + t.set_offset(offset); return t; } @@ -141,3 +145,39 @@ INLINE bool BillboardTransition:: get_axial_rotate() const { return _axial_rotate; } + +//////////////////////////////////////////////////////////////////// +// Function: BillboardTransition::set_offset +// Access: Public +// Description: Sets a linear offset in the billboard. This is +// particularly useful when eye_relative is true (which +// means the billboard rotates towards the camera plane, +// instead of towards the camera point). +// +// The billboard geometry is first rotated +// appropriately, and then translated along the linear +// offset directly towards the camera. +// +// This can be used to allow billboarding geometry to +// appear to float in front of an object, while not +// drifting away from the object as the object goes +// off-axis. Another way to achieve the same effect is +// to simply translate the billboarding geometry by some +// linear distance along the z axis before making it a +// billboard, but this does not work in eye_relative +// mode. +//////////////////////////////////////////////////////////////////// +INLINE void BillboardTransition:: +set_offset(float offset) { + _offset = offset; +} + +//////////////////////////////////////////////////////////////////// +// Function: BillboardTransition::get_axial_rotate +// Access: Public +// Description: See set_offset(). +//////////////////////////////////////////////////////////////////// +INLINE float BillboardTransition:: +get_offset() const { + return _offset; +} diff --git a/panda/src/sgattrib/billboardTransition.cxx b/panda/src/sgattrib/billboardTransition.cxx index ea633cb669..669eefdc73 100644 --- a/panda/src/sgattrib/billboardTransition.cxx +++ b/panda/src/sgattrib/billboardTransition.cxx @@ -40,7 +40,7 @@ make_copy() const { //////////////////////////////////////////////////////////////////// bool BillboardTransition:: sub_render(NodeRelation *arc, const AllAttributesWrapper &, - AllTransitionsWrapper &trans, RenderTraverser *trav) { + AllTransitionsWrapper &trans, RenderTraverser *trav) { Node *node = arc->get_child(); GraphicsStateGuardian *gsg = trav->get_gsg(); @@ -61,7 +61,7 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &, rel_mat = tt->get_matrix(); } - LVector3f camera_pos,up; + LVector3f camera_pos, up; CoordinateSystem coordsys = gsg->get_coordinate_system(); @@ -71,18 +71,18 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &, // perpendicular to the forward direction, not directly to the // camera. - if (_eye_relative) { up = _up_vector * rel_mat; camera_pos = LVector3f::forward(coordsys) * rel_mat; + } else { -// camera_pos= -rel_mat.get_row3(3); +// 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[0] = -rel_mat(3,0); + camera_pos[1] = -rel_mat(3,1); + camera_pos[2] = -rel_mat(3,2); + + up = _up_vector; } // Now determine the rotation matrix for the Billboard. @@ -93,6 +93,15 @@ sub_render(NodeRelation *arc, const AllAttributesWrapper &, look_at(rotate, camera_pos, up, coordsys); } + // Also slide the billboard geometry towards the camera according to + // the offset factor. + if (_offset != 0.0f) { + LVector3f translate(rel_mat(3, 0), rel_mat(3, 1), rel_mat(3, 2)); + translate.normalize(); + translate *= _offset; + rotate.set_row(3, translate); + } + // And finally, apply the rotation transform to the set of // transitions we've accumulated for this node. AllTransitionsWrapper new_trans; diff --git a/panda/src/sgattrib/billboardTransition.h b/panda/src/sgattrib/billboardTransition.h index 9649fe6364..0549ac9f82 100644 --- a/panda/src/sgattrib/billboardTransition.h +++ b/panda/src/sgattrib/billboardTransition.h @@ -27,9 +27,9 @@ class EXPCL_PANDA BillboardTransition : public ImmediateTransition { public: INLINE BillboardTransition(); - INLINE static BillboardTransition axis(CoordinateSystem cs = CS_default); - INLINE static BillboardTransition point_eye(CoordinateSystem cs = CS_default); - INLINE static BillboardTransition point_world(CoordinateSystem cs = CS_default); + INLINE static BillboardTransition axis(float offset = 0.0, CoordinateSystem cs = CS_default); + INLINE static BillboardTransition point_eye(float offset = 0.0, CoordinateSystem cs = CS_default); + INLINE static BillboardTransition point_world(float offset = 0.0, CoordinateSystem cs = CS_default); INLINE void set_up_vector(const LVector3f &up_vector); INLINE LVector3f get_up_vector() const; @@ -40,6 +40,9 @@ public: INLINE void set_axial_rotate(bool axial_rotate); INLINE bool get_axial_rotate() const; + INLINE void set_offset(float offset); + INLINE float get_offset() const; + virtual NodeTransition *make_copy() const; virtual bool sub_render(NodeRelation *arc, @@ -58,6 +61,7 @@ private: LVector3f _up_vector; bool _eye_relative; bool _axial_rotate; + float _offset; public: static void register_with_read_factory(void);