package com.akjava.gwt.bvh.client.threejs;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.akjava.bvh.client.BVH;
import com.akjava.bvh.client.BVHNode;
import com.akjava.bvh.client.Vec3;
import com.akjava.gwt.three.client.gwt.boneanimation.AnimationBone;
import com.akjava.gwt.three.client.gwt.boneanimation.AnimationData;
import com.akjava.gwt.three.client.gwt.boneanimation.AnimationKey;
import com.akjava.gwt.three.client.java.utils.AnimationUtils;
import com.akjava.gwt.three.client.java.utils.GWTThreeUtils;
import com.akjava.gwt.three.client.js.THREE;
import com.akjava.gwt.three.client.js.math.Matrix4;
import com.akjava.gwt.three.client.js.math.Vector3;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayNumber;
public class AnimationBoneConverter {
private List<String> nameOrderList;
public List<List<Vector3>> convertJsonBoneEndSites(BVH bvh){
List<List<Vector3>> result=new ArrayList<List<Vector3>>();
convertJsonBoneEndSites(bvh.getHiearchy(),result);
return result;
}
private void convertJsonBoneEndSites(BVHNode node,List<List<Vector3>> result){
List<Vec3> endsites=node.getEndSites();
List<Vector3> endVecs=new ArrayList<Vector3>();
for(Vec3 vec:endsites){
endVecs.add(THREE.Vector3(vec.getX(), vec.getY(), vec.getZ()));
}
result.add(endVecs);
for(BVHNode childNode:node.getJoints()){
convertJsonBoneEndSites(childNode,result);
}
}
public JsArray<AnimationBone> convertJsonBone(BVH bvh){
nameOrderList=new ArrayList<String>();
String oldName=null;
for(int i=0;i<bvh.getNameAndChannels().size();i++){
String newName=bvh.getNameAndChannels().get(i).getName();
if(newName==null){
GWT.log("null-name");
}
if(!newName.equals(oldName)){
nameOrderList.add(newName);
oldName=newName;
}
}
parentIdMaps=new HashMap<String,Integer>();
for(int i=0;i<nameOrderList.size();i++){
parentIdMaps.put(nameOrderList.get(i), i);
}
JsArray<AnimationBone> array=(JsArray<AnimationBone>)JsArray.createArray();
Map<String,AnimationBone> bones=new HashMap<String,AnimationBone>();
BVHNode root=bvh.getHiearchy();
Matrix4 mx=THREE.Matrix4();
Vector3 pos=BVHUtils.toVector3(root.getOffset());
mx.setPosition(pos);
AnimationBone bone=AnimationUtils.createAnimationBone();
bone.setParent(-1);
bone.setName(root.getName());
bone.setPos(pos);
//root dont have rot
bones.put(root.getName(), bone);
convert(bones,root,mx);
for(int i=0;i<nameOrderList.size();i++){
AnimationBone abone=bones.get(nameOrderList.get(i));
array.push(abone);
}
return array;
}
private Map<String,Integer> parentIdMaps;
private void convert(Map<String,AnimationBone> map,BVHNode parent,Matrix4 parentMx){
for(BVHNode children:parent.getJoints()){
Matrix4 mx=THREE.Matrix4();
Vector3 pos=BVHUtils.toVector3(children.getOffset());
mx.setPosition(pos);
AnimationBone bone=AnimationUtils.createAnimationBone();
bone.setParent(parentIdMaps.get(parent.getName()));
bone.setName(children.getName());
//bone rot
Vector3 rot=GWTThreeUtils.getRotation(THREE.Vector3(), pos);
//value not good as expected,TODO fix
//bone.setRotq(GWTThreeUtils.rotationQuaternion(rot));
//TODO If you wish absolutepath use parent matrix,but this version format dont need it.
//mx=mx.multiply(parentMx, mx);
Vector3 mxPos=THREE.Vector3();
mxPos.setFromMatrixPosition(mx);
bone.setPos(mxPos);
map.put(children.getName(), bone);
convert(map,children,mx);
}
}
//Dont work
public static void setBoneAngles(JsArray<AnimationBone> bones,AnimationData data,int index){
JsArrayNumber rootPos=null;
for(int i=0;i<bones.length();i++){
AnimationKey key=data.getHierarchy().get(i).getKeys().get(index);
/*
if(i==0){
//COPY only root
rootPos=GWTThreeUtils.clone(key.getPos());
bones.get(i).setPos(rootPos);
}else{
JsArrayNumber newPos=GWTThreeUtils.clone(key.getPos());
newPos.set(0, newPos.get(0)+rootPos.get(0));
newPos.set(1, newPos.get(1)+rootPos.get(1));
newPos.set(2, newPos.get(2)+rootPos.get(2));
}*/
/*
Matrix4 angleM=GWTThreeUtils.degitRotationToMatrix4(THREE.Vector3(0, 0, 45));
Vector3 pos=GWTThreeUtils.jsArrayToVector3(key.getPos());
angleM.multiplyVector3(pos);
bones.get(i).setPos(pos);
*/
//noeffect?
//bones.get(i).setRot(GWTThreeUtils.clone(key.getRot()));
}
}
}