Panda3D
cardMaker.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file cardMaker.cxx
10  * @author drose
11  * @date 2002-03-16
12  */
13 
14 #include "cardMaker.h"
15 #include "geomNode.h"
16 #include "transformState.h"
17 #include "colorAttrib.h"
18 #include "sceneGraphReducer.h"
19 #include "geom.h"
20 #include "geomTristrips.h"
21 #include "geomVertexWriter.h"
22 #include "geomVertexFormat.h"
23 
24 /**
25  * Resets all the parameters to their initial defaults.
26  */
28 reset() {
29  set_frame(0.0f, 1.0f, 0.0f, 1.0f);
30  set_uv_range(LTexCoord(0.0f, 0.0f), LTexCoord(1.0f, 1.0f));
31 
32  _has_color = false;
33  _color.set(1.0f, 1.0f, 1.0f, 1.0f);
34 
35  _has_normals = true;
36  _source_geometry = nullptr;
37  _source_frame.set(0.0f, 0.0f, 0.0f, 0.0f);
38 }
39 
40 
41 /**
42  * Generates a GeomNode that renders the specified geometry.
43  */
44 PT(PandaNode) CardMaker::
45 generate() {
46  if (_source_geometry != nullptr) {
47  return rescale_source_geometry();
48  }
49 
50  PT(GeomNode) gnode = new GeomNode(get_name());
51 
52  CPT(GeomVertexFormat) format;
53  if (_has_normals) {
54  if (_has_uvs) {
55  if (_has_3d_uvs) {
56  format = GeomVertexFormat::register_format
58  (InternalName::get_vertex(), 3,
59  GeomEnums::NT_stdfloat, GeomEnums::C_point,
60  InternalName::get_normal(), 3,
61  GeomEnums::NT_stdfloat, GeomEnums::C_normal,
62  InternalName::get_texcoord(), 3,
63  GeomEnums::NT_stdfloat, GeomEnums::C_texcoord));
64  } else {
66  }
67  } else {
68  format = GeomVertexFormat::get_v3n3();
69  }
70  } else {
71  if (_has_uvs) {
72  if (_has_3d_uvs) {
73  format = GeomVertexFormat::register_format
75  (InternalName::get_vertex(), 3,
76  GeomEnums::NT_stdfloat, GeomEnums::C_point,
77  InternalName::get_texcoord(), 3,
78  GeomEnums::NT_stdfloat, GeomEnums::C_texcoord));
79  } else {
80  format = GeomVertexFormat::get_v3t2();
81  }
82  } else {
83  format = GeomVertexFormat::get_v3();
84  }
85  }
86 
87  PT(GeomVertexData) vdata = new GeomVertexData
88  ("card", format, Geom::UH_static);
89  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
90 
91  vertex.add_data3(_ul_pos);
92  vertex.add_data3(_ll_pos);
93  vertex.add_data3(_ur_pos);
94  vertex.add_data3(_lr_pos);
95 
96  if (_has_uvs) {
97  GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
98  texcoord.add_data3(_ul_tex);
99  texcoord.add_data3(_ll_tex);
100  texcoord.add_data3(_ur_tex);
101  texcoord.add_data3(_lr_tex);
102  }
103 
104  if (_has_normals) {
105  GeomVertexWriter normal(vdata, InternalName::get_normal());
106  LVector3 n;
107  n = (_ll_pos - _ul_pos).cross(_ur_pos - _ul_pos);
108  n.normalize();
109  normal.add_data3(n);
110  n = (_lr_pos - _ll_pos).cross(_ul_pos - _ll_pos);
111  n.normalize();
112  normal.add_data3(n);
113  n = (_ul_pos - _ur_pos).cross(_lr_pos - _ur_pos);
114  n.normalize();
115  normal.add_data3(n);
116  n = (_ur_pos - _lr_pos).cross(_ll_pos - _lr_pos);
117  n.normalize();
118  normal.add_data3(n);
119  }
120 
121  PT(GeomTristrips) strip = new GeomTristrips(Geom::UH_static);
122  strip->set_shade_model(Geom::SM_uniform);
123  strip->add_next_vertices(4);
124  strip->close_primitive();
125 
126  PT(Geom) geom = new Geom(vdata);
127  geom->add_primitive(strip);
128 
129  CPT(RenderState) state = RenderState::make_empty();
130  if (_has_color) {
131  state = RenderState::make(ColorAttrib::make_flat(_color));
132  }
133 
134  gnode->add_geom(geom, state);
135 
136  return gnode;
137 }
138 
139 /**
140  * Sets the range of UV's that will be applied to the vertices. If
141  * set_has_uvs() is true (as it is by default), the vertices will be generated
142  * with the indicated range of UV's, which will be useful if a texture is
143  * applied.
144  */
146 set_uv_range(const LTexCoord3 &ll, const LTexCoord3 &lr, const LTexCoord3 &ur, const LTexCoord3 &ul) {
147  _ll_tex = ll;
148  _lr_tex = lr;
149  _ur_tex = ur;
150  _ul_tex = ul;
151  _has_uvs = true;
152  _has_3d_uvs = true;
153 }
154 
155 /**
156  * Sets the range of UV's that will be applied to the vertices. If
157  * set_has_uvs() is true (as it is by default), the vertices will be generated
158  * with the indicated range of UV's, which will be useful if a texture is
159  * applied.
160  */
162 set_uv_range(const LTexCoord &ll, const LTexCoord &lr, const LTexCoord &ur, const LTexCoord &ul) {
163  _ll_tex.set(ll[0], ll[1], 0.0f);
164  _lr_tex.set(lr[0], lr[1], 0.0f);
165  _ur_tex.set(ur[0], ur[1], 0.0f);
166  _ul_tex.set(ul[0], ul[1], 0.0f);
167  _has_uvs = true;
168  _has_3d_uvs = false;
169 }
170 
171 /**
172  * Sets the range of UV's that will be applied to the vertices. If
173  * set_has_uvs() is true (as it is by default), the vertices will be generated
174  * with the indicated range of UV's, which will be useful if a texture is
175  * applied.
176  */
178 set_uv_range(const LTexCoord &ll, const LTexCoord &ur) {
179  _ll_tex.set(ll[0], ll[1], 0.0f);
180  _lr_tex.set(ur[0], ll[1], 0.0f);
181  _ur_tex.set(ur[0], ur[1], 0.0f);
182  _ul_tex.set(ll[0], ur[1], 0.0f);
183  _has_uvs = true;
184  _has_3d_uvs = false;
185 }
186 
187 /**
188  * Sets the range of UV's that will be applied to the vertices. If
189  * set_has_uvs() is true (as it is by default), the vertices will be generated
190  * with the indicated range of UV's, which will be useful if a texture is
191  * applied.
192  */
194 set_uv_range(const LVector4 &x, const LVector4 &y, const LVector4 &z) {
195  _ll_tex.set(x[0], y[0], z[0]);
196  _lr_tex.set(x[1], y[1], z[1]);
197  _ur_tex.set(x[2], y[2], z[2]);
198  _ul_tex.set(x[3], y[3], z[3]);
199  _has_uvs = true;
200  _has_3d_uvs = true;
201 }
202 
203 /**
204  * Sets the range of UV's that will be applied to the vertices appropriately
205  * for a cube-map face.
206  */
208 set_uv_range_cube(int face) {
209  LVector4 varya(-1, 1, 1, -1);
210  LVector4 varyb(-1, -1, 1, 1);
211  LVector4 fixed( 1, 1, 1, 1);
212  switch(face) {
213  case 0: set_uv_range( fixed, -varyb, -varya); break; // positive_x
214  case 1: set_uv_range(-fixed, -varyb, varya); break; // negative_x
215  case 2: set_uv_range( varya, fixed, varyb); break; // positive_y
216  case 3: set_uv_range( varya, -fixed, -varyb); break; // negative_y
217  case 4: set_uv_range( varya, -varyb, fixed); break; // positive_z
218  case 5: set_uv_range(-varya, -varyb, -fixed); break; // negative_z
219  }
220 }
221 
222 /**
223  * Sets the range of UV's that will be applied to the vertices appropriately
224  * to show the non-pad region of the texture.
225  */
227 set_uv_range(const Texture *tex) {
228  nassertv(tex->get_texture_type() == Texture::TT_2d_texture);
229  int nonpadx = tex->get_x_size() - tex->get_pad_x_size();
230  int nonpady = tex->get_y_size() - tex->get_pad_y_size();
231  double maxu = (nonpadx*1.0) / tex->get_x_size();
232  double maxv = (nonpady*1.0) / tex->get_y_size();
233  set_uv_range(LTexCoord(0.0,0.0), LTexCoord(maxu,maxv));
234 }
235 
236 /**
237  * Generates the card by rescaling the source geometry appropriately.
238  */
239 PT(PandaNode) CardMaker::
240 rescale_source_geometry() {
241  PT(PandaNode) root = _source_geometry->copy_subgraph();
242 
243  // Determine the translate and scale appropriate for our geometry.
244  LVector3 frame_max = _ll_pos.fmax(_lr_pos.fmax(_ur_pos.fmax(_ul_pos)));
245  LVector3 frame_min = _ll_pos.fmin(_lr_pos.fmin(_ur_pos.fmax(_ul_pos)));
246  LVector3 frame_ctr = (frame_max + frame_min) * 0.5f;
247 
248  LVector3 geom_center((_source_frame[0] + _source_frame[1]) * 0.5f,
249  frame_ctr[1],
250  (_source_frame[2] + _source_frame[3]) * 0.5f);
251 
252  LVector3 scale((frame_max[0] - frame_min[0]) / (_source_frame[1] - _source_frame[0]),
253  0.0,
254  (frame_max[2] - frame_min[2]) / (_source_frame[3] - _source_frame[2]));
255 
256  LVector3 trans = frame_ctr - geom_center;
257 
258  CPT(TransformState) transform =
259  TransformState::make_pos_hpr_scale(trans, LPoint3(0.0f, 0.0f, 0.0f), scale);
260  root->set_transform(transform);
261 
262  if (_has_color) {
263  root->set_attrib(ColorAttrib::make_flat(_color));
264  }
265 
266  // Now flatten out the geometry as much as we can.
267  SceneGraphReducer reducer;
268  reducer.apply_attribs(root);
269  reducer.flatten(root, ~0);
270 
271  return root;
272 }
PT(PandaNode) CardMaker
Generates a GeomNode that renders the specified geometry.
Definition: cardMaker.cxx:44
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_uv_range_cube(int face)
Sets the range of UV's that will be applied to the vertices appropriately for a cube-map face.
Definition: cardMaker.cxx:208
void reset()
Resets all the parameters to their initial defaults.
Definition: cardMaker.cxx:28
void set_uv_range(const LTexCoord &ll, const LTexCoord &ur)
Sets the range of UV's that will be applied to the vertices.
Definition: cardMaker.cxx:178
void set_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Sets the size of the card.
Definition: cardMaker.I:52
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:34
Defines a series of triangle strips.
Definition: geomTristrips.h:23
This describes the structure of a single array within a Geom data.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This class defines the physical layout of the vertex data stored within a Geom.
static const GeomVertexFormat * get_v3t2()
Returns a standard vertex format with a 2-component texture coordinate pair and a 3-component vertex ...
static const GeomVertexFormat * get_v3n3t2()
Returns a standard vertex format with a 2-component texture coordinate pair, a 3-component normal,...
static const GeomVertexFormat * get_v3()
Returns a standard vertex format with just a 3-component vertex position.
static const GeomVertexFormat * get_v3n3()
Returns a standard vertex format with a 3-component normal and a 3-component vertex position.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void add_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row.
A container for geometry primitives.
Definition: geom.h:54
A basic node of the scene graph or data graph.
Definition: pandaNode.h:65
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
An interface for simplifying ("flattening") scene graphs by eliminating unneeded nodes and collapsing...
int flatten(PandaNode *root, int combine_siblings_bits)
Simplifies the graph by removing unnecessary nodes and nodes.
void apply_attribs(PandaNode *node, int attrib_types=~(TT_clip_plane|TT_cull_face|TT_apply_texture_color))
Walks the scene graph, accumulating attribs of the indicated types, applying them to the vertices,...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
get_texture_type
Returns the overall interpretation of the texture.
Definition: texture.h:365
int get_pad_y_size() const
Returns size of the pad region.
Definition: texture.I:629
get_y_size
Returns the height of the texture image in texels.
Definition: texture.h:346
int get_pad_x_size() const
Returns size of the pad region.
Definition: texture.I:620
get_x_size
Returns the width of the texture image in texels.
Definition: texture.h:342
Indicates a coordinate-system transform on vertices.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.