|
|
@@ -18,11 +18,31 @@
|
|
|
|
|
|
#include "eggTable.h"
|
|
|
|
|
|
-#include <string_utils.h>
|
|
|
-#include <indent.h>
|
|
|
+#include "string_utils.h"
|
|
|
+#include "indent.h"
|
|
|
|
|
|
TypeHandle EggTable::_type_handle;
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: EggTable::has_transform
|
|
|
+// Access: Public
|
|
|
+// Description: Returns true if the table contains a transform
|
|
|
+// description, false otherwise.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+bool EggTable::
|
|
|
+has_transform() const {
|
|
|
+ const_iterator ci;
|
|
|
+
|
|
|
+ for (ci = begin(); ci != end(); ++ci) {
|
|
|
+ EggNode *child = (*ci);
|
|
|
+ if (child->is_anim_matrix()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: EggTable::write
|
|
|
// Access: Public, Virtual
|
|
|
@@ -70,6 +90,66 @@ string_table_type(const string &string) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: EggTable::r_transform
|
|
|
+// Access: Protected, Virtual
|
|
|
+// Description: This is called from within the egg code by
|
|
|
+// transform(). It applies a transformation matrix
|
|
|
+// to the current node in some sensible way, then
|
|
|
+// continues down the tree.
|
|
|
+//
|
|
|
+// The first matrix is the transformation to apply; the
|
|
|
+// second is its inverse. The third parameter is the
|
|
|
+// coordinate system we are changing to, or CS_default
|
|
|
+// if we are not changing coordinate systems.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+void EggTable::
|
|
|
+r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
|
|
|
+ CoordinateSystem to_cs) {
|
|
|
+ // We need to duplicate the logic in EggGroup: if we have a matrix
|
|
|
+ // transform witin this table, apply the transformation to it, but
|
|
|
+ // then apply only the scale/rotational part of the transformation
|
|
|
+ // to any children.
|
|
|
+
|
|
|
+ // On the other hand, if we have no matrix transform within this
|
|
|
+ // table, pass the transformation through.
|
|
|
+
|
|
|
+ // This logic is complicated by the fact that matrix transforms with
|
|
|
+ // a <Table> group are not stored within the table itself, but
|
|
|
+ // rather within a child named "xform". Fortunately,
|
|
|
+ // has_transform() abstracts out this detail for us.
|
|
|
+
|
|
|
+ if (has_transform()) {
|
|
|
+ // At least one child of this table represents an animation matrix
|
|
|
+ // transform: that child gets the real matrix, while all other
|
|
|
+ // children get the truncated matrix.
|
|
|
+
|
|
|
+ LMatrix4d mat1 = mat;
|
|
|
+ LMatrix4d inv1 = inv;
|
|
|
+
|
|
|
+ // If we have a translation component, we should only apply
|
|
|
+ // it to the top matrix. All subsequent matrices get just the
|
|
|
+ // rotational component.
|
|
|
+ mat1.set_row(3, LVector3d(0.0, 0.0, 0.0));
|
|
|
+ inv1.set_row(3, LVector3d(0.0, 0.0, 0.0));
|
|
|
+
|
|
|
+ iterator ci;
|
|
|
+ for (ci = begin(); ci != end(); ++ci) {
|
|
|
+ EggNode *child = (*ci);
|
|
|
+ if (child->is_anim_matrix()) {
|
|
|
+ child->r_transform(mat, inv, to_cs);
|
|
|
+ } else {
|
|
|
+ child->r_transform(mat1, inv1, to_cs);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // No children of this table represent an animation matrix
|
|
|
+ // transform: all children get the real matrix.
|
|
|
+ EggGroupNode::r_transform(mat, inv, to_cs);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: TableType output operator
|