00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "geomTriangles.h"
00016 #include "geomVertexRewriter.h"
00017 #include "pStatTimer.h"
00018 #include "bamReader.h"
00019 #include "bamWriter.h"
00020 #include "graphicsStateGuardianBase.h"
00021
00022 TypeHandle GeomTriangles::_type_handle;
00023
00024
00025
00026
00027
00028
00029 GeomTriangles::
00030 GeomTriangles(GeomTriangles::UsageHint usage_hint) :
00031 GeomPrimitive(usage_hint)
00032 {
00033 }
00034
00035
00036
00037
00038
00039
00040 GeomTriangles::
00041 GeomTriangles(const GeomTriangles ©) :
00042 GeomPrimitive(copy)
00043 {
00044 }
00045
00046
00047
00048
00049
00050
00051 GeomTriangles::
00052 ~GeomTriangles() {
00053 }
00054
00055
00056
00057
00058
00059
00060 PT(GeomPrimitive) GeomTriangles::
00061 make_copy() const {
00062 return new GeomTriangles(*this);
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 GeomPrimitive::PrimitiveType GeomTriangles::
00077 get_primitive_type() const {
00078 return PT_polygons;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 int GeomTriangles::
00093 get_num_vertices_per_primitive() const {
00094 return 3;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103 bool GeomTriangles::
00104 draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader,
00105 bool force) const {
00106 return gsg->draw_triangles(reader, force);
00107 }
00108
00109
00110
00111
00112
00113
00114 CPT(GeomPrimitive) GeomTriangles::
00115 doubleside_impl() const {
00116 Thread *current_thread = Thread::get_current_thread();
00117 PT(GeomTriangles) reversed = new GeomTriangles(*this);
00118
00119 GeomPrimitivePipelineReader from(this, current_thread);
00120
00121
00122
00123
00124
00125
00126
00127 bool needs_rotate = false;
00128 switch (from.get_shade_model()) {
00129 case SM_flat_first_vertex:
00130 case SM_flat_last_vertex:
00131 reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate());
00132 needs_rotate = true;
00133
00134 default:
00135 break;
00136 }
00137
00138
00139 for (int i = from.get_num_vertices() - 1; i >= 0; --i) {
00140 reversed->add_vertex(from.get_vertex(i));
00141 }
00142
00143
00144
00145 if (needs_rotate) {
00146 reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate());
00147 }
00148
00149 return reversed.p();
00150 }
00151
00152
00153
00154
00155
00156
00157 CPT(GeomPrimitive) GeomTriangles::
00158 reverse_impl() const {
00159 Thread *current_thread = Thread::get_current_thread();
00160 PT(GeomTriangles) reversed = new GeomTriangles(*this);
00161
00162 GeomPrimitivePipelineReader from(this, current_thread);
00163 reversed->clear_vertices();
00164
00165 for (int i = from.get_num_vertices() - 1; i >= 0; --i) {
00166 reversed->add_vertex(from.get_vertex(i));
00167 }
00168
00169 switch (from.get_shade_model()) {
00170 case SM_flat_first_vertex:
00171 reversed->set_shade_model(SM_flat_last_vertex);
00172 reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate());
00173 break;
00174
00175 case SM_flat_last_vertex:
00176 reversed->set_shade_model(SM_flat_first_vertex);
00177 reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate());
00178 break;
00179
00180 default:
00181 break;
00182 }
00183
00184 return reversed.p();
00185 }
00186
00187
00188
00189
00190
00191
00192 CPT(GeomVertexArrayData) GeomTriangles::
00193 rotate_impl() const {
00194
00195
00196
00197 ShadeModel shade_model = get_shade_model();
00198 int num_vertices = get_num_vertices();
00199
00200 PT(GeomVertexArrayData) new_vertices = make_index_data();
00201 new_vertices->set_num_rows(num_vertices);
00202
00203 if (is_indexed()) {
00204 CPT(GeomVertexArrayData) vertices = get_vertices();
00205 GeomVertexReader from(vertices, 0);
00206 GeomVertexWriter to(new_vertices, 0);
00207
00208 switch (shade_model) {
00209 case SM_flat_first_vertex:
00210
00211 {
00212 for (int begin = 0; begin < num_vertices; begin += 3) {
00213 from.set_row_unsafe(begin + 1);
00214 to.set_data1i(from.get_data1i());
00215 to.set_data1i(from.get_data1i());
00216 from.set_row_unsafe(begin);
00217 to.set_data1i(from.get_data1i());
00218 }
00219 }
00220 break;
00221
00222 case SM_flat_last_vertex:
00223
00224 {
00225 for (int begin = 0; begin < num_vertices; begin += 3) {
00226 from.set_row_unsafe(begin + 2);
00227 to.set_data1i(from.get_data1i());
00228 from.set_row_unsafe(begin);
00229 to.set_data1i(from.get_data1i());
00230 to.set_data1i(from.get_data1i());
00231 }
00232 }
00233 break;
00234
00235 default:
00236
00237 nassertr(false, vertices);
00238 }
00239
00240 nassertr(to.is_at_end(), NULL);
00241
00242 } else {
00243
00244 int first_vertex = get_first_vertex();
00245 GeomVertexWriter to(new_vertices, 0);
00246
00247 switch (shade_model) {
00248 case SM_flat_first_vertex:
00249
00250 {
00251 for (int begin = 0; begin < num_vertices; begin += 3) {
00252 to.set_data1i(begin + 1 + first_vertex);
00253 to.set_data1i(begin + 2 + first_vertex);
00254 to.set_data1i(begin + first_vertex);
00255 }
00256 }
00257 break;
00258
00259 case SM_flat_last_vertex:
00260
00261 {
00262 for (int begin = 0; begin < num_vertices; begin += 3) {
00263 to.set_data1i(begin + 2 + first_vertex);
00264 to.set_data1i(begin + first_vertex);
00265 to.set_data1i(begin + 1 + first_vertex);
00266 }
00267 }
00268 break;
00269
00270 default:
00271
00272 nassertr(false, NULL);
00273 }
00274
00275 nassertr(to.is_at_end(), NULL);
00276 }
00277
00278 return new_vertices;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287 void GeomTriangles::
00288 register_with_read_factory() {
00289 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 TypedWritable *GeomTriangles::
00301 make_from_bam(const FactoryParams ¶ms) {
00302 GeomTriangles *object = new GeomTriangles(UH_unspecified);
00303 DatagramIterator scan;
00304 BamReader *manager;
00305
00306 parse_params(params, scan, manager);
00307 object->fillin(scan, manager);
00308
00309 return object;
00310 }