00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "clipPlaneAttrib.h"
00020 #include "pandaNode.h"
00021 #include "graphicsStateGuardianBase.h"
00022 #include "bamReader.h"
00023 #include "bamWriter.h"
00024 #include "datagram.h"
00025 #include "datagramIterator.h"
00026
00027 TypeHandle ClipPlaneAttrib::_type_handle;
00028
00029
00030
00031
00032
00033
00034
00035 CPT(RenderAttrib) ClipPlaneAttrib::
00036 make_all_off() {
00037 ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
00038 attrib->_operation = O_set;
00039 return return_new(attrib);
00040 }
00041
00042
00043
00044
00045
00046
00047
00048 CPT(RenderAttrib) ClipPlaneAttrib::
00049 make(ClipPlaneAttrib::Operation op, PlaneNode *plane) {
00050 ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
00051 attrib->_operation = op;
00052 attrib->_planes.push_back(plane);
00053 return return_new(attrib);
00054 }
00055
00056
00057
00058
00059
00060
00061
00062 CPT(RenderAttrib) ClipPlaneAttrib::
00063 make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2) {
00064 ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
00065 attrib->_operation = op;
00066 attrib->_planes.push_back(plane1);
00067 attrib->_planes.push_back(plane2);
00068
00069 attrib->_planes.sort();
00070 return return_new(attrib);
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 CPT(RenderAttrib) ClipPlaneAttrib::
00080 make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
00081 PlaneNode *plane3) {
00082 ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
00083 attrib->_operation = op;
00084 attrib->_planes.push_back(plane1);
00085 attrib->_planes.push_back(plane2);
00086 attrib->_planes.push_back(plane3);
00087
00088 attrib->_planes.sort();
00089 return return_new(attrib);
00090 }
00091
00092
00093
00094
00095
00096
00097
00098 CPT(RenderAttrib) ClipPlaneAttrib::
00099 make(ClipPlaneAttrib::Operation op, PlaneNode *plane1, PlaneNode *plane2,
00100 PlaneNode *plane3, PlaneNode *plane4) {
00101 ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
00102 attrib->_operation = op;
00103 attrib->_planes.push_back(plane1);
00104 attrib->_planes.push_back(plane2);
00105 attrib->_planes.push_back(plane3);
00106 attrib->_planes.push_back(plane4);
00107
00108 attrib->_planes.sort();
00109 return return_new(attrib);
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 bool ClipPlaneAttrib::
00119 has_plane(PlaneNode *plane) const {
00120 return _planes.find(plane) != _planes.end();
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 void ClipPlaneAttrib::
00133 issue(GraphicsStateGuardianBase *gsg) const {
00134 gsg->issue_clip_plane(this);
00135 }
00136
00137
00138
00139
00140
00141
00142 void ClipPlaneAttrib::
00143 output(ostream &out) const {
00144 out << get_type() << ":";
00145 if (_operation == O_set && _planes.empty()) {
00146 out << "all off";
00147 } else {
00148 switch (_operation) {
00149 case O_set:
00150 out << "set";
00151 break;
00152 case O_add:
00153 out << "add";
00154 break;
00155 case O_remove:
00156 out << "remove";
00157 break;
00158 }
00159
00160 Planes::const_iterator li;
00161 for (li = _planes.begin(); li != _planes.end(); ++li) {
00162 PlaneNode *plane = (*li);
00163 out << " " << *plane;
00164 }
00165 }
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 int ClipPlaneAttrib::
00184 compare_to_impl(const RenderAttrib *other) const {
00185 const ClipPlaneAttrib *ta;
00186 DCAST_INTO_R(ta, other, 0);
00187
00188 if (_operation != ta->_operation) {
00189 return (int)_operation - (int)ta->_operation;
00190 }
00191
00192 Planes::const_iterator li = _planes.begin();
00193 Planes::const_iterator oli = ta->_planes.begin();
00194
00195 while (li != _planes.end() && oli != ta->_planes.end()) {
00196 PlaneNode *plane = (*li);
00197 PlaneNode *other_plane = (*oli);
00198
00199 if (plane != other_plane) {
00200 return plane < other_plane ? -1 : 1;
00201 }
00202
00203 ++li;
00204 ++oli;
00205 }
00206
00207 if (li != _planes.end()) {
00208 return 1;
00209 }
00210 if (oli != ta->_planes.end()) {
00211 return -1;
00212 }
00213
00214 return 0;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 CPT(RenderAttrib) ClipPlaneAttrib::
00235 compose_impl(const RenderAttrib *other) const {
00236 const ClipPlaneAttrib *ta;
00237 DCAST_INTO_R(ta, other, 0);
00238
00239 if (ta->_operation == O_set) {
00240
00241 return ta;
00242 }
00243
00244 if (_operation == ta->_operation) {
00245
00246
00247 return do_add(ta, _operation);
00248
00249 } else if (ta->_operation == O_remove) {
00250
00251
00252 return do_remove(ta, _operation);
00253
00254 } else if (_operation == O_remove) {
00255
00256 return ta;
00257
00258 } else {
00259
00260 return do_add(ta, _operation);
00261 }
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 CPT(RenderAttrib) ClipPlaneAttrib::
00274 invert_compose_impl(const RenderAttrib *other) const {
00275
00276
00277
00278 return other;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 RenderAttrib *ClipPlaneAttrib::
00293 make_default_impl() const {
00294 return new ClipPlaneAttrib;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304 CPT(RenderAttrib) ClipPlaneAttrib::
00305 do_add(const ClipPlaneAttrib *other, ClipPlaneAttrib::Operation op) const {
00306 Planes::const_iterator ai = _planes.begin();
00307 Planes::const_iterator bi = other->_planes.begin();
00308
00309
00310 ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
00311 new_attrib->_operation = op;
00312 back_insert_iterator<Planes> result =
00313 back_inserter(new_attrib->_planes);
00314
00315 while (ai != _planes.end() && bi != other->_planes.end()) {
00316 if ((*ai) < (*bi)) {
00317
00318
00319 *result = *ai;
00320 ++ai;
00321 ++result;
00322 } else if ((*bi) < (*ai)) {
00323
00324
00325 *result = *bi;
00326 ++bi;
00327 ++result;
00328 } else {
00329
00330 *result = *ai;
00331 ++ai;
00332 ++bi;
00333 ++result;
00334 }
00335 }
00336
00337 while (ai != _planes.end()) {
00338 *result = *ai;
00339 ++ai;
00340 ++result;
00341 }
00342
00343 while (bi != other->_planes.end()) {
00344 *result = *bi;
00345 ++bi;
00346 ++result;
00347 }
00348
00349 return return_new(new_attrib);
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359 CPT(RenderAttrib) ClipPlaneAttrib::
00360 do_remove(const ClipPlaneAttrib *other, ClipPlaneAttrib::Operation op) const {
00361 Planes::const_iterator ai = _planes.begin();
00362 Planes::const_iterator bi = other->_planes.begin();
00363
00364
00365 ClipPlaneAttrib *new_attrib = new ClipPlaneAttrib;
00366 new_attrib->_operation = op;
00367 back_insert_iterator<Planes> result =
00368 back_inserter(new_attrib->_planes);
00369
00370 while (ai != _planes.end() && bi != other->_planes.end()) {
00371 if ((*ai) < (*bi)) {
00372
00373
00374 *result = *ai;
00375 ++ai;
00376 ++result;
00377 } else if ((*bi) < (*ai)) {
00378
00379
00380 ++bi;
00381 } else {
00382
00383 ++ai;
00384 ++bi;
00385 }
00386 }
00387
00388 while (ai != _planes.end()) {
00389 *result = *ai;
00390 ++ai;
00391 ++result;
00392 }
00393
00394 return return_new(new_attrib);
00395 }
00396
00397
00398
00399
00400
00401
00402
00403 void ClipPlaneAttrib::
00404 register_with_read_factory() {
00405 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00406 }
00407
00408
00409
00410
00411
00412
00413
00414 void ClipPlaneAttrib::
00415 write_datagram(BamWriter *manager, Datagram &dg) {
00416 RenderAttrib::write_datagram(manager, dg);
00417
00418 dg.add_int8((int)_operation);
00419 PN_uint16 num_planes = _planes.size();
00420 nassertv(num_planes == _planes.size());
00421 dg.add_uint16(num_planes);
00422
00423 Planes::const_iterator li;
00424 for (li = _planes.begin(); li != _planes.end(); ++li) {
00425 PlaneNode *plane = (*li);
00426 manager->write_pointer(dg, plane);
00427 }
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437 int ClipPlaneAttrib::
00438 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00439 int pi = RenderAttrib::complete_pointers(p_list, manager);
00440
00441 Planes::iterator li;
00442 for (li = _planes.begin(); li != _planes.end(); ++li) {
00443 PlaneNode *node;
00444 DCAST_INTO_R(node, p_list[pi++], pi);
00445 (*li) = node;
00446 }
00447
00448 return pi;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 TypedWritable *ClipPlaneAttrib::
00460 make_from_bam(const FactoryParams ¶ms) {
00461 ClipPlaneAttrib *attrib = new ClipPlaneAttrib;
00462 DatagramIterator scan;
00463 BamReader *manager;
00464
00465 parse_params(params, scan, manager);
00466 attrib->fillin(scan, manager);
00467
00468 return attrib;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478 void ClipPlaneAttrib::
00479 fillin(DatagramIterator &scan, BamReader *manager) {
00480 RenderAttrib::fillin(scan, manager);
00481
00482 _operation = (Operation)scan.get_int8();
00483 int num_planes = scan.get_uint16();
00484
00485 for (int i = 0; i < num_planes; i++) {
00486 manager->read_pointer(scan);
00487 _planes.push_back(NULL);
00488 }
00489 }