package com.akjava.gwt.three.client.java.file;
import java.util.List;
import com.akjava.gwt.lib.client.LogUtils;
import com.akjava.gwt.three.client.gwt.JSParameter;
import com.akjava.gwt.three.client.js.THREE;
import com.akjava.gwt.three.client.js.animation.AnimationClip;
import com.akjava.gwt.three.client.js.animation.KeyframeTrack;
import com.akjava.gwt.three.client.js.animation.tracks.NumberKeyframeTrack;
import com.google.common.base.Converter;
import com.google.common.collect.Lists;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayNumber;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONString;
public class MorphTargetKeyFrameConverter extends Converter<List<MorphTargetKeyFrame>,JSONMorphTargetsFile>{
@Override
protected JSONMorphTargetsFile doForward(List<MorphTargetKeyFrame> list) {
LogUtils.log("debug MorphTargetKeyFrameConverter:size:"+list.size());
if(list.isEmpty()){
throw new RuntimeException("MorphTargetKeyFrameConverter:list is empty.cant get keyName");
}
JSONMorphTargetsFile file=new JSONMorphTargetsFile();
file.put("name", new JSONString(list.get(0).getKeyName()));
JsArrayNumber times=JsArray.createArray().cast();
JsArrayNumber values=JsArray.createArray().cast();
for(MorphTargetKeyFrame frame:list){
times.push(frame.getTime());
values.push(frame.getValue());
}
file.put("times",new JSONArray( times));
file.put("values",new JSONArray( values));
LogUtils.log("debug MorphTargetKeyFrameConverter:converted:"+list.get(0).getKeyName());
return file;
}
@Override
protected List<MorphTargetKeyFrame> doBackward(JSONMorphTargetsFile morphTargetFile) {
List<MorphTargetKeyFrame> list=Lists.newArrayList();
JsArrayNumber times=morphTargetFile.getArrayNumber("times");
if(times==null){
LogUtils.log("MorphTargetKeyFrameConverter:not contain times");
return null;
}
JsArrayNumber values=morphTargetFile.getArrayNumber("values");
if(values==null){
LogUtils.log("MorphTargetKeyFrameConverter:not contain values");
return null;
}
if(times.length()!=values.length()){
LogUtils.log("MorphTargetKeyFrameConverter:difference length");
return null;
}
String name=morphTargetFile.getString("name");
if(name==null){
LogUtils.log("MorphTargetKeyFrameConverter:not contain name");
return null;
}
for(int i=0;i<times.length();i++){
MorphTargetKeyFrame frame=new MorphTargetKeyFrame(name,times.get(i),values.get(i));
list.add(frame);
}
return list;
}
public static AnimationClip converToAnimationClip(Iterable<List<MorphTargetKeyFrame>> framesList,String animationClipName,MorphtargetsModifier modifier,JSParameter morphTargetDictionary){
JsArray<KeyframeTrack> tracks=JavaScriptObject.createArray().cast();
for(List<MorphTargetKeyFrame> list:framesList){
String key=list.get(0).getKeyName();//TODO check size?
if(!morphTargetDictionary.exists(key)){
LogUtils.log("MorphTargetKeyFrameConverter-converToAnimationClip:call not exist key="+key+".skipped creating track");
continue;
}
int index=morphTargetDictionary.getInt(key);//possible null?
NumberKeyframeTrack track=morphTargetKeyFrameToTrack(key,index,list,modifier);
tracks.push(track);
}
AnimationClip clip=THREE.AnimationClip(animationClipName, -1, tracks);
return clip;
}
public static NumberKeyframeTrack morphTargetKeyFrameToTrack(String keyName,int index,List<MorphTargetKeyFrame> frames,MorphtargetsModifier modifier){
String trackName=".morphTargetInfluences["+index+"]";
JsArrayNumber times=JavaScriptObject.createArray().cast();
JsArrayNumber values=JavaScriptObject.createArray().cast();
for(MorphTargetKeyFrame frame:frames){
times.push(frame.getTime()/1000);//millisecond to second
values.push(toModifyValue(keyName,frame.getValue(),modifier));
}
NumberKeyframeTrack track=THREE.NumberKeyframeTrack(trackName, times, values);
return track;
}
//TODO BasicExpressionPanel to better location
private static double toModifyValue(String key,double value,MorphtargetsModifier modifier) {
return modifier.getModifiedValue(key, value);
}
}