00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "texMatrixAttrib.h"
00016 #include "graphicsStateGuardianBase.h"
00017 #include "dcast.h"
00018 #include "bamReader.h"
00019 #include "bamWriter.h"
00020 #include "datagram.h"
00021 #include "datagramIterator.h"
00022 #include "textureStagePool.h"
00023
00024 CPT(RenderAttrib) TexMatrixAttrib::_empty_attrib;
00025 TypeHandle TexMatrixAttrib::_type_handle;
00026 int TexMatrixAttrib::_attrib_slot;
00027
00028
00029
00030
00031
00032
00033 TexMatrixAttrib::
00034 ~TexMatrixAttrib() {
00035 }
00036
00037
00038
00039
00040
00041
00042
00043 CPT(RenderAttrib) TexMatrixAttrib::
00044 make() {
00045
00046
00047 if (_empty_attrib == (RenderAttrib *)NULL) {
00048 _empty_attrib = return_new(new TexMatrixAttrib);
00049 }
00050
00051 return _empty_attrib;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061 CPT(RenderAttrib) TexMatrixAttrib::
00062 make(const LMatrix4 &mat) {
00063 pgraph_cat.warning()
00064 << "Using deprecated TexMatrixAttrib interface.\n";
00065 if (mat == LMatrix4::ident_mat()) {
00066 return make();
00067 }
00068 CPT(TransformState) transform = TransformState::make_mat(mat);
00069 return make(TextureStage::get_default(), transform);
00070 }
00071
00072
00073
00074
00075
00076
00077
00078 CPT(RenderAttrib) TexMatrixAttrib::
00079 make(TextureStage *stage, const TransformState *transform) {
00080 return DCAST(TexMatrixAttrib, make())->add_stage(stage, transform);
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090 CPT(RenderAttrib) TexMatrixAttrib::
00091 make_default() {
00092 return return_new(new TexMatrixAttrib);
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102 CPT(RenderAttrib) TexMatrixAttrib::
00103 add_stage(TextureStage *stage, const TransformState *transform,
00104 int override) const {
00105 TexMatrixAttrib *attrib = new TexMatrixAttrib(*this);
00106 Stages::iterator si = attrib->_stages.insert(StageNode(stage)).first;
00107 (*si)._transform = transform;
00108 (*si)._override = override;
00109
00110 return return_new(attrib);
00111 }
00112
00113
00114
00115
00116
00117
00118
00119 CPT(RenderAttrib) TexMatrixAttrib::
00120 remove_stage(TextureStage *stage) const {
00121 TexMatrixAttrib *attrib = new TexMatrixAttrib(*this);
00122 attrib->_stages.erase(StageNode(stage));
00123 return return_new(attrib);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 const LMatrix4 &TexMatrixAttrib::
00133 get_mat() const {
00134 return get_mat(TextureStage::get_default());
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 bool TexMatrixAttrib::
00144 is_empty() const {
00145 return _stages.empty();
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 bool TexMatrixAttrib::
00157 has_stage(TextureStage *stage) const {
00158 Stages::const_iterator mi = _stages.find(StageNode(stage));
00159 return (mi != _stages.end());
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 int TexMatrixAttrib::
00169 get_num_stages() const {
00170 return _stages.size();
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180 TextureStage *TexMatrixAttrib::
00181 get_stage(int n) const {
00182 nassertr(n >= 0 && n < (int)_stages.size(), NULL);
00183 return _stages[n]._stage;
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193 const LMatrix4 &TexMatrixAttrib::
00194 get_mat(TextureStage *stage) const {
00195 return get_transform(stage)->get_mat();
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205 CPT(TransformState) TexMatrixAttrib::
00206 get_transform(TextureStage *stage) const {
00207 Stages::const_iterator mi = _stages.find(StageNode(stage));
00208 if (mi != _stages.end()) {
00209 return (*mi)._transform;
00210 }
00211 return TransformState::make_identity();
00212 }
00213
00214
00215
00216
00217
00218
00219 void TexMatrixAttrib::
00220 output(ostream &out) const {
00221 out << get_type() << ":";
00222
00223 Stages::const_iterator mi;
00224 for (mi = _stages.begin(); mi != _stages.end(); ++mi) {
00225 const StageNode &sn = (*mi);
00226 out << " " << sn._stage->get_name() << "(" << *sn._transform << ")";
00227 if (sn._override != 0) {
00228 out << "^" << sn._override;
00229 }
00230 }
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 int TexMatrixAttrib::
00249 compare_to_impl(const RenderAttrib *other) const {
00250 const TexMatrixAttrib *ta;
00251 DCAST_INTO_R(ta, other, 0);
00252
00253 Stages::const_iterator ai, bi;
00254 ai = _stages.begin();
00255 bi = ta->_stages.begin();
00256 while (ai != _stages.end() && bi != ta->_stages.end()) {
00257 if ((*ai) < (*bi)) {
00258
00259 return -1;
00260
00261 } else if ((*bi) < (*ai)) {
00262
00263 return 1;
00264
00265 } else {
00266
00267 ++ai;
00268 ++bi;
00269 }
00270 }
00271
00272 if (bi != ta->_stages.end()) {
00273
00274 return -1;
00275 }
00276
00277 if (ai != _stages.end()) {
00278
00279 return 1;
00280 }
00281
00282 return 0;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 size_t TexMatrixAttrib::
00296 get_hash_impl() const {
00297 size_t hash = 0;
00298 Stages::const_iterator si;
00299 for (si = _stages.begin(); si != _stages.end(); ++si) {
00300 const StageNode &sn = (*si);
00301
00302 hash = pointer_hash::add_hash(hash, sn._stage);
00303 hash = pointer_hash::add_hash(hash, sn._transform);
00304 hash = int_hash::add_hash(hash, sn._override);
00305 }
00306
00307 return hash;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 CPT(RenderAttrib) TexMatrixAttrib::
00328 compose_impl(const RenderAttrib *other) const {
00329 const TexMatrixAttrib *ta;
00330 DCAST_INTO_R(ta, other, 0);
00331
00332
00333
00334
00335 TexMatrixAttrib *attrib = new TexMatrixAttrib;
00336
00337 Stages::const_iterator ai, bi;
00338 ai = _stages.begin();
00339 bi = ta->_stages.begin();
00340 while (ai != _stages.end() && bi != ta->_stages.end()) {
00341 if ((*ai)._stage < (*bi)._stage) {
00342
00343 attrib->_stages.insert(attrib->_stages.end(), *ai);
00344 ++ai;
00345
00346 } else if ((*bi)._stage < (*ai)._stage) {
00347
00348 attrib->_stages.insert(attrib->_stages.end(), *bi);
00349 ++bi;
00350
00351 } else {
00352
00353 if ((*ai)._override == (*bi)._override) {
00354
00355 CPT(TransformState) new_transform = (*ai)._transform->compose((*bi)._transform);
00356 StageNode sn((*ai)._stage);
00357 sn._transform = new_transform;
00358 sn._override = (*ai)._override;
00359 attrib->_stages.insert(attrib->_stages.end(), sn);
00360 } else if ((*ai)._override < (*bi)._override) {
00361
00362 attrib->_stages.insert(attrib->_stages.end(), *bi);
00363 } else {
00364
00365 attrib->_stages.insert(attrib->_stages.end(), *ai);
00366 }
00367
00368 ++ai;
00369 ++bi;
00370 }
00371 }
00372
00373 while (ai != _stages.end()) {
00374
00375 attrib->_stages.insert(attrib->_stages.end(), *ai);
00376 ++ai;
00377 }
00378
00379 while (bi != ta->_stages.end()) {
00380
00381 attrib->_stages.insert(attrib->_stages.end(), *bi);
00382 ++bi;
00383 }
00384
00385 return return_new(attrib);
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 CPT(RenderAttrib) TexMatrixAttrib::
00398 invert_compose_impl(const RenderAttrib *other) const {
00399 const TexMatrixAttrib *ta;
00400 DCAST_INTO_R(ta, other, 0);
00401
00402
00403
00404
00405 TexMatrixAttrib *attrib = new TexMatrixAttrib;
00406
00407 Stages::const_iterator ai, bi;
00408 ai = _stages.begin();
00409 bi = ta->_stages.begin();
00410 while (ai != _stages.end() && bi != ta->_stages.end()) {
00411 if ((*ai)._stage < (*bi)._stage) {
00412
00413 CPT(TransformState) inv_a =
00414 (*ai)._transform->invert_compose(TransformState::make_identity());
00415 StageNode sn((*ai)._stage);
00416 sn._transform = inv_a;
00417 sn._override = (*ai)._override;
00418 attrib->_stages.insert(attrib->_stages.end(), sn);
00419 ++ai;
00420
00421 } else if ((*bi)._stage < (*ai)._stage) {
00422
00423 attrib->_stages.insert(attrib->_stages.end(), *bi);
00424 ++bi;
00425
00426 } else {
00427
00428 if ((*ai)._override == (*bi)._override) {
00429
00430 CPT(TransformState) new_transform = (*ai)._transform->invert_compose((*bi)._transform);
00431 StageNode sn((*ai)._stage);
00432 sn._transform = new_transform;
00433 sn._override = (*ai)._override;
00434 attrib->_stages.insert(attrib->_stages.end(), sn);
00435
00436 } else if ((*ai)._override < (*bi)._override) {
00437
00438 attrib->_stages.insert(attrib->_stages.end(), *bi);
00439
00440 } else {
00441
00442 CPT(TransformState) inv_a =
00443 (*ai)._transform->invert_compose(TransformState::make_identity());
00444 StageNode sn((*ai)._stage);
00445 sn._transform = inv_a;
00446 sn._override = (*ai)._override;
00447 attrib->_stages.insert(attrib->_stages.end(), sn);
00448 }
00449
00450 ++ai;
00451 ++bi;
00452 }
00453 }
00454
00455 while (ai != _stages.end()) {
00456
00457 CPT(TransformState) inv_a =
00458 (*ai)._transform->invert_compose(TransformState::make_identity());
00459 StageNode sn((*ai)._stage);
00460 sn._transform = inv_a;
00461 sn._override = (*ai)._override;
00462 attrib->_stages.insert(attrib->_stages.end(), sn);
00463 ++ai;
00464 }
00465
00466 while (bi != ta->_stages.end()) {
00467
00468 attrib->_stages.insert(attrib->_stages.end(), *bi);
00469 ++bi;
00470 }
00471
00472 return return_new(attrib);
00473 }
00474
00475
00476
00477
00478
00479
00480 CPT(RenderAttrib) TexMatrixAttrib::
00481 get_auto_shader_attrib_impl(const RenderState *state) const {
00482
00483
00484
00485
00486
00487 TexMatrixAttrib *attrib = new TexMatrixAttrib;
00488
00489 Stages::const_iterator ai;
00490 for (ai = _stages.begin(); ai != _stages.end(); ++ai) {
00491 StageNode sn((*ai)._stage);
00492 sn._transform = TransformState::make_identity();
00493 attrib->_stages.insert(attrib->_stages.end(), sn);
00494 }
00495
00496 return return_new(attrib);
00497 }
00498
00499
00500
00501
00502
00503
00504
00505 void TexMatrixAttrib::
00506 register_with_read_factory() {
00507 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00508 }
00509
00510
00511
00512
00513
00514
00515
00516 void TexMatrixAttrib::
00517 write_datagram(BamWriter *manager, Datagram &dg) {
00518 RenderAttrib::write_datagram(manager, dg);
00519
00520 dg.add_uint16(_stages.size());
00521
00522 Stages::const_iterator si;
00523 for (si = _stages.begin(); si != _stages.end(); ++si) {
00524 const StageNode &sn = (*si);
00525
00526 manager->write_pointer(dg, sn._stage);
00527 manager->write_pointer(dg, sn._transform);
00528 dg.add_int32(sn._override);
00529 }
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539 int TexMatrixAttrib::
00540 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00541 int pi = RenderAttrib::complete_pointers(p_list, manager);
00542
00543 for (size_t sni = 0; sni < _stages.size(); ++sni) {
00544
00545 PT(TextureStage) ts = DCAST(TextureStage, p_list[pi++]);
00546 ts = TextureStagePool::get_stage(ts);
00547
00548 const TransformState *transform = DCAST(TransformState, p_list[pi++]);
00549
00550 StageNode &sn = _stages[sni];
00551 sn._stage = ts;
00552 sn._transform = transform;
00553 }
00554 _stages.sort();
00555
00556 return pi;
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 TypedWritable *TexMatrixAttrib::
00568 make_from_bam(const FactoryParams ¶ms) {
00569 TexMatrixAttrib *attrib = new TexMatrixAttrib;
00570 DatagramIterator scan;
00571 BamReader *manager;
00572
00573 parse_params(params, scan, manager);
00574 attrib->fillin(scan, manager);
00575
00576 return attrib;
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586 void TexMatrixAttrib::
00587 fillin(DatagramIterator &scan, BamReader *manager) {
00588 RenderAttrib::fillin(scan, manager);
00589
00590 size_t num_stages = scan.get_uint16();
00591 for (size_t i = 0; i < num_stages; i++) {
00592 manager->read_pointer(scan);
00593 manager->read_pointer(scan);
00594 int override = 0;
00595 if (manager->get_file_minor_ver() >= 24) {
00596 override = scan.get_int32();
00597 }
00598
00599 StageNode sn(NULL);
00600 sn._override = override;
00601 _stages.push_back(sn);
00602 }
00603 }