00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "cardMaker.h"
00016 #include "geomNode.h"
00017 #include "transformState.h"
00018 #include "colorAttrib.h"
00019 #include "sceneGraphReducer.h"
00020 #include "geom.h"
00021 #include "geomTristrips.h"
00022 #include "geomVertexWriter.h"
00023 #include "geomVertexFormat.h"
00024
00025
00026
00027
00028
00029
00030 void CardMaker::
00031 reset() {
00032 set_frame(0.0f, 1.0f, 0.0f, 1.0f);
00033 set_uv_range(LTexCoord(0.0f, 0.0f), LTexCoord(1.0f, 1.0f));
00034
00035 _has_color = false;
00036 _color.set(1.0f, 1.0f, 1.0f, 1.0f);
00037
00038 _has_normals = true;
00039 _source_geometry = (PandaNode *)NULL;
00040 _source_frame.set(0.0f, 0.0f, 0.0f, 0.0f);
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050 PT(PandaNode) CardMaker::
00051 generate() {
00052 if (_source_geometry != (PandaNode *)NULL) {
00053 return rescale_source_geometry();
00054 }
00055
00056 PT(GeomNode) gnode = new GeomNode(get_name());
00057
00058 CPT(GeomVertexFormat) format;
00059 if (_has_normals) {
00060 if (_has_uvs) {
00061 if (_has_3d_uvs) {
00062 format = GeomVertexFormat::register_format
00063 (new GeomVertexArrayFormat
00064 (InternalName::get_vertex(), 3,
00065 GeomEnums::NT_stdfloat, GeomEnums::C_point,
00066 InternalName::get_normal(), 3,
00067 GeomEnums::NT_stdfloat, GeomEnums::C_vector,
00068 InternalName::get_texcoord(), 3,
00069 GeomEnums::NT_stdfloat, GeomEnums::C_texcoord));
00070 } else {
00071 format = GeomVertexFormat::get_v3n3t2();
00072 }
00073 } else {
00074 format = GeomVertexFormat::get_v3n3();
00075 }
00076 } else {
00077 if (_has_uvs) {
00078 if (_has_3d_uvs) {
00079 format = GeomVertexFormat::register_format
00080 (new GeomVertexArrayFormat
00081 (InternalName::get_vertex(), 3,
00082 GeomEnums::NT_stdfloat, GeomEnums::C_point,
00083 InternalName::get_texcoord(), 3,
00084 GeomEnums::NT_stdfloat, GeomEnums::C_texcoord));
00085 } else {
00086 format = GeomVertexFormat::get_v3t2();
00087 }
00088 } else {
00089 format = GeomVertexFormat::get_v3();
00090 }
00091 }
00092
00093 PT(GeomVertexData) vdata = new GeomVertexData
00094 ("card", format, Geom::UH_static);
00095 GeomVertexWriter vertex(vdata, InternalName::get_vertex());
00096
00097 vertex.add_data3(_ul_pos);
00098 vertex.add_data3(_ll_pos);
00099 vertex.add_data3(_ur_pos);
00100 vertex.add_data3(_lr_pos);
00101
00102 if (_has_uvs) {
00103 GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
00104 texcoord.add_data3(_ul_tex);
00105 texcoord.add_data3(_ll_tex);
00106 texcoord.add_data3(_ur_tex);
00107 texcoord.add_data3(_lr_tex);
00108 }
00109
00110 if (_has_normals) {
00111 GeomVertexWriter normal(vdata, InternalName::get_normal());
00112 LVector3 n;
00113 n = (_ll_pos - _ul_pos).cross(_ur_pos - _ul_pos);
00114 n.normalize();
00115 normal.add_data3(n);
00116 n = (_lr_pos - _ll_pos).cross(_ul_pos - _ll_pos);
00117 n.normalize();
00118 normal.add_data3(n);
00119 n = (_ul_pos - _ur_pos).cross(_lr_pos - _ur_pos);
00120 n.normalize();
00121 normal.add_data3(n);
00122 n = (_ur_pos - _lr_pos).cross(_ll_pos - _lr_pos);
00123 n.normalize();
00124 normal.add_data3(n);
00125 }
00126
00127 PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
00128 strip->set_shade_model(Geom::SM_uniform);
00129 strip->add_next_vertices(4);
00130 strip->close_primitive();
00131
00132 PT(Geom) geom = new Geom(vdata);
00133 geom->add_primitive(strip);
00134
00135 CPT(RenderState) state = RenderState::make_empty();
00136 if (_has_color) {
00137 state = RenderState::make(ColorAttrib::make_flat(_color));
00138 }
00139
00140 gnode->add_geom(geom, state);
00141
00142 return gnode.p();
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 void CardMaker::
00155 set_uv_range(const LTexCoord3 &ll, const LTexCoord3 &lr, const LTexCoord3 &ur, const LTexCoord3 &ul) {
00156 _ll_tex = ll;
00157 _lr_tex = lr;
00158 _ur_tex = ur;
00159 _ul_tex = ul;
00160 _has_uvs = true;
00161 _has_3d_uvs = true;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 void CardMaker::
00174 set_uv_range(const LTexCoord &ll, const LTexCoord &lr, const LTexCoord &ur, const LTexCoord &ul) {
00175 _ll_tex.set(ll[0], ll[1], 0.0f);
00176 _lr_tex.set(lr[0], lr[1], 0.0f);
00177 _ur_tex.set(ur[0], ur[1], 0.0f);
00178 _ul_tex.set(ul[0], ul[1], 0.0f);
00179 _has_uvs = true;
00180 _has_3d_uvs = false;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 void CardMaker::
00193 set_uv_range(const LTexCoord &ll, const LTexCoord &ur) {
00194 _ll_tex.set(ll[0], ll[1], 0.0f);
00195 _lr_tex.set(ur[0], ll[1], 0.0f);
00196 _ur_tex.set(ur[0], ur[1], 0.0f);
00197 _ul_tex.set(ll[0], ur[1], 0.0f);
00198 _has_uvs = true;
00199 _has_3d_uvs = false;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 void CardMaker::
00212 set_uv_range(const LVector4 &x, const LVector4 &y, const LVector4 &z) {
00213 _ll_tex.set(x[0], y[0], z[0]);
00214 _lr_tex.set(x[1], y[1], z[1]);
00215 _ur_tex.set(x[2], y[2], z[2]);
00216 _ul_tex.set(x[3], y[3], z[3]);
00217 _has_uvs = true;
00218 _has_3d_uvs = true;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 void CardMaker::
00228 set_uv_range_cube(int face) {
00229 LVector4 varya(-1, 1, 1, -1);
00230 LVector4 varyb(-1, -1, 1, 1);
00231 LVector4 fixed( 1, 1, 1, 1);
00232 switch(face) {
00233 case 0: set_uv_range( fixed, -varyb, -varya); break;
00234 case 1: set_uv_range(-fixed, -varyb, varya); break;
00235 case 2: set_uv_range( varya, fixed, varyb); break;
00236 case 3: set_uv_range( varya, -fixed, -varyb); break;
00237 case 4: set_uv_range( varya, -varyb, fixed); break;
00238 case 5: set_uv_range(-varya, -varyb, -fixed); break;
00239 }
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 void CardMaker::
00250 set_uv_range(const Texture *tex) {
00251 nassertv(tex->get_texture_type() == Texture::TT_2d_texture);
00252 int nonpadx = tex->get_x_size() - tex->get_pad_x_size();
00253 int nonpady = tex->get_y_size() - tex->get_pad_y_size();
00254 double maxu = (nonpadx*1.0) / tex->get_x_size();
00255 double maxv = (nonpady*1.0) / tex->get_y_size();
00256 set_uv_range(LTexCoord(0.0,0.0), LTexCoord(maxu,maxv));
00257 }
00258
00259
00260
00261
00262
00263
00264
00265 PT(PandaNode) CardMaker::
00266 rescale_source_geometry() {
00267 PT(PandaNode) root = _source_geometry->copy_subgraph();
00268
00269
00270 LVector3 frame_max = _ll_pos.fmax(_lr_pos.fmax(_ur_pos.fmax(_ul_pos)));
00271 LVector3 frame_min = _ll_pos.fmin(_lr_pos.fmin(_ur_pos.fmax(_ul_pos)));
00272 LVector3 frame_ctr = (frame_max + frame_min) * 0.5f;
00273
00274 LVector3 geom_center((_source_frame[0] + _source_frame[1]) * 0.5f,
00275 frame_ctr[1],
00276 (_source_frame[2] + _source_frame[3]) * 0.5f);
00277
00278 LVector3 scale((frame_max[0] - frame_min[0]) / (_source_frame[1] - _source_frame[0]),
00279 0.0,
00280 (frame_max[2] - frame_min[2]) / (_source_frame[3] - _source_frame[2]));
00281
00282 LVector3 trans = frame_ctr - geom_center;
00283
00284 CPT(TransformState) transform =
00285 TransformState::make_pos_hpr_scale(trans, LPoint3(0.0f, 0.0f, 0.0f), scale);
00286 root->set_transform(transform);
00287
00288 if (_has_color) {
00289 root->set_attrib(ColorAttrib::make_flat(_color));
00290 }
00291
00292
00293 SceneGraphReducer reducer;
00294 reducer.apply_attribs(root);
00295 reducer.flatten(root, ~0);
00296
00297 return root;
00298 }