package com.akjava.gwt.threejsexamples.client.examples.misc.controls; 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.cameras.PerspectiveCamera; import com.akjava.gwt.three.client.js.core.Face3; import com.akjava.gwt.three.client.js.core.Geometry; 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.lights.HemisphereLight; import com.akjava.gwt.three.client.js.lights.Light; import com.akjava.gwt.three.client.js.materials.MeshBasicMaterial; 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.gwt.core.client.JsArray; import com.google.gwt.dom.client.Element; 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 PointerLockExample extends AbstractExample{ @Override public String getName() { return "misc/controls/pointerlock"; } @Override public void animate(double timestamp) { //do requestAnimationFrame on super class render(timestamp); stats.update();//really deprecate?many still use this } private WebGLRenderer renderer; private Scene scene; private PerspectiveCamera camera; private PointerLockControls controls; private Light light; private boolean moveForward; private boolean moveLeft; private boolean moveBackward; private boolean moveRight; private boolean canJump; private Vector3 velocity ; private Raycaster raycaster; private Geometry geometry; private MeshBasicMaterial material; private JsArray<Object3D> objects; boolean controlsEnabled; double prevTime; @Override public void init() { final Element bodyElement=RootPanel.getBodyElement(); prevTime=System.currentTimeMillis(); if(!PointerLock.havePointerLock()){ Window.alert("This browser does not support Pointer Lock API.quit!" ); return; }else{ LogUtils.log("Have Pointer API"); } LogUtils.log(bodyElement); PointerLock.addPointerLockChange(new PointerLockListener() { @Override public void pointerLockChanged(NativeEvent event) { //LogUtils.log("Pointer Api Changed"); if(PointerLock.isPointerLockElement(bodyElement)){ controlsEnabled=true; controls.setEnabled(true); LogUtils.log("Pointer Api Changed:true"); }else{ controlsEnabled=false; controls.setEnabled(false); popup.show(); LogUtils.log("Pointer Api Changed:false"); } } }); final FocusPanel container = createContainerPanel(); popup = 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); popup.add(mainPanel); popup.center(); popup.show(); //To get event on root popup.addDomHandler(new MouseDownHandler() { @Override public void onMouseDown(MouseDownEvent event) { popup.hide(); container.setFocus(true); PointerLock.requestPointerLock(bodyElement); } }, MouseDownEvent.getType()); container.getElement(); velocity= THREE.Vector3(); objects=JsArray.createArray().cast(); camera = THREE.PerspectiveCamera( 75, getWindowInnerWidth() / getWindowInnerHeight(), 1, 1000 );//camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 ); scene = THREE.Scene();//scene = new THREE.Scene(); scene.setFog(THREE.Fog( 0xffffff, 0, 750 ));//scene.fog = new THREE.Fog( 0xffffff, 0, 750 ); HemisphereLight light = THREE.HemisphereLight( 0xeeeeff, 0x777788, 0.75 );//var light = new THREE.HemisphereLight( 0xeeeeff, 0x777788, 0.75 ); light.getPosition().set( 0.5, 1, 0.75 );//light.position.set( 0.5, 1, 0.75 ); scene.add( light ); controls = THREEExp.PointerLockControls( camera );//controls = new THREE.PointerLockControls( camera ); scene.add( controls.getObject() ); 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; 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 );//raycaster = new THREE.Raycaster( new THREE.Vector3(), new THREE.Vector3( 0, - 1, 0 ), 0, 10 ); // floor geometry = THREE.PlaneGeometry( 2000, 2000, 100, 100 );//geometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 ); geometry.rotateX( - Math.PI / 2 ); for ( int i = 0, l = geometry.getVertices().length(); i < l; i ++ ) {//for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) { Vector3 vertex = geometry.vertices().get(i); vertex.gwtIncrementX(Math.random() * 20 - 10); vertex.gwtIncrementY(Math.random() * 2); vertex.gwtIncrementZ(Math.random() * 20 - 10); } for ( int i = 0, l = geometry.getFaces().length(); i < l; i ++ ) {//for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) { Face3 face = geometry.faces().get(i); face.getVertexColors().set(0,THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ));//face.vertexColors[ 0 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); face.getVertexColors().set(1,THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ));//face.vertexColors[ 1 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); face.getVertexColors().set(2,THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ));//face.vertexColors[ 2 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); } material = THREE.MeshBasicMaterial( GWTParamUtils.MeshBasicMaterial().vertexColors(THREE.VertexColors) );//material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ); mesh = THREE.Mesh( geometry, material );//mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); // objects geometry = THREE.BoxGeometry( 20, 20, 20 );//geometry = new THREE.BoxGeometry( 20, 20, 20 ); for ( int i = 0, l = geometry.getFaces().length(); i < l; i ++ ) {//for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) { Face3 face = geometry.faces().get(i); face.getVertexColors().set(0,THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ));//face.vertexColors[ 0 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); face.getVertexColors().set(1,THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ));//face.vertexColors[ 1 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); face.getVertexColors().set(2,THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ));//face.vertexColors[ 2 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); } for ( int i = 0; i < 500; i ++ ) { MeshPhongMaterial material = THREE.MeshPhongMaterial( GWTParamUtils.MeshPhongMaterial().specular(0xffffff).shading(THREE.FlatShading).vertexColors(THREE.VertexColors) );//material = new THREE.MeshPhongMaterial( { specular: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors } ); Mesh mesh = THREE.Mesh( geometry, material );//var mesh = new THREE.Mesh( geometry, material ); mesh.getPosition().setX(Math.floor( Math.random() * 20 - 10 ) * 20);//mesh.position.x = Math.floor( Math.random() * 20 - 10 ) * 20; mesh.getPosition().setY(Math.floor( Math.random() * 20 ) * 20 + 10);//mesh.position.y = Math.floor( Math.random() * 20 ) * 20 + 10; mesh.getPosition().setZ(Math.floor( Math.random() * 20 - 10 ) * 20);//mesh.position.z = Math.floor( Math.random() * 20 - 10 ) * 20; scene.add( mesh ); material.getColor().setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );//material.color.setHSL( Math.random() * 0.2 + 0.5, 0.75, Math.random() * 0.25 + 0.75 ); objects.push( mesh ); } // renderer renderer = THREE.WebGLRenderer();//renderer = new THREE.WebGLRenderer(); renderer.setClearColor( 0xffffff ); renderer.setPixelRatio( GWTThreeUtils.getWindowDevicePixelRatio() );//renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( getWindowInnerWidth(), getWindowInnerHeight() );//renderer.setSize( window.innerWidth, window.innerHeight ); container.getElement().appendChild( renderer.getDomElement() ); //animate(); //stats stats = Stats.create(); stats.setPosition(0, 0); container.getElement().appendChild(stats.domElement()); //handle resize & gui initResizeHandlerAndGUI(); } private void initResizeHandlerAndGUI() { VerticalPanel gui=addResizeHandlerAndCreateGUIPanel(); gui.setWidth("200px");//some widget broke,like checkbox without parent size gui.setSpacing(2); gui.setVisible(false);//no need? } public void onWindowResize() { camera.setAspect(getWindowInnerWidth() / getWindowInnerHeight()); camera.updateProjectionMatrix(); renderer.setSize( (int)getWindowInnerWidth() , (int)getWindowInnerHeight() ); } Mesh mesh; private Stats stats; private PopupPanel popup; public void render(double now) {//GWT animateFrame has time 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 if ( moveForward ) velocity.gwtDecrementZ(400.0 * delta); if ( moveBackward ) velocity.gwtIncrementZ(400.0 * delta); if ( moveLeft ) velocity.gwtDecrementX(400.0 * delta); if ( moveRight ) velocity.gwtIncrementX(400.0 * 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() < 10 ) {//if ( controls.getObject().position.y < 10 ) { velocity.setY(0);//velocity.y = 0; controls.getObject().getPosition().setY(10);//controls.getObject().position.y = 10; canJump = true; } prevTime = time; } renderer.render( scene, camera ); } @Override public String getTokenKey() { return "pointerlock"; } }