Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/char/computedVertices.cxx

Go to the documentation of this file.
00001 // Filename: computedVertices.cxx
00002 // Created by:  drose (01Mar99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 
00020 #include "computedVertices.h"
00021 #include "characterJoint.h"
00022 #include "character.h"
00023 #include "config_char.h"
00024 
00025 #include "datagram.h"
00026 #include "datagramIterator.h"
00027 #include "bamReader.h"
00028 #include "bamWriter.h"
00029 #include "ioPtaDatagramLinMath.h"
00030 
00031 #include <algorithm>
00032 
00033 TypeHandle ComputedVertices::_type_handle;
00034 
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: ComputedVertices::VertexTransform::Copy Constructor
00038 //       Access: Public
00039 //  Description:
00040 ////////////////////////////////////////////////////////////////////
00041 ComputedVertices::VertexTransform::
00042 VertexTransform(const VertexTransform &copy) :
00043   _joint_index(copy._joint_index),
00044   _effect(copy._effect),
00045   _vindex(copy._vindex),
00046   _nindex(copy._nindex)
00047 {
00048 }
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: compute_morphs
00052 //  Description: This is a utility function called by update(), below.
00053 //               It applies each of the supplied morphs to the
00054 //               vertices in the table, according to the values of the
00055 //               relevant slider.
00056 ////////////////////////////////////////////////////////////////////
00057 template<class ValueType, class MorphType>
00058 static void
00059 compute_morphs(ValueType *table, const pvector<MorphType> &morph_list,
00060                Character *character) {
00061   TYPENAME pvector<MorphType>::const_iterator mli;
00062   for (mli = morph_list.begin(); mli != morph_list.end(); ++mli) {
00063     const MorphType &morph = (*mli);
00064     const CharacterSlider *slider;
00065     DCAST_INTO_V(slider, character->get_part(morph._slider_index));
00066     
00067     float slider_value = slider->_value;
00068     
00069     if (slider_value != 0.0f) {
00070       typedef TYPENAME MorphType::Morphs Morphs;
00071       typedef TYPENAME MorphType::MorphValue MorphValue;
00072       TYPENAME Morphs::const_iterator mi;
00073       for (mi = morph._morphs.begin(); mi != morph._morphs.end(); ++mi) {
00074         typedef TYPENAME MorphValue::VecType VecType;
00075         ushort index = (*mi)._index;
00076         const VecType &v = (*mi)._vector;
00077         
00078         table[index] += v * slider_value;
00079       }
00080     }
00081   }
00082 }
00083 
00084 ////////////////////////////////////////////////////////////////////
00085 //     Function: VertexTransform::write_datagram
00086 //       Access: Public
00087 //  Description: Function to write the important information in
00088 //               the particular object to a Datagram
00089 ////////////////////////////////////////////////////////////////////
00090 void ComputedVertices::VertexTransform::
00091 write_datagram(Datagram &dest)
00092 {
00093   int i;
00094   dest.add_int16(_joint_index);
00095   dest.add_float32(_effect);
00096   dest.add_uint16(_vindex.size());
00097   for(i = 0; i < (int)_vindex.size(); i++)
00098   {
00099     dest.add_uint16(_vindex[i]);
00100   }
00101   dest.add_uint16(_nindex.size());
00102   for(i = 0; i < (int)_nindex.size(); i++)
00103   {
00104     dest.add_uint16(_nindex[i]);
00105   }
00106 }
00107 
00108 ////////////////////////////////////////////////////////////////////
00109 //     Function: VertexTransform::read_datagram
00110 //       Access: Protected
00111 //  Description:
00112 ////////////////////////////////////////////////////////////////////
00113 void ComputedVertices::VertexTransform::
00114 read_datagram(DatagramIterator &source)
00115 {
00116   int i;
00117   _joint_index = source.get_int16();
00118   _effect = source.get_float32();
00119   int vsize = source.get_uint16();
00120   for(i = 0; i < vsize; i++)
00121   {
00122     _vindex.push_back(source.get_uint16());
00123   }
00124   int nsize = source.get_uint16();
00125   for(i = 0; i < nsize; i++)
00126   {
00127     _nindex.push_back(source.get_uint16());
00128   }
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: ComputedVertices::update
00133 //       Access: Public
00134 //  Description: Recomputes all of the _coords, _norms, etc. values
00135 //               based on the values in _orig_coords, _orig_norms,
00136 //               etc., and the current positions of all of the joints.
00137 ////////////////////////////////////////////////////////////////////
00138 void ComputedVertices::
00139 update(Character *character) {
00140   nassertv(character != (Character *)NULL);
00141   nassertv(character->_cv._coords.size() == _orig_coords.size());
00142   nassertv(character->_cv._norms.size() == _orig_norms.size());
00143   nassertv(character->_cv._texcoords.size() == _orig_texcoords.size());
00144   nassertv(character->_cv._colors.size() == _orig_colors.size());
00145 
00146   const Vertexf *orig_coords = _orig_coords;
00147   const Normalf *orig_norms = _orig_norms;
00148 
00149   memset(character->_cv._coords, 0, sizeof(Vertexf) * character->_cv._coords.size());
00150   memset(character->_cv._norms, 0, sizeof(Normalf) * character->_cv._norms.size());
00151 
00152   if (!_vertex_morphs.empty()) {
00153     // We have some vertex morphs.  Compute them first.
00154     int table_size = sizeof(Vertexf) * _orig_coords.size();
00155     Vertexf *morphed_coords = (Vertexf *)alloca(table_size);
00156     memcpy(morphed_coords, _orig_coords, table_size);
00157 
00158     compute_morphs(morphed_coords, _vertex_morphs, character);
00159     orig_coords = morphed_coords;
00160   }
00161 
00162   if (!_normal_morphs.empty()) {
00163     // We also have some normal morphs.  Compute them too.
00164     int table_size = sizeof(Normalf) * _orig_norms.size();
00165     Normalf *morphed_norms = (Normalf *)alloca(table_size);
00166     memcpy(morphed_norms, _orig_norms, table_size);
00167 
00168     compute_morphs(morphed_norms, _normal_morphs, character);
00169     orig_norms = morphed_norms;
00170   }
00171 
00172   if (!_texcoord_morphs.empty()) {
00173     // We have some uv morphs.  These don't particularly need to be
00174     // done before the joints are computed, but do them now anyway.
00175     int table_size = sizeof(TexCoordf) * _orig_texcoords.size();
00176 
00177     // **** Is this right?  Test it!
00178     //    TexCoordf *morphed_texcoords = (TexCoordf *)alloca(table_size);
00179     memcpy(character->_cv._texcoords, _orig_texcoords, table_size);
00180 
00181     compute_morphs(character->_cv._texcoords.p(), _texcoord_morphs, character);
00182   }
00183 
00184   if (!_color_morphs.empty()) {
00185     // We have some color morphs.  Do these now too.
00186     int table_size = sizeof(Colorf) * _orig_colors.size();
00187 
00188     // **** Is this right?  Test it!
00189     // Colorf *morphed_colors = (Colorf *)alloca(table_size);
00190     memcpy(character->_cv._colors, _orig_colors, table_size);
00191 
00192     compute_morphs(character->_cv._colors.p(), _color_morphs, character);
00193   }
00194 
00195   // Now that we've computed all the morphs, it's safe to transform
00196   // vertices into their proper coordinate space, according to the
00197   // current positions of all the joints.
00198 
00199   LMatrix4f mat = LMatrix4f::ident_mat();
00200   int last_joint_index = -1;
00201 
00202   VertexTransforms::const_iterator vti;
00203   for (vti = _transforms.begin(); vti != _transforms.end(); ++vti) {
00204     const VertexTransform &vt = (*vti);
00205 
00206     // We cache the matrix from the last joint, because we are likely
00207     // to encounter the same joint several times in a row.
00208     if (vt._joint_index != last_joint_index) {
00209       last_joint_index = vt._joint_index;
00210 
00211       // We won't encounter -1 after the first few joints.
00212       nassertv(vt._joint_index >= 0);
00213       CharacterJoint *joint;
00214       DCAST_INTO_V(joint, character->get_part(vt._joint_index));
00215 
00216       mat =
00217         joint->_initial_net_transform_inverse *
00218         joint->_net_transform;
00219     }
00220 
00221     Vertices::const_iterator vi;
00222     for (vi = vt._vindex.begin(); vi != vt._vindex.end(); ++vi) {
00223       int i = (*vi);
00224       character->_cv._coords[i] += (orig_coords[i] * mat) * vt._effect;
00225     }
00226     for (vi = vt._nindex.begin(); vi != vt._nindex.end(); ++vi) {
00227       int i = (*vi);
00228       character->_cv._norms[i] += (orig_norms[i] * mat) * vt._effect;
00229     }
00230   }
00231 }
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: ComputedVertices::make_orig
00235 //       Access: Public
00236 //  Description: Copies all the values loaded in the _coords, _norms,
00237 //               etc. arrays into the corresponding _orig_coords,
00238 //               etc. arrays.
00239 ////////////////////////////////////////////////////////////////////
00240 void ComputedVertices::
00241 make_orig(Character *character) {
00242   nassertv(character != (Character *)NULL);
00243 
00244   if (character->_cv._coords.empty()) {
00245     _orig_coords.clear();
00246   } else {
00247     _orig_coords = PTA_Vertexf::empty_array(0);
00248     _orig_coords.v() = character->_cv._coords.v();
00249   }
00250 
00251   if (character->_cv._norms.empty()) {
00252     _orig_norms.clear();
00253   } else {
00254     _orig_norms = PTA_Normalf::empty_array(0);
00255     _orig_norms.v() = character->_cv._norms.v();
00256   }
00257 
00258   if (character->_cv._colors.empty()) {
00259     _orig_colors.clear();
00260   } else {
00261     _orig_colors = PTA_Colorf::empty_array(0);
00262     _orig_colors.v() = character->_cv._colors.v();
00263   }
00264 
00265   if (character->_cv._texcoords.empty()) {
00266     _orig_texcoords.clear();
00267   } else {
00268     _orig_texcoords = PTA_TexCoordf::empty_array(0);
00269     _orig_texcoords.v() = character->_cv._texcoords.v();
00270   }
00271 }
00272 
00273 ////////////////////////////////////////////////////////////////////
00274 //     Function: ComputedVertices::write
00275 //       Access: Public
00276 //  Description:
00277 ////////////////////////////////////////////////////////////////////
00278 void ComputedVertices::
00279 write(ostream &out, Character *character) const {
00280   VertexTransforms::const_iterator vti;
00281 
00282   out << "ComputedVertices:\n";
00283   for (vti = _transforms.begin(); vti != _transforms.end(); ++vti) {
00284     const VertexTransform &vt = (*vti);
00285     string name;
00286     if (vt._joint_index >= 0) {
00287       name = character->get_part(vt._joint_index)->get_name();
00288     } else {
00289       name = "(root)";
00290     }
00291 
00292     out << "  " << name << " * " << vt._effect << " : "
00293     << vt._vindex.size() << " vertices and "
00294     << vt._nindex.size() << " normals\n";
00295   }
00296 
00297   VertexMorphs::const_iterator vmi;
00298   for (vmi = _vertex_morphs.begin(); vmi != _vertex_morphs.end(); ++vmi) {
00299     out << "  vertex " << (*vmi) << "\n";
00300   }
00301 
00302   NormalMorphs::const_iterator nmi;
00303   for (nmi = _normal_morphs.begin(); nmi != _normal_morphs.end(); ++nmi) {
00304     out << "  normal " << (*nmi) << "\n";
00305   }
00306 
00307   TexCoordMorphs::const_iterator tmi;
00308   for (tmi = _texcoord_morphs.begin(); tmi != _texcoord_morphs.end(); ++tmi) {
00309     out << "  uv " << (*tmi) << "\n";
00310   }
00311 
00312   ColorMorphs::const_iterator cmi;
00313   for (cmi = _color_morphs.begin(); cmi != _color_morphs.end(); ++cmi) {
00314     out << "  color " << (*cmi) << "\n";
00315   }
00316 }
00317 
00318 ////////////////////////////////////////////////////////////////////
00319 //     Function: ComputedVertices::write_datagram
00320 //       Access: Public
00321 //  Description: Function to write the important information in
00322 //               the particular object to a Datagram
00323 ////////////////////////////////////////////////////////////////////
00324 void ComputedVertices::
00325 write_datagram(BamWriter *manager, Datagram &me)
00326 {
00327   int i;
00328 
00329   me.add_uint16(_transforms.size());
00330   for(i = 0; i < (int)_transforms.size(); i++){
00331     _transforms[i].write_datagram(me);
00332   }
00333 
00334   me.add_uint16(_vertex_morphs.size());
00335   for(i = 0; i < (int)_vertex_morphs.size(); i++){
00336     _vertex_morphs[i].write_datagram(me);
00337   }
00338 
00339   me.add_uint16(_normal_morphs.size());
00340   for(i = 0; i < (int)_normal_morphs.size(); i++){
00341     _normal_morphs[i].write_datagram(me);
00342   }
00343 
00344   me.add_uint16(_texcoord_morphs.size());
00345   for(i = 0; i < (int)_texcoord_morphs.size(); i++){
00346     _texcoord_morphs[i].write_datagram(me);
00347   }
00348 
00349   me.add_uint16(_color_morphs.size());
00350   for(i = 0; i < (int)_color_morphs.size(); i++){
00351     _color_morphs[i].write_datagram(me);
00352   }
00353 
00354   //Original Coordinates for vertices, colors, normals and textures
00355   WRITE_PTA(manager, me, IPD_Vertexf::write_datagram, _orig_coords)
00356   WRITE_PTA(manager, me, IPD_Normalf::write_datagram, _orig_norms)
00357   WRITE_PTA(manager, me, IPD_Colorf::write_datagram, _orig_colors)
00358   WRITE_PTA(manager, me, IPD_TexCoordf::write_datagram, _orig_texcoords)
00359 }
00360 
00361 ////////////////////////////////////////////////////////////////////
00362 //     Function: ComputedVertices::fillin
00363 //       Access: Protected
00364 //  Description: Function that reads out of the datagram (or asks
00365 //               manager to read) all of the data that is needed to
00366 //               re-create this object and stores it in the appropiate
00367 //               place
00368 ////////////////////////////////////////////////////////////////////
00369 void ComputedVertices::
00370 fillin(DatagramIterator& scan, BamReader* manager)
00371 {
00372   int i, size;
00373 
00374   size = scan.get_uint16();
00375   for(i = 0; i < size; i++){
00376     VertexTransform vt;
00377     vt.read_datagram(scan);
00378      _transforms.push_back(vt);
00379   }
00380 
00381   size = scan.get_uint16();
00382   for(i = 0; i < size; i++){
00383     ComputedVerticesMorphVertex vm;
00384     vm.read_datagram(scan);
00385     _vertex_morphs.push_back(vm);
00386   }
00387 
00388   size = scan.get_uint16();
00389   for(i = 0; i < size; i++){
00390     ComputedVerticesMorphNormal nm;
00391     nm.read_datagram(scan);
00392     _normal_morphs.push_back(nm);
00393   }
00394 
00395   size = scan.get_uint16();
00396   for(i = 0; i < size; i++){
00397     ComputedVerticesMorphTexCoord tm;
00398     tm.read_datagram(scan);
00399     _texcoord_morphs.push_back(tm);
00400   }
00401 
00402   size = scan.get_uint16();
00403   for(i = 0; i < size; i++){
00404     ComputedVerticesMorphColor cm;
00405     cm.read_datagram(scan);
00406     _color_morphs.push_back(cm);
00407   }
00408 
00409   //Original Coordinates for vertices, colors, normals and textures
00410   READ_PTA(manager, scan, IPD_Vertexf::read_datagram, _orig_coords)
00411   READ_PTA(manager, scan, IPD_Normalf::read_datagram, _orig_norms)
00412   READ_PTA(manager, scan, IPD_Colorf::read_datagram, _orig_colors)
00413   READ_PTA(manager, scan, IPD_TexCoordf::read_datagram, _orig_texcoords)
00414 }
00415 
00416 ////////////////////////////////////////////////////////////////////
00417 //     Function: ComputedVertices::make_ComputedVertices
00418 //       Access: Protected
00419 //  Description: Factory method to generate a ComputedVertices object
00420 ////////////////////////////////////////////////////////////////////
00421 TypedWritable* ComputedVertices::
00422 make_ComputedVertices(const FactoryParams &params)
00423 {
00424   ComputedVertices *me = new ComputedVertices;
00425   DatagramIterator scan;
00426   BamReader *manager;
00427 
00428   parse_params(params, scan, manager);
00429   me->fillin(scan, manager);
00430   return me;
00431 }
00432 
00433 ////////////////////////////////////////////////////////////////////
00434 //     Function: ComputedVertices::register_with_factory
00435 //       Access: Public, Static
00436 //  Description: Factory method to generate a ComputedVertices object
00437 ////////////////////////////////////////////////////////////////////
00438 void ComputedVertices::
00439 register_with_read_factory(void)
00440 {
00441   BamReader::get_factory()->register_factory(get_class_type(), make_ComputedVertices);
00442 }
00443 
00444 
00445 
00446 
00447 

Generated on Fri May 2 00:35:25 2003 for Panda by doxygen1.3