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