<html lang="en">
<head>
<script src="http://vatelier.net:1337/vorlon.js"></script>
<link rel="stylesheet" href="http://vatelier.net/MyDemo/WebARLab/testing/css/normalize.css">
<link rel="stylesheet" href="http://vatelier.net/MyDemo/WebARLab/testing/css/main.css">
<!-- Error handling -->
<script>
window.addEventListener('error', function(event) {
var errorMessage = event.message;
var url = event.filename;
var lineNumber = event.lineno;
var columnNumber = event.colno;
console.log("ERROR: " + errorMessage + " at " + url + " : " + lineNumber + " : " + columnNumber);
});
</script>
<title>WebAR (Tango) Chair ThreeJS Example - modified for own mesh</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<meta name="description" content="WebAR (Tango) Chair ThreeJS Example - modified for own mesh">
<style>
body {
font-family: Monospace;
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
bottom: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
a { color: skyblue }
</style>
</head>
<body>
<div id="loader-wrapper">
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
</div>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> -
WebAR (Tango) Chair ThreeJS Example <a href="https://github.com/judax" target="_blank">Iker Jamardo</a>
</div>
<script src="http://vatelier.net/MyDemo/WebARLab/testing/three.js"></script>
<script src="http://vatelier.net/MyDemo/WebARLab/testing/Detector.js"></script>
<script src="http://vatelier.net/MyDemo/WebARLab/testing/stats.min.js"></script>
<script src="http://vatelier.net/MyDemo/WebARLab/testing/VRControls.js"></script>
<script src="http://vatelier.net/MyDemo/WebARLab/testing/THREE.WebAR.js"></script>
<script src="http://vatelier.net/MyDemo/WebARLab/testing/dat.gui.min.js"></script>
<script src="http://vatelier.net/MyDemo/WebARLab/testing/ColladaLoader.js"></script>
<script>
function addClass(node, className) {
if (node.classList) {
node.classList.add(className);
}
else {
node.className += ' ' + className;
}
}
function removeLoadSpinner() {
addClass(document.body, 'loaded');
setTimeout(function() {
document.body.removeChild(document.getElementById("loader-wrapper"));
}, 5000);
}
function GUI() {
this.showPointCloud = showPointCloud;
this.showSeeThroughCamera = true;
this.pointsToSkip = 0;
return this;
}
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var cameraOrtho, cameraPersp, sceneCamera, scene, renderer, cameraMesh;
var pointCloud, showPointCloud = true;
var vrDisplay;
var model;
var lastX, lastY;
var pos = new THREE.Vector3();
var USE_CUBE_AS_MODEL = false;
var gui;
if (navigator.getVRDisplays) {
navigator.getVRDisplays().then(function(vrDisplays) {
if (vrDisplays && vrDisplays.length > 0) {
for (var i = 0; i < vrDisplays.length; i++) {
vrDisplay = vrDisplays[i];
if (vrDisplay.displayName === "Tango VR Device") {
if (!USE_CUBE_AS_MODEL) {
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
var myMesh = 'http://vatelier.net/MyDemo/WebARLab/testing/geometry_5.dae';
var myMesh = "http://fabien.benetou.fr/pub/home/3DSelf/self.dae";
loader.load(myMesh , function ( collada ) {
removeLoadSpinner();
var colladaScene = collada.scene;
colladaScene.scale.x = colladaScene.scale.y = colladaScene.scale.z = 0.1;
colladaScene.rotateX(THREE.Math.degToRad(90));
// note that is good only for horizontal surfaces e.g. walls or tables
// for walls should be a different (if any) rotation
colladaScene.updateMatrix();
model = new THREE.Object3D();
model.add(colladaScene);
init(vrDisplay);
updateAndRender();
} );
}
else {
removeLoadSpinner();
init(vrDisplay);
updateAndRender();
}
break;
}
}
}
});
}
else {
console.log("No navigator.getVRDisplays");
removeLoadSpinner();
init();
updateAndRender();
}
function init(vrDisplay) {
// Initialize the dat.GUI.
var datGUI = new dat.GUI();
gui = new GUI();
datGUI.add(gui, "showPointCloud").onFinishChange(function(value) {
if (value) {
scene.add(points)
showPointCloud = true;
}
else {
scene.remove(points);
showPointCloud = false;
}
});
datGUI.add(gui, "showSeeThroughCamera");
datGUI.add(gui, "pointsToSkip", 0, 10);
// Initialize everything related to ThreeJS.
container = document.createElement( 'div' );
document.body.appendChild( container );
// Create the see through camera scene and camera
sceneCamera = new THREE.Scene();
cameraOrtho = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1000 );
cameraMesh = THREE.WebAR.createVRSeeThroughCameraMesh(vrDisplay);
sceneCamera.add(cameraMesh);
// Create the 3D scene and camera
scene = new THREE.Scene();
cameraPersp = THREE.WebAR.createVRSeeThroughCamera(vrDisplay, 0.00001, 1000);
if (!model) {
model = new THREE.Mesh(new THREE.BoxBufferGeometry(0.1, 0.1, 0.01), new THREE.MeshLambertMaterial( {color: 0x888888 } ));
}
model.position.set(Infinity, Infinity, Infinity);
scene.add(model);
var material = new THREE.PointsMaterial( { size: 0.01, vertexColors: THREE.VertexColors } );
material.depthWrite = false;
pointCloud = new THREE.WebAR.VRPointCloud(vrDisplay, true);
points = new THREE.Points( pointCloud.getBufferGeometry(), material );
points.frustumCulled = false;
points.renderDepth = 0;
if (showPointCloud)
scene.add(points);
vrControls = new THREE.VRControls(cameraPersp);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set( 0, 1, 0);
scene.add( directionalLight );
// Create the renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.autoClear = false;
document.body.appendChild( renderer.domElement );
// Create a way to measure performance
stats = new Stats();
container.appendChild( stats.dom );
// Control the resizing of the window to correctly display the scene.
window.addEventListener( 'resize', onWindowResize, false );
renderer.domElement.addEventListener("touchstart", function(event) {
if (event.changedTouches.length > 0)
lastX = event.changedTouches[0].pageX;
});
renderer.domElement.addEventListener("touchmove", function(event) {
if (event.changedTouches.length > 0 && vrDisplay) {
var x = event.changedTouches[0].pageX;
var diffX = x - lastX;
lastX = x;
model.rotateZ(THREE.Math.degToRad(diffX));
}
});
renderer.domElement.addEventListener("click", function(event) {
if (vrDisplay) {
pos.x = event.pageX / window.innerWidth;
pos.y = event.pageY / window.innerHeight;
THREE.WebAR.updateVector3Orientation(vrDisplay, pos);
var pointAndPlane = vrDisplay.getPickingPointAndPlaneInPointCloud(pos.x, pos.y);
// console.log("x = " + lastX + ", y = " + lastY + ", window.innerWidth = " + window.innerWidth + ", window.innerHeight = " + window.innerHeight + ", uvx = " + x + ", uvy = " + y + ", point[0] = " + pointAndPlane.point[0] + ", point[1] = " + pointAndPlane.point[1] + ", point[2] = " + pointAndPlane.point[2] + ", plane[0] = " + pointAndPlane.plane[0] + ", plane[1] = " + pointAndPlane.plane[1] + ", plane[2] = " + pointAndPlane.plane[2] + ", plane[3] = " + pointAndPlane.plane[3]);
if (pointAndPlane.correctValues) {
// alert(pointAndPlane.point);
// model.position.set(pointAndPlane.point[0], pointAndPlane.point[1], pointAndPlane.point[2]);
THREE.WebAR.positionAndRotateObject3DWithPickingPointAndPlaneInPointCloud(pointAndPlane, model, 0.0);
}
else {
alert("Could not retrieve the correct point and plane.");
}
}
});
}
function onWindowResize() {
// TODO: Accordingly update the perspective camera.
// cameraPersp.aspect = window.innerWidth / window.innerHeight;
// cameraPersp.updateProjectionMatrix();
THREE.WebAR.resizeVRSeeThroughCamera(vrDisplay, cameraPersp);
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function updateAndRender() {
stats.update();
// Update the see through camera scene
// IMPORTANT: This call makes sure that the camera mesh (quad) uses the correct texture coordinates depending on the camera and device orientations.
THREE.WebAR.updateCameraMeshOrientation(vrDisplay, cameraMesh);
// Render the see through camera scene
renderer.clear();
if (gui.showSeeThroughCamera)
renderer.render( sceneCamera, cameraOrtho );
// Update the perspective scene
vrControls.update();
if (vrDisplay && false) {
cameraPersp.matrixWorldNeedsUpdate = false;
cameraPersp.matrixAutoUpdate = false;
var poseMatrix = vrDisplay.getPoseMatrix();
for (var i = 0; i < 16; i++) {
cameraPersp.matrixWorld.elements[i] = poseMatrix[i];
}
}
// IMPORTANT: this call makes sure that the camera, that has taken the pose from the previous VRControls.update call, is correctly transformed depending on the device orientation.
THREE.WebAR.updateCameraOrientation(vrDisplay, cameraPersp);
pointCloud.update(showPointCloud, gui.pointsToSkip);
// Render the perspective scene
renderer.clearDepth();
renderer.render( scene, cameraPersp );
requestAnimationFrame( updateAndRender );
}
</script>
</body>
</html>
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |