Panda3D
 All Classes Functions Variables Enumerations
eggTable.cxx
1 // Filename: eggTable.cxx
2 // Created by: drose (19Feb99)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "eggTable.h"
16 
17 #include "string_utils.h"
18 #include "indent.h"
19 
20 TypeHandle EggTable::_type_handle;
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: EggTable::has_transform
24 // Access: Public
25 // Description: Returns true if the table contains a transform
26 // description, false otherwise.
27 ////////////////////////////////////////////////////////////////////
28 bool EggTable::
29 has_transform() const {
30  const_iterator ci;
31 
32  for (ci = begin(); ci != end(); ++ci) {
33  EggNode *child = (*ci);
34  if (child->is_anim_matrix()) {
35  return true;
36  }
37  }
38 
39  return false;
40 }
41 
42 ////////////////////////////////////////////////////////////////////
43 // Function: EggTable::write
44 // Access: Public, Virtual
45 // Description: Writes the table and all of its children to the
46 // indicated output stream in Egg format.
47 ////////////////////////////////////////////////////////////////////
48 void EggTable::
49 write(ostream &out, int indent_level) const {
50  test_under_integrity();
51 
52  switch (get_table_type()) {
53  case TT_table:
54  write_header(out, indent_level, "<Table>");
55  break;
56 
57  case TT_bundle:
58  write_header(out, indent_level, "<Bundle>");
59  break;
60 
61  default:
62  // invalid table type
63  nassertv(false);
64  }
65 
66  EggGroupNode::write(out, indent_level + 2);
67  indent(out, indent_level) << "}\n";
68 }
69 
70 
71 ////////////////////////////////////////////////////////////////////
72 // Function: EggTable::string_table_type
73 // Access: Public, Static
74 // Description: Returns the TableType value associated with the given
75 // string representation, or TT_invalid if the string
76 // does not match any known TableType value.
77 ////////////////////////////////////////////////////////////////////
78 EggTable::TableType EggTable::
79 string_table_type(const string &string) {
80  if (cmp_nocase_uh(string, "table") == 0) {
81  return TT_table;
82  } else if (cmp_nocase_uh(string, "bundle") == 0) {
83  return TT_bundle;
84  } else {
85  return TT_invalid;
86  }
87 }
88 
89 ////////////////////////////////////////////////////////////////////
90 // Function: EggTable::r_transform
91 // Access: Protected, Virtual
92 // Description: This is called from within the egg code by
93 // transform(). It applies a transformation matrix
94 // to the current node in some sensible way, then
95 // continues down the tree.
96 //
97 // The first matrix is the transformation to apply; the
98 // second is its inverse. The third parameter is the
99 // coordinate system we are changing to, or CS_default
100 // if we are not changing coordinate systems.
101 ////////////////////////////////////////////////////////////////////
102 void EggTable::
103 r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
104  CoordinateSystem to_cs) {
105  // We need to duplicate the logic in EggGroup: if we have a matrix
106  // transform witin this table, apply the transformation to it, but
107  // then apply only the scale/rotational part of the transformation
108  // to any children.
109 
110  // On the other hand, if we have no matrix transform within this
111  // table, pass the transformation through.
112 
113  // This logic is complicated by the fact that matrix transforms with
114  // a <Table> group are not stored within the table itself, but
115  // rather within a child named "xform". Fortunately,
116  // has_transform() abstracts out this detail for us.
117 
118  if (has_transform()) {
119  // At least one child of this table represents an animation matrix
120  // transform: that child gets the real matrix, while all other
121  // children get the truncated matrix.
122 
123  LMatrix4d mat1 = mat;
124  LMatrix4d inv1 = inv;
125 
126  // If we have a translation component, we should only apply
127  // it to the top matrix. All subsequent matrices get just the
128  // rotational component.
129  mat1.set_row(3, LVector3d(0.0, 0.0, 0.0));
130  inv1.set_row(3, LVector3d(0.0, 0.0, 0.0));
131 
132  iterator ci;
133  for (ci = begin(); ci != end(); ++ci) {
134  EggNode *child = (*ci);
135  if (child->is_anim_matrix()) {
136  child->r_transform(mat, inv, to_cs);
137  } else {
138  child->r_transform(mat1, inv1, to_cs);
139  }
140  }
141 
142  } else {
143  // No children of this table represent an animation matrix
144  // transform: all children get the real matrix.
145  EggGroupNode::r_transform(mat, inv, to_cs);
146  }
147 }
148 
149 
150 ////////////////////////////////////////////////////////////////////
151 // Function: TableType output operator
152 // Description:
153 ////////////////////////////////////////////////////////////////////
154 ostream &operator << (ostream &out, EggTable::TableType t) {
155  switch (t) {
156  case EggTable::TT_invalid:
157  return out << "invalid table";
158  case EggTable::TT_table:
159  return out << "table";
160  case EggTable::TT_bundle:
161  return out << "bundle";
162  }
163 
164  nassertr(false, out);
165  return out << "(**invalid**)";
166 }
virtual bool is_anim_matrix() const
Returns true if this node represents a table of animation transformation data, false otherwise...
Definition: eggNode.cxx:86
static TableType string_table_type(const string &string)
Returns the TableType value associated with the given string representation, or TT_invalid if the str...
Definition: eggTable.cxx:79
virtual void write(ostream &out, int indent_level) const
Writes the group and all of its children to the indicated output stream in Egg format.
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:4716
void write_header(ostream &out, int indent_level, const char *egg_keyword) const
Writes the first line of the egg object, e.g.
virtual void write(ostream &out, int indent_level) const
Writes the table and all of its children to the indicated output stream in Egg format.
Definition: eggTable.cxx:49
void set_row(int row, const LVecBase4d &v)
Replaces the indicated row of the matrix.
Definition: lmatrix.h:5452
bool has_transform() const
Returns true if the table contains a transform description, false otherwise.
Definition: eggTable.cxx:29
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:746
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:38
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85