Panda3D

transformBlend.I
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 transformBlend.I
10 * @author drose
11 * @date 2005-03-24
12 */
13
14 /**
15 *
16 */
17 INLINE TransformBlend::
18 TransformBlend() {
19 }
20
21 /**
22 *
23 */
24 INLINE TransformBlend::
25 TransformBlend(const VertexTransform *transform0, PN_stdfloat) {
26 add_transform(transform0, 1.0f);
27 }
28
29 /**
30 *
31 */
32 INLINE TransformBlend::
33 TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0,
34 const VertexTransform *transform1, PN_stdfloat weight1) {
35 add_transform(transform0, weight0);
36 add_transform(transform1, weight1);
37 normalize_weights();
38 }
39
40 /**
41 *
42 */
43 INLINE TransformBlend::
44 TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0,
45 const VertexTransform *transform1, PN_stdfloat weight1,
46 const VertexTransform *transform2, PN_stdfloat weight2) {
47 add_transform(transform0, weight0);
48 add_transform(transform1, weight1);
49 add_transform(transform2, weight2);
50 normalize_weights();
51 }
52
53 /**
54 *
55 */
56 INLINE TransformBlend::
57 TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0,
58 const VertexTransform *transform1, PN_stdfloat weight1,
59 const VertexTransform *transform2, PN_stdfloat weight2,
60 const VertexTransform *transform3, PN_stdfloat weight3) {
61 add_transform(transform0, weight0);
62 add_transform(transform1, weight1);
63 add_transform(transform2, weight2);
64 add_transform(transform3, weight3);
65 normalize_weights();
66 }
67
68 /**
69 *
70 */
71 INLINE TransformBlend::
72 TransformBlend(const TransformBlend &copy) :
73 _entries(copy._entries)
74 {
75 }
76
77 /**
78 *
79 */
80 INLINE void TransformBlend::
81 operator = (const TransformBlend &copy) {
82 _entries = copy._entries;
83 Thread *current_thread = Thread::get_current_thread();
84 clear_result(current_thread);
85 }
86
87 /**
88 *
89 */
90 INLINE TransformBlend::
91 ~TransformBlend() {
92 }
93
94 /**
95 *
96 */
97 INLINE bool TransformBlend::
98 operator < (const TransformBlend &other) const {
99 return compare_to(other) < 0;
100 }
101
102 /**
103 *
104 */
105 INLINE bool TransformBlend::
106 operator == (const TransformBlend &other) const {
107 return compare_to(other) == 0;
108 }
109
110 /**
111 *
112 */
113 INLINE bool TransformBlend::
114 operator != (const TransformBlend &other) const {
115 return compare_to(other) != 0;
116 }
117
118 /**
119 * Returns the number of transforms stored in the blend object.
120 */
121 INLINE size_t TransformBlend::
122 get_num_transforms() const {
123 return _entries.size();
124 }
125
126 /**
127 * Returns the nth transform stored in the blend object.
128 */
129 INLINE const VertexTransform *TransformBlend::
130 get_transform(size_t n) const {
131 nassertr(n < _entries.size(), nullptr);
132 return _entries[n]._transform;
133 }
134
135 /**
136 * Returns the weight associated with the nth transform stored in the blend
137 * object.
138 */
139 INLINE PN_stdfloat TransformBlend::
140 get_weight(size_t n) const {
141 nassertr(n < _entries.size(), 0.0f);
142 return _entries[n]._weight;
143 }
144
145 /**
146 * Removes the nth transform stored in the blend object.
147 */
148 INLINE void TransformBlend::
149 remove_transform(size_t n) {
150 nassertv(n < _entries.size());
151 _entries.erase(_entries.begin() + n);
152 Thread *current_thread = Thread::get_current_thread();
153 clear_result(current_thread);
154 }
155
156 /**
157 * Replaces the nth transform stored in the blend object.
158 */
159 INLINE void TransformBlend::
160 set_transform(size_t n, const VertexTransform *transform) {
161 nassertv(n < _entries.size());
162 _entries[n]._transform = transform;
163 }
164
165 /**
166 * Replaces the weight associated with the nth transform stored in the blend
167 * object.
168 */
169 INLINE void TransformBlend::
170 set_weight(size_t n, PN_stdfloat weight) {
171 nassertv(n < _entries.size());
172 _entries[n]._weight = weight;
173 }
174
175 /**
176 * Recomputes the internal representation of the blend value, if necessary.
177 * You should call this before calling get_blend() or transform_point().
178 */
179 INLINE void TransformBlend::
180 update_blend(Thread *current_thread) const {
181 CDLockedReader cdata(_cycler, current_thread);
182 if (cdata->_global_modified != VertexTransform::get_global_modified(current_thread)) {
183 CDWriter cdataw(((TransformBlend *)this)->_cycler, cdata, false);
184 ((TransformBlend *)this)->recompute_result(cdataw, current_thread);
185 }
186 }
187
188 /**
189 * Returns the current value of the blend, based on the current value of all
190 * of the nested transform objects and their associated weights.
191 *
192 * You should call update_blend() to ensure that the cache is up-to-date
193 * before calling this.
194 */
195 INLINE void TransformBlend::
196 get_blend(LMatrix4 &result, Thread *current_thread) const {
197 CDReader cdata(_cycler, current_thread);
198 result = cdata->_result;
199 }
200
201 /**
202 * Transforms the indicated point by the blend matrix.
203 *
204 * You should call update_blend() to ensure that the cache is up-to-date
205 * before calling this.
206 */
207 INLINE void TransformBlend::
208 transform_point(LPoint4 &point, Thread *current_thread) const {
209 if (!_entries.empty()) {
210 CDReader cdata(_cycler, current_thread);
211 point = point * cdata->_result;
212 }
213 }
214
215 /**
216 * Transforms the indicated point by the blend matrix.
217 *
218 * You should call update_blend() to ensure that the cache is up-to-date
219 * before calling this.
220 */
221 INLINE void TransformBlend::
222 transform_point(LPoint3 &point, Thread *current_thread) const {
223 if (!_entries.empty()) {
224 CDReader cdata(_cycler, current_thread);
225 point = point * cdata->_result;
226 }
227 }
228
229 /**
230 * Transforms the indicated vector by the blend matrix.
231 *
232 * You should call update_blend() to ensure that the cache is up-to-date
233 * before calling this.
234 */
235 INLINE void TransformBlend::
236 transform_vector(LVector3 &vector, Thread *current_thread) const {
237 if (!_entries.empty()) {
238 CDReader cdata(_cycler, current_thread);
239 vector = vector * cdata->_result;
240 }
241 }
242
243 #ifndef STDFLOAT_DOUBLE
244 /**
245 * Transforms the indicated point by the blend matrix.
246 *
247 * You should call update_blend() to ensure that the cache is up-to-date
248 * before calling this.
249 */
250 INLINE void TransformBlend::
251 transform_point(LPoint4d &point, Thread *current_thread) const {
252 if (!_entries.empty()) {
253 CDReader cdata(_cycler, current_thread);
254 point = point * LCAST(double, cdata->_result);
255 }
256 }
257 #else // STDFLOAT_DOUBLE
258 /**
259 * Transforms the indicated point by the blend matrix.
260 *
261 * You should call update_blend() to ensure that the cache is up-to-date
262 * before calling this.
263 */
264 INLINE void TransformBlend::
265 transform_point(LPoint4f &point, Thread *current_thread) const {
266 if (!_entries.empty()) {
267 CDReader cdata(_cycler, current_thread);
268 point = point * LCAST(float, cdata->_result);
269 }
270 }
271 #endif // STDFLOAT_DOUBLE
272
273 #ifndef STDFLOAT_DOUBLE
274 /**
275 * Transforms the indicated point by the blend matrix.
276 *
277 * You should call update_blend() to ensure that the cache is up-to-date
278 * before calling this.
279 */
280 INLINE void TransformBlend::
281 transform_point(LPoint3d &point, Thread *current_thread) const {
282 if (!_entries.empty()) {
283 CDReader cdata(_cycler, current_thread);
284 point = point * LCAST(double, cdata->_result);
285 }
286 }
287 #else // STDFLOAT_DOUBLE
288 /**
289 * Transforms the indicated point by the blend matrix.
290 *
291 * You should call update_blend() to ensure that the cache is up-to-date
292 * before calling this.
293 */
294 INLINE void TransformBlend::
295 transform_point(LPoint3f &point, Thread *current_thread) const {
296 if (!_entries.empty()) {
297 CDReader cdata(_cycler, current_thread);
298 point = point * LCAST(float, cdata->_result);
299 }
300 }
301 #endif // STDFLOAT_DOUBLE
302
303 #ifndef STDFLOAT_DOUBLE
304 /**
305 * Transforms the indicated vector by the blend matrix.
306 *
307 * You should call update_blend() to ensure that the cache is up-to-date
308 * before calling this.
309 */
310 INLINE void TransformBlend::
311 transform_vector(LVector3d &vector, Thread *current_thread) const {
312 if (!_entries.empty()) {
313 CDReader cdata(_cycler, current_thread);
314 vector = vector * LCAST(double, cdata->_result);
315 }
316 }
317 #else // STDFLOAT_DOUBLE
318 /**
319 * Transforms the indicated vector by the blend matrix.
320 *
321 * You should call update_blend() to ensure that the cache is up-to-date
322 * before calling this.
323 */
324 INLINE void TransformBlend::
325 transform_vector(LVector3f &vector, Thread *current_thread) const {
326 if (!_entries.empty()) {
327 CDReader cdata(_cycler, current_thread);
328 vector = vector * LCAST(float, cdata->_result);
329 }
330 }
331 #endif // STDFLOAT_DOUBLE
332
333 /**
334 * Returns a counter which is guaranteed to increment at least as often as the
335 * result of get_blend() changes.
336 */
337 INLINE UpdateSeq TransformBlend::
338 get_modified(Thread *current_thread) const {
339 CDLockedReader cdata(_cycler, current_thread);
340 if (cdata->_global_modified != VertexTransform::get_global_modified(current_thread)) {
341 CDWriter cdataw(((TransformBlend *)this)->_cycler, cdata, false);
342 ((TransformBlend *)this)->recompute_result(cdataw, current_thread);
343 return cdataw->_modified;
344 } else {
345 return cdata->_modified;
346 }
347 }
348
349 /**
350 * Provides an ordering of TransformEntries by the VertexTransform pointer
351 * only, so we can easily look up in the set to see if a particular transform
352 * exists.
353 */
354 INLINE bool TransformBlend::TransformEntry::
355 operator < (const TransformBlend::TransformEntry &other) const {
356 return _transform < other._transform;
357 }
358
359 /**
360 *
361 */
362 INLINE TransformBlend::CData::
363 CData() :
364 _result(LMatrix4::ident_mat())
365 {
366 }
367
368 /**
369 *
370 */
371 INLINE TransformBlend::CData::
372 CData(const TransformBlend::CData &copy) :
373 _result(copy._result),
374 _modified(copy._modified),
375 _global_modified(copy._global_modified)
376 {
377 }
378
379 INLINE std::ostream &
380 operator << (std::ostream &out, const TransformBlend &obj) {
381 obj.output(out);
382 return out;
383 }
CycleDataLockedReader
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
Definition: cycleDataLockedReader.h:40
CycleDataReader
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
Definition: cycleDataReader.h:35
CycleDataWriter
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
Definition: cycleDataWriter.h:34
Thread
A thread; that is, a lightweight process.
Definition: thread.h:46
Thread::get_current_thread
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition: thread.h:109
TransformBlend
This defines a single entry in a TransformBlendTable.
Definition: transformBlend.h:32
TransformBlend::update_blend
void update_blend(Thread *current_thread) const
Recomputes the internal representation of the blend value, if necessary.
Definition: transformBlend.I:180
TransformBlend::get_num_transforms
get_num_transforms
Returns the number of transforms stored in the blend object.
Definition: transformBlend.h:63
TransformBlend::transform_vector
void transform_vector(LVector3f &point, Thread *current_thread) const
Transforms the indicated vector by the blend matrix.
Definition: transformBlend.I:236
TransformBlend::get_weight
get_weight
Returns the weight associated with the indicated transform, or 0 if there is no entry for the transfo...
Definition: transformBlend.h:71
TransformBlend::set_weight
void set_weight(size_t n, PN_stdfloat weight)
Replaces the weight associated with the nth transform stored in the blend object.
Definition: transformBlend.I:170
TransformBlend::compare_to
int compare_to(const TransformBlend &other) const
Defines an arbitrary ordering for TransformBlend objects.
Definition: transformBlend.cxx:25
TransformBlend::get_blend
void get_blend(LMatrix4 &result, Thread *current_thread) const
Returns the current value of the blend, based on the current value of all of the nested transform obj...
Definition: transformBlend.I:196
TransformBlend::transform_point
void transform_point(LPoint4f &point, Thread *current_thread) const
Transforms the indicated point by the blend matrix.
Definition: transformBlend.I:208
TransformBlend::remove_transform
remove_transform
Removes the indicated transform from the blend.
Definition: transformBlend.h:70
TransformBlend::set_transform
set_transform
Replaces the nth transform stored in the blend object.
Definition: transformBlend.h:70
TransformBlend::get_transform
get_transform
Returns the nth transform stored in the blend object.
Definition: transformBlend.h:63
TransformBlend::get_modified
get_modified
Returns a counter which is guaranteed to increment at least as often as the result of get_blend() cha...
Definition: transformBlend.h:87
TransformBlend::normalize_weights
void normalize_weights()
Rescales all of the weights on the various transforms so that they sum to 1.0.
Definition: transformBlend.cxx:124
TransformBlend::add_transform
void add_transform(const VertexTransform *transform, PN_stdfloat weight)
Adds a new transform to the blend.
Definition: transformBlend.cxx:52
UpdateSeq
This is a sequence number that increments monotonically.
Definition: updateSeq.h:37
VertexTransform
This is an abstract base class that holds a pointer to some transform, computed in some arbitrary way...
Definition: vertexTransform.h:35
VertexTransform::get_global_modified
static UpdateSeq get_global_modified(Thread *current_thread)
Returns the currently highest VertexTransform::get_modified() value in the world.
Definition: vertexTransform.I:30
ordered_vector::begin
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
Definition: ordered_vector.I:41
ordered_vector::size
size_type_0 size() const
Returns the number of elements in the ordered vector.
Definition: ordered_vector.I:221
ordered_vector::empty
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
Definition: ordered_vector.I:240