Last active
September 6, 2015 03:55
-
-
Save mathdoodle/b903a8175bcea71b8660 to your computer and use it in GitHub Desktop.
BARN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"uuid": "d5b74e6d-e0e8-44e7-a691-798ca0939a7e", | |
"description": "BARN", | |
"dependencies": { | |
"DomReady": "latest", | |
"davinci-blade": "1.1.1", | |
"davinci-eight": "latest" | |
}, | |
"operatorOverloading": true | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface ITrackBall { | |
enabled: boolean; | |
rotateSpeed: number; | |
zoomSpeed: number; | |
panSpeed: number; | |
noRotate: boolean; | |
noZoom: boolean; | |
noPan: boolean; | |
staticMoving: boolean; | |
dynamicDampingFactor: number; | |
minDistance: number; | |
maxDistance: number; | |
keys: number[]; | |
update(): void; | |
handleResize(): void; | |
setSize(width: number, height: number): void; | |
} | |
var trackball = function(object: {position: EIGHT.Vector3; up: EIGHT.Vector3; lookAt: (where: EIGHT.Cartesian3)=>void}, wnd: Window): ITrackBall { | |
var document = wnd.document; | |
var documentElement = document.documentElement; | |
var screen = {left: 0, top: 0, width: 0, height: 0}; | |
var api: ITrackBall = { | |
// Provide initial values for all interface properties. | |
enabled: true, | |
rotateSpeed: 1.0, | |
zoomSpeed: 1.2, | |
panSpeed: 0.3, | |
noRotate: false, | |
noZoom: false, | |
noPan: false, | |
staticMoving: false, | |
dynamicDampingFactor: 0.2, | |
minDistance: 0, | |
maxDistance: Infinity, | |
keys: [65, 83, 68], // A S D | |
/** | |
* update | |
*/ | |
update() { | |
// target is initially the origin, so eye becomes the object position. | |
eye.subVectors(object.position, target); | |
if (!api.noRotate) { | |
rotateCamera(); | |
} | |
if (!api.noZoom) { | |
zoomCamera(); | |
} | |
if (!api.noPan) { | |
panCamera(); | |
} | |
object.position.addVectors(target, eye); | |
checkDistances(); | |
object.lookAt(target); | |
if (lastPosition.quadranceTo(object.position) > EPS) { | |
// TODO dispatchEvent( changeEvent ); | |
lastPosition.copy(object.position); | |
} | |
}, | |
/** | |
* Determine and cache screen coordinates | |
*/ | |
handleResize() { | |
var box = documentElement.getBoundingClientRect(); | |
screen.left = box.left + wnd.pageXOffset - documentElement.clientLeft; | |
screen.top = box.top + wnd.pageYOffset - documentElement.clientTop; | |
screen.width = box.width; | |
screen.height = box.height; | |
}, | |
/** | |
* | |
*/ | |
setSize(width: number, height: number) { | |
screen.width = width; | |
screen.height = height; | |
} | |
}; | |
var getMouseOnScreen: (pageX: number, pageY: number) => EIGHT.Vector2 = (function() { | |
var vector = new EIGHT.Vector2(); | |
return function (pageX: number, pageY: number) { | |
vector.set((pageX - screen.left) / screen.width, (pageY - screen.top) / screen.height); | |
return vector; | |
}; | |
}()); | |
var getMouseOnCircle: (pageX: number, pageY: number) => EIGHT.Vector2 = ( function () { | |
var vector = new EIGHT.Vector2(); | |
return function (pageX: number, pageY: number) { | |
vector.set( | |
( ( pageX - screen.width * 0.5 - screen.left ) / ( screen.width * 0.5 ) ), | |
( ( screen.height + 2 * ( screen.top - pageY ) ) / screen.width ) | |
); | |
return vector; | |
}; | |
}() ); | |
// The following variables are the state for the camera. | |
var moveCurr = new EIGHT.Vector2(); | |
var movePrev = new EIGHT.Vector2(); | |
var eye = new EIGHT.Vector3(); | |
var target = new EIGHT.Vector3(); | |
var lastAxis = new EIGHT.Vector3(); | |
var lastAngle = 0; | |
/** | |
* The effect of this function is to manipulate the up vector of the 'object' argument. | |
* rotateCamera is an immediately executed function that returns another function. | |
* This seems rather heavyweight but it does save on some temporaries being frequently created. | |
* This seems to be a common pattern. | |
* We might alternatively create a class and keep an instance around. | |
*/ | |
var rotateCamera = (function() { | |
var axis = new EIGHT.Vector3(); | |
var quaternion = new EIGHT.Quaternion(); | |
var eyeDirection = new EIGHT.Vector3(); | |
var objectUpDirection = new EIGHT.Vector3(); | |
var objectSidewaysDirection = new EIGHT.Vector3(); | |
var moveDirection = new EIGHT.Vector3(); | |
var angle: number; | |
return function () { | |
moveDirection.set( moveCurr.x - movePrev.x, moveCurr.y - movePrev.y, 0 ); | |
angle = moveDirection.magnitude(); | |
if (angle) { | |
eye.copy( object.position ).sub(target); | |
eyeDirection.copy(eye).normalize(); | |
objectUpDirection.copy(object.up).normalize(); | |
objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize(); | |
objectUpDirection.setMagnitude(moveCurr.y - movePrev.y); | |
objectSidewaysDirection.setMagnitude(moveCurr.x - movePrev.x); | |
moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) ); | |
axis.crossVectors( moveDirection, eye ).normalize(); | |
angle *= api.rotateSpeed; | |
quaternion.setFromAxisAngle( axis, angle ); | |
eye.applyQuaternion( quaternion ); | |
object.up.applyQuaternion( quaternion ); | |
lastAxis.copy( axis ); | |
lastAngle = angle; | |
} | |
else if ( !api.staticMoving && lastAngle ) { | |
lastAngle *= Math.sqrt( 1.0 - api.dynamicDampingFactor ); | |
eye.copy(object.position).sub(target); | |
quaternion.setFromAxisAngle(lastAxis, lastAngle); | |
eye.applyQuaternion( quaternion ); | |
object.up.applyQuaternion(quaternion); | |
} | |
movePrev.copy(moveCurr); | |
}; | |
}()); | |
var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 }; | |
var state = STATE.NONE; | |
var prevState = STATE.NONE; | |
var zoomStart = new EIGHT.Vector2(); | |
var zoomEnd = new EIGHT.Vector2(); | |
var touchZoomDistanceStart = 0; | |
var touchZoomDistanceEnd = 0; | |
var panStart = new EIGHT.Vector2(); | |
var panEnd = new EIGHT.Vector2(); | |
/** | |
* zoomCamera manipulates the eye variable | |
*/ | |
var zoomCamera = function () { | |
var factor; | |
if (state === STATE.TOUCH_ZOOM_PAN) { | |
factor = touchZoomDistanceStart / touchZoomDistanceEnd; | |
touchZoomDistanceStart = touchZoomDistanceEnd; | |
eye.multiplyScalar( factor ); | |
} | |
else { | |
factor = 1.0 + ( zoomEnd.y - zoomStart.y ) * api.zoomSpeed; | |
if ( factor !== 1.0 && factor > 0.0 ) { | |
eye.multiplyScalar( factor ); | |
if ( api.staticMoving ) { | |
zoomStart.copy( zoomEnd ); | |
} | |
else { | |
zoomStart.y += ( zoomEnd.y - zoomStart.y ) * api.dynamicDampingFactor; | |
} | |
} | |
} | |
}; | |
/** | |
* panCamera manipulates the objects position property. | |
*/ | |
var panCamera = (function() { | |
var mouseChange = new EIGHT.Vector2(), | |
objectUp = new EIGHT.Vector3(), | |
pan = new EIGHT.Vector3(); | |
return function () { | |
mouseChange.copy(panEnd).sub(panStart); | |
if (mouseChange.quaditude()) { | |
mouseChange.multiplyScalar(eye.magnitude() * api.panSpeed); | |
pan.copy(eye).cross(object.up).setMagnitude(mouseChange.x); | |
pan.add( objectUp.copy(object.up).setMagnitude(mouseChange.y)); | |
object.position.add( pan ); | |
target.add( pan ); | |
if (api.staticMoving ) { | |
panStart.copy(panEnd); | |
} | |
else { | |
panStart.add( mouseChange.subVectors( panEnd, panStart ).multiplyScalar( api.dynamicDampingFactor ) ); | |
} | |
} | |
}; | |
}()); | |
var checkDistances = function () { | |
if ( !api.noZoom || !api.noPan ) { | |
if (eye.quaditude() > api.maxDistance * api.maxDistance) { | |
object.position.addVectors(target, eye.setMagnitude(api.maxDistance)); | |
} | |
if (eye.quaditude() < api.minDistance * api.minDistance) { | |
object.position.addVectors(target, eye.setMagnitude(api.minDistance)); | |
} | |
} | |
}; | |
var EPS = 0.000001; | |
var lastPosition = new EIGHT.Vector3(); | |
// events | |
var changeEvent = { type: 'change' }; | |
var startEvent = { type: 'start' }; | |
var endEvent = { type: 'end' }; | |
// for reset | |
var target0 = target.clone(); | |
var position0 = object.position.clone(); | |
var up0 = object.up.clone(); | |
var reset = function () { | |
state = STATE.NONE; | |
prevState = STATE.NONE; | |
target.copy( target0 ); | |
object.position.copy( position0 ); | |
object.up.copy( up0 ); | |
eye.subVectors( object.position, target ); | |
object.lookAt( target ); | |
// TODO dispatchEvent( changeEvent ); | |
lastPosition.copy( object.position ); | |
}; | |
// listeners | |
function keydown( event ) { | |
if ( api.enabled === false ) | |
return; | |
wnd.removeEventListener( 'keydown', keydown ); | |
prevState = state; | |
if ( state !== STATE.NONE ) { | |
return; | |
} | |
else if ( event.keyCode === api.keys[ STATE.ROTATE ] && !api.noRotate ) { | |
state = STATE.ROTATE; | |
} | |
else if ( event.keyCode === api.keys[ STATE.ZOOM ] && !api.noZoom ) { | |
state = STATE.ZOOM; | |
} | |
else if ( event.keyCode === api.keys[ STATE.PAN ] && !api.noPan ) { | |
state = STATE.PAN; | |
} | |
} | |
function keyup(event) { | |
if (api.enabled === false) | |
return; | |
state = prevState; | |
wnd.addEventListener('keydown', keydown, false); | |
} | |
function mousedown(event) { | |
if (api.enabled === false) | |
return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
if (state === STATE.NONE) { | |
state = event.button; | |
} | |
if (state === STATE.ROTATE && !api.noRotate) { | |
moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY)); | |
movePrev.copy(moveCurr); | |
} | |
else if (state === STATE.ZOOM && !api.noZoom ) { | |
zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) ); | |
zoomEnd.copy(zoomStart); | |
} | |
else if (state === STATE.PAN && !api.noPan) { | |
panStart.copy(getMouseOnScreen(event.pageX, event.pageY)); | |
panEnd.copy(panStart); | |
} | |
document.addEventListener('mousemove', mousemove, false); | |
document.addEventListener('mouseup', mouseup, false); | |
// TODO dispatchEvent(startEvent); | |
} | |
function mousemove( event ) { | |
if (api.enabled === false) | |
return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
if (state === STATE.ROTATE && !api.noRotate ) { | |
movePrev.copy(moveCurr); | |
moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY)); | |
} | |
else if (state === STATE.ZOOM && !api.noZoom) { | |
zoomEnd.copy(getMouseOnScreen(event.pageX, event.pageY)); | |
} else if (state === STATE.PAN && !api.noPan) { | |
panEnd.copy(getMouseOnScreen(event.pageX, event.pageY)); | |
} | |
} | |
function mouseup(event) { | |
if (api.enabled === false) | |
return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
state = STATE.NONE; | |
document.removeEventListener('mousemove', mousemove); | |
document.removeEventListener('mouseup', mouseup); | |
// TODO dispatchEvent( endEvent ); | |
} | |
function mousewheel(event: MouseWheelEvent) { | |
if (api.enabled === false) | |
return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
var delta = 0; | |
if (event.wheelDelta) { // WebKit / Opera / Explorer 9 | |
delta = event.wheelDelta / 40; | |
} | |
else if (event.detail) { // Firefox | |
delta = - event.detail / 3; | |
} | |
zoomStart.y += delta * 0.01; | |
// dispatchEvent( startEvent ); | |
// dispatchEvent( endEvent ); | |
} | |
function touchstart( event ) { | |
if (api.enabled === false ) | |
return; | |
switch (event.touches.length) { | |
case 1: | |
state = STATE.TOUCH_ROTATE; | |
moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); | |
movePrev.copy(moveCurr); | |
break; | |
case 2: | |
state = STATE.TOUCH_ZOOM_PAN; | |
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; | |
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; | |
touchZoomDistanceEnd = touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy ); | |
var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2; | |
var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2; | |
panStart.copy( getMouseOnScreen( x, y ) ); | |
panEnd.copy(panStart); | |
break; | |
default: | |
state = STATE.NONE; | |
} | |
// dispatchEvent( startEvent ); | |
} | |
function touchmove(event) { | |
if (api.enabled === false) | |
return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
switch (event.touches.length) { | |
case 1: | |
movePrev.copy(moveCurr); | |
moveCurr.copy( getMouseOnCircle( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ) ); | |
break; | |
case 2: | |
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; | |
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; | |
touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy ); | |
var x = ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ) / 2; | |
var y = ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ) / 2; | |
panEnd.copy( getMouseOnScreen( x, y ) ); | |
break; | |
default: | |
state = STATE.NONE; | |
} | |
} | |
function touchend( event ) { | |
if (api.enabled === false) | |
return; | |
switch (event.touches.length) { | |
case 1: | |
movePrev.copy(moveCurr); | |
moveCurr.copy(getMouseOnCircle(event.touches[ 0 ].pageX, event.touches[ 0 ].pageY)); | |
break; | |
case 2: | |
touchZoomDistanceStart = touchZoomDistanceEnd = 0; | |
var x = (event.touches[ 0 ].pageX + event.touches[ 1 ].pageX) / 2; | |
var y = (event.touches[ 0 ].pageY + event.touches[ 1 ].pageY) / 2; | |
panEnd.copy(getMouseOnScreen(x, y)); | |
panStart.copy(panEnd); | |
break; | |
} | |
state = STATE.NONE; | |
// dispatchEvent( endEvent ); | |
} | |
// This works, bit we don't unhook it. | |
documentElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); | |
documentElement.addEventListener( 'mousedown', mousedown, false ); | |
documentElement.addEventListener( 'mousewheel', mousewheel, false ); | |
documentElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox | |
documentElement.addEventListener( 'touchstart', touchstart, false ); | |
documentElement.addEventListener( 'touchend', touchend, false ); | |
documentElement.addEventListener( 'touchmove', touchmove, false ); | |
wnd.addEventListener( 'keydown', keydown, false ); | |
wnd.addEventListener( 'keyup', keyup, false ); | |
api.handleResize(); | |
// force an update at start | |
api.update(); | |
return api; | |
}; | |
DomReady.ready(function() { | |
try { | |
main(); | |
} | |
catch(e) { | |
console.error(e); | |
} | |
}); | |
/** | |
* Standard basis vector in the x-axis direction. | |
*/ | |
var e1 = blade.e3ga.e1; | |
/** | |
* Standard basis vector in the y-axis direction. | |
*/ | |
var e2 = blade.e3ga.e2; | |
/** | |
* Standard basis vector in the z-axis direction. | |
*/ | |
var e3 = blade.e3ga.e3; | |
/** | |
* Returns the cosine of a number. | |
*/ | |
var cos = blade.universals.cos; | |
/** | |
* Returns e (the base of natural logarithms) raised to a power. | |
*/ | |
var exp = blade.universals.exp; | |
/** | |
* Returns the sine of a number. | |
*/ | |
var sin = blade.universals.sin; | |
/** | |
* S.I. units of measure. | |
*/ | |
var kilogram = blade.e3ga.units.kilogram; | |
var meter = blade.e3ga.units.meter; | |
var second = blade.e3ga.units.second; | |
var hertz = blade.e3ga.units.hertz; | |
class BarnMesh extends EIGHT.DefaultAttribProvider { | |
private aVertexPositionArray: Float32Array; | |
constructor() { | |
super(); | |
} | |
draw(context: WebGLRenderingContext) { | |
context.drawArrays(context.TRIANGLES, 0, this.aVertexPositionArray.length / 3); | |
} | |
dots(vertex: (x: number, y: number, z: number) => void, point: (a: number) => void) { | |
} | |
wire(vertex: (x: number, y: number, z: number) => void, line: (a: number, b: number) => void) { | |
} | |
mesh(vertex: (x: number, y: number, z: number) => void, face: (a: number, b: number, c: number) => void) { | |
// You have freedom to compute vertices and faces how you want, but return the results in canonical form. | |
vertex(-0.5, 0.0, -1.0); | |
vertex( 0.5, 0.0, -1.0); | |
vertex( 0.5, 1.0, -1.0); | |
vertex( 0.0, 1.5, -1.0); | |
vertex(-0.5, 1.0, -1.0); | |
vertex(-0.5, 0.0, 1.0); | |
vertex( 0.5, 0.0, 1.0); | |
vertex( 0.5, 1.0, 1.0); | |
vertex( 0.0, 1.5, 1.0); | |
vertex(-0.5, 1.0, 1.0); | |
face(1, 0, 2); | |
face(2, 0, 4); | |
face(2, 4, 3); | |
face(5, 6, 7); | |
face(5, 7, 9); | |
face(9, 7, 8); | |
face(6, 1, 2); | |
face(6, 2, 7); | |
face(9, 0, 5); | |
face(9, 4, 0); | |
face(8, 3, 4); | |
face(8, 4, 9); | |
face(7, 2, 3); | |
face(7, 3, 8); | |
face(5, 0, 1); | |
face(5, 1, 6); | |
} | |
update(attributes: EIGHT.ShaderVariableDecl[]) { | |
var faceList: {a: number; b: number; c: number}[] = []; | |
var vertexList: blade.Euclidean3[] = []; | |
function face(a: number, b: number, c: number) { | |
faceList.push({a: a, b: b, c: c}); | |
} | |
function vertex(x: number, y: number, z: number) { | |
vertexList.push(new blade.Euclidean3(0, x, y, z, 0, 0, 0, 0)); | |
} | |
this.mesh(vertex, face); | |
var vertices: number[] = []; | |
var normals: number[] = []; | |
var elements: number[] = []; | |
faceList.forEach(function(face) { | |
elements.push(face.a); | |
elements.push(face.b); | |
elements.push(face.c); | |
var vertexA = vertexList[face.a]; | |
vertices.push(vertexA.x); | |
vertices.push(vertexA.y); | |
vertices.push(vertexA.z); | |
var vertexB = vertexList[face.b]; | |
vertices.push(vertexB.x); | |
vertices.push(vertexB.y); | |
vertices.push(vertexB.z); | |
var vertexC = vertexList[face.c]; | |
vertices.push(vertexC.x); | |
vertices.push(vertexC.y); | |
vertices.push(vertexC.z); | |
}); | |
this.aVertexPositionArray = new Float32Array(vertices); | |
return super.update(attributes); | |
} | |
getAttribArray(name: string): {usage: EIGHT.DataUsage; data: Float32Array} { | |
switch(name) { | |
case 'aVertexPosition': { | |
return {usage: EIGHT.DataUsage.STATIC_DRAW, data: this.aVertexPositionArray}; | |
} | |
break; | |
default: { | |
return super.getAttribArray(name); | |
} | |
} | |
} | |
getAttribMeta(): EIGHT.AttribMetaInfos { | |
return super.getAttribMeta(); | |
} | |
hasElementArray(): boolean { | |
return super.hasElementArray(); | |
} | |
getElementArray(): {usage: EIGHT.DataUsage; data: Uint16Array} { | |
return super.getElementArray(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<style> | |
/* STYLE-MARKER */ | |
</style> | |
<script id='vs' type='x-shader/x-vertex'> | |
attribute vec3 aVertexPosition; | |
attribute vec3 aVertexNormal; | |
uniform vec3 uColor; | |
uniform mat4 uModelMatrix; | |
uniform mat3 uNormalMatrix; | |
uniform mat4 uViewMatrix; | |
uniform mat4 uProjectionMatrix; | |
uniform vec3 uAmbientLight; | |
uniform vec3 uDirectionalLightColor; | |
uniform vec3 uDirectionalLightDirection; | |
varying highp vec4 vColor; | |
varying highp vec3 vLight; | |
void main(void) { | |
gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aVertexPosition, 1.0); | |
vColor = vec4(uColor, 1.0); | |
vec3 L = normalize(uDirectionalLightDirection); | |
vec3 N = normalize(uNormalMatrix * aVertexNormal); | |
float cosineFactor = max(dot(N,L), 0.0); | |
vLight = uAmbientLight + cosineFactor * uDirectionalLightColor; | |
} | |
</script> | |
<script id='fs' type='x-shader/x-fragment'> | |
varying highp vec4 vColor; | |
varying highp vec3 vLight; | |
void main(void) { | |
gl_FragColor = vec4(vColor.xyz * vLight, vColor.a); | |
} | |
</script> | |
<!-- SCRIPTS-MARKER --> | |
</head> | |
<body> | |
<script> | |
// LIBS-MARKER | |
</script> | |
<script> | |
// CODE-MARKER | |
</script> | |
<canvas id='my-canvas'> | |
Your browser does not support the canvas element. | |
</canvas> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The angle of tilt of the precessing vector. | |
*/ | |
var tiltAngle = 30 * Math.PI / 180; | |
var S = exp(-(e2 ^ e1) * tiltAngle / 2); | |
var B = e3 ^ e1; | |
/** | |
* The period of the motions in the animation. | |
*/ | |
var T = 10 * second; | |
/** | |
* The frequency of the motions in the animation. | |
*/ | |
var f = (1 / T); | |
var omega = 2 * Math.PI * f; | |
class Camera { | |
private perspective: EIGHT.Perspective; | |
constructor(perspective: EIGHT.Perspective) { | |
this.perspective = perspective; | |
} | |
get position(): EIGHT.Vector3 { | |
return this.perspective.eye; | |
} | |
get up(): EIGHT.Vector3 { | |
return this.perspective.up; | |
} | |
lookAt(where: EIGHT.Cartesian3){ | |
this.perspective.look = where; | |
} | |
} | |
function main() { | |
var scene = EIGHT.scene(); | |
var canvas = <HTMLCanvasElement>document.getElementById('my-canvas'); | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
var renderer = EIGHT.renderer(canvas); | |
renderer.clearColor(0.2, 0.2, 0.2, 1.0); | |
var monitor = EIGHT.webgl(canvas).addContextUser(renderer).addContextUser(scene).start(); | |
var gl = monitor.context; | |
var camera = EIGHT.perspective().setAspect(canvas.clientWidth / canvas.clientHeight).setEye(2 * e1 + (4/3) * e2 + (8/3) * e3).setFov(75*Math.PI/180); | |
var program = EIGHT.programFromScripts('vs','fs'); | |
var barnMesh = new EIGHT.GeometryAdapter(new EIGHT.BarnGeometry(), {drawMode: EIGHT.DrawMode.TRIANGLES}); | |
monitor.addContextUser(barnMesh); | |
//var barnMesh = new BarnMesh(); | |
var model = new EIGHT.Node(); | |
var barn = EIGHT.primitive(barnMesh, program, model); | |
//var barn = EIGHT.primitive(barnMesh, EIGHT.smartProgram(barnMesh.getAttribMeta(),[model.getUniformMeta(), ambients.getUniformMeta()]), model); | |
//console.log(barn.program.vertexShader); | |
//console.log(barn.program.fragmentShader); | |
barn.model.color = new EIGHT.Vector3([1, 1, 0]); | |
scene.add(barn); | |
var t = trackball(new Camera(camera), window); | |
t.setSize(canvas.clientWidth, canvas.clientHeight); | |
//console.log(JSON.stringify(aLight.getUniformData())); | |
scene.uniform3f('uAmbientLight',0.3, 0.3, 0.3); | |
scene.uniform3f('uDirectionalLightColor', 0.7, 0.7, 0.7); | |
scene.uniform3f('uDirectionalLightDirection', 2, 3, 5); | |
EIGHT.animation((time: number) => { | |
camera.accept(scene); | |
var theta = omega * (time * second); | |
// simple harmonic motion | |
//barn.model.position.copy(1.2 * sin(theta) * e2); | |
// precession | |
var R = exp(-B * theta / 2); | |
//barn.model.attitude.copy(R * S * ~R); | |
// rotation | |
var R = exp(-B * theta / 2); | |
barn.model.attitude.copy(R); | |
// orbit | |
//barn.model.position.copy(2 * cos(theta) * e1 - sin(theta) * (e3 - 0.5 * e2)); | |
t.update(); | |
renderer.render(scene); | |
}).start(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { margin: 0; } | |
canvas { width: 100%; height: 100% } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment