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