Panda3D
accumulatedAttribs.cxx
1 // Filename: accumulatedAttribs.cxx
2 // Created by: drose (30Jan03)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "accumulatedAttribs.h"
16 #include "sceneGraphReducer.h"
17 #include "pandaNode.h"
18 #include "colorAttrib.h"
19 #include "colorScaleAttrib.h"
20 #include "texMatrixAttrib.h"
21 #include "textureAttrib.h"
22 #include "clipPlaneAttrib.h"
23 #include "cullFaceAttrib.h"
24 #include "config_pgraph.h"
25 
26 
27 ////////////////////////////////////////////////////////////////////
28 // Function: AccumulatedAttribs::Constructor
29 // Access: Public
30 // Description:
31 ////////////////////////////////////////////////////////////////////
32 AccumulatedAttribs::
33 AccumulatedAttribs() {
34  _transform = TransformState::make_identity();
35  _color_override = 0;
36  _color_scale_override = 0;
37  _tex_matrix_override = 0;
38  _texture_override = 0;
39  _clip_plane_override = 0;
40  _cull_face_override = 0;
41  _other = RenderState::make_empty();
42 }
43 
44 ////////////////////////////////////////////////////////////////////
45 // Function: AccumulatedAttribs::Copy Constructor
46 // Access: Public
47 // Description:
48 ////////////////////////////////////////////////////////////////////
49 AccumulatedAttribs::
50 AccumulatedAttribs(const AccumulatedAttribs &copy) :
51  _transform(copy._transform),
52  _color(copy._color),
53  _color_override(copy._color_override),
54  _color_scale(copy._color_scale),
55  _color_scale_override(copy._color_scale_override),
56  _tex_matrix(copy._tex_matrix),
57  _tex_matrix_override(copy._tex_matrix_override),
58  _texture(copy._texture),
59  _texture_override(copy._texture_override),
60  _clip_plane(copy._clip_plane),
61  _clip_plane_override(copy._clip_plane_override),
62  _cull_face(copy._cull_face),
63  _cull_face_override(copy._cull_face_override),
64  _other(copy._other)
65 {
66 }
67 
68 ////////////////////////////////////////////////////////////////////
69 // Function: AccumulatedAttribs::Copy Assignment
70 // Access: Public
71 // Description:
72 ////////////////////////////////////////////////////////////////////
73 void AccumulatedAttribs::
74 operator = (const AccumulatedAttribs &copy) {
75  _transform = copy._transform;
76  _color = copy._color;
77  _color_override = copy._color_override;
78  _color_scale = copy._color_scale;
79  _color_scale_override = copy._color_scale_override;
80  _tex_matrix = copy._tex_matrix;
81  _tex_matrix_override = copy._tex_matrix_override;
82  _texture = copy._texture;
83  _texture_override = copy._texture_override;
84  _clip_plane = copy._clip_plane;
85  _clip_plane_override = copy._clip_plane_override;
86  _cull_face = copy._cull_face;
87  _cull_face_override = copy._cull_face_override;
88  _other = copy._other;
89 }
90 
91 ////////////////////////////////////////////////////////////////////
92 // Function: AccumulatedAttribs::write
93 // Access: Public
94 // Description:
95 ////////////////////////////////////////////////////////////////////
96 void AccumulatedAttribs::
97 write(ostream &out, int attrib_types, int indent_level) const {
98  if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
99  _transform->write(out, indent_level);
100  }
101  if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
102  if (_color == (const RenderAttrib *)NULL) {
103  indent(out, indent_level) << "no color\n";
104  } else {
105  _color->write(out, indent_level);
106  }
107  }
108  if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) {
109  if (_color_scale == (const RenderAttrib *)NULL) {
110  indent(out, indent_level) << "no color scale\n";
111  } else {
112  _color_scale->write(out, indent_level);
113  }
114  }
115  if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) {
116  if (_tex_matrix == (const RenderAttrib *)NULL) {
117  indent(out, indent_level) << "no tex matrix\n";
118  } else {
119  _tex_matrix->write(out, indent_level);
120  }
121  }
122  if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) {
123  if (_clip_plane == (const RenderAttrib *)NULL) {
124  indent(out, indent_level) << "no clip plane\n";
125  } else {
126  _clip_plane->write(out, indent_level);
127  }
128  }
129  if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) {
130  if (_cull_face == (const RenderAttrib *)NULL) {
131  indent(out, indent_level) << "no cull face\n";
132  } else {
133  _cull_face->write(out, indent_level);
134  }
135  }
136  if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
137  _other->write(out, indent_level);
138  }
139 }
140 
141 ////////////////////////////////////////////////////////////////////
142 // Function: AccumulatedAttribs::collect
143 // Access: Public
144 // Description: Collects the state and transform from the indicated
145 // node and adds it to the accumulator, removing it from
146 // the node.
147 ////////////////////////////////////////////////////////////////////
149 collect(PandaNode *node, int attrib_types) {
150  if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
151  // Collect the node's transform.
152  nassertv(_transform != (TransformState *)NULL);
153  _transform = _transform->compose(node->get_transform());
154  node->set_transform(TransformState::make_identity());
155  node->set_prev_transform(TransformState::make_identity());
156  }
157 
158  CPT(RenderState) new_state = collect(node->get_state(), attrib_types);
159  node->set_state(new_state);
160 }
161 
162 ////////////////////////////////////////////////////////////////////
163 // Function: AccumulatedAttribs::collect
164 // Access: Public
165 // Description: Collects the state and transform from the indicated
166 // node and adds it to the accumulator, removing it from
167 // the state (and returning a new state).
168 ////////////////////////////////////////////////////////////////////
170 collect(const RenderState *state, int attrib_types) {
171  CPT(RenderState) new_state = state;
172 
173  if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
174  const RenderAttrib *node_attrib =
175  new_state->get_attrib(ColorAttrib::get_class_slot());
176  if (node_attrib != (const RenderAttrib *)NULL) {
177  int color_override = new_state->get_override(ColorAttrib::get_class_slot());
178  if (color_override >= _color_override ||
179  _color == (const RenderAttrib *)NULL) {
180  // The node has a color attribute; apply it.
181  if (_color == (const RenderAttrib *)NULL) {
182  _color = node_attrib;
183  } else {
184  _color = _color->compose(node_attrib);
185  }
186  _color_override = color_override;
187  }
188  new_state = new_state->remove_attrib(ColorAttrib::get_class_slot());
189  }
190  }
191 
192  if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) {
193  const RenderAttrib *node_attrib =
194  new_state->get_attrib(ColorScaleAttrib::get_class_slot());
195  if (node_attrib != (const RenderAttrib *)NULL) {
196  int color_scale_override = new_state->get_override(ColorScaleAttrib::get_class_slot());
197  if (color_scale_override >= _color_scale_override ||
198  _color_scale == (const RenderAttrib *)NULL) {
199  if (_color_scale == (const RenderAttrib *)NULL) {
200  _color_scale = node_attrib;
201  } else {
202  _color_scale = _color_scale->compose(node_attrib);
203  }
204  _color_scale_override = color_scale_override;
205  }
206  new_state = new_state->remove_attrib(ColorScaleAttrib::get_class_slot());
207  }
208  }
209 
210  if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) {
211  const RenderAttrib *node_attrib =
212  new_state->get_attrib(TexMatrixAttrib::get_class_slot());
213  if (node_attrib != (const RenderAttrib *)NULL) {
214  int tex_matrix_override = new_state->get_override(TexMatrixAttrib::get_class_slot());
215  if (tex_matrix_override >= _tex_matrix_override ||
216  _tex_matrix == (const RenderAttrib *)NULL) {
217  if (_tex_matrix == (const RenderAttrib *)NULL) {
218  _tex_matrix = node_attrib;
219  } else {
220  _tex_matrix = _tex_matrix->compose(node_attrib);
221  }
222  _tex_matrix_override = tex_matrix_override;
223  }
224  new_state = new_state->remove_attrib(TexMatrixAttrib::get_class_slot());
225  }
226 
227  // We also need to accumulate the texture state if we are
228  // accumulating texture matrix.
229  const RenderAttrib *tex_attrib =
230  new_state->get_attrib(TextureAttrib::get_class_slot());
231  if (tex_attrib != (const RenderAttrib *)NULL) {
232  int texture_override = new_state->get_override(TextureAttrib::get_class_slot());
233  if (texture_override >= _texture_override ||
234  _texture == (const RenderAttrib *)NULL) {
235  if (_texture == (const RenderAttrib *)NULL) {
236  _texture = tex_attrib;
237  } else {
238  _texture = _texture->compose(tex_attrib);
239  }
240  _texture_override = texture_override;
241  }
242 
243  // However, we don't remove the texture state from the node.
244  // We're just accumulating it so we can tell which texture
245  // coordinates are safe to flatten.
246  }
247  }
248 
249  if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) {
250  const RenderAttrib *node_attrib =
251  new_state->get_attrib(ClipPlaneAttrib::get_class_slot());
252  if (node_attrib != (const RenderAttrib *)NULL) {
253  int clip_plane_override = new_state->get_override(ClipPlaneAttrib::get_class_slot());
254  if (clip_plane_override >= _clip_plane_override ||
255  _clip_plane == (const RenderAttrib *)NULL) {
256  if (_clip_plane == (const RenderAttrib *)NULL) {
257  _clip_plane = node_attrib;
258  } else {
259  _clip_plane = _clip_plane->compose(node_attrib);
260  }
261  _clip_plane_override = clip_plane_override;
262  }
263  new_state = new_state->remove_attrib(ClipPlaneAttrib::get_class_slot());
264  }
265  }
266 
267  if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) {
268  const RenderAttrib *node_attrib =
269  new_state->get_attrib(CullFaceAttrib::get_class_slot());
270  if (node_attrib != (const RenderAttrib *)NULL) {
271  int cull_face_override = new_state->get_override(CullFaceAttrib::get_class_slot());
272  if (cull_face_override >= _cull_face_override ||
273  _cull_face == (const RenderAttrib *)NULL) {
274  if (_cull_face == (const RenderAttrib *)NULL) {
275  _cull_face = node_attrib;
276  } else {
277  _cull_face = _cull_face->compose(node_attrib);
278  }
279  _cull_face_override = cull_face_override;
280  }
281  new_state = new_state->remove_attrib(CullFaceAttrib::get_class_slot());
282  }
283  }
284 
285  if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
286  // Collect everything else.
287  nassertr(_other != (RenderState *)NULL, new_state);
288  _other = _other->compose(new_state);
289  new_state = RenderState::make_empty();
290  }
291 
292  return new_state;
293 }
294 
295 ////////////////////////////////////////////////////////////////////
296 // Function: AccumulatedAttribs::apply_to_node
297 // Access: Public
298 // Description: Stores the indicated attributes in the node's
299 // transform and state information; does not attempt to
300 // apply the properties to the vertices. Clears the
301 // attributes from the accumulator for future
302 // traversals.
303 ////////////////////////////////////////////////////////////////////
305 apply_to_node(PandaNode *node, int attrib_types) {
306  if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
307  node->set_transform(_transform->compose(node->get_transform())->get_unique());
308  node->reset_prev_transform();
309  _transform = TransformState::make_identity();
310  }
311 
312  if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
313  if (_color != (RenderAttrib *)NULL) {
314  const RenderAttrib *node_attrib =
315  node->get_attrib(ColorAttrib::get_class_slot());
316  if (node_attrib != (RenderAttrib *)NULL) {
317  node->set_attrib(_color->compose(node_attrib)->get_unique());
318  } else {
319  node->set_attrib(_color->get_unique());
320  }
321  _color = (RenderAttrib *)NULL;
322  }
323  }
324 
325  if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) {
326  if (_color_scale != (RenderAttrib *)NULL) {
327  const RenderAttrib *node_attrib =
328  node->get_attrib(ColorScaleAttrib::get_class_slot());
329  if (node_attrib != (RenderAttrib *)NULL) {
330  node->set_attrib(_color_scale->compose(node_attrib)->get_unique());
331  } else {
332  node->set_attrib(_color_scale->get_unique());
333  }
334  _color_scale = (RenderAttrib *)NULL;
335  }
336  }
337 
338  if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) {
339  if (_tex_matrix != (RenderAttrib *)NULL) {
340  const RenderAttrib *node_attrib =
341  node->get_attrib(TexMatrixAttrib::get_class_slot());
342  if (node_attrib != (RenderAttrib *)NULL) {
343  node->set_attrib(_tex_matrix->compose(node_attrib)->get_unique());
344  } else {
345  node->set_attrib(_tex_matrix->get_unique());
346  }
347  _tex_matrix = (RenderAttrib *)NULL;
348  }
349  }
350 
351  if ((attrib_types & SceneGraphReducer::TT_clip_plane) != 0) {
352  if (_clip_plane != (RenderAttrib *)NULL) {
353  const RenderAttrib *node_attrib =
354  node->get_attrib(ClipPlaneAttrib::get_class_slot());
355  if (node_attrib != (RenderAttrib *)NULL) {
356  node->set_attrib(_clip_plane->compose(node_attrib)->get_unique());
357  } else {
358  node->set_attrib(_clip_plane->get_unique());
359  }
360  _clip_plane = (RenderAttrib *)NULL;
361  }
362  }
363 
364  if ((attrib_types & SceneGraphReducer::TT_cull_face) != 0) {
365  if (_cull_face != (RenderAttrib *)NULL) {
366  const RenderAttrib *node_attrib =
367  node->get_attrib(CullFaceAttrib::get_class_slot());
368  if (node_attrib != (RenderAttrib *)NULL) {
369  node->set_attrib(_cull_face->compose(node_attrib)->get_unique());
370  } else {
371  node->set_attrib(_cull_face->get_unique());
372  }
373  _cull_face = (RenderAttrib *)NULL;
374  }
375  }
376 
377  if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
378  node->set_state(_other->compose(node->get_state())->get_unique());
379  _other = RenderState::make_empty();
380  }
381 }
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:60
void collect(PandaNode *node, int attrib_types)
Collects the state and transform from the indicated node and adds it to the accumulator, removing it from the node.
void reset_prev_transform(Thread *current_thread=Thread::get_current_thread())
Resets the transform that represents this node&#39;s "previous" position to the same as the current trans...
Definition: pandaNode.cxx:1336
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
void set_state(const RenderState *state, Thread *current_thread=Thread::get_current_thread())
Sets the complete RenderState that will be applied to all nodes at this level and below...
Definition: pandaNode.cxx:1216
void set_attrib(const RenderAttrib *attrib, int override=0)
Adds the indicated render attribute to the scene graph on this node.
Definition: pandaNode.cxx:1107
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
void set_prev_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that represents this node&#39;s "previous" position, one frame ago, for the purposes of detecting motion for accurate collision calculations.
Definition: pandaNode.cxx:1306
void apply_to_node(PandaNode *node, int attrib_types)
Stores the indicated attributes in the node&#39;s transform and state information; does not attempt to ap...
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that will be applied to this node and below.
Definition: pandaNode.cxx:1267