Panda3D
Loading...
Searching...
No Matches
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 */
17INLINE TransformBlend::
18TransformBlend() {
19}
20
21/**
22 *
23 */
24INLINE TransformBlend::
25TransformBlend(const VertexTransform *transform0, PN_stdfloat) {
26 add_transform(transform0, 1.0f);
27}
28
29/**
30 *
31 */
32INLINE TransformBlend::
33TransformBlend(const VertexTransform *transform0, PN_stdfloat weight0,
34 const VertexTransform *transform1, PN_stdfloat weight1) {
35 add_transform(transform0, weight0);
36 add_transform(transform1, weight1);
38}
39
40/**
41 *
42 */
43INLINE TransformBlend::
44TransformBlend(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);
51}
52
53/**
54 *
55 */
56INLINE TransformBlend::
57TransformBlend(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);
66}
67
68/**
69 *
70 */
71INLINE TransformBlend::
72TransformBlend(const TransformBlend &copy) :
73 _entries(copy._entries)
74{
75}
76
77/**
78 *
79 */
80INLINE void TransformBlend::
81operator = (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 */
90INLINE TransformBlend::
91~TransformBlend() {
92}
93
94/**
95 *
96 */
97INLINE bool TransformBlend::
98operator < (const TransformBlend &other) const {
99 return compare_to(other) < 0;
100}
101
102/**
103 *
104 */
105INLINE bool TransformBlend::
106operator == (const TransformBlend &other) const {
107 return compare_to(other) == 0;
108}
109
110/**
111 *
112 */
113INLINE bool TransformBlend::
114operator != (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 */
121INLINE size_t TransformBlend::
122get_num_transforms() const {
123 return _entries.size();
124}
125
126/**
127 * Returns the nth transform stored in the blend object.
128 */
130get_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 */
139INLINE PN_stdfloat TransformBlend::
140get_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 */
148INLINE void TransformBlend::
149remove_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 */
159INLINE void TransformBlend::
160set_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 */
170set_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 */
180update_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 */
196get_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 */
208transform_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 */
222transform_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 */
236transform_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 */
251transform_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 */
264INLINE void TransformBlend::
265transform_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 */
281transform_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 */
294INLINE void TransformBlend::
295transform_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 */
311transform_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 */
324INLINE void TransformBlend::
325transform_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 */
338get_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 */
354INLINE bool TransformBlend::TransformEntry::
355operator < (const TransformBlend::TransformEntry &other) const {
356 return _transform < other._transform;
357}
358
359/**
360 *
361 */
362INLINE TransformBlend::CData::
363CData() :
364 _result(LMatrix4::ident_mat())
365{
366}
367
368/**
369 *
370 */
371INLINE TransformBlend::CData::
372CData(const TransformBlend::CData &copy) :
373 _result(copy._result),
374 _modified(copy._modified),
375 _global_modified(copy._global_modified)
376{
377}
378
379INLINE std::ostream &
380operator << (std::ostream &out, const TransformBlend &obj) {
381 obj.output(out);
382 return out;
383}
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A thread; that is, a lightweight process.
Definition thread.h:46
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
This defines a single entry in a TransformBlendTable.
void update_blend(Thread *current_thread) const
Recomputes the internal representation of the blend value, if necessary.
get_num_transforms
Returns the number of transforms stored in the blend object.
void transform_vector(LVector3f &point, Thread *current_thread) const
Transforms the indicated vector by the blend matrix.
get_weight
Returns the weight associated with the indicated transform, or 0 if there is no entry for the transfo...
void set_weight(size_t n, PN_stdfloat weight)
Replaces the weight associated with the nth transform stored in the blend object.
int compare_to(const TransformBlend &other) const
Defines an arbitrary ordering for TransformBlend objects.
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...
void transform_point(LPoint4f &point, Thread *current_thread) const
Transforms the indicated point by the blend matrix.
remove_transform
Removes the indicated transform from the blend.
set_transform
Replaces the nth transform stored in the blend object.
get_transform
Returns the nth transform stored in the blend object.
get_modified
Returns a counter which is guaranteed to increment at least as often as the result of get_blend() cha...
void normalize_weights()
Rescales all of the weights on the various transforms so that they sum to 1.0.
void add_transform(const VertexTransform *transform, PN_stdfloat weight)
Adds a new transform to the blend.
This is a sequence number that increments monotonically.
Definition updateSeq.h:37
This is an abstract base class that holds a pointer to some transform, computed in some arbitrary way...
static UpdateSeq get_global_modified(Thread *current_thread)
Returns the currently highest VertexTransform::get_modified() value in the world.
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
size_type_0 size() const
Returns the number of elements in the ordered vector.
bool empty() const
Returns true if the ordered vector is empty, false otherwise.