00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028 #include "nel/misc/quat.h"
00029 #include "nel/misc/common.h"
00030 #include "3d/track_sampled_quat.h"
00031
00032 using namespace NLMISC;
00033 using namespace std;
00034
00035
00036 namespace NL3D
00037 {
00038
00039
00040
00041
00042
00043
00044
00045 const double NL3D_OO32767= 1.0f/32767;
00046 const double NL3D_OO65535= 1.0f/65535;
00047
00048 #ifdef NL3D_TSQ_ALLOW_QUAT_COMPRESS
00049
00050 void CTrackSampledQuat::CQuatPack::pack(const CQuat &quat)
00051 {
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 CQuatD nquat= quat;
00069 nquat.normalize();
00070
00071 sint ax= (sint)floor(nquat.x * 32767 + 0.5);
00072 sint ay= (sint)floor(nquat.y * 32767 + 0.5);
00073 sint az= (sint)floor(nquat.z * 32767 + 0.5);
00074 sint aw= (sint)floor(nquat.w * 32767 + 0.5);
00075 clamp(ax, -32767, 32767);
00076 clamp(ay, -32767, 32767);
00077 clamp(az, -32767, 32767);
00078 clamp(aw, -32767, 32767);
00079 x= ax;
00080 y= ay;
00081 z= az;
00082 w= aw;
00083 }
00084
00085
00086 void CTrackSampledQuat::CQuatPack::unpack(CQuat &quat)
00087 {
00088
00089 CQuatD quatD;
00090 quatD.x= x * NL3D_OO32767;
00091 quatD.y= y * NL3D_OO32767;
00092 quatD.z= z * NL3D_OO32767;
00093 quatD.w= w * NL3D_OO32767;
00094 quatD.normalize();
00095
00096 quat= quatD;
00097 }
00098 #endif
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 CTrackSampledQuat::CTrackSampledQuat()
00110 {
00111 }
00112
00113
00114 CTrackSampledQuat::~CTrackSampledQuat()
00115 {
00116 }
00117
00118
00119 const IAnimatedValue& CTrackSampledQuat::getValue () const
00120 {
00121 return _Value;
00122 }
00123
00124
00125 void CTrackSampledQuat::serial(NLMISC::IStream &f)
00126 {
00127
00128
00129
00130
00131
00132
00133 sint ver= f.serialVersion(1);
00134
00135 if( ver<=0 )
00136 {
00137
00138 f.serial(_LoopMode);
00139 f.serial(_BeginTime);
00140 f.serial(_EndTime) ;
00141 f.serial(_TotalRange);
00142 f.serial(_OOTotalRange);
00143 f.serial(_DeltaTime);
00144 f.serial(_OODeltaTime);
00145 f.serial(_TimeBlocks);
00146 }
00147 else
00148 {
00149
00150 CTrackSampledCommon::serialCommon(f);
00151 }
00152
00153
00154 f.serial(_Keys);
00155
00156 }
00157
00158
00159 void CTrackSampledQuat::build(const std::vector<uint16> &timeList, const std::vector<CQuat> &keyList,
00160 float beginTime, float endTime)
00161 {
00162 nlassert( endTime>beginTime || (beginTime==endTime && keyList.size()<=1) );
00163 nlassert( keyList.size()==timeList.size() );
00164 uint i;
00165
00166
00167 uint numKeys= keyList.size();
00168 _Keys.clear();
00169 _TimeBlocks.clear();
00170
00171
00172 CTrackSampledCommon::buildCommon(timeList, beginTime, endTime);
00173
00174
00175
00176
00177 _Keys.resize(numKeys);
00178 for(i=0; i<numKeys;i++)
00179 {
00180 _Keys[i].pack(keyList[i]);
00181 }
00182
00183 }
00184
00185
00186 void CTrackSampledQuat::eval (const TAnimationTime& date)
00187 {
00188
00189 uint keyId0;
00190 uint keyId1;
00191 float interpValue;
00192 TEvalType evalType= evalTime(date, _Keys.size(), keyId0, keyId1, interpValue);
00193
00194
00195 if( evalType==EvalDiscard )
00196 return;
00197
00198 else if( evalType==EvalKey0 )
00199 {
00200 _Keys[keyId0].unpack(_Value.Value);
00201 }
00202
00203 else if( evalType==EvalInterpolate )
00204 {
00205 CQuatPack valueKey0= _Keys[keyId0];
00206 CQuatPack valueKey1= _Keys[keyId1];
00207
00208
00209 if(valueKey0 == valueKey1)
00210 {
00211 valueKey0.unpack(_Value.Value);
00212 }
00213
00214 else
00215 {
00216
00217 CQuat quat0, quat1;
00218 valueKey0.unpack(quat0);
00219 valueKey1.unpack(quat1);
00220
00221
00222 _Value.Value= CQuat::slerp(quat0, quat1, interpValue);
00223 }
00224 }
00225 else
00226 {
00227 nlstop;
00228 }
00229
00230 }
00231
00232
00233 }