diff --git a/include/obj/NiBSplineCompTransformInterpolator.h b/include/obj/NiBSplineCompTransformInterpolator.h index 750a91f543b1f926070d9210f1765d49d671694c..39451391340a7531ece7208974df3b89d9085d4a 100644 --- a/include/obj/NiBSplineCompTransformInterpolator.h +++ b/include/obj/NiBSplineCompTransformInterpolator.h @@ -54,42 +54,6 @@ public: //--BEGIN MISC CUSTOM CODE--// - /*! - * Gets the base translation when a translate curve is not defined. - * \return The base translation. - */ - NIFLIB_API Vector3 GetTranslation() const; - - /*! - * Sets the base translation when a translate curve is not defined. - * \param[in] value The new base translation. - */ - NIFLIB_API void SetTranslation( Vector3 value ); - - /*! - * Gets the base rotation when a translate curve is not defined. - * \return The base rotation. - */ - NIFLIB_API Quaternion GetRotation() const; - - /*! - * Sets the base rotation when a translate curve is not defined. - * \param[in] value The new base rotation. - */ - NIFLIB_API void SetRotation( Quaternion value ); - - /*! - * Gets the base scale when a translate curve is not defined. - * \return The base scale. - */ - NIFLIB_API float GetScale() const; - - /*! - * Sets the base scale when a translate curve is not defined. - * \param[in] value The new base scale. - */ - NIFLIB_API void SetScale( float value ); - /*! * Gets translate bias. * \return The translate bias. @@ -212,18 +176,6 @@ public: //--END CUSTOM CODE--// protected: - /*! Base translation when translate curve not defined. */ - Vector3 translation; - /*! Base rotation when rotation curve not defined. */ - Quaternion rotation; - /*! Base scale when scale curve not defined. */ - float scale; - /*! Starting offset for the translation data. (USHRT_MAX for no data.) */ - unsigned int translateOffset; - /*! Starting offset for the rotation data. (USHRT_MAX for no data.) */ - unsigned int rotateOffset; - /*! Starting offset for the scale data. (USHRT_MAX for no data.) */ - unsigned int scaleOffset; /*! Translate Bias */ float translateBias; /*! Translate Multiplier */ diff --git a/include/obj/NiBSplineData.h b/include/obj/NiBSplineData.h index 9aa75b04bd60285f291b0a1c2e8ab83a9921f52c..efd2ec6203a2b9a56b11ec2ddeb8148f00f63e06 100644 --- a/include/obj/NiBSplineData.h +++ b/include/obj/NiBSplineData.h @@ -54,11 +54,25 @@ public: //--BEGIN MISC CUSTOM CODE--// + /*! + * Get floats representing the spline data. + * \return The spline data. + */ + NIFLIB_API vector<float> GetFloatControlPoints() const; + + /*! + * Get Range of signed shorts representing the data scaled by SHRT_MAX. + * \param[in] offset The start of the range. + * \param[in] count The number of control points to get. + * \return The control points that fall within the specified range. + */ + NIFLIB_API vector<float> GetFloatControlPointRange(int offset, int count) const; + /*! * Get Signed shorts representing the spline data scaled by SHRT_MAX. * \return The spline data. */ - NIFLIB_API vector<short> GetControlPoints() const; + NIFLIB_API vector<short> GetShortControlPoints() const; /*! * Get Range of signed shorts representing the data scaled by SHRT_MAX. @@ -66,16 +80,18 @@ public: * \param[in] count The number of control points to get. * \return The control points that fall within the specified range. */ - NIFLIB_API vector<short> GetControlPointRange(int offset, int count) const; + NIFLIB_API vector<short> GetShortControlPointRange(int offset, int count) const; //--END CUSTOM CODE--// protected: - /*! Unknown. Zero? */ - unsigned int unknownInt; - /*! Number of Data Points */ - mutable unsigned int count; + /*! Number of Float Data Points */ + mutable unsigned int floatCount; + /*! Float values representing the control data. */ + vector<float > floatControlPoints; + /*! Number of Short Data Points */ + mutable unsigned int shortCount; /*! Signed shorts representing the data from 0 to 1 (scaled by SHRT_MAX). */ - vector<short > controlPoints; + vector<short > shortControlPoints; public: /*! NIFLIB_HIDDEN function. For internal use only. */ NIFLIB_HIDDEN virtual void Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ); diff --git a/include/obj/NiBSplineTransformInterpolator.h b/include/obj/NiBSplineTransformInterpolator.h index c667df6080ce538081da7937f64c0b712a4b9532..395663345ca36332f7260825f52aedb76e2fe44b 100644 --- a/include/obj/NiBSplineTransformInterpolator.h +++ b/include/obj/NiBSplineTransformInterpolator.h @@ -53,7 +53,105 @@ public: NIFLIB_API virtual const Type & GetType() const; //--BEGIN MISC CUSTOM CODE--// + + /*! + * Gets the base translation when a translate curve is not defined. + * \return The base translation. + */ + NIFLIB_API Vector3 GetTranslation() const; + + /*! + * Sets the base translation when a translate curve is not defined. + * \param[in] value The new base translation. + */ + NIFLIB_API void SetTranslation( Vector3 value ); + + /*! + * Gets the base rotation when a translate curve is not defined. + * \return The base rotation. + */ + NIFLIB_API Quaternion GetRotation() const; + + /*! + * Sets the base rotation when a translate curve is not defined. + * \param[in] value The new base rotation. + */ + NIFLIB_API void SetRotation( Quaternion value ); + + /*! + * Gets the base scale when a translate curve is not defined. + * \return The base scale. + */ + NIFLIB_API float GetScale() const; + + /*! + * Sets the base scale when a translate curve is not defined. + * \param[in] value The new base scale. + */ + NIFLIB_API void SetScale( float value ); + + + /*! + * Retrieves the control quaternion rotation data. + * \return A vector containing control Quaternion data which specify rotation over time. + */ + NIFLIB_API virtual vector< Quaternion > GetQuatRotateControlData() const; + + /*! + * Retrieves the control translation data. + * \return A vector containing control Vector3 data which specify translation over time. + */ + NIFLIB_API virtual vector< Vector3 > GetTranslateControlData() const; + + /*! + * Retrieves the scale key data. + * \return A vector containing control float data which specify scale over time. + */ + NIFLIB_API virtual 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. + */ + NIFLIB_API virtual 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. + */ + NIFLIB_API virtual 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. + */ + NIFLIB_API virtual vector< Key<float> > SampleScaleKeys(int npoints, int degree) const; + + /*! + * Retrieves the number of control points used in the spline curve. + * \return The number of control points used in the spline curve. + */ + NIFLIB_API virtual int GetNumControlPt() const; //--END CUSTOM CODE--// +protected: + /*! Base translation when translate curve not defined. */ + Vector3 translation; + /*! Base rotation when rotation curve not defined. */ + Quaternion rotation; + /*! Base scale when scale curve not defined. */ + float scale; + /*! Starting offset for the translation data. (USHRT_MAX for no data.) */ + unsigned int translateOffset; + /*! Starting offset for the rotation data. (USHRT_MAX for no data.) */ + unsigned int rotateOffset; + /*! Starting offset for the scale data. (USHRT_MAX for no data.) */ + unsigned int scaleOffset; public: /*! NIFLIB_HIDDEN function. For internal use only. */ NIFLIB_HIDDEN virtual void Read( istream& in, list<unsigned int> & link_stack, const NifInfo & info ); diff --git a/src/obj/NiBSplineCompFloatInterpolator.cpp b/src/obj/NiBSplineCompFloatInterpolator.cpp index ca630f2c147d8c682dec8fea6a3e519bc310efb2..eb4ce7015288421e07619c2a85f4e5b788c47807 100644 --- a/src/obj/NiBSplineCompFloatInterpolator.cpp +++ b/src/obj/NiBSplineCompFloatInterpolator.cpp @@ -134,7 +134,7 @@ vector< float > NiBSplineCompFloatInterpolator::GetControlData() const if ((offset != USHRT_MAX) && splineData && basisData) { // has translation data int nctrl = basisData->GetNumControlPt(); int npts = nctrl * SizeofValue; - vector<short> points = splineData->GetControlPointRange(offset, npts); + vector<short> points = splineData->GetShortControlPointRange(offset, npts); value.reserve(nctrl); for (int i=0; i<npts; ) { float data = float(points[i++]) / float (32767) * multiplier + bias; @@ -152,7 +152,7 @@ vector< Key<float> > NiBSplineCompFloatInterpolator::SampleKeys(int npoints, int { int nctrl = basisData->GetNumControlPt(); int npts = nctrl * SizeofValue; - vector<short> points = splineData->GetControlPointRange(offset, npts); + vector<short> points = splineData->GetShortControlPointRange(offset, npts); vector<float> control(npts); vector<float> output(npoints*SizeofValue); for (int i=0, j=0; i<nctrl; ++i) { diff --git a/src/obj/NiBSplineCompTransformInterpolator.cpp b/src/obj/NiBSplineCompTransformInterpolator.cpp index 2846b128a7079aeccff9a7ba2387190d78970bd1..15b683618c68c494940e7d903dabc1eab31126a8 100644 --- a/src/obj/NiBSplineCompTransformInterpolator.cpp +++ b/src/obj/NiBSplineCompTransformInterpolator.cpp @@ -26,7 +26,7 @@ using namespace Niflib; //Definition of TYPE constant const Type NiBSplineCompTransformInterpolator::TYPE("NiBSplineCompTransformInterpolator", &NiBSplineTransformInterpolator::TYPE ); -NiBSplineCompTransformInterpolator::NiBSplineCompTransformInterpolator() : scale(0.0f), translateOffset((unsigned int)0), rotateOffset((unsigned int)0), scaleOffset((unsigned int)0), translateBias(0.0f), translateMultiplier(0.0f), rotationBias(0.0f), rotationMultiplier(0.0f), scaleBias(0.0f), scaleMultiplier(0.0f) { +NiBSplineCompTransformInterpolator::NiBSplineCompTransformInterpolator() : translateBias(0.0f), translateMultiplier(0.0f), rotationBias(0.0f), rotationMultiplier(0.0f), scaleBias(0.0f), scaleMultiplier(0.0f) { //--BEGIN CONSTRUCTOR CUSTOM CODE--// //--END CUSTOM CODE--// } @@ -49,12 +49,6 @@ void NiBSplineCompTransformInterpolator::Read( istream& in, list<unsigned int> & //--END CUSTOM CODE--// NiBSplineTransformInterpolator::Read( in, link_stack, info ); - NifStream( translation, in, info ); - NifStream( rotation, in, info ); - NifStream( scale, in, info ); - NifStream( translateOffset, in, info ); - NifStream( rotateOffset, in, info ); - NifStream( scaleOffset, in, info ); NifStream( translateBias, in, info ); NifStream( translateMultiplier, in, info ); NifStream( rotationBias, in, info ); @@ -71,12 +65,6 @@ void NiBSplineCompTransformInterpolator::Write( ostream& out, const map<NiObject //--END CUSTOM CODE--// NiBSplineTransformInterpolator::Write( out, link_map, info ); - NifStream( translation, out, info ); - NifStream( rotation, out, info ); - NifStream( scale, out, info ); - NifStream( translateOffset, out, info ); - NifStream( rotateOffset, out, info ); - NifStream( scaleOffset, out, info ); NifStream( translateBias, out, info ); NifStream( translateMultiplier, out, info ); NifStream( rotationBias, out, info ); @@ -95,12 +83,6 @@ std::string NiBSplineCompTransformInterpolator::asString( bool verbose ) const { stringstream out; unsigned int array_output_count = 0; out << NiBSplineTransformInterpolator::asString(); - out << " Translation: " << translation << endl; - out << " Rotation: " << rotation << endl; - out << " Scale: " << scale << endl; - out << " Translate Offset: " << translateOffset << endl; - out << " Rotate Offset: " << rotateOffset << endl; - out << " Scale Offset: " << scaleOffset << endl; out << " Translate Bias: " << translateBias << endl; out << " Translate Multiplier: " << translateMultiplier << endl; out << " Rotation Bias: " << rotationBias << endl; @@ -131,30 +113,6 @@ std::list<NiObjectRef> NiBSplineCompTransformInterpolator::GetRefs() const { //--BEGIN MISC CUSTOM CODE--// -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; } @@ -209,7 +167,7 @@ vector< Quaternion > NiBSplineCompTransformInterpolator::GetQuatRotateControlDat 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<short> points = splineData->GetShortControlPointRange(rotateOffset, npts); value.reserve(nctrl); for (int i=0; i<npts; ) { Quaternion key; @@ -229,7 +187,7 @@ vector< Vector3 > NiBSplineCompTransformInterpolator::GetTranslateControlData() if ((translateOffset != USHRT_MAX) && splineData && basisData) { // has translation data int nctrl = basisData->GetNumControlPt(); int npts = nctrl * SizeofTrans; - vector<short> points = splineData->GetControlPointRange(translateOffset, npts); + vector<short> points = splineData->GetShortControlPointRange(translateOffset, npts); value.reserve(nctrl); for (int i=0; i<npts; ) { Vector3 key; @@ -248,7 +206,7 @@ vector< float > NiBSplineCompTransformInterpolator::GetScaleControlData() const if ((scaleOffset != USHRT_MAX) && splineData && basisData) { // has translation data int nctrl = basisData->GetNumControlPt(); int npts = nctrl * SizeofScale; - vector<short> points = splineData->GetControlPointRange(scaleOffset, npts); + vector<short> points = splineData->GetShortControlPointRange(scaleOffset, npts); value.reserve(nctrl); for (int i=0; i<npts; ) { float data = float(points[i++]) / float (32767) * scaleMultiplier + scaleBias; @@ -264,7 +222,7 @@ vector< Key<Quaternion> > NiBSplineCompTransformInterpolator::SampleQuatRotateKe 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<short> points = splineData->GetShortControlPointRange(rotateOffset, npts); vector<float> control(npts); vector<float> output(npoints*SizeofQuat); for (int i=0, j=0; i<nctrl; ++i) { @@ -302,7 +260,7 @@ vector< Key<Vector3> > NiBSplineCompTransformInterpolator::SampleTranslateKeys(i 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<short> points = splineData->GetShortControlPointRange(translateOffset, npts); vector<float> control(npts); vector<float> output(npoints*SizeofTrans); for (int i=0, j=0; i<nctrl; ++i) { @@ -338,7 +296,7 @@ vector< Key<float> > NiBSplineCompTransformInterpolator::SampleScaleKeys(int npo { int nctrl = basisData->GetNumControlPt(); int npts = nctrl * SizeofScale; - vector<short> points = splineData->GetControlPointRange(scaleOffset, npts); + vector<short> points = splineData->GetShortControlPointRange(scaleOffset, npts); vector<float> control(npts); vector<float> output(npoints*SizeofScale); for (int i=0, j=0; i<nctrl; ++i) { diff --git a/src/obj/NiBSplineData.cpp b/src/obj/NiBSplineData.cpp index c8ecb7ea72a795ffdb19cd883d41d517b8bf9322..133d6669ebe31e2e2c7716811ef48db5641422a9 100644 --- a/src/obj/NiBSplineData.cpp +++ b/src/obj/NiBSplineData.cpp @@ -19,7 +19,7 @@ using namespace Niflib; //Definition of TYPE constant const Type NiBSplineData::TYPE("NiBSplineData", &NiObject::TYPE ); -NiBSplineData::NiBSplineData() : unknownInt((unsigned int)0), count((unsigned int)0) { +NiBSplineData::NiBSplineData() : floatCount((unsigned int)0), shortCount((unsigned int)0) { //--BEGIN CONSTRUCTOR CUSTOM CODE--// //--END CUSTOM CODE--// } @@ -42,11 +42,15 @@ void NiBSplineData::Read( istream& in, list<unsigned int> & link_stack, const Ni //--END CUSTOM CODE--// NiObject::Read( in, link_stack, info ); - NifStream( unknownInt, in, info ); - NifStream( count, in, info ); - controlPoints.resize(count); - for (unsigned int i1 = 0; i1 < controlPoints.size(); i1++) { - NifStream( controlPoints[i1], in, info ); + NifStream( floatCount, in, info ); + floatControlPoints.resize(floatCount); + for (unsigned int i1 = 0; i1 < floatControlPoints.size(); i1++) { + NifStream( floatControlPoints[i1], in, info ); + }; + NifStream( shortCount, in, info ); + shortControlPoints.resize(shortCount); + for (unsigned int i1 = 0; i1 < shortControlPoints.size(); i1++) { + NifStream( shortControlPoints[i1], in, info ); }; //--BEGIN POST-READ CUSTOM CODE--// @@ -58,11 +62,15 @@ void NiBSplineData::Write( ostream& out, const map<NiObjectRef,unsigned int> & l //--END CUSTOM CODE--// NiObject::Write( out, link_map, info ); - count = (unsigned int)(controlPoints.size()); - NifStream( unknownInt, out, info ); - NifStream( count, out, info ); - for (unsigned int i1 = 0; i1 < controlPoints.size(); i1++) { - NifStream( controlPoints[i1], out, info ); + shortCount = (unsigned int)(shortControlPoints.size()); + floatCount = (unsigned int)(floatControlPoints.size()); + NifStream( floatCount, out, info ); + for (unsigned int i1 = 0; i1 < floatControlPoints.size(); i1++) { + NifStream( floatControlPoints[i1], out, info ); + }; + NifStream( shortCount, out, info ); + for (unsigned int i1 = 0; i1 < shortControlPoints.size(); i1++) { + NifStream( shortControlPoints[i1], out, info ); }; //--BEGIN POST-WRITE CUSTOM CODE--// @@ -76,11 +84,24 @@ std::string NiBSplineData::asString( bool verbose ) const { stringstream out; unsigned int array_output_count = 0; out << NiObject::asString(); - count = (unsigned int)(controlPoints.size()); - out << " Unknown Int: " << unknownInt << endl; - out << " Count: " << count << endl; + shortCount = (unsigned int)(shortControlPoints.size()); + floatCount = (unsigned int)(floatControlPoints.size()); + out << " Float Count: " << floatCount << endl; + array_output_count = 0; + for (unsigned int i1 = 0; i1 < floatControlPoints.size(); i1++) { + if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) { + out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl; + break; + }; + if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) { + break; + }; + out << " Float Control Points[" << i1 << "]: " << floatControlPoints[i1] << endl; + array_output_count++; + }; + out << " Short Count: " << shortCount << endl; array_output_count = 0; - for (unsigned int i1 = 0; i1 < controlPoints.size(); i1++) { + for (unsigned int i1 = 0; i1 < shortControlPoints.size(); i1++) { if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) { out << "<Data Truncated. Use verbose mode to see complete listing.>" << endl; break; @@ -88,7 +109,7 @@ std::string NiBSplineData::asString( bool verbose ) const { if ( !verbose && ( array_output_count > MAXARRAYDUMP ) ) { break; }; - out << " Control Points[" << i1 << "]: " << controlPoints[i1] << endl; + out << " Short Control Points[" << i1 << "]: " << shortControlPoints[i1] << endl; array_output_count++; }; return out.str(); @@ -115,17 +136,33 @@ std::list<NiObjectRef> NiBSplineData::GetRefs() const { //--BEGIN MISC CUSTOM CODE--// -vector<short > NiBSplineData::GetControlPoints() const +vector<float> NiBSplineData::GetFloatControlPoints() const +{ + return floatControlPoints; +} + +vector<float> NiBSplineData::GetFloatControlPointRange(int offset, int count) const +{ + vector<float> value; + if (offset < 0 || count < 0 || ((offset + count) > int(floatControlPoints.size()))) + throw runtime_error("Invalid offset or count."); + vector<float>::const_iterator srcbeg = floatControlPoints.begin(), srcend = floatControlPoints.begin(); + std::advance(srcbeg, offset); + std::advance(srcend, offset + count); + return vector<float>(srcbeg, srcend); +} + +vector<short > NiBSplineData::GetShortControlPoints() const { - return controlPoints; + return shortControlPoints; } -vector<short > NiBSplineData::GetControlPointRange(int offset, int count) const +vector<short > NiBSplineData::GetShortControlPointRange(int offset, int count) const { vector<short> value; - if (offset < 0 || count < 0 || ((offset + count) > int(controlPoints.size()))) + if (offset < 0 || count < 0 || ((offset + count) > int(shortControlPoints.size()))) throw runtime_error("Invalid offset or count."); - vector<short>::const_iterator srcbeg = controlPoints.begin(), srcend = controlPoints.begin(); + vector<short>::const_iterator srcbeg = shortControlPoints.begin(), srcend = shortControlPoints.begin(); std::advance(srcbeg, offset); std::advance(srcend, offset + count); return vector<short>(srcbeg, srcend); diff --git a/src/obj/NiBSplineTransformInterpolator.cpp b/src/obj/NiBSplineTransformInterpolator.cpp index 6eb200a1e759530d0fdfcab7b945b184943464f1..4cd746d4574158f31b198eca7ced4bda37ed8757 100644 --- a/src/obj/NiBSplineTransformInterpolator.cpp +++ b/src/obj/NiBSplineTransformInterpolator.cpp @@ -8,6 +8,12 @@ All rights reserved. Please see niflib.h for license. */ //-----------------------------------NOTICE----------------------------------// //--BEGIN FILE HEAD CUSTOM CODE--// +#include "../../include/obj/NiBSplineBasisData.h" +#include "../../include/obj/NiBSplineData.h" + +static const int SizeofQuat = 4; +static const int SizeofTrans = 3; +static const int SizeofScale = 1; //--END CUSTOM CODE--// #include "../../include/FixLink.h" @@ -19,7 +25,7 @@ using namespace Niflib; //Definition of TYPE constant const Type NiBSplineTransformInterpolator::TYPE("NiBSplineTransformInterpolator", &NiBSplineInterpolator::TYPE ); -NiBSplineTransformInterpolator::NiBSplineTransformInterpolator() { +NiBSplineTransformInterpolator::NiBSplineTransformInterpolator() : scale(0.0f), translateOffset((unsigned int)0), rotateOffset((unsigned int)0), scaleOffset((unsigned int)0) { //--BEGIN CONSTRUCTOR CUSTOM CODE--// //--END CUSTOM CODE--// } @@ -42,6 +48,12 @@ void NiBSplineTransformInterpolator::Read( istream& in, list<unsigned int> & lin //--END CUSTOM CODE--// NiBSplineInterpolator::Read( in, link_stack, info ); + NifStream( translation, in, info ); + NifStream( rotation, in, info ); + NifStream( scale, in, info ); + NifStream( translateOffset, in, info ); + NifStream( rotateOffset, in, info ); + NifStream( scaleOffset, in, info ); //--BEGIN POST-READ CUSTOM CODE--// //--END CUSTOM CODE--// @@ -52,6 +64,12 @@ void NiBSplineTransformInterpolator::Write( ostream& out, const map<NiObjectRef, //--END CUSTOM CODE--// NiBSplineInterpolator::Write( out, link_map, info ); + NifStream( translation, out, info ); + NifStream( rotation, out, info ); + NifStream( scale, out, info ); + NifStream( translateOffset, out, info ); + NifStream( rotateOffset, out, info ); + NifStream( scaleOffset, out, info ); //--BEGIN POST-WRITE CUSTOM CODE--// //--END CUSTOM CODE--// @@ -64,6 +82,12 @@ std::string NiBSplineTransformInterpolator::asString( bool verbose ) const { stringstream out; unsigned int array_output_count = 0; out << NiBSplineInterpolator::asString(); + out << " Translation: " << translation << endl; + out << " Rotation: " << rotation << endl; + out << " Scale: " << scale << endl; + out << " Translate Offset: " << translateOffset << endl; + out << " Rotate Offset: " << rotateOffset << endl; + out << " Scale Offset: " << scaleOffset << endl; return out.str(); //--BEGIN POST-STRING CUSTOM CODE--// @@ -87,4 +111,199 @@ std::list<NiObjectRef> NiBSplineTransformInterpolator::GetRefs() const { } //--BEGIN MISC CUSTOM CODE--// +Vector3 NiBSplineTransformInterpolator::GetTranslation() const { + return translation; +} + +void NiBSplineTransformInterpolator::SetTranslation( Vector3 value ) { + translation = value; +} + +Quaternion NiBSplineTransformInterpolator::GetRotation() const { + return rotation; +} + +void NiBSplineTransformInterpolator::SetRotation( Quaternion value ) { + rotation = value; +} + +float NiBSplineTransformInterpolator::GetScale() const { + return scale; +} + +void NiBSplineTransformInterpolator::SetScale( float value ) { + scale = value; +} + + +vector< Quaternion > NiBSplineTransformInterpolator::GetQuatRotateControlData() const +{ + vector< Quaternion > value; + if ((rotateOffset != USHRT_MAX) && splineData && basisData) { // has rotation data + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofQuat; + vector<float> points = splineData->GetFloatControlPointRange(rotateOffset, npts); + value.reserve(nctrl); + for (int i=0; i<npts; ) { + Quaternion key; + key.w = float(points[i++]); + key.x = float(points[i++]); + key.y = float(points[i++]); + key.z = float(points[i++]); + value.push_back(key); + } + } + return value; +} + +vector< Vector3 > NiBSplineTransformInterpolator::GetTranslateControlData() const +{ + vector< Vector3 > value; + if ((translateOffset != USHRT_MAX) && splineData && basisData) { // has translation data + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofTrans; + vector<float> points = splineData->GetFloatControlPointRange(translateOffset, npts); + value.reserve(nctrl); + for (int i=0; i<npts; ) { + Vector3 key; + key.x = float(points[i++]); + key.y = float(points[i++]); + key.z = float(points[i++]); + value.push_back(key); + } + } + return value; +} + +vector< float > NiBSplineTransformInterpolator::GetScaleControlData() const +{ + vector< float > value; + if ((scaleOffset != USHRT_MAX) && splineData && basisData) { // has translation data + int nctrl = basisData->GetNumControlPt(); + int npts = nctrl * SizeofScale; + vector<float> points = splineData->GetFloatControlPointRange(scaleOffset, npts); + value.reserve(nctrl); + for (int i=0; i<npts; ) { + float data = float(points[i++]); + value.push_back(data); + } + } + return value; +} + +vector< Key<Quaternion> > NiBSplineTransformInterpolator::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<float> points = splineData->GetFloatControlPointRange(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++]); + } + if (degree>=nctrl) + degree = nctrl - 1; + // 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++]; + key.data.x = output[j++]; + key.data.y = output[j++]; + key.data.z = output[j++]; + value.push_back(key); + time += incr; + } + } + return value; +} + +vector< Key<Vector3> > NiBSplineTransformInterpolator::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<float> points = splineData->GetFloatControlPointRange(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++]); + } + // 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++]; + key.data.y = output[j++]; + key.data.z = output[j++]; + value.push_back(key); + time += incr; + } + } + return value; +} + +vector< Key<float> > NiBSplineTransformInterpolator::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<float> points = splineData->GetFloatControlPointRange(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++]; + value.push_back(key); + time += incr; + } + } + return value; +} + +int NiBSplineTransformInterpolator::GetNumControlPt() const +{ + if (basisData) + { + return basisData->GetNumControlPt(); + } + return 0; +} + //--END CUSTOM CODE--//