Merge branch 'ryzom/ark-features' into main/gingo-test
[ryzomcore.git] / nel / src / 3d / track_sampled_quat_small_header.cpp
blobcb0a28f3b278733c7242c7d012517c3a2b7a76c2
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
19 #include "nel/3d/track_sampled_quat_small_header.h"
20 #include "nel/misc/algo.h"
23 using namespace std;
24 using namespace NLMISC;
26 #ifdef DEBUG_NEW
27 #define new DEBUG_NEW
28 #endif
30 namespace NL3D
34 // ***************************************************************************
35 CTrackSampledQuatSmallHeader::CTrackSampledQuatSmallHeader(CTrackSamplePack *pack, uint8 headerIndex, uint8 numKeys, uint16 keyIndex)
37 nlassert(pack);
38 _TrackSamplePack= pack;
39 _IndexTrackHeader= headerIndex;
40 _NumKeys= numKeys;
41 _KeyIndex= keyIndex;
44 // ***************************************************************************
45 CTrackSampledQuatSmallHeader::~CTrackSampledQuatSmallHeader()
50 // ***************************************************************************
51 bool CTrackSampledQuatSmallHeader::getLoopMode() const
53 return _TrackSamplePack->TrackHeaders[_IndexTrackHeader].LoopMode;
56 // ***************************************************************************
57 TAnimationTime CTrackSampledQuatSmallHeader::getBeginTime () const
59 return _TrackSamplePack->TrackHeaders[_IndexTrackHeader].BeginTime;
62 // ***************************************************************************
63 TAnimationTime CTrackSampledQuatSmallHeader::getEndTime () const
65 return _TrackSamplePack->TrackHeaders[_IndexTrackHeader].EndTime;
68 // ***************************************************************************
69 CTrackSampledQuatSmallHeader::TEvalType CTrackSampledQuatSmallHeader::evalTime (const TAnimationTime& date, uint &keyId0, uint &keyId1, float &interpValue)
71 /* IF YOU CHANGE THIS CODE, CHANGE too CTrackSampledQuatCommon
74 // Empty? quit
75 if(_NumKeys==0)
76 return EvalDiscard;
78 // One Key? easy, and quit.
79 if(_NumKeys==1)
81 keyId0= 0;
82 return EvalKey0;
85 // Get the Track header info
86 CTrackSampleHeader &trackHeader= _TrackSamplePack->TrackHeaders[_IndexTrackHeader];
88 // manage Loop
89 //=====================
90 float localTime;
91 if(trackHeader.LoopMode)
93 nlassert(trackHeader.TotalRange>0);
94 // get relative to BeginTime.
95 localTime= date-trackHeader.BeginTime;
97 // force us to be in interval [0, _TotalRange[.
98 if( localTime<0 || localTime>=trackHeader.TotalRange )
100 double d= localTime*trackHeader.OOTotalRange;
102 // floor(d) is the truncated number of loops.
103 d= localTime- floor(d)*trackHeader.TotalRange;
104 localTime= (float)d;
106 // For precision problems, ensure correct range.
107 if(localTime<0 || localTime >= trackHeader.TotalRange)
108 localTime= 0;
112 else
114 // get relative to BeginTime.
115 localTime= date-trackHeader.BeginTime;
118 // get times ptr in packed data
119 uint8 *times= &_TrackSamplePack->Times[_KeyIndex];
122 // Find the first key before localTime
123 //=====================
124 // get the frame in the track.
125 sint frame= (sint)floor(localTime*trackHeader.OODeltaTime);
126 // clamp to uint8
127 clamp(frame, 0, 255);
129 // get the key.
130 keyId0= searchLowerBound(times, _NumKeys, (uint8)frame);
132 // Get the Frame of Key0.
133 uint frameKey0= times[keyId0];
136 // Interpolate with next key
137 //=====================
139 // If not the last Key
140 if(keyId0<(uint)_NumKeys-1)
142 // Get the next key.
143 keyId1= keyId0+1;
144 uint frameKey1= times[keyId1];
146 // unpack time.
147 float time0= frameKey0*trackHeader.DeltaTime;
148 float time1= frameKey1*trackHeader.DeltaTime;
150 // interpolate.
151 float t= (localTime-time0);
152 // If difference is one frame, optimize.
153 if(frameKey1-frameKey0==1)
154 t*= trackHeader.OODeltaTime;
155 else
156 t/= (time1-time0);
157 clamp(t, 0.f, 1.f);
159 // store this interp value.
160 interpValue= t;
162 return EvalInterpolate;
164 // else (last key of anim), just eval this key.
165 return EvalKey0;
168 // ***************************************************************************
169 const IAnimatedValue &CTrackSampledQuatSmallHeader::eval (const TAnimationTime& date, CAnimatedValueBlock &avBlock)
171 /* IF YOU CHANGE THIS CODE, CHANGE too CTrackSampledQuatSmallHeader
174 // **** Eval time, and get key interpolation info
175 uint keyId0;
176 uint keyId1;
177 float interpValue;
178 TEvalType evalType= evalTime(date, keyId0, keyId1, interpValue);
180 // **** Eval Keys
181 // get starting keys
182 CQuatPack *keys= &_TrackSamplePack->Keys[_KeyIndex];
184 // Discard?
185 if( evalType==EvalDiscard )
186 return avBlock.ValQuat;
187 // One Key? easy, and quit.
188 else if( evalType==EvalKey0 )
190 keys[keyId0].unpack(avBlock.ValQuat.Value);
192 // interpolate
193 else if( evalType==EvalInterpolate )
195 CQuatPack valueKey0= keys[keyId0];
196 CQuatPack valueKey1= keys[keyId1];
198 // If the 2 keys have same value, just unpack.
199 if(valueKey0 == valueKey1)
201 valueKey0.unpack(avBlock.ValQuat.Value);
203 // else interpolate
204 else
206 // unpack key value.
207 CQuat quat0, quat1;
208 valueKey0.unpack(quat0);
209 valueKey1.unpack(quat1);
211 // interpolate
212 avBlock.ValQuat.Value= CQuat::slerp(quat0, quat1, interpValue);
215 else
217 nlstop;
220 return avBlock.ValQuat;
224 // ***************************************************************************
225 void CTrackSampledQuatSmallHeader::serial(NLMISC::IStream &/* f */)
227 // CTrackSampledQuatSmallHeader not designed to be serialsied
228 nlstop;
233 } // NL3D