Panda3D
Loading...
Searching...
No Matches
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 */
29AccumulatedAttribs::
30AccumulatedAttribs() {
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 */
44AccumulatedAttribs::
45AccumulatedAttribs(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 */
66void AccumulatedAttribs::
67operator = (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 */
87void AccumulatedAttribs::
88write(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 */
137collect(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 */
155collect(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 */
286apply_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.
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
void collect(PandaNode *node, int attrib_types)
Collects the state and transform from the indicated node and adds it to the accumulator,...
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...
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
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...
set_state
Sets the complete RenderState that will be applied to all nodes at this level and below.
Definition pandaNode.h:173
set_transform
Sets the transform that will be applied to this node and below.
Definition pandaNode.h:183
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,...
void set_attrib(const RenderAttrib *attrib, int override=0)
Adds the indicated render attribute to the scene graph on this node.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
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.
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.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.