Panda3D

eggTable.cxx

00001 // Filename: eggTable.cxx
00002 // Created by:  drose (19Feb99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "eggTable.h"
00016 
00017 #include "string_utils.h"
00018 #include "indent.h"
00019 
00020 TypeHandle EggTable::_type_handle;
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: EggTable::has_transform
00024 //       Access: Public
00025 //  Description: Returns true if the table contains a transform
00026 //               description, false otherwise.
00027 ////////////////////////////////////////////////////////////////////
00028 bool EggTable::
00029 has_transform() const {
00030   const_iterator ci;
00031 
00032   for (ci = begin(); ci != end(); ++ci) {
00033     EggNode *child = (*ci);
00034     if (child->is_anim_matrix()) {
00035       return true;
00036     }
00037   }
00038   
00039   return false;
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: EggTable::write
00044 //       Access: Public, Virtual
00045 //  Description: Writes the table and all of its children to the
00046 //               indicated output stream in Egg format.
00047 ////////////////////////////////////////////////////////////////////
00048 void EggTable::
00049 write(ostream &out, int indent_level) const {
00050   test_under_integrity();
00051 
00052   switch (get_table_type()) {
00053   case TT_table:
00054     write_header(out, indent_level, "<Table>");
00055     break;
00056 
00057   case TT_bundle:
00058     write_header(out, indent_level, "<Bundle>");
00059     break;
00060 
00061   default:
00062     // invalid table type
00063     nassertv(false);
00064   }
00065 
00066   EggGroupNode::write(out, indent_level + 2);
00067   indent(out, indent_level) << "}\n";
00068 }
00069 
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: EggTable::string_table_type
00073 //       Access: Public, Static
00074 //  Description: Returns the TableType value associated with the given
00075 //               string representation, or TT_invalid if the string
00076 //               does not match any known TableType value.
00077 ////////////////////////////////////////////////////////////////////
00078 EggTable::TableType EggTable::
00079 string_table_type(const string &string) {
00080   if (cmp_nocase_uh(string, "table") == 0) {
00081     return TT_table;
00082   } else if (cmp_nocase_uh(string, "bundle") == 0) {
00083     return TT_bundle;
00084   } else {
00085     return TT_invalid;
00086   }
00087 }
00088 
00089 ////////////////////////////////////////////////////////////////////
00090 //     Function: EggTable::r_transform
00091 //       Access: Protected, Virtual
00092 //  Description: This is called from within the egg code by
00093 //               transform().  It applies a transformation matrix
00094 //               to the current node in some sensible way, then
00095 //               continues down the tree.
00096 //
00097 //               The first matrix is the transformation to apply; the
00098 //               second is its inverse.  The third parameter is the
00099 //               coordinate system we are changing to, or CS_default
00100 //               if we are not changing coordinate systems.
00101 ////////////////////////////////////////////////////////////////////
00102 void EggTable::
00103 r_transform(const LMatrix4d &mat, const LMatrix4d &inv,
00104             CoordinateSystem to_cs) {
00105   // We need to duplicate the logic in EggGroup: if we have a matrix
00106   // transform witin this table, apply the transformation to it, but
00107   // then apply only the scale/rotational part of the transformation
00108   // to any children.
00109 
00110   // On the other hand, if we have no matrix transform within this
00111   // table, pass the transformation through.
00112 
00113   // This logic is complicated by the fact that matrix transforms with
00114   // a <Table> group are not stored within the table itself, but
00115   // rather within a child named "xform".  Fortunately,
00116   // has_transform() abstracts out this detail for us.
00117 
00118   if (has_transform()) {
00119     // At least one child of this table represents an animation matrix
00120     // transform: that child gets the real matrix, while all other
00121     // children get the truncated matrix.
00122 
00123     LMatrix4d mat1 = mat;
00124     LMatrix4d inv1 = inv;
00125 
00126     // If we have a translation component, we should only apply
00127     // it to the top matrix.  All subsequent matrices get just the
00128     // rotational component.
00129     mat1.set_row(3, LVector3d(0.0, 0.0, 0.0));
00130     inv1.set_row(3, LVector3d(0.0, 0.0, 0.0));
00131 
00132     iterator ci;
00133     for (ci = begin(); ci != end(); ++ci) {
00134       EggNode *child = (*ci);
00135       if (child->is_anim_matrix()) {
00136         child->r_transform(mat, inv, to_cs);
00137       } else {
00138         child->r_transform(mat1, inv1, to_cs);
00139       }
00140     }
00141 
00142   } else {
00143     // No children of this table represent an animation matrix
00144     // transform: all children get the real matrix.
00145     EggGroupNode::r_transform(mat, inv, to_cs);
00146   }
00147 }
00148 
00149 
00150 ////////////////////////////////////////////////////////////////////
00151 //     Function: TableType output operator
00152 //  Description:
00153 ////////////////////////////////////////////////////////////////////
00154 ostream &operator << (ostream &out, EggTable::TableType t) {
00155   switch (t) {
00156   case EggTable::TT_invalid:
00157     return out << "invalid table";
00158   case EggTable::TT_table:
00159     return out << "table";
00160   case EggTable::TT_bundle:
00161     return out << "bundle";
00162   }
00163 
00164   nassertr(false, out);
00165   return out << "(**invalid**)";
00166 }
 All Classes Functions Variables Enumerations