00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "fltBead.h"
00016 #include "fltRecordReader.h"
00017 #include "fltRecordWriter.h"
00018 #include "fltTransformGeneralMatrix.h"
00019 #include "fltTransformPut.h"
00020 #include "fltTransformRotateAboutEdge.h"
00021 #include "fltTransformRotateAboutPoint.h"
00022 #include "fltTransformScale.h"
00023 #include "fltTransformTranslate.h"
00024 #include "fltTransformRotateScale.h"
00025 #include "config_flt.h"
00026
00027 #include "dcast.h"
00028
00029 #include <assert.h>
00030
00031 TypeHandle FltBead::_type_handle;
00032
00033
00034
00035
00036
00037
00038 FltBead::
00039 FltBead(FltHeader *header) : FltRecord(header) {
00040 _has_transform = false;
00041 _transform = LMatrix4d::ident_mat();
00042 _replicate_count = 0;
00043 }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 bool FltBead::
00054 has_transform() const {
00055 return _has_transform;
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065 const LMatrix4d &FltBead::
00066 get_transform() const {
00067 return _has_transform ? _transform : LMatrix4d::ident_mat();
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 void FltBead::
00079 set_transform(const LMatrix4d &mat) {
00080 clear_transform();
00081 FltTransformGeneralMatrix *step = new FltTransformGeneralMatrix(_header);
00082 step->set_matrix(mat);
00083 add_transform_step(step);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 void FltBead::
00093 clear_transform() {
00094 _has_transform = false;
00095 _transform = LMatrix4d::ident_mat();
00096 _transform_steps.clear();
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 int FltBead::
00110 get_num_transform_steps() const {
00111 return _transform_steps.size();
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121 FltTransformRecord *FltBead::
00122 get_transform_step(int n) {
00123 nassertr(n >= 0 && n < (int)_transform_steps.size(),
00124 (FltTransformRecord *)NULL);
00125 return _transform_steps[n];
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135 const FltTransformRecord *FltBead::
00136 get_transform_step(int n) const {
00137 nassertr(n >= 0 && n < (int)_transform_steps.size(),
00138 (const FltTransformRecord *)NULL);
00139 return _transform_steps[n];
00140 }
00141
00142
00143
00144
00145
00146
00147
00148 void FltBead::
00149 add_transform_step(FltTransformRecord *record) {
00150 if (!_has_transform) {
00151 _has_transform = true;
00152 _transform = record->get_matrix();
00153 } else {
00154 _transform = record->get_matrix() * _transform;
00155 }
00156 _transform_steps.push_back(record);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 int FltBead::
00170 get_replicate_count() const {
00171 return _replicate_count;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 void FltBead::
00183 set_replicate_count(int count) {
00184 _replicate_count = count;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 bool FltBead::
00196 extract_record(FltRecordReader &reader) {
00197 if (!FltRecord::extract_record(reader)) {
00198 return false;
00199 }
00200 return true;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 bool FltBead::
00213 extract_ancillary(FltRecordReader &reader) {
00214 FltTransformRecord *step = (FltTransformRecord *)NULL;
00215
00216 switch (reader.get_opcode()) {
00217 case FO_transform_matrix:
00218 return extract_transform_matrix(reader);
00219
00220 case FO_general_matrix:
00221 step = new FltTransformGeneralMatrix(_header);
00222 break;
00223
00224 case FO_put:
00225 step = new FltTransformPut(_header);
00226 break;
00227
00228 case FO_rotate_about_edge:
00229 step = new FltTransformRotateAboutEdge(_header);
00230 break;
00231
00232 case FO_rotate_about_point:
00233 step = new FltTransformRotateAboutPoint(_header);
00234 break;
00235
00236 case FO_scale:
00237 step = new FltTransformScale(_header);
00238 break;
00239
00240 case FO_translate:
00241 step = new FltTransformTranslate(_header);
00242 break;
00243
00244 case FO_rotate_and_scale:
00245 step = new FltTransformRotateScale(_header);
00246 break;
00247
00248 case FO_replicate:
00249 return extract_replicate_count(reader);
00250
00251 default:
00252 return FltRecord::extract_ancillary(reader);
00253 }
00254
00255
00256 nassertr(step != (FltTransformRecord *)NULL, false);
00257 if (!step->extract_record(reader)) {
00258 return false;
00259 }
00260 _transform_steps.push_back(DCAST(FltTransformRecord, step));
00261
00262 return true;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 bool FltBead::
00274 build_record(FltRecordWriter &writer) const {
00275 if (!FltRecord::build_record(writer)) {
00276 return false;
00277 }
00278 return true;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288 FltError FltBead::
00289 write_ancillary(FltRecordWriter &writer) const {
00290 if (_has_transform) {
00291 FltError result = write_transform(writer);
00292 if (result != FE_ok) {
00293 return result;
00294 }
00295 }
00296 if (_replicate_count != 0) {
00297 FltError result = write_replicate_count(writer);
00298 if (result != FE_ok) {
00299 return result;
00300 }
00301 }
00302
00303
00304 return FltRecord::write_ancillary(writer);
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 bool FltBead::
00317 extract_transform_matrix(FltRecordReader &reader) {
00318 nassertr(reader.get_opcode() == FO_transform_matrix, false);
00319 DatagramIterator &iterator = reader.get_iterator();
00320
00321 LMatrix4d matrix;
00322 for (int r = 0; r < 4; r++) {
00323 for (int c = 0; c < 4; c++) {
00324 matrix(r, c) = iterator.get_be_float32();
00325 }
00326 }
00327 check_remaining_size(iterator);
00328
00329 _transform_steps.clear();
00330 _has_transform = true;
00331 _transform = matrix;
00332
00333 return true;
00334 }
00335
00336
00337
00338
00339
00340
00341 bool FltBead::
00342 extract_replicate_count(FltRecordReader &reader) {
00343 nassertr(reader.get_opcode() == FO_replicate, false);
00344 DatagramIterator &iterator = reader.get_iterator();
00345
00346 _replicate_count = iterator.get_be_int16();
00347 iterator.skip_bytes(2);
00348
00349 check_remaining_size(iterator);
00350 return true;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 FltError FltBead::
00360 write_transform(FltRecordWriter &writer) const {
00361
00362 writer.set_opcode(FO_transform_matrix);
00363 Datagram &datagram = writer.update_datagram();
00364
00365 for (int r = 0; r < 4; r++) {
00366 for (int c = 0; c < 4; c++) {
00367 datagram.add_be_float32(_transform(r, c));
00368 }
00369 }
00370
00371 FltError result = writer.advance();
00372 if (result != FE_ok) {
00373 return result;
00374 }
00375
00376
00377 Transforms::const_iterator ti;
00378 for (ti = _transform_steps.begin(); ti != _transform_steps.end(); ++ti) {
00379 if (!(*ti)->build_record(writer)) {
00380 assert(!flt_error_abort);
00381 return FE_invalid_record;
00382 }
00383 FltError result = writer.advance();
00384 if (result != FE_ok) {
00385 return result;
00386 }
00387 }
00388
00389 return FE_ok;
00390 }
00391
00392
00393
00394
00395
00396
00397 FltError FltBead::
00398 write_replicate_count(FltRecordWriter &writer) const {
00399 if (_replicate_count != 0) {
00400 writer.set_opcode(FO_replicate);
00401 Datagram &datagram = writer.update_datagram();
00402
00403 datagram.add_be_int16(_replicate_count);
00404 datagram.pad_bytes(2);
00405
00406 FltError result = writer.advance();
00407 if (result != FE_ok) {
00408 return result;
00409 }
00410 }
00411
00412 return FE_ok;
00413 }