pgraph: fixed-depth billboards, bam additions (6.43)

This makes it possible to use BillboardEffect to specify a fixed distance to the camera, in order to keep them at a fixed apparent size.

This also enables serialization to .bam of the reference NodePaths of BillboardEffect and CompassEffect.
This commit is contained in:
rdb 2018-12-06 23:24:45 +01:00
parent b38faadf5f
commit 89236ac136
9 changed files with 88 additions and 15 deletions

View File

@ -86,6 +86,15 @@ get_axial_rotate() const {
return _axial_rotate; return _axial_rotate;
} }
/**
* Returns true if this billboard always appears at a fixed distance from the
* camera.
*/
INLINE bool BillboardEffect::
get_fixed_depth() const {
return _fixed_depth;
}
/** /**
* Returns the distance toward the camera (or the look_at_point) the billboard * Returns the distance toward the camera (or the look_at_point) the billboard
* is moved towards, after rotating. This can be used to ensure the billboard * is moved towards, after rotating. This can be used to ensure the billboard

View File

@ -29,7 +29,7 @@ TypeHandle BillboardEffect::_type_handle;
CPT(RenderEffect) BillboardEffect:: CPT(RenderEffect) BillboardEffect::
make(const LVector3 &up_vector, bool eye_relative, make(const LVector3 &up_vector, bool eye_relative,
bool axial_rotate, PN_stdfloat offset, const NodePath &look_at, bool axial_rotate, PN_stdfloat offset, const NodePath &look_at,
const LPoint3 &look_at_point) { const LPoint3 &look_at_point, bool fixed_depth) {
BillboardEffect *effect = new BillboardEffect; BillboardEffect *effect = new BillboardEffect;
effect->_up_vector = up_vector; effect->_up_vector = up_vector;
effect->_eye_relative = eye_relative; effect->_eye_relative = eye_relative;
@ -37,6 +37,7 @@ make(const LVector3 &up_vector, bool eye_relative,
effect->_offset = offset; effect->_offset = offset;
effect->_look_at = look_at; effect->_look_at = look_at;
effect->_look_at_point = look_at_point; effect->_look_at_point = look_at_point;
effect->_fixed_depth = fixed_depth;
effect->_off = false; effect->_off = false;
return return_new(effect); return return_new(effect);
} }
@ -82,7 +83,9 @@ output(std::ostream &out) const {
if (_eye_relative) { if (_eye_relative) {
out << " eye"; out << " eye";
} }
if (_offset != 0.0f) { if (_fixed_depth) {
out << " depth " << -_offset;
} else if (_offset != 0.0f) {
out << " offset " << _offset; out << " offset " << _offset;
} }
if (!_look_at.is_empty()) { if (!_look_at.is_empty()) {
@ -201,6 +204,9 @@ compare_to_impl(const RenderEffect *other) const {
if (_eye_relative != ta->_eye_relative) { if (_eye_relative != ta->_eye_relative) {
return (int)_eye_relative - (int)ta->_eye_relative; return (int)_eye_relative - (int)ta->_eye_relative;
} }
if (_fixed_depth != ta->_fixed_depth) {
return (int)_fixed_depth - (int)ta->_fixed_depth;
}
if (_offset != ta->_offset) { if (_offset != ta->_offset) {
return _offset < ta->_offset ? -1 : 1; return _offset < ta->_offset ? -1 : 1;
} }
@ -274,11 +280,17 @@ compute_billboard(CPT(TransformState) &node_transform,
// Also slide the billboard geometry towards the camera according to the // Also slide the billboard geometry towards the camera according to the
// offset factor. // offset factor.
if (_offset != 0.0f) { if (_offset != 0.0f || _fixed_depth) {
LVector3 translate(rel_mat(3, 0), rel_mat(3, 1), rel_mat(3, 2)); LVector3 translate(rel_mat(3, 0), rel_mat(3, 1), rel_mat(3, 2));
LPoint3 pos;
if (_fixed_depth) {
pos = translate / rel_mat(3, 3);
} else {
pos.fill(0.0f);
}
translate.normalize(); translate.normalize();
translate *= _offset; translate *= _offset;
rotate.set_row(3, translate); rotate.set_row(3, pos + translate);
} }
node_transform = translate->compose(TransformState::make_mat(rotate))->compose(node_transform); node_transform = translate->compose(TransformState::make_mat(rotate))->compose(node_transform);
@ -307,7 +319,25 @@ write_datagram(BamWriter *manager, Datagram &dg) {
dg.add_stdfloat(_offset); dg.add_stdfloat(_offset);
_look_at_point.write_datagram(dg); _look_at_point.write_datagram(dg);
// *** We don't write out the _look_at NodePath right now. Maybe we should. if (manager->get_file_minor_ver() >= 43) {
_look_at.write_datagram(manager, dg);
dg.add_bool(_fixed_depth);
}
}
/**
* Receives an array of pointers, one for each time manager->read_pointer()
* was called in fillin(). Returns the number of pointers processed.
*/
int BillboardEffect::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = RenderEffect::complete_pointers(p_list, manager);
if (manager->get_file_minor_ver() >= 43) {
pi += _look_at.complete_pointers(p_list + pi, manager);
}
return pi;
} }
/** /**
@ -341,4 +371,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
_axial_rotate = scan.get_bool(); _axial_rotate = scan.get_bool();
_offset = scan.get_stdfloat(); _offset = scan.get_stdfloat();
_look_at_point.read_datagram(scan); _look_at_point.read_datagram(scan);
if (manager->get_file_minor_ver() >= 43) {
_look_at.fillin(scan, manager);
_fixed_depth = scan.get_stdfloat();
}
} }

View File

@ -34,7 +34,8 @@ PUBLISHED:
bool axial_rotate, bool axial_rotate,
PN_stdfloat offset, PN_stdfloat offset,
const NodePath &look_at, const NodePath &look_at,
const LPoint3 &look_at_point); const LPoint3 &look_at_point,
bool fixed_depth = false);
INLINE static CPT(RenderEffect) make_axis(); INLINE static CPT(RenderEffect) make_axis();
INLINE static CPT(RenderEffect) make_point_eye(); INLINE static CPT(RenderEffect) make_point_eye();
INLINE static CPT(RenderEffect) make_point_world(); INLINE static CPT(RenderEffect) make_point_world();
@ -43,6 +44,7 @@ PUBLISHED:
INLINE const LVector3 &get_up_vector() const; INLINE const LVector3 &get_up_vector() const;
INLINE bool get_eye_relative() const; INLINE bool get_eye_relative() const;
INLINE bool get_axial_rotate() const; INLINE bool get_axial_rotate() const;
INLINE bool get_fixed_depth() const;
INLINE PN_stdfloat get_offset() const; INLINE PN_stdfloat get_offset() const;
INLINE const NodePath &get_look_at() const; INLINE const NodePath &get_look_at() const;
INLINE const LPoint3 &get_look_at_point() const; INLINE const LPoint3 &get_look_at_point() const;
@ -72,9 +74,10 @@ private:
private: private:
bool _off; bool _off;
LVector3 _up_vector;
bool _eye_relative; bool _eye_relative;
bool _axial_rotate; bool _axial_rotate;
bool _fixed_depth;
LVector3 _up_vector;
PN_stdfloat _offset; PN_stdfloat _offset;
NodePath _look_at; NodePath _look_at;
LPoint3 _look_at_point; LPoint3 _look_at_point;
@ -82,6 +85,8 @@ private:
public: public:
static void register_with_read_factory(); static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg); virtual void write_datagram(BamWriter *manager, Datagram &dg);
virtual int complete_pointers(TypedWritable **plist,
BamReader *manager);
protected: protected:
static TypedWritable *make_from_bam(const FactoryParams &params); static TypedWritable *make_from_bam(const FactoryParams &params);

View File

@ -284,8 +284,25 @@ void CompassEffect::
write_datagram(BamWriter *manager, Datagram &dg) { write_datagram(BamWriter *manager, Datagram &dg) {
RenderEffect::write_datagram(manager, dg); RenderEffect::write_datagram(manager, dg);
dg.add_uint16(_properties); dg.add_uint16(_properties);
// *** We don't write out the _reference NodePath right now. Maybe we
// should. if (manager->get_file_minor_ver() >= 43) {
_reference.write_datagram(manager, dg);
}
}
/**
* Receives an array of pointers, one for each time manager->read_pointer()
* was called in fillin(). Returns the number of pointers processed.
*/
int CompassEffect::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = RenderEffect::complete_pointers(p_list, manager);
if (manager->get_file_minor_ver() >= 43) {
pi += _reference.complete_pointers(p_list + pi, manager);
}
return pi;
} }
/** /**
@ -313,4 +330,8 @@ void CompassEffect::
fillin(DatagramIterator &scan, BamReader *manager) { fillin(DatagramIterator &scan, BamReader *manager) {
RenderEffect::fillin(scan, manager); RenderEffect::fillin(scan, manager);
_properties = scan.get_uint16(); _properties = scan.get_uint16();
if (manager->get_file_minor_ver() >= 43) {
_reference.fillin(scan, manager);
}
} }

View File

@ -90,6 +90,8 @@ private:
public: public:
static void register_with_read_factory(); static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg); virtual void write_datagram(BamWriter *manager, Datagram &dg);
virtual int complete_pointers(TypedWritable **plist,
BamReader *manager);
protected: protected:
static TypedWritable *make_from_bam(const FactoryParams &params); static TypedWritable *make_from_bam(const FactoryParams &params);

View File

@ -1752,7 +1752,7 @@ set_billboard_axis(PN_stdfloat offset) {
* the camera. * the camera.
*/ */
INLINE void NodePath:: INLINE void NodePath::
set_billboard_point_eye(PN_stdfloat offset) { set_billboard_point_eye(PN_stdfloat offset, bool fixed_depth) {
set_billboard_point_eye(NodePath(), offset); set_billboard_point_eye(NodePath(), offset);
} }

View File

@ -4744,11 +4744,11 @@ set_billboard_axis(const NodePath &camera, PN_stdfloat offset) {
* the camera, towards a specified "camera" instead of to the viewing camera. * the camera, towards a specified "camera" instead of to the viewing camera.
*/ */
void NodePath:: void NodePath::
set_billboard_point_eye(const NodePath &camera, PN_stdfloat offset) { set_billboard_point_eye(const NodePath &camera, PN_stdfloat offset, bool fixed_depth) {
nassertv_always(!is_empty()); nassertv_always(!is_empty());
CPT(RenderEffect) billboard = BillboardEffect::make CPT(RenderEffect) billboard = BillboardEffect::make
(LVector3::up(), true, false, (LVector3::up(), true, false,
offset, camera, LPoint3(0.0f, 0.0f, 0.0f)); offset, camera, LPoint3(0.0f, 0.0f, 0.0f), fixed_depth);
node()->set_effect(billboard); node()->set_effect(billboard);
} }

View File

@ -815,10 +815,10 @@ PUBLISHED:
void do_billboard_point_eye(const NodePath &camera, PN_stdfloat offset); void do_billboard_point_eye(const NodePath &camera, PN_stdfloat offset);
void do_billboard_point_world(const NodePath &camera, PN_stdfloat offset); void do_billboard_point_world(const NodePath &camera, PN_stdfloat offset);
INLINE void set_billboard_axis(PN_stdfloat offset = 0.0); INLINE void set_billboard_axis(PN_stdfloat offset = 0.0);
INLINE void set_billboard_point_eye(PN_stdfloat offset = 0.0); INLINE void set_billboard_point_eye(PN_stdfloat offset = 0.0, bool fixed_depth = false);
INLINE void set_billboard_point_world(PN_stdfloat offset = 0.0); INLINE void set_billboard_point_world(PN_stdfloat offset = 0.0);
void set_billboard_axis(const NodePath &camera, PN_stdfloat offset); void set_billboard_axis(const NodePath &camera, PN_stdfloat offset);
void set_billboard_point_eye(const NodePath &camera, PN_stdfloat offset); void set_billboard_point_eye(const NodePath &camera, PN_stdfloat offset, bool fixed_depth = false);
void set_billboard_point_world(const NodePath &camera, PN_stdfloat offset); void set_billboard_point_world(const NodePath &camera, PN_stdfloat offset);
void clear_billboard(); void clear_billboard();
bool has_billboard() const; bool has_billboard() const;

View File

@ -32,7 +32,7 @@ static const unsigned short _bam_major_ver = 6;
// Bumped to major version 6 on 2006-02-11 to factor out PandaNode::CData. // Bumped to major version 6 on 2006-02-11 to factor out PandaNode::CData.
static const unsigned short _bam_first_minor_ver = 14; static const unsigned short _bam_first_minor_ver = 14;
static const unsigned short _bam_minor_ver = 42; static const unsigned short _bam_minor_ver = 43;
// Bumped to minor version 14 on 2007-12-19 to change default ColorAttrib. // Bumped to minor version 14 on 2007-12-19 to change default ColorAttrib.
// Bumped to minor version 15 on 2008-04-09 to add TextureAttrib::_implicit_sort. // Bumped to minor version 15 on 2008-04-09 to add TextureAttrib::_implicit_sort.
// Bumped to minor version 16 on 2008-05-13 to add Texture::_quality_level. // Bumped to minor version 16 on 2008-05-13 to add Texture::_quality_level.
@ -62,5 +62,6 @@ static const unsigned short _bam_minor_ver = 42;
// Bumped to minor version 40 on 2016-01-11 to make NodePaths writable. // Bumped to minor version 40 on 2016-01-11 to make NodePaths writable.
// Bumped to minor version 41 on 2016-03-02 to change LensNode, Lens, and Camera. // Bumped to minor version 41 on 2016-03-02 to change LensNode, Lens, and Camera.
// Bumped to minor version 42 on 2016-04-08 to expand ColorBlendAttrib. // Bumped to minor version 42 on 2016-04-08 to expand ColorBlendAttrib.
// Bumped to minor version 43 on 2018-12-06 to expand BillboardEffect and CompassEffect.
#endif #endif