From 63fb613f36a37ce51119edf36ef71a8e50d798b4 Mon Sep 17 00:00:00 2001 From: Tazpn <tazpn@users.sourceforge.net> Date: Sat, 8 Jul 2006 13:21:24 +0000 Subject: [PATCH] 1. Update niflib with bspline interpolation abilities 2. Change mergeniftrees to default phase to 0.0f instead of 1.0f as its a better default value. --- gen/obj_defines.h | 9 +- gen/obj_impl.cpp | 21 +- niflib.cpp | 2 +- obj/NiBSplineBasisData.cpp | 8 + obj/NiBSplineBasisData.h | 6 + obj/NiBSplineCompTransformInterpolator.cpp | 236 +++++++++++++++++++++ obj/NiBSplineCompTransformInterpolator.h | 93 +++++++- obj/NiBSplineData.cpp | 15 ++ obj/NiBSplineData.h | 10 + obj/NiBSplineInterpolator.cpp | 102 ++++++++- obj/NiBSplineInterpolator.h | 5 + 11 files changed, 498 insertions(+), 9 deletions(-) diff --git a/gen/obj_defines.h b/gen/obj_defines.h index 3cd44b8d..da28ac78 100644 --- a/gen/obj_defines.h +++ b/gen/obj_defines.h @@ -2196,7 +2196,12 @@ return InternalGetRefs(); \ Vector3 translation; \ Quaternion rotation; \ float scale; \ -Vector3 unkVector1; \ +ushort translateOffset; \ +ushort unkInt1; \ +ushort rotateOffset; \ +ushort unkInt2; \ +ushort scaleOffset; \ +ushort unkInt3; \ float translateBias; \ float translateMultiplier; \ float rotationBias; \ @@ -2209,7 +2214,7 @@ float scaleMultiplier; \ #define NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_PARENT NiBSplineInterpolator \ #define NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_CONSTRUCT \ - : scale(0.0f), translateBias(0.0f), translateMultiplier(0.0f), rotationBias(0.0f), rotationMultiplier(0.0f), scaleBias(0.0f), scaleMultiplier(0.0f) \ + : scale(0.0f), translateOffset((ushort)0), unkInt1((ushort)0), rotateOffset((ushort)0), unkInt2((ushort)0), scaleOffset((ushort)0), unkInt3((ushort)0), translateBias(0.0f), translateMultiplier(0.0f), rotationBias(0.0f), rotationMultiplier(0.0f), scaleBias(0.0f), scaleMultiplier(0.0f) \ #define NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_READ \ InternalRead( in, link_stack, version, user_version ); \ diff --git a/gen/obj_impl.cpp b/gen/obj_impl.cpp index df56df67..8466cbd9 100644 --- a/gen/obj_impl.cpp +++ b/gen/obj_impl.cpp @@ -4550,7 +4550,12 @@ void NiBSplineCompTransformInterpolator::InternalRead( istream& in, list<uint> & NifStream( translation, in, version ); NifStream( rotation, in, version ); NifStream( scale, in, version ); - NifStream( unkVector1, in, version ); + NifStream( translateOffset, in, version ); + NifStream( unkInt1, in, version ); + NifStream( rotateOffset, in, version ); + NifStream( unkInt2, in, version ); + NifStream( scaleOffset, in, version ); + NifStream( unkInt3, in, version ); NifStream( translateBias, in, version ); NifStream( translateMultiplier, in, version ); NifStream( rotationBias, in, version ); @@ -4564,7 +4569,12 @@ void NiBSplineCompTransformInterpolator::InternalWrite( ostream& out, map<NiObje NifStream( translation, out, version ); NifStream( rotation, out, version ); NifStream( scale, out, version ); - NifStream( unkVector1, out, version ); + NifStream( translateOffset, out, version ); + NifStream( unkInt1, out, version ); + NifStream( rotateOffset, out, version ); + NifStream( unkInt2, out, version ); + NifStream( scaleOffset, out, version ); + NifStream( unkInt3, out, version ); NifStream( translateBias, out, version ); NifStream( translateMultiplier, out, version ); NifStream( rotationBias, out, version ); @@ -4579,7 +4589,12 @@ std::string NiBSplineCompTransformInterpolator::InternalAsString( bool verbose ) out << " Translation: " << translation << endl; out << " Rotation: " << rotation << endl; out << " Scale: " << scale << endl; - out << " Unk Vector 1: " << unkVector1 << endl; + out << " Translate Offset: " << translateOffset << endl; + out << " Unk Int 1: " << unkInt1 << endl; + out << " Rotate Offset: " << rotateOffset << endl; + out << " Unk Int 2: " << unkInt2 << endl; + out << " Scale Offset: " << scaleOffset << endl; + out << " Unk Int 3: " << unkInt3 << endl; out << " Translate Bias: " << translateBias << endl; out << " Translate Multiplier: " << translateMultiplier << endl; out << " Rotation Bias: " << rotationBias << endl; diff --git a/niflib.cpp b/niflib.cpp index 9e953658..622a49f7 100644 --- a/niflib.cpp +++ b/niflib.cpp @@ -839,7 +839,7 @@ void MergeNifTrees( const Ref<NiNode> & target, const Ref<NiControllerSequence> ctlr->SetStartTime( right->GetStartTime() ); ctlr->SetStopTime( right->GetStopTime() ); ctlr->SetFrequency( right->GetFrequency() ); - ctlr->SetPhase( 1.0f ); //TODO: Is phase somewhere in NiControllerSequence? + ctlr->SetPhase( 0.0f ); //TODO: Is phase somewhere in NiControllerSequence? } } } diff --git a/obj/NiBSplineBasisData.cpp b/obj/NiBSplineBasisData.cpp index d3af49cb..18b50aac 100644 --- a/obj/NiBSplineBasisData.cpp +++ b/obj/NiBSplineBasisData.cpp @@ -35,3 +35,11 @@ const Type & NiBSplineBasisData::GetType() const { return TYPE; }; +uint NiBSplineBasisData::GetNumControlPt() const { + return numControlPt; +} + +void NiBSplineBasisData::SetNumControlPt( uint value ) { + numControlPt = value; +} + diff --git a/obj/NiBSplineBasisData.h b/obj/NiBSplineBasisData.h index ee99bff4..345893aa 100644 --- a/obj/NiBSplineBasisData.h +++ b/obj/NiBSplineBasisData.h @@ -32,6 +32,12 @@ public: virtual list<NiObjectRef> GetRefs() const; virtual const Type & GetType() const; + /*! + * The number of control points (Usually number of frames for animation). + */ + uint GetNumControlPt() const; + void SetNumControlPt( uint value ); + protected: NI_B_SPLINE_BASIS_DATA_MEMBERS STANDARD_INTERNAL_METHODS diff --git a/obj/NiBSplineCompTransformInterpolator.cpp b/obj/NiBSplineCompTransformInterpolator.cpp index ebf906ec..8885e6af 100644 --- a/obj/NiBSplineCompTransformInterpolator.cpp +++ b/obj/NiBSplineCompTransformInterpolator.cpp @@ -2,8 +2,14 @@ All rights reserved. Please see niflib.h for licence. */ #include "NiBSplineCompTransformInterpolator.h" +#include "NiBSplineBasisData.h" +#include "NiBSplineData.h" using namespace Niflib; +static const int SizeofQuat = 4; +static const int SizeofTrans = 3; +static const int SizeofScale = 1; + //Definition of TYPE constant const Type NiBSplineCompTransformInterpolator::TYPE("NiBSplineCompTransformInterpolator", &NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_PARENT::TypeConst() ); @@ -35,3 +41,233 @@ const Type & NiBSplineCompTransformInterpolator::GetType() const { return TYPE; }; +Vector3 NiBSplineCompTransformInterpolator::GetTranslation() const { + return translation; +} + +void NiBSplineCompTransformInterpolator::SetTranslation( Vector3 value ) { + translation = value; +} + +Quaternion NiBSplineCompTransformInterpolator::GetRotation() const { + return rotation; +} + +void NiBSplineCompTransformInterpolator::SetRotation( Quaternion value ) { + rotation = value; +} + +float NiBSplineCompTransformInterpolator::GetScale() const { + return scale; +} + +void NiBSplineCompTransformInterpolator::SetScale( float value ) { + scale = value; +} + +float NiBSplineCompTransformInterpolator::GetTranslateBias() const { + return translateBias; +} + +void NiBSplineCompTransformInterpolator::SetTranslateBias( float value ) { + translateBias = value; +} + +float NiBSplineCompTransformInterpolator::GetTranslateMultiplier() const { + return translateMultiplier; +} + +void NiBSplineCompTransformInterpolator::SetTranslateMultiplier( float value ) { + translateMultiplier = value; +} + +float NiBSplineCompTransformInterpolator::GetRotationBias() const { + return rotationBias; +} + +void NiBSplineCompTransformInterpolator::SetRotationBias( float value ) { + rotationBias = value; +} + +float NiBSplineCompTransformInterpolator::GetRotationMultiplier() const { + return rotationMultiplier; +} + +void NiBSplineCompTransformInterpolator::SetRotationMultiplier( float value ) { + rotationMultiplier = value; +} + +float NiBSplineCompTransformInterpolator::GetScaleBias() const { + return scaleBias; +} + +void NiBSplineCompTransformInterpolator::SetScaleBias( float value ) { + scaleBias = value; +} + +float NiBSplineCompTransformInterpolator::GetScaleMultiplier() const { + return scaleMultiplier; +} + +void NiBSplineCompTransformInterpolator::SetScaleMultiplier( float value ) { + scaleMultiplier = value; +} + +vector< Quaternion > NiBSplineCompTransformInterpolator::GetQuatRotateControlData() const +{ + vector< Quaternion > value; + if ((rotateOffset != USHRT_MAX) && splineData && basisData) { // has rotation data + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofQuat; + vector<short> points = splineData->GetControlPointRange(rotateOffset, npts); + value.reserve(nctrl); + for (int i=0; i<npts; ) { + Quaternion key; + key.w = float(points[i++]) / float (32767) * rotationMultiplier + rotationBias; + key.x = float(points[i++]) / float (32767) * rotationMultiplier + rotationBias; + key.y = float(points[i++]) / float (32767) * rotationMultiplier + rotationBias; + key.z = float(points[i++]) / float (32767) * rotationMultiplier + rotationBias; + value.push_back(key); + } + } + return value; +} + +vector< Vector3 > NiBSplineCompTransformInterpolator::GetTranslateControlData() const +{ + vector< Vector3 > value; + if ((translateOffset != USHRT_MAX) && splineData && basisData) { // has translation data + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofTrans; + vector<short> points = splineData->GetControlPointRange(translateOffset, npts); + value.reserve(nctrl); + for (int i=0; i<npts; ) { + Vector3 key; + key.x = float(points[i++]) / float (32767) * translateMultiplier + translateBias; + key.y = float(points[i++]) / float (32767) * translateMultiplier + translateBias; + key.z = float(points[i++]) / float (32767) * translateMultiplier + translateBias; + value.push_back(key); + } + } + return value; +} + +vector< float > NiBSplineCompTransformInterpolator::GetScaleControlData() const +{ + vector< float > value; + if ((scaleOffset != USHRT_MAX) && splineData && basisData) { // has translation data + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofScale; + vector<short> points = splineData->GetControlPointRange(scaleOffset, npts); + value.reserve(nctrl); + for (int i=0; i<npts; ) { + float data = float(points[i++]) / float (32767) * scaleMultiplier + scaleBias; + value.push_back(data); + } + } + return value; +} + +vector< Key<Quaternion> > NiBSplineCompTransformInterpolator::SampleQuatRotateKeys(int npoints, int degree) const +{ + vector< Key<Quaternion> > value; + if ((rotateOffset != USHRT_MAX) && splineData && basisData) { // has rotation data + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofQuat; + vector<short> points = splineData->GetControlPointRange(rotateOffset, npts); + vector<float> control(npts); + vector<float> output(npoints*SizeofQuat); + for (int i=0, j=0; i<nctrl; ++i) { + for (int k=0; k<SizeofQuat; ++k) + control[i*SizeofQuat + k] = float(points[j++]) / float (32767); + } + // fit data + bspline(nctrl-1, degree+1, SizeofQuat, &control[0], &output[0], npoints); + + // copy to key + float time = GetStartTime(); + float incr = (GetStopTime() - GetStartTime()) / float(npoints) ; + value.reserve(npoints); + for (int i=0, j=0; i<npoints; i++) { + Key<Quaternion> key; + key.time = time; + key.backward_tangent.Set(1.0f,0.0f,0.0f,0.0f); + key.forward_tangent.Set(1.0f,0.0f,0.0f,0.0f); + key.data.w = output[j++] * rotationMultiplier + rotationBias; + key.data.x = output[j++] * rotationMultiplier + rotationBias; + key.data.y = output[j++] * rotationMultiplier + rotationBias; + key.data.z = output[j++] * rotationMultiplier + rotationBias; + value.push_back(key); + time += incr; + } + } + return value; +} + +vector< Key<Vector3> > NiBSplineCompTransformInterpolator::SampleTranslateKeys(int npoints, int degree) const +{ + vector< Key<Vector3> > value; + if ((translateOffset != USHRT_MAX) && splineData && basisData) { // has rotation data + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofTrans; + vector<short> points = splineData->GetControlPointRange(translateOffset, npts); + vector<float> control(npts); + vector<float> output(npoints*SizeofTrans); + for (int i=0, j=0; i<nctrl; ++i) { + for (int k=0; k<SizeofTrans; ++k) + control[i*SizeofTrans + k] = float(points[j++]) / float (32767); + } + // fit data + bspline(nctrl-1, degree+1, SizeofTrans, &control[0], &output[0], npoints); + + // copy to key + float time = GetStartTime(); + float incr = (GetStopTime() - GetStartTime()) / float(npoints) ; + value.reserve(npoints); + for (int i=0, j=0; i<npoints; i++) { + Key<Vector3> key; + key.time = time; + key.backward_tangent.Set(0.0f,0.0f,0.0f); + key.forward_tangent.Set(0.0f,0.0f,0.0f); + key.data.x = output[j++] * translateMultiplier + translateBias; + key.data.y = output[j++] * translateMultiplier + translateBias; + key.data.z = output[j++] * translateMultiplier + translateBias; + value.push_back(key); + time += incr; + } + } + return value; +} + +vector< Key<float> > NiBSplineCompTransformInterpolator::SampleScaleKeys(int npoints, int degree) const +{ + vector< Key<float> > value; + if ((scaleOffset != USHRT_MAX) && splineData && basisData) // has rotation data + { + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofScale; + vector<short> points = splineData->GetControlPointRange(scaleOffset, npts); + vector<float> control(npts); + vector<float> output(npoints*SizeofScale); + for (int i=0, j=0; i<nctrl; ++i) { + control[i] = float(points[j++]) / float (32767); + } + // fit data + bspline(nctrl-1, degree+1, SizeofScale, &control[0], &output[0], npoints); + + // copy to key + float time = GetStartTime(); + float incr = (GetStopTime() - GetStartTime()) / float(npoints) ; + value.reserve(npoints); + for (int i=0, j=0; i<npoints; i++) { + Key<float> key; + key.time = time; + key.backward_tangent = 0.0f; + key.forward_tangent = 0.0f; + key.data = output[j++] * scaleMultiplier + scaleBias; + value.push_back(key); + time += incr; + } + } + return value; +} \ No newline at end of file diff --git a/obj/NiBSplineCompTransformInterpolator.h b/obj/NiBSplineCompTransformInterpolator.h index 408d81fd..e8297e00 100644 --- a/obj/NiBSplineCompTransformInterpolator.h +++ b/obj/NiBSplineCompTransformInterpolator.h @@ -16,9 +16,8 @@ class NiBSplineCompTransformInterpolator; typedef Ref<NiBSplineCompTransformInterpolator> NiBSplineCompTransformInterpolatorRef; /*! - * NiBSplineCompTransformInterpolator - Unknown. + * NiBSplineCompTransformInterpolator */ - class NIFLIB_API NiBSplineCompTransformInterpolator : public NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_PARENT { public: NiBSplineCompTransformInterpolator(); @@ -35,6 +34,96 @@ public: virtual list<NiObjectRef> GetRefs() const; virtual const Type & GetType() const; + /*! + * Base translation when translate curve not defined. + */ + Vector3 GetTranslation() const; + void SetTranslation( Vector3 value ); + + /*! + * Base rotation when rotation curve not defined. + */ + Quaternion GetRotation() const; + void SetRotation( Quaternion value ); + + /*! + * Base scale when scale curve not defined. + */ + float GetScale() const; + void SetScale( float value ); + + /*! + * Translate Bias + */ + float GetTranslateBias() const; + void SetTranslateBias( float value ); + + /*! + * Translate Multiplier + */ + float GetTranslateMultiplier() const; + void SetTranslateMultiplier( float value ); + + /*! + * Rotation Bias + */ + float GetRotationBias() const; + void SetRotationBias( float value ); + + /*! + * Rotation Multiplier + */ + float GetRotationMultiplier() const; + void SetRotationMultiplier( float value ); + + /*! + * Scale Bias + */ + float GetScaleBias() const; + void SetScaleBias( float value ); + + /*! + * Scale Multiplier + */ + float GetScaleMultiplier() const; + void SetScaleMultiplier( float value ); + + /*! Retrieves the control quaternion rotation data. + * \return A vector containing control Quaternion data which specify rotation over time. + */ + vector< Quaternion > GetQuatRotateControlData() const; + + /*! Retrieves the control translation data. + * \return A vector containing control Vector3 data which specify translation over time. + */ + vector< Vector3 > GetTranslateControlData() const; + + /*! Retrieves the scale key data. + * \return A vector containing control float data which specify scale over time. + */ + vector< float > GetScaleControlData() const; + + /*! Retrieves the sampled quaternion rotation key data between start and stop time. + * \param npoints The number of data points to sample between start and stop time. + * \param degree N-th order degree of polynomial used to fit the data. + * \return A vector containing Key<Quaternion> data which specify rotation over time. + */ + vector< Key<Quaternion> > SampleQuatRotateKeys(int npoints, int degree) const; + + /*! Retrieves the sampled scale key data between start and stop time. + * \param npoints The number of data points to sample between start and stop time. + * \param degree N-th order degree of polynomial used to fit the data. + * \return A vector containing Key<Vector3> data which specify translation over time. + */ + vector< Key<Vector3> > SampleTranslateKeys(int npoints, int degree) const; + + /*! Retrieves the sampled scale key data between start and stop time. + * \param npoints The number of data points to sample between start and stop time. + * \param degree N-th order degree of polynomial used to fit the data. + * \return A vector containing Key<float> data which specify scale over time. + */ + vector< Key<float> > SampleScaleKeys(int npoints, int degree) const; + protected: NI_B_SPLINE_COMP_TRANSFORM_INTERPOLATOR_MEMBERS STANDARD_INTERNAL_METHODS diff --git a/obj/NiBSplineData.cpp b/obj/NiBSplineData.cpp index 9f6decde..91cc61bb 100644 --- a/obj/NiBSplineData.cpp +++ b/obj/NiBSplineData.cpp @@ -35,3 +35,18 @@ const Type & NiBSplineData::GetType() const { return TYPE; }; +vector<short > NiBSplineData::GetControlPoints() const +{ + return controlPoints; +} + +vector<short > NiBSplineData::GetControlPointRange(int offset, int count) const +{ + vector<short> value; + if (offset < 0 || count < 0 || ((offset + count) > int(controlPoints.size()))) + throw runtime_error("Invalid offset or count."); + vector<short>::const_iterator srcbeg = controlPoints.begin(), srcend = controlPoints.begin(); + std::advance(srcbeg, offset); + std::advance(srcend, offset + count); + return vector<short>(srcbeg, srcend); +} \ No newline at end of file diff --git a/obj/NiBSplineData.h b/obj/NiBSplineData.h index 1d8bfa4d..261ea1b6 100644 --- a/obj/NiBSplineData.h +++ b/obj/NiBSplineData.h @@ -32,6 +32,16 @@ public: virtual list<NiObjectRef> GetRefs() const; virtual const Type & GetType() const; + /*! + * Get Signed shorts representing the data scaled by SHRT_MAX. + */ + vector<short > GetControlPoints() const; + + /*! + * Get Range of signed shorts representing the data scaled by SHRT_MAX. + */ + vector<short > GetControlPointRange(int offset, int count) const; + protected: NI_B_SPLINE_DATA_MEMBERS STANDARD_INTERNAL_METHODS diff --git a/obj/NiBSplineInterpolator.cpp b/obj/NiBSplineInterpolator.cpp index ea280a1b..4a1d1dd2 100644 --- a/obj/NiBSplineInterpolator.cpp +++ b/obj/NiBSplineInterpolator.cpp @@ -67,4 +67,104 @@ Ref<NiBSplineBasisData > NiBSplineInterpolator::GetBasisData() const { void NiBSplineInterpolator::SetBasisData( Ref<NiBSplineBasisData > value ) { basisData = value; -} \ No newline at end of file +} +/********************************************************************* +Simple b-spline curve algorithm + +Copyright 1994 by Keith Vertanen (vertankd@cda.mrs.umn.edu) + +Released to the public domain (your mileage may vary) + +Found at: Programmers Heaven (www.programmersheaven.com/zone3/cat415/6660.htm) +Modified by: Theo +- reformat and convert doubles to floats +- removed point structure in favor of arbitrary sized float array +**********************************************************************/ +static void copy_floats(float* dest, float *src, int l) +{ + for (int i=0; i<l; ++i) + dest[i] = src[i]; +} + +// calculate the blending value +static float blend(int k, int t, int *u, float v) +{ + float value; + if (t==1) { // base case for the recursion + value = ((u[k]<=v) && (v<u[k+1])) ? 1.0f : 0.0f; + } else { + if ((u[k+t-1]==u[k]) && (u[k+t]==u[k+1])) // check for divide by zero + value = 0; + else if (u[k+t-1]==u[k]) // if a term's denominator is zero,use just the other + value = (u[k+t] - v) / (u[k+t] - u[k+1]) * blend(k+1, t-1, u, v); + else if (u[k+t]==u[k+1]) + value = (v - u[k]) / (u[k+t-1] - u[k]) * blend(k, t-1, u, v); + else + value = (v - u[k]) / (u[k+t-1] - u[k]) * blend(k, t-1, u, v) + + (u[k+t] - v) / (u[k+t] - u[k+1]) * blend(k+1, t-1, u, v); + } + return value; +} + +// figure out the knots +static void compute_intervals(int *u, int n, int t) +{ + for (int j=0; j<=n+t; j++) { + if (j<t) + u[j]=0; + else if ((t<=j) && (j<=n)) + u[j]=j-t+1; + else if (j>n) + u[j]=n-t+2; // if n-t=-2 then we're screwed, everything goes to 0 + } +} + +static void compute_point(int *u, int n, int t, float v, int l, float *control, float *output) +{ + // initialize the variables that will hold our output + for (int j=0; j<l; j++) + output[j] = 0; + for (int k=0; k<=n; k++) { + float temp = blend(k,t,u,v); // same blend is used for each dimension coordinate + for (int j=0; j<l; j++) + output[j] = output[j] + control[k*l + j] * temp; + } +} + +/********************************************************************* +bspline(int n, int t, int l, float *control, float *output, int num_output) + +Parameters: +n - the number of control points minus 1 +t - the degree of the polynomial plus 1 +l - size of control and output float vector block +control - control point array made up of float structure +output - array in which the calculate spline points are to be put +num_output - how many points on the spline are to be calculated + +Pre-conditions: +n+2>t (no curve results if n+2<=t) +control array contains the number of points specified by n +output array is the proper size to hold num_output point structures + +control and output vectors must be contiguous float arrays + +**********************************************************************/ +void NiBSplineInterpolator::bspline(int n, int t, int l, float *control, float *output, int num_output) +{ + float *calc = new float[l]; + int *u = new int[n+t+1]; + compute_intervals(u, n, t); + + float increment=(float)(n-t+2)/(num_output-1); // how much parameter goes up each time + float interval=0; + for (int output_index=0; output_index<num_output-1; output_index++) { + compute_point(u, n, t, interval, l, control, calc); + copy_floats(&output[output_index*l], calc, l); + interval=interval+increment; // increment our parameter + } + copy_floats(&output[(num_output-1)*l], &control[n*l], l); // put in the last points + delete [] u; + delete [] calc; +} + diff --git a/obj/NiBSplineInterpolator.h b/obj/NiBSplineInterpolator.h index c3feaabd..4cef7d35 100644 --- a/obj/NiBSplineInterpolator.h +++ b/obj/NiBSplineInterpolator.h @@ -60,6 +60,11 @@ public: Ref<NiBSplineBasisData > GetBasisData() const; void SetBasisData( Ref<NiBSplineBasisData > value ); +protected: + + // internal method for bspline calculation in child classes + static void bspline(int n, int t, int l, float *control, float *output, int num_output); + protected: NI_B_SPLINE_INTERPOLATOR_MEMBERS STANDARD_INTERNAL_METHODS -- GitLab