1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
19 #include "nel/3d/track_sampled_quat_small_header.h"
20 #include "nel/misc/algo.h"
24 using namespace NLMISC
;
34 // ***************************************************************************
35 CTrackSampledQuatSmallHeader::CTrackSampledQuatSmallHeader(CTrackSamplePack
*pack
, uint8 headerIndex
, uint8 numKeys
, uint16 keyIndex
)
38 _TrackSamplePack
= pack
;
39 _IndexTrackHeader
= headerIndex
;
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
78 // One Key? easy, and quit.
85 // Get the Track header info
86 CTrackSampleHeader
&trackHeader
= _TrackSamplePack
->TrackHeaders
[_IndexTrackHeader
];
89 //=====================
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
;
106 // For precision problems, ensure correct range.
107 if(localTime
<0 || localTime
>= trackHeader
.TotalRange
)
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
);
127 clamp(frame
, 0, 255);
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)
144 uint frameKey1
= times
[keyId1
];
147 float time0
= frameKey0
*trackHeader
.DeltaTime
;
148 float time1
= frameKey1
*trackHeader
.DeltaTime
;
151 float t
= (localTime
-time0
);
152 // If difference is one frame, optimize.
153 if(frameKey1
-frameKey0
==1)
154 t
*= trackHeader
.OODeltaTime
;
159 // store this interp value.
162 return EvalInterpolate
;
164 // else (last key of anim), just eval this key.
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
178 TEvalType evalType
= evalTime(date
, keyId0
, keyId1
, interpValue
);
182 CQuatPack
*keys
= &_TrackSamplePack
->Keys
[_KeyIndex
];
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
);
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
);
208 valueKey0
.unpack(quat0
);
209 valueKey1
.unpack(quat1
);
212 avBlock
.ValQuat
.Value
= CQuat::slerp(quat0
, quat1
, interpValue
);
220 return avBlock
.ValQuat
;
224 // ***************************************************************************
225 void CTrackSampledQuatSmallHeader::serial(NLMISC::IStream
&/* f */)
227 // CTrackSampledQuatSmallHeader not designed to be serialsied