package com.akjava.gwt.threejsexamples.client.examples.sweethome; import java.util.List; import com.akjava.gwt.html5.client.pointerlock.PointerLock; import com.akjava.gwt.html5.client.pointerlock.PointerLock.PointerLockListener; import com.akjava.gwt.lib.client.LogUtils; 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.PointerLockControls; import com.akjava.gwt.three.client.gwt.GWTParamUtils; import com.akjava.gwt.three.client.gwt.core.Intersect; 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.animation.AnimationClip; import com.akjava.gwt.three.client.js.animation.AnimationMixer; 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.Object3D; import com.akjava.gwt.three.client.js.core.Raycaster; import com.akjava.gwt.three.client.js.extras.geometries.PlaneBufferGeometry; import com.akjava.gwt.three.client.js.extras.helpers.PointLightHelper; import com.akjava.gwt.three.client.js.extras.helpers.SpotLightHelper; import com.akjava.gwt.three.client.js.lights.AmbientLight; import com.akjava.gwt.three.client.js.lights.DirectionalLight; import com.akjava.gwt.three.client.js.lights.PointLight; import com.akjava.gwt.three.client.js.loaders.ObjectLoader; import com.akjava.gwt.three.client.js.loaders.ObjectLoader.ObjectLoadHandler; import com.akjava.gwt.three.client.js.materials.MeshPhongMaterial; import com.akjava.gwt.three.client.js.math.Vector3; import com.akjava.gwt.three.client.js.objects.Mesh; import com.akjava.gwt.three.client.js.renderers.WebGLRenderer; import com.akjava.gwt.three.client.js.scenes.Scene; import com.google.common.collect.Lists; import com.google.gwt.core.client.JsArray; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.VerticalPanel; public class SweetHomePointerLockExample extends AbstractExample{ @Override public String getName() { return "SweetHome/loadjson_pointerlock"; } @Override public void animate(double timestamp) { render(timestamp); stats.update();//really deprecate?many still use this } private WebGLRenderer renderer; private Scene scene; private PerspectiveCamera camera; private Stats stats; int WIDTH; int HEIGHT; double FLOOR; double windowHalfX,windowHalfY; double mouseX=0; double mouseY=0; Clock clock; AnimationMixer mixer; AnimationClip sceneAnimationClip; private PointerLockControls controls; private boolean controlsEnabled; private PopupPanel titlePopup; private Raycaster raycaster; private boolean moveForward; private boolean moveLeft; private boolean moveBackward; private boolean moveRight; private boolean canJump; private Vector3 velocity ; private JsArray<Object3D> objects; @Override public void init() { if(!PointerLock.havePointerLock()){ Window.alert("This browser does not support Pointer Lock API.quit!" ); return; }else{ LogUtils.log("Have Pointer API"); } velocity= THREE.Vector3(); objects=JsArray.createArray().cast(); PointerLock.addPointerLockChange(new PointerLockListener() { @Override public void pointerLockChanged(NativeEvent event) { //LogUtils.log("Pointer Api Changed"); if(PointerLock.isPointerLocked()){ controlsEnabled=true; controls.setEnabled(true); LogUtils.log("Pointer Api Changed:true"); }else{ controlsEnabled=false; controls.setEnabled(false); titlePopup.show(); LogUtils.log("Pointer Api Changed:false"); } } }); //do pointer lock,TODO method titlePopup = new PopupPanel(false); VerticalPanel mainPanel=new VerticalPanel(); Label label1=new Label("Click here to Play!"); mainPanel.add(label1); Label label2=new Label("(W, A, S, D = Move, SPACE = Jump, MOUSE = Look around)"); mainPanel.add(label2); titlePopup.add(mainPanel); titlePopup.center(); titlePopup.show(); final FocusPanel container = createContainerPanel(); //To get event on root titlePopup.addDomHandler(new MouseDownHandler() { @Override public void onMouseDown(MouseDownEvent event) { titlePopup.hide(); container.setFocus(true); PointerLock.requestPointerLock(RootPanel.getBodyElement()); } }, MouseDownEvent.getType()); container.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { // TODO Auto-generated method stub switch ( event.getNativeKeyCode() ) { case 38: // up case 87: // w moveForward = true; break; case 37: // left case 65: // a moveLeft = true; break; case 40: // down case 83: // s moveBackward = true; break; case 39: // right case 68: // d moveRight = true; break; case 32: // space if ( canJump == true ) velocity.gwtIncrementY(350); canJump = false; LogUtils.log("jumping"); break; } } }); container.addKeyUpHandler(new KeyUpHandler() { @Override public void onKeyUp(KeyUpEvent event) { switch( event.getNativeKeyCode() ) { case 38: // up case 87: // w moveForward = false; break; case 37: // left case 65: // a moveLeft = false; break; case 40: // down case 83: // s moveBackward = false; break; case 39: // right case 68: // d moveRight = false; break; } } }); raycaster = THREE.Raycaster( THREE.Vector3(), THREE.Vector3( 0, - 1, 0 ), 0, 10 ); //global FLOOR= -250;//var FLOOR = -250; windowHalfX = getWindowInnerWidth() / 2;//var windowHalfX = window.innerWidth / 2; windowHalfY = getWindowInnerHeight() / 2;//var windowHalfY = window.innerHeight / 2; clock = THREE.Clock();//var clock = new THREE.Clock(); WIDTH = (int)getWindowInnerWidth(); HEIGHT = (int)getWindowInnerHeight(); // scene scene = null;//load later // renderer renderer = THREE.WebGLRenderer( GWTParamUtils.WebGLRenderer().antialias(true) );//renderer = new THREE.WebGLRenderer( { antialias: true } ); //renderer.setClearColor( scene.getFog().getColor());//renderer.setClearColor( scene.fog.color ); renderer.setPixelRatio( GWTThreeUtils.getWindowDevicePixelRatio() );//renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( WIDTH, HEIGHT ); renderer.setGammaInput(true);//renderer.gammaInput = true; renderer.setGammaOutput(true);//renderer.gammaOutput = true; renderer.getShadowMap().setEnabled(true);//renderer.shadowMap.enabled = true; container.getElement().appendChild( renderer.getDomElement() ); // camera camera = THREE.PerspectiveCamera(70, getWindowInnerWidth()/getWindowInnerHeight(), 1, 10000 ); camera.getPosition().set( 0, 0,0 );// controls = THREEExp.PointerLockControls( camera );//controls = new THREE.PointerLockControls( camera ); PlaneBufferGeometry geometry = THREE.PlaneBufferGeometry( 16000, 16000 );//var geometry = new THREE.PlaneBufferGeometry( 16000, 16000 ); MeshPhongMaterial material = THREE.MeshPhongMaterial( GWTParamUtils.MeshPhongMaterial().emissive(0x000000) );//var material = new THREE.MeshPhongMaterial( { emissive: 0x000000 } ); Mesh ground = THREE.Mesh( geometry, material );//var ground = new THREE.Mesh( geometry, material ); ground.getPosition().set( 0, FLOOR, 0 );//ground.position.set( 0, FLOOR, 0 ); ground.getRotation().setX(-Math.PI/2);//ground.rotation.x = -Math.PI/2; /*scene.add( ground );*/ ground.setReceiveShadow(true);//ground.receiveShadow = true; //stats stats = Stats.create(); stats.setPosition(0, 0); container.getElement().appendChild(stats.domElement()); //add html info container.add(createAbsoluteHTML("<div style='text:white'><a href='http://threejs.org' target='_blank'>three.js</a> - scene animation</a>" ,100,10)); //handle resize & gui initResizeHandlerAndGUI(); //setDebugAnimateOneTimeOnly(true); /* JSONLoader loader = THREE.JSONLoader();//var loader = new THREE.ObjectLoader(); loader.load( "untitled.json",new JSONLoadHandler() { @Override public void loaded(Geometry geometry, JsArray<Material> materials) { // TODO Auto-generated method stub LogUtils.log("material"); LogUtils.log(materials); Mesh mesh=THREE.Mesh(geometry,THREE.MeshBasicMaterial()); scene.add(mesh); } });*/ ObjectLoader loader = THREE.ObjectLoader();//var loader = new THREE.ObjectLoader(); loader.load( "sweethome/userguideexamplefixed.json?t="+System.currentTimeMillis(),new ObjectLoadHandler() { @Override public void onLoad(Object3D object) { //ObjectHasAnimations hasAnimation=object.cast(); //sceneAnimationClip = hasAnimation.getAnimations().get(0); scene = object.cast(); AmbientLight ambientLight=THREE.AmbientLight(0x222222); scene.add(ambientLight); DirectionalLight dlight=THREE.DirectionalLight(0x222222); dlight.getPosition().set(-1, 1, 1).normalize(); JsArray<Object3D> objects=scene.getChildren(); List<String> needDoubleSides=Lists.newArrayList("461","147","454"); for(int i=0;i<objects.length();i++){ Object3D obj=objects.get(i); String name=obj.getName(); if(obj.getName().endsWith("628") || obj.getName().endsWith("634") || obj.getName().endsWith("622")|| obj.getName().endsWith("640") || obj.getName().endsWith("527") //kitchen || obj.getName().endsWith("612") //bus ){ Mesh mesh=obj.cast(); addLight(mesh); //mesh.setVisible(false); }else if(endsWith(needDoubleSides,name)){ Mesh mesh=obj.cast(); MeshPhongMaterial material=mesh.getMaterial().cast(); material.setSide(THREE.DoubleSide); } } controls.getObject().getPosition().set(-226,cameraY,-340);//start At scene.add(controls.getObject());//very important //scene.setFog(THREE.Fog( 0xffffff, 2000, 10000 ));//scene.fog = new THREE.Fog( 0xffffff, 2000, 10000 ); // //mixer = THREE.AnimationMixer( scene );//mixer = new THREE.AnimationMixer( scene ); //mixer.clipAction( sceneAnimationClip ).play();//mixer.addAction( new THREE.AnimationAction( sceneAnimationClip ) ); } } ); } private boolean endsWith(List<String> names,String name){ for(String need:names){ if(name.endsWith(need)){ return true; } } return false; } private SpotLightHelper lightHelper; private int cameraY=150; private void addLight(Mesh mesh){ mesh.getGeometry().computeBoundingSphere(); Vector3 pos=mesh.getGeometry().getBoundingSphere().getCenter().clone(); pos.applyEuler(mesh.getRotation()); PointLight pointLight = THREE.PointLight( 0x222222 );//var directionalLight = new THREE.DirectionalLight( 0x444444 ); pointLight.setDistance(800); pointLight.setIntensity(2); pointLight.setDecay(0.90); pointLight.getPosition().copy(pos); scene.add( pointLight ); PointLightHelper pheloper=THREE.PointLightHelper(pointLight, 5); //scene.add(pheloper); MeshPhongMaterial material=mesh.getMaterial().cast(); material.getColor().set(0x888888); material.getEmissive().set(0xcc8c8c8);//shinning } private void initResizeHandlerAndGUI() { VerticalPanel gui=addResizeHandlerAndCreateGUIPanel(); gui.setWidth("200px");//some widget broke,like checkbox without parent size gui.setSpacing(2); } public void onWindowResize() { windowHalfX = getWindowInnerWidth() / 2; windowHalfY = getWindowInnerHeight() / 2; camera.setAspect(getWindowInnerWidth() / getWindowInnerHeight()); camera.updateProjectionMatrix(); renderer.setSize( (int)getWindowInnerWidth() , (int)getWindowInnerHeight() ); } public void render(double now) { if(scene==null){ return;//not loaded yet; } if(lightHelper!=null){ lightHelper.update(); } double delta=clock.getDelta(); if ( controlsEnabled ) { raycaster.getRay().getOrigin().copy( controls.getObject().getPosition());//raycaster.ray.origin.copy( controls.getObject().position ); raycaster.getRay().getOrigin().gwtIncrementY(-10);//raycaster.ray.origin.y -= 10; JsArray<Intersect> intersections = raycaster.intersectObjects( objects ); boolean isOnObject = intersections.length() > 0; //double time = now; //double delta = ( time - prevTime ) / 1000; velocity.gwtDecrementX((velocity.getX() * 10.0 * delta)) ; velocity.gwtDecrementZ((velocity.getZ() * 10.0 * delta)) ; velocity.gwtDecrementY((9.8 * 100.0 * delta)); // 100.0 = mass double move=800; if ( moveForward ) velocity.gwtDecrementZ(move * delta); if ( moveBackward ) velocity.gwtIncrementZ(move * delta); if ( moveLeft ) velocity.gwtDecrementX(move * delta); if ( moveRight ) velocity.gwtIncrementX(move * delta); if ( isOnObject == true ) { velocity.setY(Math.max( 0, velocity.getY()));//velocity.y = Math.max( 0, velocity.y ); canJump = true; } controls.getObject().translateX( velocity.getX() * delta ); controls.getObject().translateY( velocity.getY() * delta ); controls.getObject().translateZ( velocity.getZ() * delta ); if ( controls.getObject().getPosition().getY() < cameraY ) {//if ( controls.getObject().position.y < 10 ) { velocity.setY(0);//velocity.y = 0; controls.getObject().getPosition().setY(cameraY);//controls.getObject().position.y = 10; canJump = true; } //prevTime = time; } // ThreeLog.log(controls.getObject().getPosition()); renderer.render( scene, camera ); } @Override public void stop() { super.stop(); if(popup!=null){ popup.hide(); popup=null; } } @Override public String getTokenKey() { return "sweethome_json_pointerlock"; } }