added offset to billboard

This commit is contained in:
David Rose 2001-05-25 04:02:20 +00:00
parent fc09df09a8
commit 85e54125fa
3 changed files with 68 additions and 15 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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);