Permalink
f552b31 May 18, 2018
3 contributors

Users who have contributed to this file

@TrevorFSmith @joshmarinacci @blairmacintyre
311 lines (287 sloc) 8.68 KB
<html>
<head>
<title>Spinners example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body, html {
padding: 0;
margin: 0;
overflow: hidden;
position: fixed;
width: 100%;
height: 100vh;
-webkit-user-select: none;
user-select: none;
}
#target {
width: 100%;
height: 100%;
position: absolute;
}
.common-message {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 20px;
}
</style>
<link rel="stylesheet" href="../common.css"/>
<script src="../libs/three.min.js"></script>
<script src="../libs/loaders/BinaryLoader.js"></script>
<script src="../libs/postprocessing/EffectComposer.js"></script>
<script src="../libs/shaders/ConvolutionShader.js"></script>
<script src="../libs/postprocessing/ShaderPass.js"></script>
<script src="../libs/postprocessing/MaskPass.js"></script>
<script src="../libs/shaders/CopyShader.js"></script>
<script src="../libs/shaders/FilmShader.js"></script>
<script src="../libs/postprocessing/RenderPass.js"></script>
<script src="../libs/postprocessing/BloomPass.js"></script>
<script src="../libs/postprocessing/FilmPass.js"></script>
<script type="module" src="../../polyfill/XRPolyfill.js"></script>
<script nomodule src="../../dist/webxr-polyfill.js"></script>
<script src="../common.js"></script>
</head>
<body>
<div id="target" />
<div onclick="hideMe(this)" id="description">
<h2>Peoples</h2>
<h5>(click to dismiss)</h5>
<p>Place animated people on surfaces by tapping.</p>
</div>
<script>
/*
This is the THREE.js example from https://threejs.org/examples/webgl_points_dynamic.html ported to WebXR
*/
class PageApp extends ThingsOnSurfacesApp {
constructor(domElement){
super(domElement, false)
this.clock = new THREE.Clock()
this.meshes = []
this.clonemeshes = []
this.geometries = []
this.femaleGeometry = null
this.maleGeometry = null
this.colors = [
0xff4422,
0xff9955,
0xff77dd,
0xff7744,
0xff5522,
0xff9922,
0xff99ff
]
const loader = new THREE.BinaryLoader()
loader.load('../models/female02/Female02_bin.js', geometry => {
this.femaleGeometry = geometry
this.geometries.push(this.femaleGeometry)
// Add a first model so that it's clear that the scene is running and before hit testing can find an anchor
let firstNode = this.createSceneGraphNode()
firstNode.position.set(0, 0, -2)
this.floorGroup.add(firstNode)
})
loader.load('../models/male02/Male02_bin.js', geometry => {
this.maleGeometry = geometry
this.geometries.push(this.maleGeometry)
})
this.composer = new THREE.EffectComposer(this.renderer)
this.composer.addPass(new THREE.RenderPass(this.scene, this.camera))
this.composer.addPass(new THREE.BloomPass(0.75))
let filmPass = new THREE.FilmPass(0.5, 0.5, 1448, false)
filmPass.renderToScreen = true
this.composer.addPass(filmPass)
}
updateScene(frame){
super.updateScene(frame)
let delta = 10 * this.clock.getDelta()
delta = delta < 2 ? delta : 2
let data = null
let vertices = null
let vertices_tmp = null
let vl = null
let d = null
let vt = null
let mesh = null
let p = null
for(let j = 0, jl = this.meshes.length; j < jl; j ++){
data = this.meshes[j]
mesh = data.mesh
vertices = data.vertices
vertices_tmp = data.vertices_tmp
vl = data.vl
if (! data.dynamic) continue
if (data.start > 0){
data.start -= 1
} else {
if (!data.started){
data.direction = -1
data.started = true
}
}
for (let i = 0; i < vl; i ++){
p = vertices[i]
vt = vertices_tmp[i]
// falling down
if (data.direction < 0){
if (p.y > 0){
p.x += 1.5 * (0.50 - Math.random()) * data.speed * delta
p.y += 3.0 * (0.25 - Math.random()) * data.speed * delta
p.z += 1.5 * (0.50 - Math.random()) * data.speed * delta
} else {
if (! vt[3]){
vt[3] = 1
data.down += 1
}
}
}
// rising up
if (data.direction > 0){
d = Math.abs(p.x - vt[0]) + Math.abs(p.y - vt[1]) + Math.abs(p.z - vt[2])
if (d > 1){
p.x += - (p.x - vt[0]) / d * data.speed * delta * (0.85 - Math.random())
p.y += - (p.y - vt[1]) / d * data.speed * delta * (1 + Math.random())
p.z += - (p.z - vt[2]) / d * data.speed * delta * (0.85 - Math.random())
} else {
if (! vt[4]){
vt[4] = 1
data.up += 1
}
}
}
}
// all down
if (data.down === vl){
if (data.delay === 0){
data.direction = 1
data.speed = 10
data.down = 0
data.delay = 320
for(let i = 0; i < vl; i ++){
vertices_tmp[i][3] = 0
}
} else {
data.delay -= 1
}
}
// all up
if (data.up === vl){
if (data.delay === 0){
data.direction = -1
data.speed = 35
data.up = 0
data.delay = 120
for(let i = 0; i < vl; i ++){
vertices_tmp[i][4] = 0
}
} else {
data.delay -= 1
}
}
mesh.geometry.verticesNeedUpdate = true
}
}
doRender(){
this.renderer.clear()
this.composer.render(0.01)
}
// Called during construction to allow the app to populate this.scene
initializeScene(){
// Add a box at the scene origin
let box = new THREE.Mesh(
new THREE.BoxBufferGeometry(0.1, 0.1, 0.1),
new THREE.MeshPhongMaterial({ color: '#DDFFDD' })
)
box.position.set(0, 0.05, 0)
var axesHelper = AxesHelper( 0.2 );
this.floorGroup.add( axesHelper );
this.floorGroup.add(box)
// Add a few lights
this.scene.add(new THREE.AmbientLight('#FFF', 0.2))
let directionalLight = new THREE.DirectionalLight('#FFF', 0.6)
directionalLight.position.set(0, 10, 0)
this.scene.add(directionalLight)
}
createSceneGraphNode(){
const group = new THREE.Group()
group.add(this.createMesh(
this.geometries[Math.floor(this.geometries.length * Math.random())],
0.006,
0,0,0,
0.005,
this.colors[Math.floor(this.colors.length * Math.random())],
true
))
return group
}
createMesh(originalGeometry, scale, x, y, z, pointSize, color, dynamic){
let i, c, mesh, p
let vertices = originalGeometry.vertices
let vl = vertices.length
let geometry = new THREE.Geometry()
let vertices_tmp = []
for (i = 0; i < vl; i ++){
p = vertices[i]
geometry.vertices[i] = p.clone()
vertices_tmp[i] = [p.x, p.y, p.z, 0, 0]
}
if (dynamic){
c = color
mesh = new THREE.Points(geometry, new THREE.PointsMaterial({ size: pointSize, color: c }))
this.clonemeshes.push({ mesh: mesh, speed: 0.5 + Math.random() })
} else {
mesh = new THREE.Points(geometry, new THREE.PointsMaterial({ size: pointSize, color: color }))
}
mesh.scale.x = mesh.scale.y = mesh.scale.z = scale
mesh.position.x = x
mesh.position.y = y
mesh.position.z = z
mesh.quaternion.setFromEuler(new THREE.Euler(0, (Math.PI * 2) * Math.random(), 0))
this.meshes.push({
mesh: mesh,
vertices: geometry.vertices,
vertices_tmp: vertices_tmp,
vl: vl,
down: 0,
up: 0,
direction: 0,
speed: 35,
delay: Math.floor(10 * Math.random()),
started: false,
start: Math.floor(100 * Math.random()),
dynamic: dynamic
})
mesh.name = 'prettyperson: ' + Math.random()
return mesh
}
}
function AxesHelper( size ) {
size = size || 1;
var vertices = [
0, 0, 0, size, 0, 0,
0, 0, 0, 0, size, 0,
0, 0, 0, 0, 0, size
];
var colors = [
1, 0, 0, 1, 0.6, 0,
0, 1, 0, 0.6, 1, 0,
0, 0, 1, 0, 0.6, 1
];
var geometry = new THREE.BufferGeometry();
geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
return new THREE.LineSegments(geometry, material);
}
window.addEventListener('DOMContentLoaded', () => {
setTimeout(() => {
try {
window.pageApp = new PageApp(document.getElementById('target'))
} catch(e){
console.error('page error', e)
}
}, 1000)
})
</script>
</body>
</html>