package com.akjava.gwt.threejsexamples.client.examples.animation.skinning; import com.akjava.gwt.stats.client.Stats; import com.akjava.gwt.three.client.examples.js.THREEExp; import com.akjava.gwt.three.client.examples.js.controls.OrbitControls; import com.akjava.gwt.three.client.gwt.GWTParamUtils; import com.akjava.gwt.three.client.java.ui.example.AbstractExample; import com.akjava.gwt.three.client.java.utils.GWTThreeUtils; import com.akjava.gwt.three.client.js.THREE; import com.akjava.gwt.three.client.js.cameras.PerspectiveCamera; import com.akjava.gwt.three.client.js.core.Clock; import com.akjava.gwt.three.client.js.core.Geometry; import com.akjava.gwt.three.client.js.lights.DirectionalLight; import com.akjava.gwt.three.client.js.loaders.JSONLoader.JSONLoadHandler; import com.akjava.gwt.three.client.js.materials.Material; import com.akjava.gwt.three.client.js.renderers.WebGLRenderer; import com.akjava.gwt.three.client.js.scenes.Scene; import com.akjava.gwt.threejsexamples.client.examples.animation.skinning.BlendCharacterGui.BlendData; import com.google.gwt.core.client.JsArray; import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.VerticalPanel; public class BlendingExample extends AbstractExample{ @Override public String getName() { return "animation/skinning/blending"; } @Override public void animate(double timestamp) { //do requestAnimationFrame on super class render(timestamp); stats.update();//really deprecate?many still use this } public void weightAnimation(BlendData data){ for ( int i = 0; i < data.getAnims().length(); ++i ) { blendCharacter.applyWeight(data.getAnims().get(i), data.getWeights().get(i)); } } private WebGLRenderer renderer; private Scene scene; private PerspectiveCamera camera; Clock clock = THREE.Clock(); boolean isFrameStepping; double timeToStep; private Stats stats; private BlendCharacter blendCharacter; private BlendCharacterGui gui; private OrbitControls controls; private FocusPanel container; @Override public void init() { container = createContainerPanel(); scene = THREE.Scene(); scene.add(THREE.AmbientLight( 0xaaaaaa )); DirectionalLight light = THREE.DirectionalLight( 0xffffff, 1.5 ); light.getPosition().set( 0, 0, 1000 ); scene.add( light ); //create renderer renderer = THREE.WebGLRenderer(GWTParamUtils.WebGLRenderer().antialias(true).alpha(false)); renderer.setClearColor( 0x777777); renderer.setPixelRatio( GWTThreeUtils.getWindowDevicePixelRatio()); renderer.setSize( (int)getWindowInnerWidth() , (int)getWindowInnerHeight() ); renderer.setAutoClear(true); container.getElement().appendChild(renderer.getDomElement()); //stats stats = Stats.create(); stats.setPosition(0, 0); container.getElement().appendChild(stats.domElement()); container.add(createAbsoluteHTML("<a href='http://threejs.org' target='_blank'>three.js</a> - Skeletal Animation Blending" + "<br><br> Adjust blend weights to affect the animations that are currently playing." + "<br> Cross fades (and warping) blend between 2 animations and end with a single animation." ,100,10)); //resize-handler generate on super-class,take care of gui blendCharacter = new BlendCharacter(); blendCharacter.load("models/skinned/marine/marine_anims.js", new JSONLoadHandler() { @Override public void loaded(Geometry geometry, JsArray<Material> materials) { //camera and gui would be create on call start start(); } }); } private void start(){ blendCharacter.getRotation().setY(Math.PI * -135 / 180); scene.add( blendCharacter.getSkinnedMesh() ); scene.add(blendCharacter.getSkeletonHelper()); double aspect = getWindowInnerWidth() / getWindowInnerHeight(); double radius = blendCharacter.getGeometry().getBoundingSphere().getRadius(); camera = THREE.PerspectiveCamera( 45, aspect, 1, 10000 ); camera.getPosition().set( 0.0, radius, radius * 3.5 ); controls = THREEExp.OrbitControls(camera,container.getElement() ); controls.setTarget(THREE.Vector3( 0, radius, 0 )); controls.update(); // Set default weights blendCharacter.applyWeight("idle",1.0/3);//must be double value on java blendCharacter.applyWeight("walk",1.0/3);//must be double value on java blendCharacter.applyWeight("run",1.0/3);//must be double value on java pauseAnimation();//for gui weight modify gui = new BlendCharacterGui(blendCharacter,this); VerticalPanel controlPanel=addResizeHandlerAndCreateGUIPanel(); controlPanel.add(gui); updateGUI();//for show //render(0);//test } public void onWindowResize() { camera.setAspect(getWindowInnerWidth() / getWindowInnerHeight()); camera.updateProjectionMatrix(); renderer.setSize( (int)getWindowInnerWidth() , (int)getWindowInnerHeight() ); } public void render(double now) {//GWT animateFrame has time //check ready if(gui==null){ return; } double scale = gui.getTimeScale(); double delta = clock.getDelta(); double stepSize = (!isFrameStepping) ? delta * scale: timeToStep; //LogUtils.log(stepSize); // modify blend weights blendCharacter.update( stepSize ); blendCharacter.getSkeletonHelper().update(); //not-paused,need modify weight by hand on GWT if(blendCharacter.getMixer().getTimeScale()!=0){ gui.update(blendCharacter.getMixer().getTime()); } renderer.render( scene, camera ); stats.update(); // if we are stepping, consume time // ( will equal step size next time a single step is desired ) timeToStep = 0; } public void startAnimation(BlendData data) { blendCharacter.stopAll(); blendCharacter.unPauseAll(); // the blend mesh will combine 1 or more animations for ( int i = 0; i < data.getAnims().length(); ++i ) { blendCharacter.play(data.getAnims().get(i), data.getWeights().get(i)); } isFrameStepping = false; } /* never called public void onStopAnimation() { blendCharacter.stopAll(); isFrameStepping = false; } */ public void stepAnimation(double stepSize) { blendCharacter.unPauseAll(); isFrameStepping = true; timeToStep = stepSize; } public void pauseAnimation() { if( isFrameStepping ){ blendCharacter.unPauseAll(); }else{ blendCharacter.pauseAll(); } isFrameStepping = false; } public void crossfade(BlendData data) { blendCharacter.stopAll(); blendCharacter.crossfade( data.getFrom(), data.getTo(), data.getTime() ); isFrameStepping = false; } public void wrap(BlendData data) { blendCharacter.stopAll(); blendCharacter.warp( data.getFrom(), data.getTo(), data.getTime() ); isFrameStepping = false; } public void lockCameraChanged(Boolean value) { controls.setEnabled(!value); } public void showModelChanged(Boolean value) { blendCharacter.showModel( value ); } public void showSkeletonChanged(Boolean value) { blendCharacter.showSkeleton( value ); } @Override public String getTokenKey() { return "blending"; } }