package com.akjava.gwt.threejsexamples.client.examples.vr; 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.MouseControls; import com.akjava.gwt.three.client.examples.js.controls.OrbitControls; import com.akjava.gwt.three.client.examples.js.controls.VRControls; import com.akjava.gwt.three.client.examples.js.effects.StereoEffect; 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.Raycaster; import com.akjava.gwt.three.client.js.extras.geometries.BoxGeometry; import com.akjava.gwt.three.client.js.lights.DirectionalLight; import com.akjava.gwt.three.client.js.lights.Light; import com.akjava.gwt.three.client.js.materials.Material; import com.akjava.gwt.three.client.js.materials.MeshLambertMaterial; import com.akjava.gwt.three.client.js.math.THREEMath; import com.akjava.gwt.three.client.js.math.Vector2; 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.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.VerticalPanel; public class VrStereoExample extends AbstractExample{ @Override public String getName() { return "vr/cubes"; } @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; Mesh mesh; private Stats stats; private VRControls vrControls; private VRControls headControls; private StereoEffect vrEffect; private Raycaster raycaster; Vector2 mouse=THREE.Vector2(); Mesh INTERSECTED; private MouseControls mouseControls; @Override public void init() { FocusPanel container = createContainerPanel(); container.addMouseMoveHandler(new MouseMoveHandler() { @Override public void onMouseMove(MouseMoveEvent event) { onDocumentMouseMove(event); } }); camera = THREE.PerspectiveCamera( 70, getWindowInnerWidth() / getWindowInnerHeight(), 1, 10000 );//camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 ); scene = THREE.Scene();//scene = new THREE.Scene(); DirectionalLight light = THREE.DirectionalLight( 0xffffff, 1 );//var light = new THREE.DirectionalLight( 0xffffff, 1 ); light.getPosition().set( 1, 1, 1 ).normalize();//light.position.set( 1, 1, 1 ).normalize(); scene.add( light ); BoxGeometry geometry = THREE.BoxGeometry( 20, 20, 20 );//var geometry = new THREE.BoxGeometry( 20, 20, 20 ); for ( int i = 0; i < 2000; i ++ ) { Mesh object = THREE.Mesh( geometry, THREE.MeshLambertMaterial( GWTParamUtils.MeshLambertMaterial().color((int)(Math.random() * 0xffffff)) ) );//var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) ); object.getPosition().setX(Math.random() * 800 - 400);//object.position.x = Math.random() * 800 - 400; object.getPosition().setY(Math.random() * 800 - 400);//object.position.y = Math.random() * 800 - 400; object.getPosition().setZ(Math.random() * 800 - 400);//object.position.z = Math.random() * 800 - 400; object.getRotation().setX(Math.random() * 2 * Math.PI);//object.rotation.x = Math.random() * 2 * Math.PI; object.getRotation().setY(Math.random() * 2 * Math.PI);//object.rotation.y = Math.random() * 2 * Math.PI; object.getRotation().setZ(Math.random() * 2 * Math.PI);//object.rotation.z = Math.random() * 2 * Math.PI; object.getScale().setX(Math.random() + 0.5);//object.scale.x = Math.random() + 0.5; object.getScale().setY(Math.random() + 0.5);//object.scale.y = Math.random() + 0.5; object.getScale().setZ(Math.random() + 0.5);//object.scale.z = Math.random() + 0.5; scene.add( object ); } raycaster = THREE.Raycaster();//raycaster = new THREE.Raycaster(); renderer = THREE.WebGLRenderer( GWTParamUtils.WebGLRenderer().antialias(true) ); renderer.setClearColor( 0xf0f0f0); renderer.setPixelRatio( GWTThreeUtils.getWindowDevicePixelRatio() ); renderer.setSize( getWindowInnerWidth(), getWindowInnerHeight() ); renderer.setSortObjects(false); //TODO handle mouse button //var fullScreenButton = document.querySelector( '.full-screen' ); //var mouseLookButton = document.querySelector( '.mouse-look' ); boolean mouseLook = false;//var mouseLook = false; /* fullScreenButton.setOnclick(function() {)//fullScreenButton.onclick = function() { vrEffect.setFullScreen( true ); }; */ vrControls = THREEExp.VRControls(camera);//vrControls = new THREE.VRControls(camera); mouseControls = THREEExp.MouseControls(camera);//mouseControls = new THREE.MouseControls(camera); headControls = vrControls; /*TODO handle buttons mouseLookButton.setOnclick(function() {)//mouseLookButton.onclick = function() { mouseLook = !mouseLook; if (mouseLook) { headControls = mouseControls; mouseLookButton.getClassList().add('enabled');//mouseLookButton.classList.add('enabled'); } else { headControls = vrControls; mouseLookButton.getClassList().remove('enabled');//mouseLookButton.classList.remove('enabled'); } } */ vrEffect = THREEExp.StereoEffect(renderer); // renderer container.getElement().appendChild( renderer.getDomElement() ); //stats stats = Stats.create(); stats.setPosition(0, 0); container.getElement().appendChild(stats.domElement()); //add html info container.add(createAbsoluteHTML("<a href='http://threejs.org' target='_blank'>three.js</a> webgl - interactive cubes (StereoEffect version)" ,100,10)); onWindowResize();//somehow oninitial fail to draw //handle resize & gui initResizeHandlerAndGUI(); } protected void onDocumentMouseMove(MouseMoveEvent event) { event.preventDefault(); mouse.setX(( event.getClientX() / getWindowInnerWidth()) * 2 - 1);//mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.setY(- ( event.getClientY() / getWindowInnerHeight()) * 2 + 1);//mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; } private void initResizeHandlerAndGUI() { VerticalPanel gui=addResizeHandlerAndCreateGUIPanel(); gui.setWidth("200px");//some widget broke,like checkbox without parent size gui.setSpacing(2); //TODO create-gui } public void onWindowResize() { camera.setAspect(getWindowInnerWidth() / getWindowInnerHeight()); camera.updateProjectionMatrix(); vrEffect.setSize( (int)getWindowInnerWidth() , (int)getWindowInnerHeight() ); } double theta; double radius = 100; public MeshLambertMaterial toMeshLambertMaterial(Material material){ return material.cast(); } private int INTERSECTED_currentHex; public void render(double now) {//GWT animateFrame has time theta += 0.1; camera.getPosition().setX(radius * Math.sin( THREEMath.degToRad( theta ) ));//camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) ); camera.getPosition().setY(radius * Math.sin( THREEMath.degToRad( theta ) ));//camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) ); camera.getPosition().setZ(radius * Math.cos( THREEMath.degToRad( theta ) ));//camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) ); camera.lookAt( scene.getPosition());//camera.lookAt( scene.position ); camera.updateMatrixWorld(); // find intersections raycaster.setFromCamera( mouse, camera ); JsArray<Intersect> intersects = raycaster.intersectObjects( scene.getChildren());//var intersects = raycaster.intersectObjects( scene.children ); if ( intersects.length() > 0 ) { if ( INTERSECTED != intersects.get(0).getObject()) {//if ( INTERSECTED != intersects[ 0 ].object ) { if ( INTERSECTED!=null ) toMeshLambertMaterial(INTERSECTED.getMaterial()).getEmissive().setHex( INTERSECTED_currentHex);//if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex ); INTERSECTED = intersects.get(0).getObject().cast(); INTERSECTED_currentHex=toMeshLambertMaterial(INTERSECTED.getMaterial()).getEmissive().getHex(); toMeshLambertMaterial(INTERSECTED.getMaterial()).getEmissive().setHex( 0xff0000 );//INTERSECTED.material.emissive.setHex( 0xff0000 ); } } else { if ( INTERSECTED!=null ) toMeshLambertMaterial(INTERSECTED.getMaterial()).getEmissive().setHex( INTERSECTED_currentHex);//if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex ); INTERSECTED = null; } headControls.update(); vrEffect.render( scene, camera ); } @Override public String getTokenKey() { return "stereocubes"; } }