00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "geomTristrips.h"
00016 #include "geomTriangles.h"
00017 #include "geomVertexRewriter.h"
00018 #include "pStatTimer.h"
00019 #include "bamReader.h"
00020 #include "bamWriter.h"
00021 #include "graphicsStateGuardianBase.h"
00022
00023 TypeHandle GeomTristrips::_type_handle;
00024
00025
00026
00027
00028
00029
00030 GeomTristrips::
00031 GeomTristrips(GeomTristrips::UsageHint usage_hint) :
00032 GeomPrimitive(usage_hint)
00033 {
00034 }
00035
00036
00037
00038
00039
00040
00041 GeomTristrips::
00042 GeomTristrips(const GeomTristrips ©) :
00043 GeomPrimitive(copy)
00044 {
00045 }
00046
00047
00048
00049
00050
00051
00052 GeomTristrips::
00053 ~GeomTristrips() {
00054 }
00055
00056
00057
00058
00059
00060
00061 PT(GeomPrimitive) GeomTristrips::
00062 make_copy() const {
00063 return new GeomTristrips(*this);
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 GeomPrimitive::PrimitiveType GeomTristrips::
00078 get_primitive_type() const {
00079 return PT_polygons;
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 int GeomTristrips::
00090 get_geom_rendering() const {
00091 if (is_indexed()) {
00092 return GR_triangle_strip | GR_indexed_other;
00093 } else {
00094 return GR_triangle_strip;
00095 }
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 int GeomTristrips::
00108 get_num_unused_vertices_per_primitive() const {
00109 return 2;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 bool GeomTristrips::
00119 draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader,
00120 bool force) const {
00121 return gsg->draw_tristrips(reader, force);
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 CPT(GeomPrimitive) GeomTristrips::
00139 decompose_impl() const {
00140 PT(GeomTriangles) triangles = new GeomTriangles(get_usage_hint());
00141 triangles->set_shade_model(get_shade_model());
00142 CPTA_int ends = get_ends();
00143
00144 int num_vertices = get_num_vertices();
00145
00146
00147
00148
00149
00150 if (get_shade_model() == SM_flat_first_vertex) {
00151
00152
00153 int vi = -2;
00154 int li = 0;
00155 while (li < (int)ends.size()) {
00156
00157 vi += 2;
00158 int end = ends[li];
00159 nassertr(vi + 2 <= end, NULL);
00160 int v0 = get_vertex(vi);
00161 ++vi;
00162 int v1 = get_vertex(vi);
00163 ++vi;
00164 bool reversed = false;
00165 while (vi < end) {
00166 int v2 = get_vertex(vi);
00167 ++vi;
00168 if (reversed) {
00169 if (v0 != v1 && v0 != v2 && v1 != v2) {
00170 triangles->add_vertex(v0);
00171 triangles->add_vertex(v2);
00172 triangles->add_vertex(v1);
00173 triangles->close_primitive();
00174 }
00175 reversed = false;
00176 } else {
00177 if (v0 != v1 && v0 != v2 && v1 != v2) {
00178 triangles->add_vertex(v0);
00179 triangles->add_vertex(v1);
00180 triangles->add_vertex(v2);
00181 triangles->close_primitive();
00182 }
00183 reversed = true;
00184 }
00185 v0 = v1;
00186 v1 = v2;
00187 }
00188 ++li;
00189 }
00190 nassertr(vi == num_vertices, NULL);
00191
00192 } else {
00193
00194
00195 int vi = -2;
00196 int li = 0;
00197 while (li < (int)ends.size()) {
00198
00199 vi += 2;
00200 int end = ends[li];
00201 nassertr(vi + 2 <= end, NULL);
00202 int v0 = get_vertex(vi);
00203 ++vi;
00204 int v1 = get_vertex(vi);
00205 ++vi;
00206 bool reversed = false;
00207 while (vi < end) {
00208 int v2 = get_vertex(vi);
00209 if (reversed) {
00210 if (v0 != v1 && v0 != v2 && v1 != v2) {
00211 triangles->add_vertex(v1);
00212 triangles->add_vertex(v0);
00213 triangles->add_vertex(v2);
00214 triangles->close_primitive();
00215 }
00216 reversed = false;
00217 } else {
00218 if (v0 != v1 && v0 != v2 && v1 != v2) {
00219 triangles->add_vertex(v0);
00220 triangles->add_vertex(v1);
00221 triangles->add_vertex(v2);
00222 triangles->close_primitive();
00223 }
00224 reversed = true;
00225 }
00226 ++vi;
00227 v0 = v1;
00228 v1 = v2;
00229 }
00230 ++li;
00231 }
00232 nassertr(vi == num_vertices, NULL);
00233 }
00234
00235 return triangles.p();
00236 }
00237
00238
00239
00240
00241
00242
00243 CPT(GeomPrimitive) GeomTristrips::
00244 doubleside_impl() const {
00245
00246
00247 return decompose_impl()->doubleside();
00248 }
00249
00250
00251
00252
00253
00254
00255 CPT(GeomPrimitive) GeomTristrips::
00256 reverse_impl() const {
00257
00258
00259 return decompose_impl()->reverse();
00260 }
00261
00262
00263
00264
00265
00266
00267 CPT(GeomVertexArrayData) GeomTristrips::
00268 rotate_impl() const {
00269
00270
00271
00272
00273
00274 CPTA_int ends = get_ends();
00275
00276 PT(GeomVertexArrayData) new_vertices = make_index_data();
00277 new_vertices->set_num_rows(get_num_vertices());
00278
00279 if (is_indexed()) {
00280 CPT(GeomVertexArrayData) vertices = get_vertices();
00281 GeomVertexReader from(vertices, 0);
00282 GeomVertexWriter to(new_vertices, 0);
00283
00284 int begin = 0;
00285 int last_added = 0;
00286 CPTA_int::const_iterator ei;
00287 for (ei = ends.begin(); ei != ends.end(); ++ei) {
00288 int end = (*ei);
00289 int num_vertices = end - begin;
00290
00291 if (begin != 0) {
00292
00293 to.set_data1i(last_added);
00294 from.set_row_unsafe(end - 1);
00295 to.set_data1i(from.get_data1i());
00296 begin += 2;
00297 }
00298
00299
00300
00301 nassertr((num_vertices & 1) == 0, NULL);
00302 for (int vi = end - 1; vi >= begin; --vi) {
00303 from.set_row_unsafe(vi);
00304 last_added = from.get_data1i();
00305 to.set_data1i(last_added);
00306 }
00307
00308 begin = end;
00309 }
00310
00311 nassertr(to.is_at_end(), NULL);
00312
00313 } else {
00314
00315 int first_vertex = get_first_vertex();
00316 GeomVertexWriter to(new_vertices, 0);
00317
00318 int begin = 0;
00319 int last_added = 0;
00320 CPTA_int::const_iterator ei;
00321 for (ei = ends.begin(); ei != ends.end(); ++ei) {
00322 int end = (*ei);
00323 int num_vertices = end - begin;
00324
00325 if (begin != 0) {
00326
00327 to.set_data1i(last_added);
00328 to.set_data1i(end - 1 + first_vertex);
00329 begin += 2;
00330 }
00331
00332
00333
00334 nassertr((num_vertices & 1) == 0, NULL);
00335 for (int vi = end - 1; vi >= begin; --vi) {
00336 last_added = vi + first_vertex;
00337 to.set_data1i(last_added);
00338 }
00339
00340 begin = end;
00341 }
00342
00343 nassertr(to.is_at_end(), NULL);
00344 }
00345 return new_vertices;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354 bool GeomTristrips::
00355 requires_unused_vertices() const {
00356 return true;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 void GeomTristrips::
00369 append_unused_vertices(GeomVertexArrayData *vertices, int vertex) {
00370 GeomVertexReader from(vertices, 0);
00371 from.set_row_unsafe(vertices->get_num_rows() - 1);
00372 int prev = from.get_data1i();
00373
00374 GeomVertexWriter to(vertices, 0);
00375 to.set_row_unsafe(vertices->get_num_rows());
00376
00377 to.add_data1i(prev);
00378 to.add_data1i(vertex);
00379 }
00380
00381
00382
00383
00384
00385
00386
00387 void GeomTristrips::
00388 register_with_read_factory() {
00389 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 TypedWritable *GeomTristrips::
00401 make_from_bam(const FactoryParams ¶ms) {
00402 GeomTristrips *object = new GeomTristrips(UH_unspecified);
00403 DatagramIterator scan;
00404 BamReader *manager;
00405
00406 parse_params(params, scan, manager);
00407 object->fillin(scan, manager);
00408
00409 return object;
00410 }