package com.akjava.gwt.threejsexamples.client.examples.animation.skinning; import java.util.Map; import com.akjava.gwt.three.client.js.animation.AnimationClip; import com.akjava.gwt.threejsexamples.client.LabeledInputRangeWidget; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArrayNumber; import com.google.gwt.core.client.JsArrayString; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.VerticalPanel; public class BlendCharacterGui extends VerticalPanel{ private Map<String,AnimationClip> animations; BlendingExample blendingExample; private LabeledInputRangeWidget idleRange; private LabeledInputRangeWidget walkRange; private LabeledInputRangeWidget runRange; private LabeledInputRangeWidget timeScaleRange; private LabeledInputRangeWidget stepSizeRange; private LabeledInputRangeWidget crossfadeTimeRange; private BlendCharacter character; //private AnimationMixer mixer; public double getTimeScale(){ return timeScaleRange.getValue(); } public BlendCharacterGui(BlendCharacter character,final BlendingExample blendingExample) { this.blendingExample=blendingExample; this.character=character; VerticalPanel settings=new VerticalPanel(); add(settings); Label settingsLabel=new Label("Settings"); settings.add(settingsLabel); CheckBox lockCamera=new CheckBox("Lock Camera"); lockCamera.setValue(false); settings.add(lockCamera); CheckBox showModel=new CheckBox("Show Model"); showModel.setValue(true); settings.add(showModel); CheckBox showSkeleton=new CheckBox("Show Skeleton"); showSkeleton.setValue(false); settings.add(showSkeleton); timeScaleRange = new LabeledInputRangeWidget("Time Scale",0,1,0.01); settings.add(timeScaleRange); timeScaleRange.setValue(1); stepSizeRange = new LabeledInputRangeWidget("Step Size",0.01, 0.1, 0.01 ); settings.add(stepSizeRange); stepSizeRange.setValue(0.016); crossfadeTimeRange = new LabeledInputRangeWidget("Crossfade Time",0.1, 6.0, 0.05 ); settings.add(crossfadeTimeRange); crossfadeTimeRange.setValue(3.5); LabeledInputRangeWidget test=new LabeledInputRangeWidget("Time scale",0,1,0.01); settings.add(test); //TODO need code compatible VerticalPanel playback=new VerticalPanel(); add(playback); Label playbackLabel=new Label("Playback"); playback.add(playbackLabel); Button startBt=new Button("start"); startBt.setWidth("200px"); playback.add(startBt); Button pauseBt=new Button("pause"); pauseBt.setWidth("200px"); playback.add(pauseBt); Button stepBt=new Button("step"); stepBt.setWidth("200px"); playback.add(stepBt); Button idletowalkBt=new Button("idle to walk"); idletowalkBt.setWidth("200px"); playback.add(idletowalkBt); Button walktorunBt=new Button("walk to run"); walktorunBt.setWidth("200px"); playback.add(walktorunBt); Button warpwalktorunBt=new Button("warp walk to run"); warpwalktorunBt.setWidth("200px"); playback.add(warpwalktorunBt); VerticalPanel blendTurning=new VerticalPanel(); add(blendTurning); Label blendTurningLabel=new Label("Blend Tuning"); blendTurning.add(blendTurningLabel); idleRange = new LabeledInputRangeWidget("idle",0,1,0.01); blendTurning.add(idleRange); walkRange = new LabeledInputRangeWidget("walk",0,1,0.01); blendTurning.add(walkRange); runRange = new LabeledInputRangeWidget("run",0,1,0.01); blendTurning.add(runRange); //set values idleRange.setValue(0.33); walkRange.setValue(0.33); runRange.setValue(0.33); startBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { blendingExample.startAnimation(getAnimationData()); } }); stepBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { blendingExample.stepAnimation(stepSizeRange.getValue()); } }); pauseBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { blendingExample.pauseAnimation(); } }); idletowalkBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { crossfade("idle", "walk"); } }); walktorunBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { crossfade("walk", "run"); } }); warpwalktorunBt.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { wrap("walk", "run"); } }); lockCamera.addValueChangeHandler(new ValueChangeHandler<Boolean>() { @Override public void onValueChange(ValueChangeEvent<Boolean> event) { blendingExample.lockCameraChanged(event.getValue()); } }); showModel.addValueChangeHandler(new ValueChangeHandler<Boolean>() { @Override public void onValueChange(ValueChangeEvent<Boolean> event) { blendingExample.showModelChanged(event.getValue()); } }); showSkeleton.addValueChangeHandler(new ValueChangeHandler<Boolean>() { @Override public void onValueChange(ValueChangeEvent<Boolean> event) { blendingExample.showSkeletonChanged(event.getValue()); } }); ValueChangeHandler<Number> onBlendChanged=new ValueChangeHandler<Number>() { @Override public void onValueChange(ValueChangeEvent<Number> event) { //weight(((Range)event.getSource()).getName()); //LogUtils.log("weight-changed"); //onWeight(); } }; idleRange.addtRangeListener(onBlendChanged); walkRange.addtRangeListener(onBlendChanged); runRange.addtRangeListener(onBlendChanged); } public void update(double time){ //TODO update only crossfade or wraping idleRange.setValue(character.getWeight("idle")); walkRange.setValue(character.getWeight("walk")); runRange.setValue(character.getWeight("run")); } /* protected void onWeight(){ String[] names={"idle","walk","run"}; for(String name:names){ for(int i=0;i<mixer.getActions().length();i++){ AnimationMixerAction action=mixer.getActions().get(i); if(action.getClip().getName().equals(name)){ double value=0; if(name.equals("idle")){ value=idleRange.getValue(); }else if(name.equals("walk")){ value=walkRange.getValue(); }else{ value=runRange.getValue(); } if(action.getWeightAt(mixer.getTime())!=value){ action.setWeight(value); //LogUtils. } } } } } */ /* protected void weight(String name) { LabeledInputRangeWidget main; LabeledInputRangeWidget remain1; LabeledInputRangeWidget remain2; if(name.equals("idle")){ main=idleRange; remain1=walkRange; remain2=runRange; }else if(name.equals("walk")){ main=walkRange; remain1=idleRange; remain2=runRange; }else{ main=runRange; remain1=walkRange; remain2=idleRange; } //TODO make group range function? double remain=1.0-main.getValue(); if(remain1.getValue()==0 && remain2.getValue()==0){ remain1.setValue(remain/2); remain2.setValue(remain/2); }else{ double sum=remain1.getValue()+remain2.getValue(); remain1.setValue(remain*(remain1.getValue()/sum)); remain2.setValue(remain*(remain2.getValue()/sum)); } //call event blendingExample.weightAnimation(getAnimationData()); } */ private BlendData getAnimationData() { return createAnimationData(idleRange.getValue(),walkRange.getValue(),runRange.getValue()); } public final native BlendData createAnimationData(double idle,double walk,double run) /*-{ return { detail: { anims: [ "idle", "walk", "run" ], weights: [ idle, walk, run ] } }; }-*/; public final native BlendData createAnimationData(String from,String to,double time) /*-{ return { detail: { from:from, to:to, time:time } }; }-*/; public void crossfade(String from,String to ) { BlendData data=createAnimationData(from,to,crossfadeTimeRange.getValue()); blendingExample.crossfade(data); } public void wrap(String from,String to ) { BlendData data=createAnimationData(from,to,crossfadeTimeRange.getValue()); blendingExample.wrap(data); } public static final class BlendData extends JavaScriptObject{ protected BlendData(){} public final native JsArrayString getAnims() /*-{ return this.detail.anims; }-*/; public final native JsArrayNumber getWeights() /*-{ return this.detail.weights; }-*/; public final native String getFrom() /*-{ return this.detail.from; }-*/; public final native String getTo() /*-{ return this.detail.to; }-*/; public final native double getTime() /*-{ return this.detail.time; }-*/; } //TODO support oninput }