// // ElisKeyframe.m // Elis Colors // // Created by 柳 on 09/09/15. // Copyright 2009 __MyCompanyName__. All rights reserved. // #import "ElisKeyframe.h" static float convertQTTimeToSecond(QTTime t) { return (float)t.timeValue/t.timeScale; } @implementation ElisKeyframe - (id)init { [super init]; timesAndValues = [[NSMutableDictionary alloc] init]; cacheTime = NAN; return self; } - (void)setValueForTime:(float)value time:(QTTime)time { int i, j; long long tmp1, tmp2; [timesAndValues setObject:[NSNumber numberWithFloat:value] forKey:[NSNumber numberWithFloat:convertQTTimeToSecond(time)]]; sortedTimes = [[timesAndValues allKeys] sortedArrayUsingSelector:@selector(compare:)]; // 常識的に考えて、NSArrayである必要なくね? Cの配列でよくね? cacheTime = NAN; // Cの配列時代の実装。挿入ソート? // for(i = 0; i < index-1; i++){ // if(times[i].timeValue == time.timeValue){ // values[i] = value; // return; // } // if(times[i].timeValue <= time.timeValue && time.timeValue <= times[i+1].timeValue){ // for(j = index; j > i+1; j--){ // times[j] = times[j-1]; // values[j] = values[j-1]; // } // times[i+1] = time; // values[i+1] = value; // return; // } // } // if(times[index-1].timeValue == time.timeValue) values[index-1] = value; // else if(times[index-1].timeValue <= time.timeValue){ // times[index] = time; // values[index++] = value; // }else{ // times[index] = times[index-1]; // values[index] = values[index-1]; // times[index-1] = time; // values[index-1] = value; // index++; // } // return; } // いろいろすさまじい。ボトルネックになりそうだなあここ。 // 描画を実行する度に2回呼ばれる。キャッシュするか。 - (float)getValueForTime:(QTTime)time { // long long now = time.timeValue; // int i; // for(i = 0; i < index-1; i++){ // if(times[i].timeValue <= now && now <= times[i+1].timeValue){ // return ((float)(times[i+1].timeValue - now) * values[i] + // (float)(now - times[i].timeValue) * values[i+1])/(times[i+1].timeValue - times[i].timeValue); // } // } // if(now <= times[0].timeValue) return values[0]; // if(times[index-1].timeValue <= now) return values[index-1]; float now = convertQTTimeToSecond(time); if(cacheTime == now) return cacheValue; cacheTime = now; int i, size = [sortedTimes count]; if(size == 1){ cacheValue = [[timesAndValues objectForKey:[sortedTimes objectAtIndex:0]] floatValue]; return cacheValue; } if([[sortedTimes lastObject] floatValue] <= now){ cacheValue = [[timesAndValues objectForKey:[sortedTimes lastObject]] floatValue]; return cacheValue; } for(i = 0; i < size-1; i++){ if([[sortedTimes objectAtIndex:i] floatValue] <= now && now <= [[sortedTimes objectAtIndex:i+1] floatValue]){ cacheValue = (([[sortedTimes objectAtIndex:i+1] floatValue] - now) * [[timesAndValues objectForKey:[sortedTimes objectAtIndex:i]] floatValue] + (now - [[sortedTimes objectAtIndex:i] floatValue]) * [[timesAndValues objectForKey:[sortedTimes objectAtIndex:i+1]] floatValue]) / ([[sortedTimes objectAtIndex:i+1] floatValue] - [[sortedTimes objectAtIndex:i] floatValue]); return cacheValue; } } return cacheValue; } @end