341 lines
12 KiB
Plaintext
341 lines
12 KiB
Plaintext
// Filename: transformBlend.I
|
|
// Created by: drose (24Mar05)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::
|
|
TransformBlend() {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::
|
|
TransformBlend(const VertexTransform *transform0, float) {
|
|
add_transform(transform0, 1.0f);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::
|
|
TransformBlend(const VertexTransform *transform0, float weight0,
|
|
const VertexTransform *transform1, float weight1) {
|
|
add_transform(transform0, weight0);
|
|
add_transform(transform1, weight1);
|
|
normalize_weights();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::
|
|
TransformBlend(const VertexTransform *transform0, float weight0,
|
|
const VertexTransform *transform1, float weight1,
|
|
const VertexTransform *transform2, float weight2) {
|
|
add_transform(transform0, weight0);
|
|
add_transform(transform1, weight1);
|
|
add_transform(transform2, weight2);
|
|
normalize_weights();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::
|
|
TransformBlend(const VertexTransform *transform0, float weight0,
|
|
const VertexTransform *transform1, float weight1,
|
|
const VertexTransform *transform2, float weight2,
|
|
const VertexTransform *transform3, float weight3) {
|
|
add_transform(transform0, weight0);
|
|
add_transform(transform1, weight1);
|
|
add_transform(transform2, weight2);
|
|
add_transform(transform3, weight3);
|
|
normalize_weights();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::Copy Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::
|
|
TransformBlend(const TransformBlend ©) :
|
|
_entries(copy._entries)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::Copy Assignment Operator
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void TransformBlend::
|
|
operator = (const TransformBlend ©) {
|
|
_entries = copy._entries;
|
|
Thread *current_thread = Thread::get_current_thread();
|
|
clear_result(current_thread);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::Destructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::
|
|
~TransformBlend() {
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::operator <
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool TransformBlend::
|
|
operator < (const TransformBlend &other) const {
|
|
return compare_to(other) < 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::operator ==
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool TransformBlend::
|
|
operator == (const TransformBlend &other) const {
|
|
return compare_to(other) == 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::operator !=
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool TransformBlend::
|
|
operator != (const TransformBlend &other) const {
|
|
return compare_to(other) != 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::get_num_transforms
|
|
// Access: Published
|
|
// Description: Returns the number of transforms stored in the blend
|
|
// object.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE int TransformBlend::
|
|
get_num_transforms() const {
|
|
return _entries.size();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::get_transform
|
|
// Access: Published
|
|
// Description: Returns the nth transform stored in the blend
|
|
// object.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE const VertexTransform *TransformBlend::
|
|
get_transform(int n) const {
|
|
nassertr(n >= 0 && n < (int)_entries.size(), NULL);
|
|
return _entries[n]._transform;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::get_weight
|
|
// Access: Published
|
|
// Description: Returns the weight associated with the nth transform
|
|
// stored in the blend object.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE float TransformBlend::
|
|
get_weight(int n) const {
|
|
nassertr(n >= 0 && n < (int)_entries.size(), 0.0f);
|
|
return _entries[n]._weight;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::set_transform
|
|
// Access: Published
|
|
// Description: Replaces the nth transform stored in the blend
|
|
// object.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void TransformBlend::
|
|
set_transform(int n, const VertexTransform *transform) {
|
|
nassertv(n >= 0 && n < (int)_entries.size());
|
|
_entries[n]._transform = transform;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::set_weight
|
|
// Access: Published
|
|
// Description: Replaces the weight associated with the nth transform
|
|
// stored in the blend object.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void TransformBlend::
|
|
set_weight(int n, float weight) {
|
|
nassertv(n >= 0 && n < (int)_entries.size());
|
|
_entries[n]._weight = weight;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::update_blend
|
|
// Access: Published
|
|
// Description: Recomputes the internal representation of the blend
|
|
// value, if necessary. You should call this before
|
|
// calling get_blend() or transform_point().
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void TransformBlend::
|
|
update_blend(Thread *current_thread) const {
|
|
CDLockedReader cdata(_cycler, current_thread);
|
|
if (cdata->_global_modified != VertexTransform::get_global_modified(current_thread)) {
|
|
CDWriter cdataw(((TransformBlend *)this)->_cycler, cdata, false);
|
|
((TransformBlend *)this)->recompute_result(cdataw, current_thread);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::get_blend
|
|
// Access: Published
|
|
// Description: Returns the current value of the blend, based on the
|
|
// current value of all of the nested transform objects
|
|
// and their associated weights.
|
|
//
|
|
// You should call update_blend() to ensure that the
|
|
// cache is up-to-date before calling this.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void TransformBlend::
|
|
get_blend(LMatrix4f &result, Thread *current_thread) const {
|
|
CDReader cdata(_cycler, current_thread);
|
|
result = cdata->_result;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::transform_point
|
|
// Access: Published
|
|
// Description: Transforms the indicated point by the blend matrix.
|
|
//
|
|
// You should call update_blend() to ensure that the
|
|
// cache is up-to-date before calling this.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void TransformBlend::
|
|
transform_point(LPoint4f &point, Thread *current_thread) const {
|
|
if (!_entries.empty()) {
|
|
CDReader cdata(_cycler, current_thread);
|
|
point = point * cdata->_result;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::transform_point
|
|
// Access: Published
|
|
// Description: Transforms the indicated point by the blend matrix.
|
|
//
|
|
// You should call update_blend() to ensure that the
|
|
// cache is up-to-date before calling this.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void TransformBlend::
|
|
transform_point(LPoint3f &point, Thread *current_thread) const {
|
|
if (!_entries.empty()) {
|
|
CDReader cdata(_cycler, current_thread);
|
|
point = point * cdata->_result;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::transform_vector
|
|
// Access: Published
|
|
// Description: Transforms the indicated vector by the blend matrix.
|
|
//
|
|
// You should call update_blend() to ensure that the
|
|
// cache is up-to-date before calling this.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE void TransformBlend::
|
|
transform_vector(LVector3f &vector, Thread *current_thread) const {
|
|
if (!_entries.empty()) {
|
|
CDReader cdata(_cycler, current_thread);
|
|
vector = vector * cdata->_result;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::get_modified
|
|
// Access: Published
|
|
// Description: Returns a counter which is guaranteed to increment at
|
|
// least as often as the result of get_blend() changes.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE UpdateSeq TransformBlend::
|
|
get_modified(Thread *current_thread) const {
|
|
CDLockedReader cdata(_cycler, current_thread);
|
|
if (cdata->_global_modified != VertexTransform::get_global_modified(current_thread)) {
|
|
CDWriter cdataw(((TransformBlend *)this)->_cycler, cdata, false);
|
|
((TransformBlend *)this)->recompute_result(cdataw, current_thread);
|
|
return cdataw->_modified;
|
|
} else {
|
|
return cdata->_modified;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::TransformEntry::operator <
|
|
// Access: Public
|
|
// Description: Provides an ordering of TransformEntries by the
|
|
// VertexTransform pointer only, so we can easily look
|
|
// up in the set to see if a particular transform
|
|
// exists.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE bool TransformBlend::TransformEntry::
|
|
operator < (const TransformBlend::TransformEntry &other) const {
|
|
return _transform < other._transform;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::CData::Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::CData::
|
|
CData() :
|
|
_result(LMatrix4f::ident_mat())
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: TransformBlend::CData::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE TransformBlend::CData::
|
|
CData(const TransformBlend::CData ©) :
|
|
_result(copy._result),
|
|
_modified(copy._modified),
|
|
_global_modified(copy._global_modified)
|
|
{
|
|
}
|
|
|
|
INLINE ostream &
|
|
operator << (ostream &out, const TransformBlend &obj) {
|
|
obj.output(out);
|
|
return out;
|
|
}
|