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