176 lines
7.1 KiB
C++
176 lines
7.1 KiB
C++
//----------------------------------------------------------------------------//
|
|
// //
|
|
// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation //
|
|
// and distributed under the MIT License (MIT). //
|
|
// //
|
|
// Copyright (c) Guillaume Blanc //
|
|
// //
|
|
// Permission is hereby granted, free of charge, to any person obtaining a //
|
|
// copy of this software and associated documentation files (the "Software"), //
|
|
// to deal in the Software without restriction, including without limitation //
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense, //
|
|
// and/or sell copies of the Software, and to permit persons to whom the //
|
|
// Software is furnished to do so, subject to the following conditions: //
|
|
// //
|
|
// The above copyright notice and this permission notice shall be included in //
|
|
// all copies or substantial portions of the Software. //
|
|
// //
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL //
|
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING //
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER //
|
|
// DEALINGS IN THE SOFTWARE. //
|
|
// //
|
|
//----------------------------------------------------------------------------//
|
|
|
|
#ifndef OZZ_OZZ_ANIMATION_RUNTIME_TRACK_H_
|
|
#define OZZ_OZZ_ANIMATION_RUNTIME_TRACK_H_
|
|
|
|
#include "ozz/animation/runtime/export.h"
|
|
#include "ozz/base/io/archive_traits.h"
|
|
#include "ozz/base/maths/quaternion.h"
|
|
#include "ozz/base/maths/vec_float.h"
|
|
#include "ozz/base/platform.h"
|
|
#include "ozz/base/span.h"
|
|
|
|
namespace ozz {
|
|
namespace animation {
|
|
|
|
// Forward declares the TrackBuilder, used to instantiate a Track.
|
|
namespace offline {
|
|
class TrackBuilder;
|
|
}
|
|
|
|
namespace internal {
|
|
// Runtime user-channel track internal implementation.
|
|
// The runtime track data structure exists for 1 to 4 float types (FloatTrack,
|
|
// ..., Float4Track) and quaternions (QuaternionTrack). See RawTrack for more
|
|
// details on track content. The runtime track data structure is optimized for
|
|
// the processing of ozz::animation::TrackSamplingJob and
|
|
// ozz::animation::TrackTriggeringJob. Keyframe ratios, values and interpolation
|
|
// mode are all store as separate buffers in order to access the cache
|
|
// coherently. Ratios are usually accessed/read alone from the jobs that all
|
|
// start by looking up the keyframes to interpolate indeed.
|
|
template <typename _ValueType>
|
|
class OZZ_ANIMATION_DLL Track {
|
|
public:
|
|
typedef _ValueType ValueType;
|
|
|
|
Track();
|
|
|
|
// Allow move.
|
|
Track(Track&& _other);
|
|
Track& operator=(Track&& _other);
|
|
|
|
// Disables copy and assignation.
|
|
Track(Track const&) = delete;
|
|
void operator=(Track const&) = delete;
|
|
|
|
~Track();
|
|
|
|
// Keyframe accessors.
|
|
span<const float> ratios() const { return ratios_; }
|
|
span<const _ValueType> values() const { return values_; }
|
|
span<const uint8_t> steps() const { return steps_; }
|
|
|
|
// Get the estimated track's size in bytes.
|
|
size_t size() const;
|
|
|
|
// Get track name.
|
|
const char* name() const { return name_ ? name_ : ""; }
|
|
|
|
// Serialization functions.
|
|
// Should not be called directly but through io::Archive << and >> operators.
|
|
void Save(ozz::io::OArchive& _archive) const;
|
|
void Load(ozz::io::IArchive& _archive, uint32_t _version);
|
|
|
|
private:
|
|
// TrackBuilder class is allowed to allocate a Track.
|
|
friend class offline::TrackBuilder;
|
|
|
|
// Internal destruction function.
|
|
void Allocate(size_t _keys_count, size_t _name_len);
|
|
void Deallocate();
|
|
|
|
// Keyframe ratios (0 is the beginning of the track, 1 is the end).
|
|
span<float> ratios_;
|
|
|
|
// Keyframe values.
|
|
span<_ValueType> values_;
|
|
|
|
// Keyframe modes (1 bit per key): 1 for step, 0 for linear.
|
|
span<uint8_t> steps_;
|
|
|
|
// Track name.
|
|
char* name_ = nullptr;
|
|
};
|
|
|
|
// Definition of operations policies per track value type.
|
|
template <typename _ValueType>
|
|
struct TrackPolicy {
|
|
inline static _ValueType Lerp(const _ValueType& _a, const _ValueType& _b,
|
|
float _alpha) {
|
|
return math::Lerp(_a, _b, _alpha);
|
|
}
|
|
inline static float Distance(const _ValueType& _a, const _ValueType& _b) {
|
|
return math::Length(_a - _b);
|
|
}
|
|
inline static _ValueType identity() { return _ValueType(0.f); }
|
|
};
|
|
|
|
// Specialization for float policy.
|
|
template <>
|
|
inline float TrackPolicy<float>::Distance(const float& _a, const float& _b) {
|
|
return std::abs(_a - _b);
|
|
}
|
|
|
|
// Specialization for quaternions policy.
|
|
template <>
|
|
inline math::Quaternion TrackPolicy<math::Quaternion>::Lerp(
|
|
const math::Quaternion& _a, const math::Quaternion& _b, float _alpha) {
|
|
// Uses NLerp to favor speed. This same function is used when optimizing the
|
|
// curve (key frame reduction), so "constant speed" interpolation can still be
|
|
// approximated with a lower tolerance value if it matters.
|
|
return math::NLerp(_a, _b, _alpha);
|
|
}
|
|
template <>
|
|
inline float TrackPolicy<math::Quaternion>::Distance(
|
|
const math::Quaternion& _a, const math::Quaternion& _b) {
|
|
const float cos_half_angle =
|
|
_a.x * _b.x + _a.y * _b.y + _a.z * _b.z + _a.w * _b.w;
|
|
// Return value is 1 - half cosine, so the closer the quaternions, the closer
|
|
// to 0.
|
|
return 1.f - math::Min(1.f, std::abs(cos_half_angle));
|
|
}
|
|
template <>
|
|
inline math::Quaternion TrackPolicy<math::Quaternion>::identity() {
|
|
return math::Quaternion::identity();
|
|
}
|
|
} // namespace internal
|
|
|
|
// Runtime track data structure instantiation.
|
|
class OZZ_ANIMATION_DLL FloatTrack : public internal::Track<float> {};
|
|
class OZZ_ANIMATION_DLL Float2Track : public internal::Track<math::Float2> {};
|
|
class OZZ_ANIMATION_DLL Float3Track : public internal::Track<math::Float3> {};
|
|
class OZZ_ANIMATION_DLL Float4Track : public internal::Track<math::Float4> {};
|
|
class OZZ_ANIMATION_DLL QuaternionTrack
|
|
: public internal::Track<math::Quaternion> {};
|
|
|
|
} // namespace animation
|
|
namespace io {
|
|
OZZ_IO_TYPE_VERSION(1, animation::FloatTrack)
|
|
OZZ_IO_TYPE_TAG("ozz-float_track", animation::FloatTrack)
|
|
OZZ_IO_TYPE_VERSION(1, animation::Float2Track)
|
|
OZZ_IO_TYPE_TAG("ozz-float2_track", animation::Float2Track)
|
|
OZZ_IO_TYPE_VERSION(1, animation::Float3Track)
|
|
OZZ_IO_TYPE_TAG("ozz-float3_track", animation::Float3Track)
|
|
OZZ_IO_TYPE_VERSION(1, animation::Float4Track)
|
|
OZZ_IO_TYPE_TAG("ozz-float4_track", animation::Float4Track)
|
|
OZZ_IO_TYPE_VERSION(1, animation::QuaternionTrack)
|
|
OZZ_IO_TYPE_TAG("ozz-quat_track", animation::QuaternionTrack)
|
|
} // namespace io
|
|
} // namespace ozz
|
|
#endif // OZZ_OZZ_ANIMATION_RUNTIME_TRACK_H_
|