vector<int> searchRange(vector<int>& nums, int target) { int left = searchLowerBound(nums, target); int right = searchUpperBound(nums, target); vector<int> range; range.push_back(left); range.push_back(right); return range; }
// *************************************************************************** CTrackSampledCommon::TEvalType CTrackSampledCommon::evalTime (const TAnimationTime& date, uint numKeys, uint &keyId0, uint &keyId1, float &interpValue) { /* IF YOU CHANGE THIS CODE, CHANGE too CTrackSampledQuatSmallHeader */ // Empty? quit if(numKeys==0) return EvalDiscard; // One Key? easy, and quit. if(numKeys==1) { keyId0= 0; return EvalKey0; } // manage Loop //===================== float localTime; if(_LoopMode) { nlassert(_TotalRange>0); // get relative to BeginTime. localTime= date-_BeginTime; // force us to be in interval [0, _TotalRange[. if( localTime<0 || localTime>=_TotalRange ) { double d= localTime*_OOTotalRange; // floor(d) is the truncated number of loops. d= localTime- floor(d)*_TotalRange; localTime= (float)d; // For precision problems, ensure correct range. if(localTime<0 || localTime >= _TotalRange) localTime= 0; } } else { // get relative to BeginTime. localTime= date-_BeginTime; } // Find the first key before localTime //===================== // get the frame in the track. sint frame= (sint)floor(localTime*_OODeltaTime); // clamp to uint16 clamp(frame, 0, 65535); // Search the TimeBlock. CTimeBlock keyTB; keyTB.TimeOffset= frame; uint tbId; tbId= searchLowerBound(_TimeBlocks.getPtr(), _TimeBlocks.size(), keyTB); // get this timeBlock. CTimeBlock &timeBlock= _TimeBlocks[tbId]; // get frame relative to this timeBlock. sint frameRel= frame-timeBlock.TimeOffset; // clamp to uint8 clamp(frameRel, 0, 255); // get the key in this timeBlock. uint keyIdRel; keyIdRel= searchLowerBound(timeBlock.Times.getPtr(), timeBlock.Times.size(), (uint8)frameRel); // Get the Frame and Value of Key0. uint frameKey0= timeBlock.TimeOffset + timeBlock.Times[keyIdRel]; // this is the key to evaluate keyId0= timeBlock.KeyOffset + keyIdRel; // Interpolate with next key //===================== // If not the last Key if(keyId0<numKeys-1) { // Get the next key. keyId1= keyId0+1; uint frameKey1; // If last key of the timeBlock, get the first time of the next timeBlock. if( keyIdRel+1 >= timeBlock.Times.size() ) { nlassert(tbId+1<_TimeBlocks.size()); frameKey1= _TimeBlocks[tbId+1].TimeOffset; } else { frameKey1= timeBlock.TimeOffset + timeBlock.Times[keyIdRel+1]; } // unpack time. float time0= frameKey0*_DeltaTime; float time1= frameKey1*_DeltaTime; // interpolate. float t= (localTime-time0); // If difference is one frame, optimize. if(frameKey1-frameKey0==1) t*= _OODeltaTime; else t/= (time1-time0); clamp(t, 0.f, 1.f); // store this interp value. interpValue= t; return EvalInterpolate; } // else (last key of anim), just eval this key. return EvalKey0; }