Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/pointcache/alembic/abc_interpolate.h')
-rw-r--r--source/blender/pointcache/alembic/abc_interpolate.h236
1 files changed, 236 insertions, 0 deletions
diff --git a/source/blender/pointcache/alembic/abc_interpolate.h b/source/blender/pointcache/alembic/abc_interpolate.h
new file mode 100644
index 00000000000..102f4680c81
--- /dev/null
+++ b/source/blender/pointcache/alembic/abc_interpolate.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2015, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PTC_ABC_INTERPOLATE_H
+#define PTC_ABC_INTERPOLATE_H
+
+#include <Alembic/Abc/ISampleSelector.h>
+#include <Alembic/Abc/IScalarProperty.h>
+#include <Alembic/Abc/TypedPropertyTraits.h>
+#include <Alembic/Abc/ITypedArrayProperty.h>
+#include <Alembic/Abc/ITypedScalarProperty.h>
+#include <Alembic/Abc/TypedArraySample.h>
+
+extern "C" {
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+}
+
+namespace PTC {
+
+using namespace Alembic;
+using namespace Abc;
+
+using Alembic::Util::shared_ptr;
+
+enum InterpolateSemanticDefault {
+ InterpolateSemanticDefault_None = 0,
+};
+
+enum InterpolateSemanticVector {
+ InterpolateSemanticVector_Linear = 0,
+ InterpolateSemanticVector_Slerp = 1,
+};
+
+/* linear blending for primitive types */
+template <typename T>
+BLI_INLINE T interpolate_sample(const T &val0, const T &val1, float t)
+{
+ return val0 * (1.0f-t) + val1 * t;
+}
+
+/* vector semantics */
+BLI_INLINE V3f interpolate_sample(const V3f &val0, const V3f &val1, float t, InterpolateSemanticVector semantic)
+{
+ switch (semantic) {
+ case InterpolateSemanticVector_Linear:
+ return val0 * (1.0f-t) + val1 * t;
+ case InterpolateSemanticVector_Slerp:
+ V3f result;
+ interp_v3_v3v3_slerp_safe(result.getValue(), val0.getValue(), val1.getValue(), t);
+ return result;
+ }
+ return V3f(0.0f, 0.0f, 0.0f);
+}
+
+BLI_INLINE Quatf interpolate_sample(const Quatf &val0, const Quatf &val1, float t)
+{
+ float qt0[4] = {val0.r, val0.v.x, val0.v.y, val0.v.z};
+ float qt1[4] = {val1.r, val1.v.x, val1.v.y, val1.v.z};
+ float result[4];
+ interp_qt_qtqt(result, qt0, qt1, t);
+ return Quatf(result[0], result[1], result[2], result[3]);
+}
+
+BLI_INLINE M44f interpolate_sample(const M44f &val0, const M44f &val1, float t)
+{
+ float loc[3], quat[4], size[3];
+ float loc0[3], quat0[4], size0[3];
+ float loc1[3], quat1[4], size1[3];
+ mat4_decompose(loc0, quat0, size0, (float (*)[4])val0.getValue());
+ mat4_decompose(loc1, quat1, size1, (float (*)[4])val1.getValue());
+
+ /* linear interpolation for rotation and scale */
+ interp_v3_v3v3(loc, loc0, loc1, t);
+
+ /* use simpe nlerp instead of slerp. it's faster and almost the same */
+ interp_v4_v4v4(quat, quat0, quat1, t);
+ normalize_qt(quat);
+
+ interp_v3_v3v3(size, size0, size1, t);
+
+ M44f result;
+ loc_quat_size_to_mat4((float (*)[4])result.getValue(), loc, quat, size);
+
+ return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* These wrapper types allow calling all the interpolate_sample variants without knowing the semantics type
+ * structs are required for this, since partial specialization does not work with functions.
+ */
+
+/* forward declaration */
+template <typename ArraySampleT, typename SemanticT>
+BLI_INLINE shared_ptr<ArraySampleT> interpolate_sample(const ArraySampleT &val0, const ArraySampleT &val1, float t, SemanticT semantic);
+
+template <typename T, typename SemanticT>
+struct InterpolateSampleCaller {
+ BLI_INLINE T call(const T &val0, const T &val1, float t, SemanticT semantic)
+ {
+ return interpolate_sample(val0, val1, t, semantic);
+ }
+};
+
+template <typename T>
+struct InterpolateSampleCaller<T, InterpolateSemanticDefault> {
+ BLI_INLINE T call(const T &val0, const T &val1, float t, InterpolateSemanticDefault)
+ {
+ return interpolate_sample(val0, val1, t);
+ }
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* Scalar Properties */
+
+template <typename PropT, typename SemanticT>
+typename PropT::value_type abc_interpolate_sample_linear(const PropT &prop, chrono_t time, SemanticT semantic)
+{
+ typedef typename PropT::value_type value_type;
+
+ ISampleSelector ss0(time, ISampleSelector::kFloorIndex);
+ ISampleSelector ss1(time, ISampleSelector::kCeilIndex);
+
+ index_t index0 = ss0.getIndex(prop.getTimeSampling(), prop.getNumSamples());
+ index_t index1 = ss1.getIndex(prop.getTimeSampling(), prop.getNumSamples());
+ if (index0 == index1) {
+ /* no interpolation needed */
+ return prop.getValue(ss0);
+ }
+ else {
+ chrono_t time0 = prop.getTimeSampling()->getSampleTime(index0);
+ chrono_t time1 = prop.getTimeSampling()->getSampleTime(index1);
+
+ float t = (time1 > time0) ? (time - time0) / (time1 - time0) : 0.0f;
+ return InterpolateSampleCaller<value_type, SemanticT>::call(prop.getValue(ss0), prop.getValue(ss1), t, semantic);
+ }
+}
+
+template <typename PropT>
+typename PropT::value_type abc_interpolate_sample_linear(const PropT &prop, chrono_t time)
+{
+ return abc_interpolate_sample_linear(prop, time, InterpolateSemanticDefault_None);
+}
+
+
+/* Array Properties */
+
+template <typename ArraySampleT, typename SemanticT>
+BLI_INLINE shared_ptr<ArraySampleT> interpolate_array_sample(const ArraySampleT &val0, const ArraySampleT &val1, float t, SemanticT semantic)
+{
+ typedef ArraySampleT sample_type;
+ typedef shared_ptr<ArraySampleT> sample_ptr_type;
+ typedef typename ArraySampleT::value_type value_type;
+
+ size_t size0 = val0.size();
+ size_t size1 = val1.size();
+ size_t maxsize = size0 > size1 ? size0 : size1;
+ size_t minsize = size0 < size1 ? size0 : size1;
+
+ const value_type *data0 = val0.get();
+ const value_type *data1 = val1.get();
+ value_type *result = new value_type[maxsize];
+ value_type *data = result;
+
+ for (size_t i = 0; i < minsize; ++i) {
+ *data = InterpolateSampleCaller<value_type, SemanticT>::call(*data0, *data1, t, semantic);
+ ++data;
+ ++data0;
+ ++data1;
+ }
+
+ if (size0 > minsize) {
+ for (size_t i = minsize; i < size0; ++i) {
+ *data = *data0;
+ ++data;
+ ++data0;
+ }
+ }
+ else if (size1 > minsize) {
+ for (size_t i = minsize; i < size1; ++i) {
+ *data = *data1;
+ ++data;
+ ++data1;
+ }
+ }
+
+ return sample_ptr_type(new sample_type(result, maxsize));
+}
+
+template <typename TraitsT, typename SemanticT>
+shared_ptr<typename ITypedArrayProperty<TraitsT>::sample_type> abc_interpolate_sample_linear(const ITypedArrayProperty<TraitsT> &prop, chrono_t time, SemanticT semantic)
+{
+ ISampleSelector ss0(time, ISampleSelector::kFloorIndex);
+ ISampleSelector ss1(time, ISampleSelector::kCeilIndex);
+
+ index_t index0 = ss0.getIndex(prop.getTimeSampling(), prop.getNumSamples());
+ index_t index1 = ss1.getIndex(prop.getTimeSampling(), prop.getNumSamples());
+ if (index0 == index1) {
+ /* no interpolation needed */
+ return prop.getValue(ss0);
+ }
+ else {
+ chrono_t time0 = prop.getTimeSampling()->getSampleTime(index0);
+ chrono_t time1 = prop.getTimeSampling()->getSampleTime(index1);
+
+ float t = (time1 > time0) ? (time - time0) / (time1 - time0) : 0.0f;
+ return interpolate_array_sample(*prop.getValue(ss0), *prop.getValue(ss1), t, semantic);
+ }
+}
+
+template <typename TraitsT>
+shared_ptr<typename ITypedArrayProperty<TraitsT>::sample_type> abc_interpolate_sample_linear(const ITypedArrayProperty<TraitsT> &prop, chrono_t time)
+{
+ return abc_interpolate_sample_linear(prop, time, InterpolateSemanticDefault_None);
+}
+
+} /* namespace PTC */
+
+#endif /* PTC_ABC_INTERPOLATE_H */