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

pandatool/src/flt/fltBead.cxx

Go to the documentation of this file.
00001 // Filename: fltBead.cxx
00002 // Created by:  drose (24Aug00)
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 #include "fltBead.h"
00020 #include "fltRecordReader.h"
00021 #include "fltRecordWriter.h"
00022 #include "fltTransformGeneralMatrix.h"
00023 #include "fltTransformPut.h"
00024 #include "fltTransformRotateAboutEdge.h"
00025 #include "fltTransformRotateAboutPoint.h"
00026 #include "fltTransformScale.h"
00027 #include "fltTransformTranslate.h"
00028 #include "fltTransformRotateScale.h"
00029 #include "config_flt.h"
00030 
00031 #include "dcast.h"
00032 
00033 #include <assert.h>
00034 
00035 TypeHandle FltBead::_type_handle;
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: FltBead::Constructor
00039 //       Access: Public
00040 //  Description:
00041 ////////////////////////////////////////////////////////////////////
00042 FltBead::
00043 FltBead(FltHeader *header) : FltRecord(header) {
00044   _has_transform = false;
00045   _transform = LMatrix4d::ident_mat();
00046   _replicate_count = 0;
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: FltBead::has_transform
00051 //       Access: Public
00052 //  Description: Returns true if the bead has been transformed, false
00053 //               otherwise.  If this returns true, get_transform()
00054 //               will return the single-precision net transformation,
00055 //               and get_num_transform_steps() will return nonzero.
00056 ////////////////////////////////////////////////////////////////////
00057 bool FltBead::
00058 has_transform() const {
00059   return _has_transform;
00060 }
00061 
00062 ////////////////////////////////////////////////////////////////////
00063 //     Function: FltBead::get_transform
00064 //       Access: Public
00065 //  Description: Returns the single-precision 4x4 matrix that
00066 //               represents the transform applied to this bead, or the
00067 //               identity matrix if the bead has not been transformed.
00068 ////////////////////////////////////////////////////////////////////
00069 const LMatrix4d &FltBead::
00070 get_transform() const {
00071   return _has_transform ? _transform : LMatrix4d::ident_mat();
00072 }
00073 
00074 ////////////////////////////////////////////////////////////////////
00075 //     Function: FltBead::set_transform
00076 //       Access: Public
00077 //  Description: Replaces the transform matrix on this bead.  This
00078 //               implicitly removes all of the transform steps added
00079 //               previously, and replaces them with a single 4x4
00080 //               general matrix transform step.
00081 ////////////////////////////////////////////////////////////////////
00082 void FltBead::
00083 set_transform(const LMatrix4d &mat) {
00084   clear_transform();
00085   FltTransformGeneralMatrix *step = new FltTransformGeneralMatrix(_header);
00086   step->set_matrix(mat);
00087   add_transform_step(step);
00088 }
00089 
00090 ////////////////////////////////////////////////////////////////////
00091 //     Function: FltBead::clear_transform
00092 //       Access: Public
00093 //  Description: Removes any transform matrix and all transform steps
00094 //               on this bead.
00095 ////////////////////////////////////////////////////////////////////
00096 void FltBead::
00097 clear_transform() {
00098   _has_transform = false;
00099   _transform = LMatrix4d::ident_mat();
00100   _transform_steps.clear();
00101 }
00102 
00103 ////////////////////////////////////////////////////////////////////
00104 //     Function: FltBead::get_num_transform_steps
00105 //       Access: Public
00106 //  Description: Returns the number of individual steps that define
00107 //               the net transform on this bead as returned by
00108 //               set_transform().  Each step is a single
00109 //               transformation; the concatenation of all
00110 //               transformations will produce the matrix represented
00111 //               by set_transform().
00112 ////////////////////////////////////////////////////////////////////
00113 int FltBead::
00114 get_num_transform_steps() const {
00115   return _transform_steps.size();
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: FltBead::get_transform_step
00120 //       Access: Public
00121 //  Description: Returns the nth individual step that defines
00122 //               the net transform on this bead.  See
00123 //               get_num_transform_steps().
00124 ////////////////////////////////////////////////////////////////////
00125 FltTransformRecord *FltBead::
00126 get_transform_step(int n) {
00127   nassertr(n >= 0 && n < (int)_transform_steps.size(),
00128            (FltTransformRecord *)NULL);
00129   return _transform_steps[n];
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //     Function: FltBead::get_transform_step
00134 //       Access: Public
00135 //  Description: Returns the nth individual step that defines
00136 //               the net transform on this bead.  See
00137 //               get_num_transform_steps().
00138 ////////////////////////////////////////////////////////////////////
00139 const FltTransformRecord *FltBead::
00140 get_transform_step(int n) const {
00141   nassertr(n >= 0 && n < (int)_transform_steps.size(),
00142            (const FltTransformRecord *)NULL);
00143   return _transform_steps[n];
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: FltBead::add_transform_step
00148 //       Access: Public
00149 //  Description: Applies the indicated transform step to the net
00150 //               transformation applied to the bead.
00151 ////////////////////////////////////////////////////////////////////
00152 void FltBead::
00153 add_transform_step(FltTransformRecord *record) {
00154   if (!_has_transform) {
00155     _has_transform = true;
00156     _transform = record->get_matrix();
00157   } else {
00158     _transform = record->get_matrix() * _transform;
00159   }
00160   _transform_steps.push_back(record);
00161 }
00162 
00163 ////////////////////////////////////////////////////////////////////
00164 //     Function: FltBead::get_replicate_count
00165 //       Access: Public
00166 //  Description: Returns the replicate count of this bead.  If this is
00167 //               nonzero, it means that the bead is implicitly copied
00168 //               this number of additional times (for replicate_count
00169 //               + 1 total copies), applying the transform on this
00170 //               bead for each copy.  In this case, the transform does
00171 //               *not* apply to the initial copy of the bead.
00172 ////////////////////////////////////////////////////////////////////
00173 int FltBead::
00174 get_replicate_count() const {
00175   return _replicate_count;
00176 }
00177 
00178 ////////////////////////////////////////////////////////////////////
00179 //     Function: FltBead::set_replicate_count
00180 //       Access: Public
00181 //  Description: Changes the replicate count of this bead.  If you are
00182 //               setting the replicate count to some nonzero number,
00183 //               you must also set a transform on the bead.  See
00184 //               set_replicate_count().
00185 ////////////////////////////////////////////////////////////////////
00186 void FltBead::
00187 set_replicate_count(int count) {
00188   _replicate_count = count;
00189 }
00190 
00191 ////////////////////////////////////////////////////////////////////
00192 //     Function: FltBead::extract_record
00193 //       Access: Protected, Virtual
00194 //  Description: Fills in the information in this bead based on the
00195 //               information given in the indicated datagram, whose
00196 //               opcode has already been read.  Returns true on
00197 //               success, false if the datagram is invalid.
00198 ////////////////////////////////////////////////////////////////////
00199 bool FltBead::
00200 extract_record(FltRecordReader &reader) {
00201   if (!FltRecord::extract_record(reader)) {
00202     return false;
00203   }
00204   return true;
00205 }
00206 
00207 ////////////////////////////////////////////////////////////////////
00208 //     Function: FltBead::extract_ancillary
00209 //       Access: Protected, Virtual
00210 //  Description: Checks whether the given bead, which follows this
00211 //               bead sequentially in the file, is an ancillary record
00212 //               of this bead.  If it is, extracts the relevant
00213 //               information and returns true; otherwise, leaves it
00214 //               alone and returns false.
00215 ////////////////////////////////////////////////////////////////////
00216 bool FltBead::
00217 extract_ancillary(FltRecordReader &reader) {
00218   FltTransformRecord *step = (FltTransformRecord *)NULL;
00219 
00220   switch (reader.get_opcode()) {
00221   case FO_transform_matrix:
00222     return extract_transform_matrix(reader);
00223 
00224   case FO_general_matrix:
00225     step = new FltTransformGeneralMatrix(_header);
00226     break;
00227 
00228   case FO_put:
00229     step = new FltTransformPut(_header);
00230     break;
00231 
00232   case FO_rotate_about_edge:
00233     step = new FltTransformRotateAboutEdge(_header);
00234     break;
00235 
00236   case FO_rotate_about_point:
00237     step = new FltTransformRotateAboutPoint(_header);
00238     break;
00239 
00240   case FO_scale:
00241     step = new FltTransformScale(_header);
00242     break;
00243 
00244   case FO_translate:
00245     step = new FltTransformTranslate(_header);
00246     break;
00247 
00248   case FO_rotate_and_scale:
00249     step = new FltTransformRotateScale(_header);
00250     break;
00251 
00252   case FO_replicate:
00253     return extract_replicate_count(reader);
00254 
00255   default:
00256     return FltRecord::extract_ancillary(reader);
00257   }
00258 
00259   // A transform step.
00260   nassertr(step != (FltTransformRecord *)NULL, false);
00261   if (!step->extract_record(reader)) {
00262     return false;
00263   }
00264   _transform_steps.push_back(DCAST(FltTransformRecord, step));
00265 
00266   return true;
00267 }
00268 
00269 ////////////////////////////////////////////////////////////////////
00270 //     Function: FltBead::build_record
00271 //       Access: Protected, Virtual
00272 //  Description: Fills up the current record on the FltRecordWriter with
00273 //               data for this record, but does not advance the
00274 //               writer.  Returns true on success, false if there is
00275 //               some error.
00276 ////////////////////////////////////////////////////////////////////
00277 bool FltBead::
00278 build_record(FltRecordWriter &writer) const {
00279   if (!FltRecord::build_record(writer)) {
00280     return false;
00281   }
00282   return true;
00283 }
00284 
00285 ////////////////////////////////////////////////////////////////////
00286 //     Function: FltBead::write_ancillary
00287 //       Access: Protected, Virtual
00288 //  Description: Writes whatever ancillary records are required for
00289 //               this record.  Returns FE_ok on success, or something
00290 //               else if there is some error.
00291 ////////////////////////////////////////////////////////////////////
00292 FltError FltBead::
00293 write_ancillary(FltRecordWriter &writer) const {
00294   if (_has_transform) {
00295     FltError result = write_transform(writer);
00296     if (result != FE_ok) {
00297       return result;
00298     }
00299   }
00300   if (_replicate_count != 0) {
00301     FltError result = write_replicate_count(writer);
00302     if (result != FE_ok) {
00303       return result;
00304     }
00305   }
00306 
00307 
00308   return FltRecord::write_ancillary(writer);
00309 }
00310 
00311 ////////////////////////////////////////////////////////////////////
00312 //     Function: FltBead::extract_transform_matrix
00313 //       Access: Private
00314 //  Description: Reads a transform matrix ancillary bead.  This
00315 //               defines the net transformation that has been applied
00316 //               to the bead, and precedes the set of individual
00317 //               transform steps that define how this net transform
00318 //               was computed.
00319 ////////////////////////////////////////////////////////////////////
00320 bool FltBead::
00321 extract_transform_matrix(FltRecordReader &reader) {
00322   nassertr(reader.get_opcode() == FO_transform_matrix, false);
00323   DatagramIterator &iterator = reader.get_iterator();
00324 
00325   LMatrix4d matrix;
00326   for (int r = 0; r < 4; r++) {
00327     for (int c = 0; c < 4; c++) {
00328       matrix(r, c) = iterator.get_be_float32();
00329     }
00330   }
00331   check_remaining_size(iterator);
00332 
00333   _transform_steps.clear();
00334   _has_transform = true;
00335   _transform = matrix;
00336 
00337   return true;
00338 }
00339 
00340 ////////////////////////////////////////////////////////////////////
00341 //     Function: FltBead::extract_replicate_count
00342 //       Access: Private
00343 //  Description: Reads a replicate count ancillary bead.
00344 ////////////////////////////////////////////////////////////////////
00345 bool FltBead::
00346 extract_replicate_count(FltRecordReader &reader) {
00347   nassertr(reader.get_opcode() == FO_replicate, false);
00348   DatagramIterator &iterator = reader.get_iterator();
00349 
00350   _replicate_count = iterator.get_be_int16();
00351   iterator.skip_bytes(2);
00352 
00353   check_remaining_size(iterator);
00354   return true;
00355 }
00356 
00357 ////////////////////////////////////////////////////////////////////
00358 //     Function: FltBead::write_transform
00359 //       Access: Private
00360 //  Description: Writes out the transformation and all of its defining
00361 //               steps.
00362 ////////////////////////////////////////////////////////////////////
00363 FltError FltBead::
00364 write_transform(FltRecordWriter &writer) const {
00365   // First, write out the initial transform indication.
00366   writer.set_opcode(FO_transform_matrix);
00367   Datagram &datagram = writer.update_datagram();
00368 
00369   for (int r = 0; r < 4; r++) {
00370     for (int c = 0; c < 4; c++) {
00371       datagram.add_be_float32(_transform(r, c));
00372     }
00373   }
00374 
00375   FltError result = writer.advance();
00376   if (result != FE_ok) {
00377     return result;
00378   }
00379 
00380   // Now, write out each of the steps of the transform.
00381   Transforms::const_iterator ti;
00382   for (ti = _transform_steps.begin(); ti != _transform_steps.end(); ++ti) {
00383     if (!(*ti)->build_record(writer)) {
00384       assert(!flt_error_abort);
00385       return FE_invalid_record;
00386     }
00387     FltError result = writer.advance();
00388     if (result != FE_ok) {
00389       return result;
00390     }
00391   }
00392 
00393   return FE_ok;
00394 }
00395 
00396 ////////////////////////////////////////////////////////////////////
00397 //     Function: FltBead::write_replicate_count
00398 //       Access: Private
00399 //  Description: Writes out the replicate count, if needed.
00400 ////////////////////////////////////////////////////////////////////
00401 FltError FltBead::
00402 write_replicate_count(FltRecordWriter &writer) const {
00403   if (_replicate_count != 0) {
00404     writer.set_opcode(FO_replicate);
00405     Datagram &datagram = writer.update_datagram();
00406 
00407     datagram.add_be_int16(_replicate_count);
00408     datagram.pad_bytes(2);
00409 
00410     FltError result = writer.advance();
00411     if (result != FE_ok) {
00412       return result;
00413     }
00414   }
00415 
00416   return FE_ok;
00417 }

Generated on Fri May 2 03:19:01 2003 for Panda-Tool by doxygen1.3