mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
robustify transform and object type interface
This commit is contained in:
parent
dd98ca18a7
commit
efc0a0b45b
@ -27,6 +27,25 @@ get_group_type() const {
|
||||
return (GroupType)(_flags & F_group_type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroup::is_instance_type
|
||||
// Access: Public
|
||||
// Description: Returns true if this group is an instance type node;
|
||||
// i.e. it begins the root of a local coordinate space.
|
||||
// This is not related to instancing (multiple copies of
|
||||
// a node in a scene graph).
|
||||
//
|
||||
// This also includes the case of the node including a
|
||||
// billboard flag without an explicit center, which
|
||||
// implicitly makes the node behave like an instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggGroup::
|
||||
is_instance_type() const {
|
||||
return
|
||||
(get_group_type() == GT_instance) ||
|
||||
(get_billboard_type() != BT_none && !has_billboard_center());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroup::set_billboard_type
|
||||
// Access: Public
|
||||
@ -37,6 +56,8 @@ set_billboard_type(BillboardType type) {
|
||||
// Make sure the user didn't give us any stray bits.
|
||||
nassertv((type & ~F_billboard_type)==0);
|
||||
_flags = (_flags & ~F_billboard_type) | type;
|
||||
// This may change the transform space of this node.
|
||||
update_under(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -74,6 +95,8 @@ INLINE void EggGroup::
|
||||
set_billboard_center(const LPoint3d &billboard_center) {
|
||||
_billboard_center = billboard_center;
|
||||
_flags2 |= F2_billboard_center;
|
||||
// This may change the transform space of this node.
|
||||
update_under(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -84,6 +107,8 @@ set_billboard_center(const LPoint3d &billboard_center) {
|
||||
INLINE void EggGroup::
|
||||
clear_billboard_center() {
|
||||
_flags2 &= ~F2_billboard_center;
|
||||
// This may change the transform space of this node.
|
||||
update_under(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -22,9 +22,9 @@
|
||||
#include "eggBin.h"
|
||||
#include "lexerDefs.h"
|
||||
|
||||
#include <indent.h>
|
||||
#include <string_utils.h>
|
||||
#include <lmatrix.h>
|
||||
#include "indent.h"
|
||||
#include "string_utils.h"
|
||||
#include "lmatrix.h"
|
||||
|
||||
|
||||
TypeHandle EggGroup::_type_handle;
|
||||
@ -119,6 +119,43 @@ set_group_type(GroupType type) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroup::has_object_type
|
||||
// Access: Public
|
||||
// Description: Returns true if the indicated object type has been
|
||||
// added to the group, or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggGroup::
|
||||
has_object_type(const string &object_type) const {
|
||||
vector_string::const_iterator oi;
|
||||
for (oi = _object_types.begin(); oi != _object_types.end(); ++oi) {
|
||||
if (cmp_nocase_uh((*oi), object_type) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroup::remove_object_type
|
||||
// Access: Public
|
||||
// Description: Removes the first instance of the indicated object
|
||||
// type from the group if it is present. Returns true
|
||||
// if the object type was found and removed, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggGroup::
|
||||
remove_object_type(const string &object_type) {
|
||||
vector_string::iterator oi;
|
||||
for (oi = _object_types.begin(); oi != _object_types.end(); ++oi) {
|
||||
if (cmp_nocase_uh((*oi), object_type) == 0) {
|
||||
_object_types.erase(oi);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroup::write
|
||||
// Access: Public, Virtual
|
||||
@ -680,10 +717,6 @@ egg_start_parse_body() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggGroup::
|
||||
adjust_under() {
|
||||
// Billboards without an explicit center are an implicit instance.
|
||||
bool is_billboard_instance =
|
||||
(get_billboard_type() != BT_none && !has_billboard_center());
|
||||
|
||||
// If we have our own transform, it carries forward.
|
||||
|
||||
// As of 4/18/01, this now also affects the local_coord flag, below.
|
||||
@ -699,9 +732,11 @@ adjust_under() {
|
||||
new MatrixFrame(invert(get_node_frame()));
|
||||
_vertex_to_node =
|
||||
new MatrixFrame(get_vertex_frame() * get_node_frame_inv());
|
||||
_node_to_vertex =
|
||||
new MatrixFrame(get_node_frame() * get_vertex_frame_inv());
|
||||
}
|
||||
|
||||
if (get_group_type() == GT_instance || is_billboard_instance) {
|
||||
if (is_instance_type()) {
|
||||
_under_flags |= UF_under_instance;
|
||||
if (_under_flags & UF_under_transform) {
|
||||
// If we've reached an instance node and we're under a
|
||||
@ -716,6 +751,7 @@ adjust_under() {
|
||||
_vertex_frame = _node_frame;
|
||||
_vertex_frame_inv = _node_frame_inv;
|
||||
_vertex_to_node = NULL;
|
||||
_node_to_vertex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -753,7 +789,7 @@ r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
|
||||
mat1.set_row(3, LVector3d(0.0, 0.0, 0.0));
|
||||
inv1.set_row(3, LVector3d(0.0, 0.0, 0.0));
|
||||
|
||||
set_transform(inv1 * get_transform() * mat);
|
||||
internal_set_transform(inv1 * get_transform() * mat);
|
||||
|
||||
EggGroupNode::r_transform(mat1, inv1, to_cs);
|
||||
} else {
|
||||
@ -799,11 +835,26 @@ r_flatten_transforms() {
|
||||
}
|
||||
|
||||
if (get_group_type() != GT_joint) {
|
||||
clear_transform();
|
||||
internal_clear_transform();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroup::transform_changed
|
||||
// Access: Protected, Virtual
|
||||
// Description: This virtual method is inherited by EggTransform3d;
|
||||
// it is called whenever the transform is changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggGroup::
|
||||
transform_changed() {
|
||||
// Recompute all of the cached transforms at this node and below.
|
||||
// We should probably make this smarter and do lazy evaluation of
|
||||
// these transforms, rather than having to recompute the whole tree
|
||||
// with every change to a parent node's transform.
|
||||
update_under(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -100,6 +100,7 @@ public:
|
||||
|
||||
void set_group_type(GroupType type);
|
||||
INLINE GroupType get_group_type() const;
|
||||
INLINE bool is_instance_type() const;
|
||||
|
||||
INLINE void set_billboard_type(BillboardType type);
|
||||
INLINE BillboardType get_billboard_type() const;
|
||||
@ -136,6 +137,8 @@ public:
|
||||
INLINE void clear_object_types();
|
||||
INLINE int get_num_object_types() const;
|
||||
INLINE string get_object_type(int index) const;
|
||||
bool has_object_type(const string &object_type) const;
|
||||
bool remove_object_type(const string &object_type);
|
||||
|
||||
INLINE void set_model_flag(bool flag);
|
||||
INLINE bool get_model_flag() const;
|
||||
@ -201,6 +204,8 @@ protected:
|
||||
CoordinateSystem to_cs);
|
||||
virtual void r_flatten_transforms();
|
||||
|
||||
virtual void transform_changed();
|
||||
|
||||
private:
|
||||
|
||||
enum Flags {
|
||||
|
@ -212,6 +212,26 @@ get_vertex_to_node() const {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggNode::get_node_to_vertex
|
||||
// Access: Public
|
||||
// Description: Returns the transformation matrix suitable for
|
||||
// converting vertices in the coordinate space of the
|
||||
// node to the appropriate coordinate space for storing
|
||||
// in the egg file. This is the same thing as:
|
||||
//
|
||||
// get_node_frame() * get_vertex_frame_inv()
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const LMatrix4d &EggNode::
|
||||
get_node_to_vertex() const {
|
||||
if (_node_to_vertex == (LMatrix4d *)NULL) {
|
||||
return LMatrix4d::ident_mat();
|
||||
} else {
|
||||
return *_node_to_vertex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggNode::transform
|
||||
@ -259,4 +279,5 @@ transform_vertices_only(const LMatrix4d &mat) {
|
||||
INLINE void EggNode::
|
||||
flatten_transforms() {
|
||||
r_flatten_transforms();
|
||||
update_under(0);
|
||||
}
|
||||
|
@ -244,6 +244,7 @@ update_under(int depth_offset) {
|
||||
_vertex_frame_inv = NULL;
|
||||
_node_frame_inv = NULL;
|
||||
_vertex_to_node = NULL;
|
||||
_node_to_vertex = NULL;
|
||||
} else {
|
||||
depth = _parent->_depth + 1;
|
||||
_under_flags = _parent->_under_flags;
|
||||
@ -252,6 +253,7 @@ update_under(int depth_offset) {
|
||||
_vertex_frame_inv = _parent->_vertex_frame_inv;
|
||||
_node_frame_inv = _parent->_node_frame_inv;
|
||||
_vertex_to_node = _parent->_vertex_to_node;
|
||||
_node_to_vertex = _parent->_node_to_vertex;
|
||||
}
|
||||
|
||||
if (depth - _depth != depth_offset) {
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
INLINE const LMatrix4d &get_vertex_frame_inv() const;
|
||||
INLINE const LMatrix4d &get_node_frame_inv() const;
|
||||
INLINE const LMatrix4d &get_vertex_to_node() const;
|
||||
INLINE const LMatrix4d &get_node_to_vertex() const;
|
||||
|
||||
INLINE void transform(const LMatrix4d &mat);
|
||||
INLINE void transform_vertices_only(const LMatrix4d &mat);
|
||||
@ -112,6 +113,7 @@ protected:
|
||||
PT(MatrixFrame) _vertex_frame_inv;
|
||||
PT(MatrixFrame) _node_frame_inv;
|
||||
PT(MatrixFrame) _vertex_to_node;
|
||||
PT(MatrixFrame) _node_to_vertex;
|
||||
|
||||
|
||||
public:
|
||||
|
@ -90,6 +90,29 @@ INLINE EggTransform3d::Component::
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::clear_transform
|
||||
// Access: Public
|
||||
// Description: Resets the transform to empty, identity.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggTransform3d::
|
||||
clear_transform() {
|
||||
internal_clear_transform();
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::add_matrix
|
||||
// Access: Public
|
||||
// Description: Appends an arbitrary 4x4 matrix to the current
|
||||
// transform.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggTransform3d::
|
||||
add_matrix(const LMatrix4d &mat) {
|
||||
internal_add_matrix(mat);
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::has_transform
|
||||
// Access: Public
|
||||
@ -111,8 +134,8 @@ has_transform() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggTransform3d::
|
||||
set_transform(const LMatrix4d &mat) {
|
||||
clear_transform();
|
||||
add_matrix(mat);
|
||||
internal_set_transform(mat);
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -203,3 +226,15 @@ get_component_matrix(int n) const {
|
||||
nassertr(_components[n]._matrix != (LMatrix4d *)NULL, LMatrix4d::ident_mat());
|
||||
return *_components[n]._matrix;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::internal_set_transform
|
||||
// Access: Protected
|
||||
// Description: Sets the overall transform without calling
|
||||
// transform_changed().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggTransform3d::
|
||||
internal_set_transform(const LMatrix4d &mat) {
|
||||
internal_clear_transform();
|
||||
internal_add_matrix(mat);
|
||||
}
|
||||
|
@ -63,17 +63,6 @@ EggTransform3d::
|
||||
~EggTransform3d() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::clear_transform
|
||||
// Access: Public
|
||||
// Description: Resets the transform to empty, identity.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTransform3d::
|
||||
clear_transform() {
|
||||
_components.clear();
|
||||
_transform = LMatrix4d::ident_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::add_translate
|
||||
// Access: Public
|
||||
@ -85,6 +74,7 @@ add_translate(const LVector3d &translate) {
|
||||
_components.push_back(Component(CT_translate));
|
||||
_components.back()._vector = new LVector3d(translate);
|
||||
_transform *= LMatrix4d::translate_mat(translate);
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -98,6 +88,7 @@ void EggTransform3d::
|
||||
add_rotx(double angle) {
|
||||
_components.push_back(Component(CT_rotx, angle));
|
||||
_transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(1.0, 0.0, 0.0));
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -111,6 +102,7 @@ void EggTransform3d::
|
||||
add_roty(double angle) {
|
||||
_components.push_back(Component(CT_roty, angle));
|
||||
_transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 1.0, 0.0));
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -124,6 +116,7 @@ void EggTransform3d::
|
||||
add_rotz(double angle) {
|
||||
_components.push_back(Component(CT_rotz, angle));
|
||||
_transform *= LMatrix4d::rotate_mat_normaxis(angle, LVector3d(0.0, 0.0, 1.0));
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -139,6 +132,7 @@ add_rotate(double angle, const LVector3d &axis) {
|
||||
_components.push_back(Component(CT_rotate, angle));
|
||||
_components.back()._vector = new LVector3d(normaxis);
|
||||
_transform *= LMatrix4d::rotate_mat(angle, normaxis);
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -151,6 +145,7 @@ add_rotate(double angle, const LVector3d &axis) {
|
||||
void EggTransform3d::
|
||||
add_rotate(const LQuaterniond &quat) {
|
||||
add_rotate(quat.get_angle(), quat.get_axis());
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -164,6 +159,7 @@ add_scale(const LVecBase3d &scale) {
|
||||
_components.push_back(Component(CT_scale));
|
||||
_components.back()._vector = new LVector3d(scale);
|
||||
_transform *= LMatrix4d::scale_mat(scale);
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -175,19 +171,7 @@ void EggTransform3d::
|
||||
add_uniform_scale(double scale) {
|
||||
_components.push_back(Component(CT_uniform_scale, scale));
|
||||
_transform *= LMatrix4d::scale_mat(scale);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::add_matrix
|
||||
// Access: Public
|
||||
// Description: Appends an arbitrary 4x4 matrix to the current
|
||||
// transform.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTransform3d::
|
||||
add_matrix(const LMatrix4d &mat) {
|
||||
_components.push_back(Component(CT_matrix));
|
||||
_components.back()._matrix = new LMatrix4d(mat);
|
||||
_transform *= mat;
|
||||
transform_changed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -253,3 +237,41 @@ write(ostream &out, int indent_level) const {
|
||||
|
||||
indent(out, indent_level) << "}\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::internal_clear_transform
|
||||
// Access: Public
|
||||
// Description: Resets the transform to empty without calling
|
||||
// transform_changed().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTransform3d::
|
||||
internal_clear_transform() {
|
||||
_components.clear();
|
||||
_transform = LMatrix4d::ident_mat();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::internal_add_matrix
|
||||
// Access: Public
|
||||
// Description: Appends an arbitrary 4x4 matrix to the current
|
||||
// transform, without calling transform_changed().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTransform3d::
|
||||
internal_add_matrix(const LMatrix4d &mat) {
|
||||
_components.push_back(Component(CT_matrix));
|
||||
_components.back()._matrix = new LMatrix4d(mat);
|
||||
_transform *= mat;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTransform3d::transform_changed
|
||||
// Access: Protected, Virtual
|
||||
// Description: This virtual method is called whenever the transform
|
||||
// is changed; it is intended to provide a hook for
|
||||
// derived classes (e.g. EggGroup) to update their
|
||||
// internal cache appropriately.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTransform3d::
|
||||
transform_changed() {
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ public:
|
||||
EggTransform3d &operator = (const EggTransform3d ©);
|
||||
~EggTransform3d();
|
||||
|
||||
void clear_transform();
|
||||
INLINE void clear_transform();
|
||||
|
||||
void add_translate(const LVector3d &translate);
|
||||
void add_rotx(double angle);
|
||||
@ -47,7 +47,7 @@ public:
|
||||
void add_rotate(const LQuaterniond &quat);
|
||||
void add_scale(const LVecBase3d &scale);
|
||||
void add_uniform_scale(double scale);
|
||||
void add_matrix(const LMatrix4d &mat);
|
||||
INLINE void add_matrix(const LMatrix4d &mat);
|
||||
|
||||
INLINE bool has_transform() const;
|
||||
INLINE void set_transform(const LMatrix4d &mat);
|
||||
@ -74,6 +74,13 @@ public:
|
||||
|
||||
void write(ostream &out, int indent_level) const;
|
||||
|
||||
protected:
|
||||
void internal_clear_transform();
|
||||
void internal_add_matrix(const LMatrix4d &mat);
|
||||
INLINE void internal_set_transform(const LMatrix4d &mat);
|
||||
|
||||
virtual void transform_changed();
|
||||
|
||||
private:
|
||||
class Component {
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user