three.js

113 days ago by jason3

 
       

TODO:

  1. Figure out the JSON format and have Sage generate that automatically.  See the plot.js file in this worksheet's data directory, or use convert script that comes with three.js to see how it changes the .obj files (which Sage can already generate)
  2. Make a RotateControl and use that instead of the TrackballControls.  The problem with the trackball is that it rotates the camera instead of the object, which means that the lighting on the surface never changes.  If instead we rotate the object, the lights will cast different illumination as the object is rotated around.
  3. Make the fullscreen and screenshot plugins work.  We don't want to capture keystrokes if they are captured document-wide---instead, make double-click do fullscreen (which already happens) and make a link to get a screenshot.
  4. Make the 3d plot window accept resizing (see the THREEx WindowResize plugin for ideas, but we probably can't use that since it is meant for webgl things that take up the entire window).
  5. Make the trackball and other controls work with more than one plot on the screen.
 
       
threejsdir='http://sage.math.washington.edu/home/jason/threejsboilerplate/vendor/three.js' threexjsdir='http://sage.math.washington.edu/home/jason/threejsboilerplate/vendor/threex' html(""" <script src="%(dir)s/Three.js"></script> <script src="%(dir)s/Detector.js"></script> <script src="%(xdir)s/THREEx.screenshot.js"></script> <script src="%(xdir)s/THREEx.FullScreen.js"></script> <script src="%(xdir)s/THREEx.WindowResize.js"></script> """%{'dir':threejsdir,'xdir':threexjsdir}) 
       














import random code=""" <!-- three.js container --> <div id="container%(id)s"></div> <!-- info on screen display --> <div id="info"> <div class="top"> <a href="http://learningthreejs.com/blog/2011/12/20/boilerplate-for-three-js/" target="_blank">LearningThree.js</a> boiler plate for <a href="https://github.com/mrdoob/three.js/" target="_blank">three.js</a> </div> <div class="bottom" id="inlineDoc" > </div> </div> <script type="text/javascript"> var myfun = function() { var scene, renderer; var camera, cameraControl; var tryWebgl = %(trywebgl)s; // if false, always use canvas renderer // Need to have a timeout so that there is enough time for the browser // to create the container div before trying to add the webgl context // Apparently the notebook's built-in sleep of 50 ms is not enough setTimeout(function() { if(!init()) {animate();} }, 100); // init the scene function init(){ var width=800; var height=600 if( tryWebgl && Detector.webgl ){ renderer = new THREE.WebGLRenderer({ antialias: true, // to get smoother output preserveDrawingBuffer: true // to allow screenshot }); renderer.setClearColorHex( 0xBBBBBB, 1 ); }else{ renderer = new THREE.CanvasRenderer(); } renderer.setSize( width, height ); document.getElementById('container%(id)s').appendChild(renderer.domElement); // create a scene scene = new THREE.Scene(); /********* Camera *****************/ camera = new THREE.PerspectiveCamera(35, width/height, 1, 10000 ); camera.position.set(0, 0, 5); scene.add(camera); /********** Camera Control **************/ cameraControls = new THREE.TrackballControls( camera, renderer.domElement ); /********** Lights **************/ var light = new THREE.AmbientLight( 0x888888 ); scene.add( light ); var light = new THREE.DirectionalLight( 0xffaa00 ); light.position.set( 1,1,1 ).normalize(); scene.add( light ); var light = new THREE.DirectionalLight( 0x00ff00 ); light.position.set( -1,-1,-1 ).normalize(); scene.add( light ); var light = new THREE.PointLight( 0x0000ff ); light.position.set( .59-0.5, .29-0.5, .87-0.5 ).normalize().multiplyScalar(1.2); scene.add( light ); var light= new THREE.PointLight( 0xff0000 ); light.position.set( .49, .01, .01 ).normalize().multiplyScalar(1.2); scene.add( light ); /*********** Objects *******************/ var group = new THREE.Object3D(); // TORUS var geometry = new THREE.TorusGeometry( 1, 0.42, 16, 16 ); var material = new THREE.MeshLambertMaterial({/*ambient: 0x808080, */color: 0xff88ff}); var mesh = new THREE.Mesh( geometry, material ); group.add( mesh ); // SADDLE PLOT loader = new THREE.JSONLoader(); loader.load( 'http://sagenb.org/home/jason3/539/data/plot.js', function ( geometry ) { zmesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() ); zmesh.position.set( 0, 0, 0 ); zmesh.scale.set( 0.5, 0.5, 0.1 ); group.add( zmesh ); } ); scene.add(group); } // animation loop function animate() { // loop on request animation loop // - it has to be at the begining of the function // - see details at http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating requestAnimationFrame( animate, document.getElementById('container') ); // do the render render(); } // render the scene function render() { // update camera controls cameraControls.update(); // actually render the scene renderer.render( scene, camera ); } }();</script> """ 
       
html("<h1>Using WegGL if possible</h1>"+code%{'id':random.randint(0,1e6), 'trywebgl': 'true'}) 
       

Using WegGL if possible

LearningThree.js boiler plate for three.js

Using WegGL if possible

LearningThree.js boiler plate for three.js
html("<h1>Using HTML5 Canvas</h1>"+code%{'id':random.randint(0,1e6), 'trywebgl': 'false'}) 
       
"""For screenshots, fullscreen: // requires customized THREEx javascript // see https://github.com/jasongrout/threex/tree/bind-element // transparently support window resize //THREEx.WindowResize.bind(renderer, camera); // allow 'p' to make screenshot myscreenshot = function() {THREEx.Screenshot.doScreenshot(renderer);}; document.getElementById('inlineDoc').innerHTML += "<button onclick='myscreenshot'>Get Screenshot</button>"; THREEx.Screenshot.bindKey(renderer, {bindElement:renderer.domElement}); // allow 'f' to go fullscreen where this feature is supported if( THREEx.FullScreen.available() ){ THREEx.FullScreen.bindKey({element:renderer.domElement, dblclick: true}); document.getElementById('inlineDoc').innerHTML += "- <i>f</i> for fullscreen"; } """ 
       
http://sagenb.org/home/jason3/539/data/plot.js 
       
f(x,y)=x^2-y^2 p=plot3d(f,(x,-3,3),(y,-3,3)) with open(DATA+'plot.obj','w') as f: f.write(p.obj()) convert_ascii(DATA+'plot.obj','','',DATA+'plot.js')