00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "geomTransformer.h"
00020 #include "geomNode.h"
00021 #include "renderState.h"
00022
00023
00024
00025
00026
00027
00028 GeomTransformer::
00029 GeomTransformer() {
00030 }
00031
00032
00033
00034
00035
00036
00037 GeomTransformer::
00038 ~GeomTransformer() {
00039 }
00040
00041
00042
00043
00044
00045
00046
00047
00048 bool GeomTransformer::
00049 transform_vertices(Geom *geom, const LMatrix4f &mat) {
00050 bool transformed = false;
00051
00052 nassertr(geom != (Geom *)NULL, false);
00053
00054 PTA_Vertexf coords;
00055 PTA_ushort index;
00056
00057 geom->get_coords(coords, index);
00058
00059 if (!coords.empty()) {
00060
00061
00062 SourceVertices sv;
00063 sv._mat = mat;
00064 sv._coords = coords;
00065
00066 PTA_Vertexf &new_coords = _vertices[sv];
00067
00068 if (new_coords.is_null()) {
00069
00070 new_coords.reserve(coords.size());
00071 PTA_Vertexf::const_iterator vi;
00072 for (vi = coords.begin(); vi != coords.end(); ++vi) {
00073 new_coords.push_back((*vi) * mat);
00074 }
00075 nassertr(new_coords.size() == coords.size(), false);
00076 }
00077
00078 geom->set_coords(new_coords, index);
00079 transformed = true;
00080 }
00081
00082
00083 PTA_Normalf norms;
00084 GeomBindType bind;
00085
00086 geom->get_normals(norms, bind, index);
00087
00088 if (bind != G_OFF) {
00089 SourceNormals sn;
00090 sn._mat = mat;
00091 sn._norms = norms;
00092
00093 PTA_Normalf &new_norms = _normals[sn];
00094
00095 if (new_norms.is_null()) {
00096
00097 new_norms.reserve(norms.size());
00098 PTA_Normalf::const_iterator ni;
00099 for (ni = norms.begin(); ni != norms.end(); ++ni) {
00100 Normalf new_norm = (*ni) * mat;
00101 new_norm.normalize();
00102 new_norms.push_back(new_norm);
00103 }
00104 nassertr(new_norms.size() == norms.size(), false);
00105 }
00106
00107 geom->set_normals(new_norms, bind, index);
00108 transformed = true;
00109 }
00110
00111 return transformed;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 bool GeomTransformer::
00127 transform_vertices(GeomNode *node, const LMatrix4f &mat) {
00128 bool any_changed = false;
00129
00130 GeomNode::CDWriter cdata(node->_cycler);
00131 GeomNode::Geoms::iterator gi;
00132 for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
00133 GeomNode::GeomEntry &entry = (*gi);
00134 PT(Geom) new_geom = entry._geom->make_copy();
00135 if (transform_vertices(new_geom, mat)) {
00136 entry._geom = new_geom;
00137 any_changed = true;
00138 }
00139 }
00140
00141 return any_changed;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 bool GeomTransformer::
00153 transform_texcoords(Geom *geom, const LMatrix4f &mat) {
00154 bool transformed = false;
00155
00156 nassertr(geom != (Geom *)NULL, false);
00157
00158 PTA_TexCoordf texcoords;
00159 GeomBindType bind;
00160 PTA_ushort index;
00161
00162 geom->get_texcoords(texcoords, bind, index);
00163
00164 if (bind != G_OFF) {
00165
00166
00167 SourceTexCoords stc;
00168 stc._mat = mat;
00169 stc._texcoords = texcoords;
00170
00171 PTA_TexCoordf &new_texcoords = _texcoords[stc];
00172
00173 if (new_texcoords.is_null()) {
00174
00175 new_texcoords.reserve(texcoords.size());
00176 PTA_TexCoordf::const_iterator tci;
00177 for (tci = texcoords.begin(); tci != texcoords.end(); ++tci) {
00178 const TexCoordf &tc = (*tci);
00179 LVecBase4f v4(tc[0], tc[1], 0.0f, 1.0f);
00180 v4 = v4 * mat;
00181 new_texcoords.push_back(TexCoordf(v4[0] / v4[3], v4[1] / v4[3]));
00182 }
00183 nassertr(new_texcoords.size() == texcoords.size(), false);
00184 }
00185
00186 geom->set_texcoords(new_texcoords, bind, index);
00187 transformed = true;
00188 }
00189
00190 return transformed;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 bool GeomTransformer::
00206 transform_texcoords(GeomNode *node, const LMatrix4f &mat) {
00207 bool any_changed = false;
00208
00209 GeomNode::CDWriter cdata(node->_cycler);
00210 GeomNode::Geoms::iterator gi;
00211 for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
00212 GeomNode::GeomEntry &entry = (*gi);
00213 PT(Geom) new_geom = entry._geom->make_copy();
00214 if (transform_texcoords(new_geom, mat)) {
00215 entry._geom = new_geom;
00216 any_changed = true;
00217 }
00218 }
00219
00220 return any_changed;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 bool GeomTransformer::
00232 set_color(Geom *geom, const Colorf &color) {
00233
00234
00235
00236
00237 PTA_Colorf &new_colors = _fcolors[color];
00238
00239 if (new_colors.is_null()) {
00240
00241 new_colors.push_back(color);
00242 }
00243
00244 geom->set_colors(new_colors, G_OVERALL);
00245 return true;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 bool GeomTransformer::
00258 set_color(GeomNode *node, const Colorf &color) {
00259 bool any_changed = false;
00260
00261 GeomNode::CDWriter cdata(node->_cycler);
00262 GeomNode::Geoms::iterator gi;
00263 for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
00264 GeomNode::GeomEntry &entry = (*gi);
00265 PT(Geom) new_geom = entry._geom->make_copy();
00266 if (set_color(new_geom, color)) {
00267 entry._geom = new_geom;
00268 any_changed = true;
00269 }
00270 }
00271
00272 return any_changed;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282 bool GeomTransformer::
00283 transform_colors(Geom *geom, const LVecBase4f &scale) {
00284 bool transformed = false;
00285
00286 nassertr(geom != (Geom *)NULL, false);
00287
00288 PTA_Colorf colors;
00289 GeomBindType bind;
00290 PTA_ushort index;
00291
00292 geom->get_colors(colors, bind, index);
00293
00294 if (bind != G_OFF) {
00295
00296
00297 SourceColors sc;
00298 sc._scale = scale;
00299 sc._colors = colors;
00300
00301 PTA_Colorf &new_colors = _tcolors[sc];
00302
00303 if (new_colors.is_null()) {
00304
00305 new_colors.reserve(colors.size());
00306 PTA_Colorf::const_iterator ci;
00307 for (ci = colors.begin(); ci != colors.end(); ++ci) {
00308 const Colorf &c = (*ci);
00309 Colorf transformed(c[0] * scale[0],
00310 c[1] * scale[1],
00311 c[2] * scale[2],
00312 c[3] * scale[3]);
00313 new_colors.push_back(transformed);
00314 }
00315 nassertr(new_colors.size() == colors.size(), false);
00316 }
00317
00318 geom->set_colors(new_colors, bind, index);
00319 transformed = true;
00320 }
00321
00322 return transformed;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 bool GeomTransformer::
00337 transform_colors(GeomNode *node, const LVecBase4f &scale) {
00338 bool any_changed = false;
00339
00340 GeomNode::CDWriter cdata(node->_cycler);
00341 GeomNode::Geoms::iterator gi;
00342 for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
00343 GeomNode::GeomEntry &entry = (*gi);
00344 PT(Geom) new_geom = entry._geom->make_copy();
00345 if (transform_colors(new_geom, scale)) {
00346 entry._geom = new_geom;
00347 any_changed = true;
00348 }
00349 }
00350
00351 return any_changed;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 bool GeomTransformer::
00363 apply_state(GeomNode *node, const RenderState *state) {
00364 bool any_changed = false;
00365
00366 GeomNode::CDWriter cdata(node->_cycler);
00367 GeomNode::Geoms::iterator gi;
00368 for (gi = cdata->_geoms.begin(); gi != cdata->_geoms.end(); ++gi) {
00369 GeomNode::GeomEntry &entry = (*gi);
00370 CPT(RenderState) new_state = state->compose(entry._state);
00371 if (entry._state != new_state) {
00372 entry._state = new_state;
00373 any_changed = true;
00374 }
00375 }
00376
00377 return any_changed;
00378 }