Forgejo Up

This commit is contained in:
Amit Kumar Nandi 2024-10-03 06:42:49 +05:30
parent 34467fc960
commit c51788eb87
79 changed files with 53535 additions and 1 deletions

21
.eslintrc.yml Normal file
View file

@ -0,0 +1,21 @@
extends: airbnb
plugins:
- react
- jsx-a11y
- import
rules:
semi: ["error", "never"]
no-plusplus: 0
no-restricted-syntax: ["off", "ForInStatement"]
max-len: 0
newline-per-chained-call: 0
no-undef: 1
"no-param-reassign": [2, {"props": false}]
no-debugger: 0
globals:
document: true
THREE: true
window: true
debug: true
THREERobot: true
define: true

41
.gitignore vendored Normal file
View file

@ -0,0 +1,41 @@
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
.DS_Store

24
LICENSE
View file

@ -1,3 +1,4 @@
<<<<<<< HEAD
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@ -71,3 +72,26 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=======
MIT License
Copyright (c) 2017 Maximilian Beck maximilian@glumb.de
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
>>>>>>> 244abf3 (Forgejo Up)

View file

@ -1,3 +1,38 @@
<<<<<<< HEAD
# Kinesim
Kinesim is a Three.Js based robotics simulator that runs in browser.
Kinesim is a Three.Js based robotics simulator that runs in browser.
=======
# robot-gui
A three.js based 3D robot interface.
# How To
Download or clone. Open `index.html` or [RoboSim](https://aamitn.github.io/rg/). Enjoy 🤖😀
You may need to use Chrome, since some ES6 features are not supported in other browsers yet.
![robot-gui](https://user-images.githubusercontent.com/3062564/31865318-7d97605e-b76d-11e7-8ab4-7c2a9e17be3d.png)
# Geometry
Configure the robot geometry using the *geometry* tab.
![bildschirmfoto 2017-10-22 um 21 14 02](https://user-images.githubusercontent.com/3062564/31865347-f8010804-b76d-11e7-8452-e003677da2c7.png)
# Angle limits
Angle limits are shown visualy. *red* negative, *green* positive
![bildschirmfoto 2017-10-22 um 21 16 38](https://user-images.githubusercontent.com/3062564/31865367-56242556-b76e-11e7-8fe4-36e69f55b920.png)
# Toggle Space
Switch between global and TCP aligned controls
![bildschirmfoto 2017-10-22 um 21 18 43](https://user-images.githubusercontent.com/3062564/31865385-a52db932-b76e-11e7-8408-797bd0959bab.png)
![bildschirmfoto 2017-10-22 um 21 18 53](https://user-images.githubusercontent.com/3062564/31865386-a54e6218-b76e-11e7-8250-1c183d723121.png)
# Working Space
Click add Pose to visualize the working area for the current TCP orientation. Add muliple poses to compare work area vs orientation.
![bildschirmfoto 2017-10-22 um 21 22 20](https://user-images.githubusercontent.com/3062564/31865429-3429e0c0-b76f-11e7-8ed3-f40d0fca6aaa.png)
![bildschirmfoto 2017-10-22 um 21 22 51](https://user-images.githubusercontent.com/3062564/31865591-71863d9a-b771-11e7-9d5d-9f010903c221.png)
>>>>>>> 244abf3 (Forgejo Up)

96
css/main.css Normal file
View file

@ -0,0 +1,96 @@
body {
overflow : hidden;
padding : 0;
margin : 0;
color : #222;
background-color: #BBB;
font-family : arial;
font-size : 100%;
}
#info .top {
position : absolute;
top : 0px;
width : 100%;
padding : 5px;
text-align : center;
}
#info a {
color : #66F;
text-decoration : none;
}
#info a:hover {
text-decoration : underline;
}
#info .bottom {
position : absolute;
bottom : 0px;
right : 5px;
padding : 5px;
}
/* DAT GUI */
.dg.main.taller-than-window .close-button {
border-top: 1px solid #ddd!important;
}
.dg.main .close-button {
background-color: #ccc!important;
}
.dg.main .close-button:hover {
background-color: #ddd!important;
}
.dg {
color: #555!important;
text-shadow: none !important;
}
.dg.main::-webkit-scrollbar {
background: #fafafa!important;
}
.dg.main::-webkit-scrollbar-thumb {
background: #bbb!important;
}
div.dg li:not(.folder) {
background: #e8e8e8!important;
border-color: #dadada;
}
.dg li.save-row .button {
text-shadow: none !important;
}
.dg li.title {
background: #e8e8e8 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat!important;
}
.dg .cr.function:hover,.dg .cr.boolean:hover {
background: #fff!important;
}
.dg .c input[type=text] {
background: #f9f9f9!important;
}
.dg .c input[type=text]:hover {
background: #eee!important;
}
.dg .c input[type=text]:focus {
background: #eee!important;
color: #555!important;
}
.dg .c .slider {
background: #e9e9e9!important;
}
.dg .c .slider:hover {
background: #eee!important;
}

79
index.html Normal file
View file

@ -0,0 +1,79 @@
<!doctype html>
<html>
<head>
<title>KineSim:NANDI MECHATRONICS</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<script src="js/require.js" charset="utf-8"></script>
<!-- <script src="/socket.io/socket.io.js"></script> -->
<script src="vendor/three.js/Three.js"></script>
<script src="vendor/three.js/Detector.js"></script>
<script src="vendor/three.js/Stats.js"></script>
<script src="vendor/threex/THREEx.screenshot.js"></script>
<script src="vendor/threex/THREEx.FullScreen.js"></script>
<script src="vendor/threex/THREEx.WindowResize.js"></script>
<script src="vendor/three.js/OrbitControls.js"></script>
<script src="vendor/three.js/TransformControls.js"></script>
<script src="vendor/EventDispatcher.js"></script>
<script src="js/THREERobot.js"></script>
<!-- src="https://www.gstatic.com/firebasejs/5.10.0/firebase.js"
// Initialize Firebase
var config = {
apiKey: "AIzaSyAdrZldfGjyHeqF0lM6dP1O1P8Dvp037qw",
authDomain: "kinesim-73962.firebaseapp.com",
databaseURL: "https://kinesim-73962.firebaseio.com",
projectId: "kinesim-73962",
storageBucket: "kinesim-73962.appspot.com",
messagingSenderId: "1094292124039"
};
firebase.initializeApp(config); -->
<!-- three.js container -->
<link href="css/main.css" rel="stylesheet" />
<style>
.mydiv{
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #115baf;
color: white;
text-align: center;
font-family: "Trebuchet MS", Helvetica, sans-serif;
}
</style>
</head>
<body>
<div class= "mydiv"> RoboSim™ | Browser-Based Robotics Simulator | Amit Kumar Nandi | Nandi Mechatronics Pvt. Ltd.®</div>
<!-- three.js container -->
<div id="container"></div>
<script type="text/javascript">
var debug = {}
requirejs.config({
// urlArgs: "bust=" + (new Date()).getTime(),
baseUrl: 'js',
paths: {
State: '../vendor/state/State',
Kinematic: 'InverseKinematic'
},
});
require(['Hmi'], function(Hmi) {
let hmi = new Hmi()
});
</script>
</body>
</html>

139
js/Hmi.js Normal file
View file

@ -0,0 +1,139 @@
define((require, exports, module) => {
const Robot = require('Robot')
const RobotTHREE = require('RobotTHREE')
const RobotGui = require('Robot.Gui')
const Target = require('Target')
const TargetGui = require('Target.Gui')
const gui = require('UiDat')
const THREEView = require('THREEView')
const storeManager = require('State')
const ws = require('WorkingSpace')
const Path = require('Path.Gui')
const Kinematic = require('Kinematic')
// const RemoteRobot = require('RemoteRobot')
const logger = store => dispatch => (action, data) => {
console.group(`ACTION ${action}`)
console.log(`action: %c${action}`, 'color:green')
console.log('data: ', data)
console.log('%cstore before: ', 'color:orange', store.getState())
const newState = dispatch(action, data)
console.log('%cnew state: ', 'color:green', newState)
console.groupEnd()
return newState
}
const mid = store => dispatch => (action, data) => {
const oldState = store.getState()
const oldStateCopy = JSON.parse(JSON.stringify(oldState))
const newState = dispatch(action, data)
function compare(o, n, os) {
for (const i of Object.keys(o).concat(Object.keys(n))) {
if (typeof n[i] === 'undefined') {
if (os === n) {
console.warn('nooohohoohoh did not change state, bro!')
console.warn('element was removed, but parent not changed')
}
} else if (typeof o[i] === 'undefined') {
if (os === n) {
console.warn('nooohohoohoh did not change state, bro!')
console.warn('element was added, but parent not changed')
}
} else if (!!o[i] && typeof (o[i]) === 'object') {
// console.log('aaaa')
//
compare(o[i], n[i], os[i])
} else {
if (typeof n[i] === 'undefined' || o[i] !== n[i]) { // el deleted, or value not same
// value has changed todo iter over newState (missing ones were deleted, dont matter. new ones dont matter either hm....)
// new state cant be old state, if a child changed
if (os === n) {
console.warn('nooohohoohoh did not change state, bro!')
console.group(`state ${action}`)
console.log(`oldStateCopy: ${o[i]}`)
console.log(`oldState: %c${os[i]}`, 'color: red')
console.log(`newState: ${n[i]}`)
console.groupEnd()
}
}
// console.log(i, o[i] === n[i])
}
}
}
compare(oldStateCopy, newState, oldState)
return newState
}
storeManager.applyMiddleware(logger, mid)
/* POLYFILL */
const reduce = Function.bind.call(Function.call, Array.prototype.reduce)
const isEnumerable = Function.bind.call(Function.call, Object.prototype.propertyIsEnumerable)
const concat = Function.bind.call(Function.call, Array.prototype.concat)
const keys = Reflect.ownKeys
if (!Object.values) {
Object.values = function values(O) {
return reduce(keys(O), (v, k) => concat(v, typeof k === 'string' && isEnumerable(O, k) ? [O[k]] : []), [])
}
}
/* END POLYFILL */
class Hmi {
constructor() {
const maxAngleVelocity = 90.0 / (180.0 * Math.PI) / 1000.0
const store = storeManager.createStore('Hmi', {})
const scope = this
/* THREEJS SCENE SETUP */
const {
scene,
renderer,
camera,
} = require('THREEScene')
this.scene = scene
this.renderer = renderer
this.camera = camera
/* END THREEJS SCENE SETUP */
/* DAT GUI */
const hmiGui = gui.addFolder('HMI')
gui.remember(scope.state)
const fun = {
resetTargetAngles: () => {
Robot.dispatch('ROBOT_CHANGE_ANGLES', {
A0: 0,
A1: 0,
A2: 0,
A3: 0,
A4: 0,
A5: 0,
})
},
}
hmiGui.add(fun, 'resetTargetAngles').onChange(() => {
})
window.debug.show = false
hmiGui.add(window.debug, 'show')
/* CONNECT MODULES */
}
}
module.exports = Hmi
})

462
js/InverseKinematic.js Normal file
View file

@ -0,0 +1,462 @@
define((require, exports, module) => {
const Serial = {
println(text) {
// // console.log(text)
},
}
const arrows = {}
function addArrow(name, from, to, color = 0xffff00, length = 10) {
if (arrows.hasOwnProperty(name)) {
window.debug.scene.remove(arrows[name])
}
if (!window.debug.show) return
const toPoint = new THREE.Vector3(to[0], to[1], to[2])
const origin = new THREE.Vector3(from[0], from[1], from[2])
// length = length || toPoint.sub(origin).length()
// toPoint.normalize()
arrows[name] = new THREE.ArrowHelper(toPoint.sub(origin).normalize(), origin, length, color, 2, 1)
window.debug.scene.add(arrows[name])
}
function addVectorArrow(name, from, vector, color, length) {
addArrow(name, from, [from[0] + vector[0], from[1] + vector[1], from[2] + vector[2]], color, length)
}
const spheres = {}
function addSphere(name, position, color = 0xffff00, diameter = 1) {
if (spheres.hasOwnProperty(name)) {
window.debug.scene.remove(spheres[name])
}
if (!window.debug.show) return
const geometry = new THREE.SphereGeometry(diameter, 32, 32)
const material = new THREE.MeshBasicMaterial({
color,
})
spheres[name] = new THREE.Mesh(geometry, material)
spheres[name].position.set(position[0], position[1], position[2])
window.debug.scene.add(spheres[name])
}
class InverseKinematic {
constructor(geometry) {
this.OK = 0
this.OUT_OF_RANGE = 1
this.OUT_OF_BOUNDS = 2
this.V1_length_x_z = Math.sqrt(Math.pow(geometry[1][0], 2) + Math.pow(geometry[1][2], 2))
this.V4_length_x_y_z = Math.sqrt(Math.pow(geometry[4][0], 2) + Math.pow(geometry[4][2], 2) + Math.pow(-geometry[4][1], 2))
this.J_initial_absolute = []
const tmpPos = [0, 0, 0]
for (let i = 0; i < geometry.length; i++) {
this.J_initial_absolute.push([tmpPos[0], tmpPos[1], tmpPos[2]])
tmpPos[0] += geometry[i][0]
tmpPos[1] += geometry[i][1]
tmpPos[2] += geometry[i][2]
}
this.R_corrected = [0, 0, 0, 0, 0, 0]
this.R_corrected[1] += Math.PI / 2
this.R_corrected[1] -= Math.atan2(geometry[1][0], geometry[1][2]) // correct offset bone
this.R_corrected[2] += Math.PI / 2
this.R_corrected[2] += Math.atan2((geometry[2][2] + geometry[3][2]), (geometry[2][0] + geometry[3][0])) // correct offset bone V2,V3
this.R_corrected[2] += Math.atan2(geometry[1][0], geometry[1][2]) // correct bone offset of V1
this.R_corrected[4] += Math.PI
this.geometry = geometry
}
calculateAngles(x, y, z, a, b, c, angles, config = [false, false, false]) {
const cc = Math.cos(c)
const sc = Math.sin(c)
const cb = Math.cos(b)
const sb = Math.sin(b)
const ca = Math.cos(a)
const sa = Math.sin(a)
const targetVectorZ = [
sb, -sa * cb,
ca * cb,
]
const R = [
this.R_corrected[0],
this.R_corrected[1],
this.R_corrected[2],
this.R_corrected[3],
this.R_corrected[4],
this.R_corrected[5],
]
const J = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
]
// ---- J5 ----
J[5][0] = x
J[5][1] = y
J[5][2] = z
addSphere('J5', J[5])
// ---- J4 ----
// vector
J[4][0] = x - this.V4_length_x_y_z * targetVectorZ[0]
J[4][1] = y - this.V4_length_x_y_z * targetVectorZ[1]
J[4][2] = z - this.V4_length_x_y_z * targetVectorZ[2]
addSphere('J4', J[4])
// ---- R0 ----
// # J4
const alphaR0 = Math.asin(this.J_initial_absolute[4][1] / this.length2(J[4][1], J[4][0]))
R[0] += Math.atan2(J[4][1], J[4][0])
R[0] += -alphaR0
if (config[0]) {
R[0] += 2 * alphaR0 - Math.PI
}
if (-this.J_initial_absolute[4][1] > this.length2(J[4][2], J[4][0])) {
Serial.println('out of reach')
}
// ---- J1 ----
// # R0
J[1][0] = Math.cos(R[0]) * this.geometry[0][0] + Math.sin(R[0]) * -this.geometry[0][1]
J[1][1] = Math.sin(R[0]) * this.geometry[0][0] + Math.cos(R[0]) * this.geometry[0][1]
J[1][2] = this.geometry[0][2]
addSphere('J1', J[1], 0x00ff00)
// ---- rotate J4 into x,z plane ----
// # J4 R0
const J4_x_z = []
J4_x_z[0] = Math.cos(R[0]) * J[4][0] + Math.sin(R[0]) * J[4][1]
J4_x_z[1] = Math.sin(R[0]) * J[4][0] + Math.cos(R[0]) * -J[4][1] // 0
J4_x_z[2] = J[4][2]
addSphere('J4_x_z', J4_x_z, 0xff0000)
// ---- J1J4_projected_length_square ----
// # J4 R0
const J1J4_projected_length_square = Math.pow(J4_x_z[0] - this.J_initial_absolute[1][0], 2) + Math.pow(J4_x_z[2] - this.J_initial_absolute[1][2], 2) // not using Math.sqrt
// ---- R2 ----
// # J4 R0
const J2J4_length_x_z = this.length2(this.geometry[2][0] + this.geometry[3][0], this.geometry[2][2] + this.geometry[3][2])
R[2] += ((config[1] ? !config[0] : config[0]) ? 1.0 : -1.0) * Math.acos((-J1J4_projected_length_square + Math.pow(J2J4_length_x_z, 2) + Math.pow(this.V1_length_x_z, 2)) / (2.0 * (J2J4_length_x_z) * this.V1_length_x_z))
R[2] -= 2 * Math.PI
R[2] = ((R[2] + 3 * Math.PI) % (2 * Math.PI)) - Math.PI // clamp -180/180 degree
// ---- R1 ----
// # J4 R0
const J1J4_projected_length = Math.sqrt(J1J4_projected_length_square)
R[1] -= Math.atan2((J4_x_z[2] - this.J_initial_absolute[1][2]), (J4_x_z[0] - this.J_initial_absolute[1][0])) // a''
R[1] += ((config[1] ? !config[0] : config[0]) ? 1.0 : -1.0) * Math.acos((J1J4_projected_length_square - Math.pow(J2J4_length_x_z, 2) + Math.pow(this.V1_length_x_z, 2)) / (2.0 * J1J4_projected_length * this.V1_length_x_z)) // a
R[1] = ((R[1] + 3 * Math.PI) % (2 * Math.PI)) - Math.PI
// ---- J2 ----
// # R1 R0
const ta = Math.cos(R[0])
const tb = Math.sin(R[0])
const tc = this.geometry[0][0]
const d = this.geometry[0][2]
const e = -this.geometry[0][1]
const f = Math.cos(R[1])
const g = Math.sin(R[1])
const h = this.geometry[1][0]
const i = this.geometry[1][2]
const j = -this.geometry[1][1]
const k = Math.cos(R[2])
const l = Math.sin(R[2])
const m = this.geometry[2][0]
const n = this.geometry[2][2]
const o = -this.geometry[2][1]
J[2][0] = ta * tc + tb * e + ta * f * h - ta * -g * i + tb * j
J[2][1] = -(-tb * tc + ta * e - tb * f * h + tb * -g * i + ta * j)
J[2][2] = d + -g * h + f * i
addSphere('J2', J[2], 0x0000ff)
J[3][0] = J[2][0] + ta * f * k * m - ta * -g * -l * m - ta * -g * k * n - ta * f * -l * n + tb * o
J[3][1] = J[2][1] - (-tb * f * k * m + tb * -g * -l * m + tb * -g * k * n + tb * f * -l * n + ta * o)
J[3][2] = J[2][2] + -g * k * m + f * -l * m + f * k * n + g * -l * n
addSphere('J3', J[3], 0x0000ff)
// ---- J4J3 J4J5 ----
// # J3 J4 J5
const J4J5_vector = [J[5][0] - J[4][0], J[5][1] - J[4][1], J[5][2] - J[4][2]]
const J4J3_vector = [J[3][0] - J[4][0], J[3][1] - J[4][1], J[3][2] - J[4][2]]
// ---- R3 ----
// # J3 J4 J5
const J4J5_J4J3_normal_vector = this.cross(J4J5_vector, J4J3_vector)
addVectorArrow('normal J4', J[4], J4J5_J4J3_normal_vector, 0xbada55, 8)
const ZY_parallel_aligned_vector = [
10 * -Math.sin(R[0]),
10 * Math.cos(R[0]),
0,
]
const ZY_aligned_J4J3_normal_vector = this.cross(ZY_parallel_aligned_vector, J4J3_vector)
addVectorArrow('normal J4 Y_vectors', J[4], ZY_aligned_J4J3_normal_vector, 0xff00ff)
addVectorArrow('XZ_parallel_aligned_vector', J[4], ZY_parallel_aligned_vector, 0x11ff11)
R[3] = this.angleBetween(J4J5_J4J3_normal_vector, ZY_parallel_aligned_vector, ZY_aligned_J4J3_normal_vector)
if (config[2]) // rotate 180 and clamp -180,180
{
R[3] += Math.PI
}
R[3] = ((R[3] + 3 * Math.PI) % (2 * Math.PI)) - Math.PI
// ---- R4 ----
// # J4 J3 J5 R3
R[4] += ((config[2]) ? 1 : -1) * this.angleBetween2(J4J5_vector, J4J3_vector)
// clamp -180,180
R[4] = ((R[4] + 3 * Math.PI) % (2 * Math.PI)) - Math.PI
// ---- R5 ----
// # J4 J5 J3
const targetVectorY = [-cb * sc,
ca * cc - sa * sb * sc,
sa * cc + ca * sb * sc,
]
R[5] -= this.angleBetween(J4J5_J4J3_normal_vector, targetVectorY, this.cross(targetVectorZ, targetVectorY))
if (config[2]) R[5] += Math.PI
R[5] = ((R[5] + 3 * Math.PI) % (2 * Math.PI)) - Math.PI
// ---- Error handling ----
const error = false
const outOfBounds = [false, false, false, false, false, false]
angles[0] = R[0]
angles[1] = R[1]
angles[2] = R[2]
angles[3] = R[3]
angles[4] = R[4]
angles[5] = R[5]
}
calculateTCP(R0, R1, R2, R3, R4, R5, jointsResult) {
const joints = [
[],
[],
[],
[],
[],
[],
]
this.calculateCoordinates(R0, R1, R2, R3, R4, R5, joints)
jointsResult[0] = joints[5][0]
jointsResult[1] = joints[5][1]
jointsResult[2] = joints[5][2]
jointsResult[3] = joints[5][3]
jointsResult[4] = joints[5][4]
jointsResult[5] = joints[5][5]
}
calculateCoordinates(R0, R1, R2, R3, R4, R5, jointsResult, config = [false, false, false]) {
// todo detect config
const a = Math.cos(R0)
const b = Math.sin(R0)
const c = this.geometry[0][0]
const d = this.geometry[0][1]
const e = this.geometry[0][2]
const f = Math.cos(R1)
const g = Math.sin(R1)
const h = this.geometry[1][0]
const i = this.geometry[1][1]
const j = this.geometry[1][2]
const k = Math.cos(R2)
const l = Math.sin(R2)
const m = this.geometry[2][0]
const n = this.geometry[2][1]
const o = this.geometry[2][2]
const p = Math.cos(R3)
const q = Math.sin(R3)
const r = this.geometry[3][0]
const s = this.geometry[3][1]
const t = this.geometry[3][2]
const u = Math.cos(R4)
const v = Math.sin(R4)
const w = this.geometry[4][0]
const x = this.geometry[4][1]
const y = this.geometry[4][2]
const A = Math.cos(R5)
const B = Math.sin(R5)
jointsResult[0][0] = 0
jointsResult[0][1] = 0
jointsResult[0][2] = 0
jointsResult[1][0] = jointsResult[0][0] + a * c - b * d
jointsResult[1][1] = jointsResult[0][1] + b * c + a * d
jointsResult[1][2] = jointsResult[0][2] + e
jointsResult[2][0] = jointsResult[1][0] + a * f * h - b * i + a * g * j
jointsResult[2][1] = jointsResult[1][1] + b * f * h + a * i + b * g * j
jointsResult[2][2] = jointsResult[1][2] + -g * h + f * j
jointsResult[3][0] = jointsResult[2][0] + a * f * k * m - a * g * l * m - b * n + a * g * k * o + a * f * l * o
jointsResult[3][1] = jointsResult[2][1] + b * f * k * m - b * g * l * m + a * n + b * g * k * o + b * f * l * o
jointsResult[3][2] = jointsResult[2][2] - g * k * m - f * l * m + f * k * o - g * l * o
jointsResult[4][0] = jointsResult[3][0] + a * f * k * r - a * g * l * r - b * p * s + a * g * k * q * s + a * f * l * q * s + a * g * k * p * t + a * f * l * p * t + b * q * t
jointsResult[4][1] = jointsResult[3][1] + b * f * k * r - b * g * l * r + a * p * s + b * g * k * q * s + b * f * l * q * s + b * g * k * p * t + b * f * l * p * t - a * q * t
jointsResult[4][2] = jointsResult[3][2] - g * k * r - f * l * r + f * k * q * s - g * l * q * s + f * k * p * t - g * l * p * t
jointsResult[5][0] = jointsResult[4][0] + a * f * k * u * w - a * g * l * u * w - a * g * k * p * v * w - a * f * l * p * v * w - b * q * v * w - b * p * x + a * g * k * q * x + a * f * l * q * x + a * g * k * p * u * y + a * f * l * p * u * y + b * q * u * y + a * f * k * v * y - a * g * l * v * y
jointsResult[5][1] = jointsResult[4][1] + b * f * k * u * w - b * g * l * u * w - b * g * k * p * v * w - b * f * l * p * v * w + a * q * v * w + a * p * x + b * g * k * q * x + b * f * l * q * x + b * g * k * p * u * y + b * f * l * p * u * y - a * q * u * y + b * f * k * v * y - b * g * l * v * y
jointsResult[5][2] = jointsResult[4][2] - g * k * u * w - f * l * u * w - f * k * p * v * w + g * l * p * v * w + f * k * q * x - g * l * q * x + f * k * p * u * y - g * l * p * u * y - g * k * v * y - f * l * v * y
const M = [
[-B * b * p + B * a * g * k * q + B * a * f * l * q - A * a * g * k * p * u - A * a * f * l * p * u - A * b * q * u - A * a * f * k * v + A * a * g * l * v, -A * b * p + A * a * g * k * q + A * a * f * l * q + B * a * g * k * p * u + B * a * f * l * p * u + B * b * q * u + B * a * f * k * v - B * a * g * l * v, a * f * k * u - a * g * l * u - a * g * k * p * v - a * f * l * p * v - b * q * v],
[B * a * p + B * b * g * k * q + B * b * f * l * q - A * b * g * k * p * u - A * b * f * l * p * u + A * a * q * u - A * b * f * k * v + A * b * g * l * v, A * a * p + A * b * g * k * q + A * b * f * l * q + B * b * g * k * p * u + B * b * f * l * p * u - B * a * q * u + B * b * f * k * v - B * b * g * l * v, b * f * k * u - b * g * l * u - b * g * k * p * v - b * f * l * p * v + a * q * v],
[B * f * k * q - B * g * l * q - A * f * k * p * u + A * g * l * p * u + A * g * k * v + A * f * l * v, A * f * k * q - A * g * l * q + B * f * k * p * u - B * g * l * p * u - B * g * k * v - B * f * l * v, -g * k * u - f * l * u - f * k * p * v + g * l * p * v],
]
// https://www.geometrictools.com/Documentation/EulerAngles.pdf
let thetaY,
thetaX,
thetaZ
if (M[0][2] < 1) {
if (M[0][2] > -1) {
thetaY = Math.asin(M[0][2])
thetaX = Math.atan2(-M[1][2], M[2][2])
thetaZ = Math.atan2(-M[0][1], M[0][0])
} else {
thetaY = -Math.PI / 2
thetaX = -Math.atan2(M[1][0], M[1][1])
thetaZ = 0
}
} else {
thetaY = +Math.PI / 2
thetaX = Math.atan2(M[1][0], M[1][1])
thetaZ = 0
}
jointsResult[5][3] = thetaX
jointsResult[5][4] = thetaY
jointsResult[5][5] = thetaZ
}
cross(vectorA, vectorB, result = []) {
result[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1]
result[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2]
result[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0]
return result
}
dot(vectorA, vectorB) {
return vectorA[0] * vectorB[0] + vectorA[1] * vectorB[1] + vectorA[2] * vectorB[2]
}
/**
* @param {array} vectorA angle from
* @param {array} vectorB angle to
* @param {array} referenceVector angle to set 0 degree from. coplanar with vecA and vecB
* @return {number} description
* @example angleBetween([1,0,0],[0,1,0],[0,0,1]) // PI/2
*/
angleBetween(vectorA, vectorB, referenceVector) {
// angle = atan2(norm(cross(a, b)), dot(a, b))
const norm = this.length3(this.cross(vectorA, vectorB))
const angle = Math.atan2(norm, (vectorB[0] * vectorA[0] + vectorB[1] * vectorA[1] + vectorB[2] * vectorA[2]))
const tmp = referenceVector[0] * vectorA[0] + referenceVector[1] * vectorA[1] + referenceVector[2] * vectorA[2]
const sign = (tmp > 0.0001) ? 1.0 : -1.0
return angle * sign
}
length3(vector) {
return Math.sqrt(Math.pow(vector[0], 2) + Math.pow(vector[1], 2) + Math.pow(vector[2], 2))
}
length2(a, b) {
return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2))
}
angleBetween2(v1, v2) {
let angle
// turn vectors into unit vectors
// this.normalize(v1,v1)
// this.normalize(v2,v2)
//
// var angle = Math.acos(this.dot(v1, v2))
// // if no noticable rotation is available return zero rotation
// // this way we avoid Cross product artifacts
// if (Math.abs(angle) < 0.0001) return 0
// // in this case there are 2 lines on the same axis
// // // angle = atan2(norm(cross(a, b)), dot(a, b))
const cross = this.cross(v1, v2)
return Math.atan2(this.length3(cross), this.dot(v1, v2))
}
normalize(vector, result) {
const length = Math.sqrt((vector[0] * vector[0]) + (vector[1] * vector[1]) + (vector[2] * vector[2]))
result[0] = vector[0] / length
result[1] = vector[1] / length
result[2] = vector[2] / length
}
}
function kinematic() {
return InverseKinematic
}
module.exports = InverseKinematic
})

100
js/Path.Gui.js Normal file
View file

@ -0,0 +1,100 @@
define((require, exports, module) => {
const gui = require('UiDat')
const storeManager = require('State')
const robotStore = require('Robot') // todo dont export store but a handle which acceps the name of the consuming module const targetStore = getStoreFrom('myModule') -> myModule accesses store targetStore
const pathGuiStore = storeManager.createStore('PathGui', {
points: [],
currentPoint: 0,
move: false,
})
// the returned value of an action is set to the selected object
// helper is needed, since dat.gui wants to modify the object, so we cant use ist on the state
const pathGUI = gui.addFolder('PathGui')
let interval = null
pathGuiStore.listen([() => robotStore.getState().target, state => state], (robState, state) => {
if (state.move && !interval && state.points.length > 0) {
let i = 0
let currentPoint = state.currentPoint
let lastPoint = (currentPoint + state.points.length - 1) % state.points.length
interval = setInterval(() => {
i += 0.01
const tp = state.points[currentPoint].position
const sp = state.points[lastPoint].position
const position = {
x: sp.x + (tp.x - sp.x) * i,
y: sp.y + (tp.y - sp.y) * i,
z: sp.z + (tp.z - sp.z) * i,
}
const tr = state.points[currentPoint].rotation
const sr = state.points[lastPoint].rotation
const rotation = {
x: sr.x + (tr.x - sr.x) * i,
y: sr.y + (tr.y - sr.y) * i,
z: sr.z + (tr.z - sr.z) * i,
}
robotStore.dispatch('ROBOT_CHANGE_TARGET', {
position,
rotation,
})
if (i >= 1) {
i = 0
lastPoint = currentPoint
currentPoint = (currentPoint + 1) % state.points.length
// clearInterval(interval)
}
}, 100)
} else if (!state.move && interval) {
clearInterval(interval)
interval = false
}
})
pathGuiStore.action('ADD_POINT', (state, data) => ({
...state,
points: [...state.points, data],
}))
pathGuiStore.action('SET_MOVE', (state, data) => ({
...state,
move: data,
}))
pathGuiStore.action('NEXT_POINT', state => ({
...state,
currentPoint: (state.currentPoint + 1) % state.points.length,
}))
const methods = {
savePoint: () => {},
next: () => {},
prev: () => {},
move: false,
}
pathGUI.add(methods, 'savePoint').onChange(() => {
const {
position,
rotation,
} = robotStore.getState().target
pathGuiStore.dispatch('ADD_POINT', {
position,
rotation,
})
})
pathGUI.add(methods, 'move').onChange(() => {
pathGuiStore.dispatch('SET_MOVE', methods.move)
})
pathGUI.add(methods, 'next').onChange(() => {
pathGuiStore.dispatch('NEXT_POINT')
})
module.exports = pathGuiStore
})

161
js/RemoteRobot.js Normal file
View file

@ -0,0 +1,161 @@
define((require, exports, module) => {
const storeManager = require('State')
const robotStore = require('Robot')
const io = require('/socket.io/socket.io.js')
const gui = require('UiDat')
/**
* + state per module
* + render on state changed
* + get state from other modules
*
* --- onStore update render ---
* get data From other stores
* - store might not have changed, so no update
*/
const defaultState = {
sendData: false,
sendDataInterval: 4000,
selectedUSBDevice: 'None',
remoteStatus: 'unknown',
USBDevices: [],
}
const store = storeManager.createStore('RemoteRobot', defaultState)
store.action('CHANGE_SEND_DATA', (state, data) => Object.assign({}, state, {
sendData: data,
}))
store.action('CHANGE_SEND_DATA_INTERVAL', (state, data) => Object.assign({}, state, {
sendDataInterval: data,
}))
store.action('SET_AVAILABLE_USB_DEVICES', (state, data) => Object.assign({}, state, {
USBDevices: data,
}))
store.action('SELECT_USB_DEVICE', (state, data) => Object.assign({}, state, {
selectedUSBDevice: data,
}))
store.action('CHANGE_REMOTE_STATUS', (state, data) => Object.assign({}, state, {
remoteStatus: data,
}))
const remoteRobotGui = gui.addFolder('RemoteRobot')
const guiHelper = Object.assign({}, defaultState)
let addedDropdownGui = false
store.listen((state) => {
guiHelper.sendData = state.sendData
guiHelper.sendDataInterval = state.sendDataInterval
guiHelper.selectedUSBDevice = state.selectedUSBDevice
guiHelper.remoteStatus = state.remoteStatus
guiHelper.USBDevices = state.USBDevices
if (state.USBDevices[0] && !addedDropdownGui) {
addedDropdownGui = true
// add the gui after the dropdoenlist is available, since its content cant be changed
remoteRobotGui.add(guiHelper, 'selectedUSBDevice', guiHelper.USBDevices).onChange(() => {
console.log(guiHelper.selectedUSBDevice)
store.dispatch('SELECT_USB_DEVICE', guiHelper.selectedUSBDevice)
socket.emit('connectToPort', {
port: guiHelper.selectedUSBDevice,
}, (result) => {
// doto only if successfull
store.dispatch('CHANGE_REMOTE_STATUS', 'portOpen')
console.log(`connected: ${result}`)
})
})
}
// Iterate over all controllers
for (const i in remoteRobotGui.__controllers) {
remoteRobotGui.__controllers[i].updateDisplay()
// console.log('update')
}
})
// REMOTE ROBOT
const socket = io()
const setupComplete = false
const ports = []
remoteRobotGui.add(guiHelper, 'remoteStatus')
remoteRobotGui.add(guiHelper, 'sendDataInterval').onChange(() => {
store.dispatch('CHANGE_SEND_DATA_INTERVAL', guiHelper.sendDataInterval)
})
let interval
remoteRobotGui.add(guiHelper, 'sendData').onChange(() => {
if (store.getState().remoteStatus === 'portOpen') {
store.dispatch('CHANGE_SEND_DATA', guiHelper.sendData)
if (store.getState().sendData) {
interval = setInterval(() => {
const outOfBound = robotStore.getState().jointOutOfBound.reduce((previous, current) => previous || current, false)
if (!outOfBound) {
socket.emit('write', {
port: store.getState().selectedUSBDevice,
message: `M00 V0 R0 ${(robotStore.getState().angles.A0 / Math.PI * 180).toFixed(3)} ` +
`R1 ${(robotStore.getState().angles.A1 / Math.PI * 180).toFixed(3)} ` +
`R2 ${(robotStore.getState().angles.A2 / Math.PI * 180).toFixed(3)} ` +
`R3 ${(robotStore.getState().angles.A3 / Math.PI * 180).toFixed(3)} ` +
`R4 ${(robotStore.getState().angles.A4 / Math.PI * 180).toFixed(3)} ` +
`R5 ${(robotStore.getState().angles.A5 / Math.PI * 180).toFixed(3)} \r`,
},
(res) => {
console.log(res)
})
}
}, store.getState().sendDataInterval)
} else {
clearInterval(interval)
}
}
})
socket.emit('getPortList', {}, (ports) => {
console.log(ports)
store.dispatch('SET_AVAILABLE_USB_DEVICES', ports)
const interval = null
})
socket.on('data', (data) => {
console.log(data)
// todo
// this.Robot.setAngles([20, 1, 1, 1, 1, 1])
})
socket.on('portStatusChanged', (data) => {
store.dispatch('CHANGE_REMOTE_STATUS', data.status)
})
/* END DAT GUI */
/* INIT MODULES */
// this.Robot = new Robot(this.state, this.scene)
// this.RobotTHREE = new RobotTHREE(this.state, this.scene)
// this.Robot.setVisible(this.state.showRobot)
// this.Target = new Target(this.state, this.scene, this.camera, this.renderer, this.cameraControls)
// remote robot
// const geometryArray = Object.values(this.state.Robot.geometry).map(val => [val.x, val.y, val.z])
// const jointLimitsArray = Object.values(this.state.Robot.jointLimits)
//
// this.THREERemoteRobot = new THREE.Group()
// this.THREERemoteRobot.visible = scope.state.showRemoteRobot
// this.scene.add(this.THREERemoteRobot)
// this.RemoteRobot = new THREERobot(geometryArray, jointLimitsArray, this.THREERemoteRobot)
/* END INIT MODULES */
module.exports = store
})

107
js/Robot.Gui.js Normal file
View file

@ -0,0 +1,107 @@
define((require, exports, module) => {
const gui = require('UiDat')
const storeManager = require('State')
const robotStore = require('Robot')
const geometry = storeManager.getStore('Robot').getState().geometry
const jointLimits = storeManager.getStore('Robot').getState().jointLimits
const robotGuiStore = storeManager.createStore('RobotGui', {})
const DEG_TO_RAD = Math.PI / 180
const RAD_TO_DEG = 180 / Math.PI
/* DAT GUI */
const geometryGui = gui.addFolder('robot geometry')
for (const link in geometry) {
if (link) {
const linkFolder = geometryGui.addFolder(`link ${link}`)
for (const axis in geometry[link]) {
if (axis) {
gui.remember(geometry[link])
linkFolder.add(geometry[link], axis).min(-10).max(10).step(0.1).onChange(() => {
robotStore.dispatch('ROBOT_CHANGE_GEOMETRY', geometry)
})
}
}
}
}
const anglesDeg = {
A0: 0,
A1: 0,
A2: 0,
A3: 0,
A4: 0,
A5: 0,
}
const configuration = {
1: false,
2: false,
3: false,
}
const jointLimitsDeg = {
J0: [-190, 190],
J1: [-58, 90],
J2: [-135, 40],
J3: [-90, 75],
J4: [-139, 20],
J5: [-188, 181],
}
robotStore.listen([state => state.angles], (angles) => {
Object.keys(anglesDeg).forEach((k) => {
anglesDeg[k] = angles[k] / Math.PI * 180
})
})
const anglesGui = gui.addFolder('angles')
let i = 0
for (const key in anglesDeg) {
anglesGui.add(anglesDeg, key).min(jointLimits[`J${i}`][0] * RAD_TO_DEG).max(jointLimits[`J${i++}`][1] * RAD_TO_DEG).step(1).listen().onChange(() => {
const anglesRad = {}
for (const key in anglesDeg) {
if (anglesDeg.hasOwnProperty(key)) {
anglesRad[key] = anglesDeg[key] * DEG_TO_RAD
}
}
robotStore.dispatch('ROBOT_CHANGE_ANGLES', anglesRad)
})
}
const configurationGui = gui.addFolder('configuration')
for (const key in configuration) {
configurationGui.add(configuration, key).listen().onChange(() => {
robotStore.dispatch('ROBOT_CHANGE_CONFIGURATION', Object.values(configuration))
})
}
const angleLimitGui = anglesGui.addFolder('angle limits')
for (const joint in jointLimitsDeg) {
if (joint) {
const jointFolder = angleLimitGui.addFolder(`joint ${joint}`)
for (const limit in jointLimitsDeg[joint]) {
if (limit) {
// gui.remember(jointLimitsDeg[joint])
(j => jointFolder.add(jointLimitsDeg[j], limit).name((limit == 0) ? 'min' : 'max').min(-360).max(360).step(1).onChange(() => {
limts_rad = {}
limts_rad[j] = [
jointLimitsDeg[j][0] * DEG_TO_RAD,
jointLimitsDeg[j][1] * DEG_TO_RAD,
]
robotStore.dispatch('ROBOT_CHANGE_JOINT_LIMITS', limts_rad)
}))(joint)
}
}
}
}
/* END DAT GUI */
module.exports = robotStore
})

298
js/Robot.js Normal file
View file

@ -0,0 +1,298 @@
define((require, exports, module) => {
const storeManager = require('State')
const Kinematic = require('Kinematic')
localState = {
jointOutOfBound: [false, false, false, false, false, false],
}
const maxAngleVelocity = 90.0 / (180.0 * Math.PI) / 1000.0
const geo = [
[2.5 + 2.3, 0, 7.3],
[0, 0, 13.0],
[1, 0, 2],
[12.6, 0, 0],
[3.6, 0, 0],
[0, 0, 0],
]
const defaultRobotState = {
target: {
position: {
x: 10,
y: 10,
z: 10,
},
rotation: {
x: Math.PI,
y: 0,
z: 0,
},
},
angles: {
A0: 0,
A1: 0,
A2: 0,
A3: 0,
A4: 0,
A5: 0,
},
jointOutOfBound: [false, false, false, false, false, false],
maxAngleVelocities: {
J0: maxAngleVelocity,
J1: maxAngleVelocity,
J2: maxAngleVelocity,
J3: maxAngleVelocity,
J4: maxAngleVelocity,
J5: maxAngleVelocity,
},
jointLimits: {
J0: [-190 / 180 * Math.PI, 190 / 180 * Math.PI],
J1: [-90 / 180 * Math.PI, 90 / 180 * Math.PI],
J2: [-135 / 180 * Math.PI, 45 / 180 * Math.PI],
J3: [-90 / 180 * Math.PI, 75 / 180 * Math.PI],
J4: [-139 / 180 * Math.PI, 90 / 180 * Math.PI],
J5: [-188 / 180 * Math.PI, 181 / 180 * Math.PI],
},
configuration: [false, false, false],
geometry: {
V0: {
x: geo[0][0],
y: geo[0][1],
z: geo[0][2],
},
V1: {
x: geo[1][0],
y: geo[1][1],
z: geo[1][2],
},
V2: {
x: geo[2][0],
y: geo[2][1],
z: geo[2][2],
},
V3: {
x: geo[3][0],
y: geo[3][1],
z: geo[3][2],
},
V4: {
x: geo[4][0],
y: geo[4][1],
z: geo[4][2],
},
},
}
const robotStore = storeManager.createStore('Robot', defaultRobotState)
let IK
function updateIK(geometry) {
const geo = Object.values(geometry).map((val, i, array) => [val.x, val.y, val.z])
// todo not optimal, since IK is a sideeffect
IK = new Kinematic(geo)
}
robotStore.listen([state => state.geometry], (geometry) => {
updateIK(geometry)
})
const calculateAngles = (jointLimits, position, rotation, configuration) => {
const angles = []
IK.calculateAngles(
position.x,
position.y,
position.z,
rotation.x,
rotation.y,
rotation.z,
angles,
configuration
)
outOfBounds = [false, false, false, false, false, false]
let i = 0
for (const index in jointLimits) {
if (angles[i] < jointLimits[index][0] || angles[i] > jointLimits[index][1]) {
outOfBounds[i] = true
}
i++
}
return {
angles,
outOfBounds,
}
}
/* --- Reducer --- */
robotStore.action('ROBOT_CHANGE_TARGET', (state, data) => {
const {
angles,
outOfBounds,
} = calculateAngles(state.jointLimits, data.position, data.rotation, state.configuration)
return Object.assign({}, state, {
target: {
position: Object.assign({}, data.position),
rotation: Object.assign({}, data.rotation),
},
}, {
angles: {
A0: angles[0],
A1: angles[1],
A2: angles[2],
A3: angles[3],
A4: angles[4],
A5: angles[5],
},
}, {
jointOutOfBound: [...outOfBounds],
})
})
robotStore.action('ROBOT_CHANGE_ANGLES', (state, angles) => {
const TCPpose = []
IK.calculateTCP(
angles.A0,
angles.A1,
angles.A2,
angles.A3,
angles.A4,
angles.A5,
TCPpose,
)
// IK.calculateAngles(TCPpose[0], TCPpose[1], TCPpose[2], TCPpose[3], TCPpose[4], TCPpose[5], angles)
return Object.assign({}, state, {
target: {
position: {
x: TCPpose[0],
y: TCPpose[1],
z: TCPpose[2],
},
rotation: {
x: TCPpose[3],
y: TCPpose[4],
z: TCPpose[5],
},
},
}, {
angles: {
A0: angles.A0,
A1: angles.A1,
A2: angles.A2,
A3: angles.A3,
A4: angles.A4,
A5: angles.A5,
},
})
// return Object.assign({}, state, {
// target: {
// position: {
// x: TCPpose[0],
// y: TCPpose[1],
// z: TCPpose[2],
// },
// rotation: {
// x: TCPpose[3],
// y: TCPpose[4],
// z: TCPpose[5],
// },
// },
// }, {
// angles: {
// A0: angles[0],
// A1: angles[1],
// A2: angles[2],
// A3: angles[3],
// A4: angles[4],
// A5: angles[5],
// },
// })
// { todo
// jointOutOfBound: [...result],
// }
})
robotStore.action('ROBOT_CHANGE_GEOMETRY', (state, data) => {
const geo = Object.assign({}, state.geometry, data)
updateIK(geo)
const {
angles,
outOfBounds,
} = calculateAngles(state.jointLimits, state.target.position, state.target.rotation, state.configuration)
return Object.assign({}, state, {
angles: {
A0: angles[0],
A1: angles[1],
A2: angles[2],
A3: angles[3],
A4: angles[4],
A5: angles[5],
},
}, {
jointOutOfBound: [...outOfBounds],
}, {
geometry: {
V0: {
x: geo.V0.x,
y: geo.V0.y,
z: geo.V0.z,
},
V1: {
x: geo.V1.x,
y: geo.V1.y,
z: geo.V1.z,
},
V2: {
x: geo.V2.x,
y: geo.V2.y,
z: geo.V2.z,
},
V3: {
x: geo.V3.x,
y: geo.V3.y,
z: geo.V3.z,
},
V4: {
x: geo.V4.x,
y: geo.V4.y,
z: geo.V4.z,
},
},
})
})
robotStore.action('ROBOT_CHANGE_JOINT_LIMITS', (state, data) => {
const {
outOfBounds,
} = calculateAngles(state.jointLimits, state.target.position, state.target.rotation, state.configuration)
return { ...state,
jointOutOfBound: [...outOfBounds],
jointLimits: { ...state.jointLimits,
...data,
},
}
})
robotStore.action('ROBOT_CHANGE_CONFIGURATION', (state, data) => {
const {
angles,
outOfBounds,
} = calculateAngles(state.jointLimits, state.target.position, state.target.rotation, data)
return Object.assign({}, state, {
angles: {
A0: angles[0],
A1: angles[1],
A2: angles[2],
A3: angles[3],
A4: angles[4],
A5: angles[5],
},
configuration: [...data],
jointOutOfBound: [...outOfBounds],
})
})
module.exports = robotStore
})
// todo -> get rid of scene injection using require scene -> threerobot handles 3d view

55
js/RobotTHREE.js Normal file
View file

@ -0,0 +1,55 @@
define((require, exports, module) => {
const storeManager = require('State')
const { scene } = require('THREEScene')
const robotStore = require('Robot')
const THREESimulationRobot = new THREE.Group()
scene.add(THREESimulationRobot)
const robotTHREEStore = storeManager.createStore('RobotTHREE', {})
let VisualRobot
robotStore.listen([state => state.geometry, state => state.jointLimits], (geometry, jointLimits) => {
buildRobot({ geometry, jointLimits }) // after GUI loaded in the stored values
})
const cacheState = {
jointOutOfBound: [false, false, false, false, false, false],
}
robotStore.listen((state) => {
const angles = Object.values(state.angles)
VisualRobot.setAngles(angles)
for (let i = 0; i < 6; i++) { // do some caching
if (!cacheState.jointOutOfBound[i] && state.jointOutOfBound[i]) { // highlight only on change
VisualRobot.highlightJoint(i, 0xff0000)
} else if (cacheState.jointOutOfBound[i] && !state.jointOutOfBound[i]) {
VisualRobot.highlightJoint(i)
}
}
cacheState.jointOutOfBound = state.jointOutOfBound
})
function buildRobot(state) {
if (state.geometry.V3.y !== 0 || state.geometry.V3.z !== 0 || state.geometry.V4.y !== 0 || state.geometry.V4.z !== 0) {
alert('geometry where V3 y,z not 0 and V4 x,z not 0 are not supported, yet')
state.geometry.V3.y =
state.geometry.V3.z =
state.geometry.V4.y =
state.geometry.V4.x = 0
}
while (THREESimulationRobot.children.length) {
THREESimulationRobot.remove(THREESimulationRobot.children[0])
}
// object to nested arrays
const geometry = Object.values(state.geometry).map((val, i, array) => [val.x, val.y, val.z])
const jointLimits = Object.values(state.jointLimits)
VisualRobot = new THREERobot(geometry, jointLimits, THREESimulationRobot)
}
module.exports = robotStore
})

194
js/THREERobot.js Normal file
View file

@ -0,0 +1,194 @@
const THREERobot = function (V_initial, limits, scene) {
this.THREE = new THREE.Group()
this.robotBones = []
this.joints = []
const scope = this
let parentObject = this.THREE
// parentObject.rotation.x = Math.PI / 2
// let colors = [
// 0x05668D,
// 0x028090,
// 0x00A896,
// 0x02C39A,
// 0xF0F3BD,
// 0x0
// ]
const colors = [
0xaaaaaa,
0xbbbbbb,
0xbcbcbc,
0xcbcbcb,
0xcccccc,
0x0,
]
function createCube(x, y, z, w, h, d, min, max, jointNumber) {
const thicken = 1
const w_thickened = Math.abs(w) + thicken
const h_thickened = Math.abs(h) + thicken
const d_thickened = Math.abs(d) + thicken
const material = new THREE.MeshLambertMaterial({
color: colors[jointNumber],
})
const geometry = new THREE.CubeGeometry(w_thickened, h_thickened, d_thickened)
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(w / 2, h / 2, d / 2)
const group = new THREE.Object3D()
group.position.set(x, y, z)
group.add(mesh)
console.log(min, max)
// min = min / 180 * Math.PI
// max = max / 180 * Math.PI
const jointGeo1 = new THREE.CylinderGeometry(0.8, 0.8, 0.8 * 2, 32, 32, false, -min, 2 * Math.PI - max + min)
const jointGeoMax = new THREE.CylinderGeometry(0.8, 0.8, 0.8 * 2, 32, 32, false, -max, max)
const jointGeoMin = new THREE.CylinderGeometry(0.8, 0.8, 0.8 * 2, 32, 32, false, 0, -min)
const jointMesh1 = new THREE.Mesh(jointGeo1, new THREE.MeshBasicMaterial({
color: 0xffbb00,
}))
const jointMeshMax = new THREE.Mesh(jointGeoMax, new THREE.MeshBasicMaterial({
color: 0x009900,
}))
const jointMeshMin = new THREE.Mesh(jointGeoMin, new THREE.MeshBasicMaterial({
color: 0xdd2200,
}))
const joint = new THREE.Group()
// joint.add(jointMesh1, jointMesh2)
joint.add(jointMeshMax, jointMeshMin, jointMesh1)
scope.joints.push(joint)
switch (jointNumber) {
case 0:
joint.rotation.x = Math.PI / 2
break
case 1:
// joint.rotation.x = Math.PI / 2
break
case 2:
// joint.rotation.x = Math.PI / 2
break
case 3:
joint.rotation.z = Math.PI / 2
// joint.rotation.y = Math.PI
break
case 4:
// joint.rotation.x = Math.PI / 2
joint.rotation.y = Math.PI / 2
break
case 5:
joint.rotation.x = Math.PI / 2
group.rotation.y = Math.PI / 2
// group.rotation.z = Math.PI
// group.rotation.z = -Math.PI / 2
// group.rotation.y += Math.PI
// joint.rotation.z = +Math.PI / 2
// const axisHelper = new THREE.AxisHelper(3)
// axisHelper.rotation.x = Math.PI
// group.add(axisHelper)
const arrowZ = new THREE.ArrowHelper(new THREE.Vector3(0, 0, 1), new THREE.Vector3(0, 0, 0), 3, 0x0000ff)
arrowZ.line.material.linewidth = 4
group.add(arrowZ)
const arrowY = new THREE.ArrowHelper(new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 0), 3, 0x00ff00)
arrowY.line.material.linewidth = 4
group.add(arrowY)
const arrowX = new THREE.ArrowHelper(new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 0, 0), 3, 0xff0000)
arrowX.line.material.linewidth = 4
group.add(arrowX)
// joint.add(getVectorArrow([0,0,0],[0,0,5]))
break
}
group.add(joint)
return group
}
let x = 0,
y = 0,
z = 0
V_initial.push([0, 0, 0]) // add a 6th pseudo link for 6 axis
for (let i = 0; i < V_initial.length; i++) {
const link = V_initial[i]
const linkGeo = createCube(x, y, z, link[0], link[1], link[2], limits[i][0], limits[i][1], i)
x = link[0]
y = link[1]
z = link[2]
console.log(link[0], link[1], link[2])
parentObject.add(linkGeo)
parentObject = linkGeo
this.robotBones.push(linkGeo)
}
scene.add(this.THREE)
this.angles = [0, 0, 0, 0, 0, 0]
}
THREERobot.prototype = {
setAngles(angles) {
this.angles = angles
this.robotBones[0].rotation.z = angles[0]
this.robotBones[1].rotation.y = angles[1]
this.robotBones[2].rotation.y = angles[2]
this.robotBones[3].rotation.x = angles[3]
this.robotBones[4].rotation.y = angles[4]
this.robotBones[5].rotation.z = angles[5]
},
setAngle(index, angle) {
this.angles[index] = angle
this.setAngles(this.angles)
},
highlightJoint(jointIndex, hexColor) {
if (jointIndex >= this.joints.length) {
console.warn(`cannot highlight joint: ${jointIndex} (out of index: ${this.joints.length})`)
}
if (hexColor) {
this._colorObjectAndChildren(this.joints[jointIndex], hexColor)
} else {
this._resetObjectAndChildrenColor(this.joints[jointIndex])
}
},
_colorObjectAndChildren(object, hexColor) {
const scope = this
object.traverse((node) => {
scope._colorObject(node, hexColor)
})
},
_colorObject(object, hexColor) {
if (object.material) {
if (!object.initalMaterial) {
object.initalMaterial = object.material
}
object.material = object.material.clone()
object.material.color.setHex(hexColor)
}
},
_resetObjectAndChildrenColor(object, hexColor) {
const scope = this
object.traverse((node) => {
scope._resetObjectColor(node)
})
},
_resetObjectColor(object) {
if (object.initalMaterial) {
object.material = object.initalMaterial
}
},
}

89
js/THREEScene.js Normal file
View file

@ -0,0 +1,89 @@
define((require, exports, module) => {
const storeManager = require('State')
const THREEStore = storeManager.createStore('THREE', {})
/* THREEJS SCENE SETUP */
const renderer = new THREE.WebGLRenderer({
antialias: true, // to get smoother output
preserveDrawingBuffer: false, // no screenshot -> faster?
})
renderer.setClearColor(0x333333)
renderer.setSize(window.innerWidth, window.innerHeight)
document.getElementById('container').appendChild(renderer.domElement)
// create a scene
const scene = new THREE.Scene()
window.debug.scene = scene
// toggle camera mode
const perspectiveCamera = true
let camera
if (perspectiveCamera) {
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 10000)
} else {
camera = new THREE.OrthographicCamera(
window.innerWidth / -2,
window.innerWidth / 2,
window.innerHeight / 2,
window.innerHeight / -2, -500, 1000)
camera.zoom = 20
camera.updateProjectionMatrix()
}
camera.up.set(0, 0, 1)
camera.position.set(25, 25, 25)
scene.add(camera)
// lights
const light = new THREE.AmbientLight(0xaaaaaa)
scene.add(light)
const light2 = new THREE.DirectionalLight(0xaaaaaa)
light2.position.set(1, 1.3, 1).normalize()
scene.add(light2)
cameraControls = new THREE.OrbitControls(camera, renderer.domElement)
cameraControls.addEventListener('change', () => renderer.render(scene, camera))
function onWindowResize() {
if (perspectiveCamera) {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
} else {
camera.left = window.innerWidth / -2
camera.right = window.innerWidth / 2
camera.top = window.innerHeight / 2
camera.bottom = window.innerHeight / -2
camera.updateProjectionMatrix()
}
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.render(scene, camera)
}
window.addEventListener('resize', onWindowResize, false)
const size = 10
const step = 20
const gridHelper = new THREE.GridHelper(size, step)
gridHelper.rotation.x = Math.PI / 2
scene.add(gridHelper)
const axisHelper = new THREE.AxisHelper(5)
scene.add(axisHelper)
/* END THREEJS SCENE SETUP */
THREEStore.listen(() => {
// kickass trick to render after other listeners. Stack and stuff
setTimeout(() => {
renderer.render(scene, camera)
}, 0)
})
module.exports.scene = scene
module.exports.renderer = renderer
module.exports.camera = camera
})

83
js/THREEView.js Normal file
View file

@ -0,0 +1,83 @@
define((require, exports, module) => {
class THREEView {
constructor() {
/* THREEJS SCENE SETUP */
// this.renderer = new THREE.WebGLRenderer({
// antialias: true, // to get smoother output
// preserveDrawingBuffer: false, // no screenshot -> faster?
// })
// this.renderer.setClearColor(0x333333)
//
// this.renderer.setSize(window.innerWidth, window.innerHeight)
// document.getElementById('container').appendChild(this.renderer.domElement)
//
// // create a scene
// this.scene = new THREE.Scene()
// debug.scene = this.scene
//
// // toggle camera mode
// const perspectiveCamera = true
// if (perspectiveCamera) {
// this.camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 10000)
// } else {
// this.camera = new THREE.OrthographicCamera(
// window.innerWidth / -2,
// window.innerWidth / 2,
// window.innerHeight / 2,
// window.innerHeight / -2, -500, 1000)
// this.camera.zoom = 20
// this.camera.updateProjectionMatrix()
// }
//
// this.camera.position.set(25, 25, -25)
// this.scene.add(this.camera)
//
// // lights
// const light = new THREE.AmbientLight(0xaaaaaa)
// this.scene.add(light)
// const light2 = new THREE.DirectionalLight(0xaaaaaa)
// light2.position.set(1, 1.3, 1).normalize()
// this.scene.add(light2)
//
// this.cameraControls = new THREE.OrbitControls(this.camera, this.renderer.domElement)
// this.cameraControls.addEventListener('change', this.render.bind(this))
//
// function onWindowResize() {
// if (perspectiveCamera) {
// scope.camera.aspect = window.innerWidth / window.innerHeight
// scope.camera.updateProjectionMatrix()
// } else {
// scope.camera.left = window.innerWidth / -2
// scope.camera.right = window.innerWidth / 2
// scope.camera.top = window.innerHeight / 2
// scope.camera.bottom = window.innerHeight / -2
// scope.camera.updateProjectionMatrix()
// }
//
// scope.renderer.setSize(window.innerWidth, window.innerHeight)
// scope.render()
// }
//
// window.addEventListener('resize', onWindowResize, false)
//
// const size = 10
// const step = 20
//
// const gridHelper = new THREE.GridHelper(size, step)
// this.scene.add(gridHelper)
//
// const axisHelper = new THREE.AxisHelper(5)
// this.scene.add(axisHelper)
/* END THREEJS SCENE SETUP */
}
render() {
this.renderer.render(this.scene, this.camera)
}
}
module.exports = new THREEView()
})

134
js/Target.Gui.js Normal file
View file

@ -0,0 +1,134 @@
define((require, exports, module) => {
const gui = require('UiDat')
const storeManager = require('State')
const targetStore = require('Target') // todo dont export store but a handle which acceps the name of the consuming module const targetStore = getStoreFrom('myModule') -> myModule accesses store targetStore
/**
* + state per module
* + render on state changed
* + get state from other modules
*
* --- onStore update render ---
* get data From other stores
* - store might not have changed, so no update
*/
const targetGuiStore = storeManager.createStore('TargetGui', {})
// the returned value of an action is set to the selected object
// helper is needed, since dat.gui wants to modify the object, so we cant use ist on the state
const targetGUI = gui.addFolder('targetGui')
const helper = {
position: {
x: 10,
y: 10,
z: 10,
},
rotation: {
x: 10,
y: 10,
z: 10,
},
followTarget: true, // will be set on listen anyways
eulerRingsVisible: false,
controlVisible: false,
manipulate: 'world',
controlMode: 't/r',
}
targetStore.listen([() => targetGuiStore.getStore('Robot').getState().target, state => state], (targetT, state) => {
helper.followTarget = state.followTarget
helper.eulerRingsVisible = state.eulerRingsVisible
helper.controlVisible = state.controlVisible
helper.manipulate = state.manipulate
helper.controlMode = state.controlMode
helper.position.x = state.position.x
helper.position.y = state.position.y
helper.position.z = state.position.z
helper.rotation.x = state.rotation.x
helper.rotation.y = state.rotation.y
helper.rotation.z = state.rotation.z
// Iterate over all controllers
for (const i in targetGUI.__controllers) {
targetGUI.__controllers[i].updateDisplay()
}
})
function toggleSpace() {
targetStore.dispatch('CONTROL_SPACE_TOGGLE')
}
targetGUI.add({
toggleSpace,
}, 'toggleSpace')
targetGUI.add(helper, 'controlMode', ['translate', 'rotate']).onChange(() => {
targetStore.dispatch('CHANGE_CONTROL_MODE', helper.controlMode)
})
targetGUI.add(helper, 'followTarget').onChange(() => {
targetStore.dispatch('CHANGE_FOLLOW_TARGET', helper.followTarget)
})
targetGUI.add(helper.position, 'x').step(0.1).onChange(() => {
targetStore.dispatch('TARGET_CHANGE_TARGET', {
position: {
x: helper.position.x,
},
})
})
targetGUI.add(helper.position, 'y').step(0.1).onChange(() => {
targetStore.dispatch('TARGET_CHANGE_TARGET', {
position: {
y: helper.position.y,
},
})
})
targetGUI.add(helper.position, 'z').step(0.1).onChange(() => {
targetStore.dispatch('TARGET_CHANGE_TARGET', {
position: {
z: helper.position.z,
},
})
})
targetGUI.add(helper.rotation, 'x').min(-Math.PI).max(Math.PI).step(0.01).onChange(() => {
targetStore.dispatch('TARGET_CHANGE_TARGET', {
rotation: {
x: helper.rotation.x,
},
})
})
targetGUI.add(helper.rotation, 'y').min(-Math.PI).max(Math.PI).step(0.01).onChange(() => {
targetStore.dispatch('TARGET_CHANGE_TARGET', {
rotation: {
y: helper.rotation.y,
},
})
})
targetGUI.add(helper.rotation, 'z').min(-Math.PI).max(Math.PI).step(0.01).onChange(() => {
targetStore.dispatch('TARGET_CHANGE_TARGET', {
rotation: {
z: helper.rotation.z,
},
})
})
targetGUI.add(helper, 'eulerRingsVisible').onChange(() => {
targetStore.dispatch('SET_EULER_RINGS_VISIBLE', helper.eulerRingsVisible) // todo bad practice to get the store data outside of listen
})
targetGUI.add(helper, 'controlVisible').onChange(() => {
targetStore.dispatch('SET_CONTROL_VISIBLE', helper.controlVisible)
})
module.exports = targetGuiStore
})

300
js/Target.js Normal file
View file

@ -0,0 +1,300 @@
define((require, exports, module) => {
const storeManager = require('State')
const robotStore = require('Robot')
const {
scene,
camera,
renderer,
} = require('THREEScene')
/**
* + state per module
* + render on state changed
* + get state from other modules
*
* --- onStore update render ---
* get data From other stores
* - store might not have changed, so no update
*/
const defaultState = {
controlSpace: 'world',
eulerRingsVisible: false,
controlVisible: true,
controlMode: 'translate',
followTarget: true,
manipulate: 'rotate',
position: {
x: 10,
y: 10,
z: 10,
},
rotation: {
x: 0,
y: 0,
z: 0,
},
}
const store = storeManager.createStore('Target', defaultState)
store.action('CHANGE_FOLLOW_TARGET', (state, data) => {
if (data) {
store.getStore('Robot').dispatch('ROBOT_CHANGE_TARGET', {
position: state.position,
rotation: state.rotation,
})
}
return Object.assign({}, state, {
followTarget: data,
})
})
store.action('SET_EULER_RINGS_VISIBLE', (state, data) => Object.assign({}, state, {
eulerRingsVisible: data,
}))
store.action('SET_CONTROL_VISIBLE', (state, data) => Object.assign({}, state, {
controlVisible: data,
}))
const sphereGeo = new THREE.CylinderGeometry(1, 1, 1 * 2, 32)
const target = new THREE.Group()
const targetCylinder = new THREE.Mesh(sphereGeo, new THREE.MeshBasicMaterial({
transparent: true,
opacity: 0.7,
color: 0xaaaaaa,
}))
targetCylinder.rotation.x = Math.PI / 2
targetCylinder.position.z += 1
target.add(targetCylinder)
const arrowZ = new THREE.ArrowHelper(new THREE.Vector3(0, 0, 1), new THREE.Vector3(0, 0, 0), 4, 0x0000ff)
// arrowZ.line.material.linewidth = 4
target.add(arrowZ)
const arrowY = new THREE.ArrowHelper(new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 0), 4, 0x00ff00)
// arrowY.line.material.linewidth = 4
target.add(arrowY)
const arrowX = new THREE.ArrowHelper(new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 0, 0), 4, 0xff0000)
// arrowX.line.material.linewidth = 4
//
target.rotation.y = Math.PI / 2
target.rotation.z = -Math.PI
target.add(arrowX)
// const axisHelper = new THREE.AxisHelper(5)
// target.add(axisHelper)
// ZYX fixed axis -> XYZ moving axis
target.rotation.order = 'XYZ'
scene.add(target)
/* CONTROLS */
function createRing(radius, color, axis) {
const sphere_radius = 0.12
const ringMaterial = new THREE.MeshLambertMaterial({
color,
})
// create ring shape
const circleMesh = new THREE.Mesh(
new THREE.TorusGeometry(radius, 0.05, 6, 50),
ringMaterial,
)
const sphereMesh = new THREE.Mesh(
new THREE.SphereGeometry(sphere_radius, 12, 10),
ringMaterial,
)
sphereMesh.position.x = radius
const composite = new THREE.Object3D()
composite.add(circleMesh)
composite.add(sphereMesh)
// composite.add(coneMesh)
if (axis === 'x') {
composite.rotation.y = Math.PI / 2
} else if (axis === 'y') {
composite.rotation.x = Math.PI / 2
}
const ringObj = new THREE.Object3D()
ringObj.add(composite)
return ringObj
}
let ringx
let ringy
let ringz
// Euler https://www.udacity.com/course/viewer#!/c-cs291/l-91073092/m-123949249
function createAllRings(parentObject) {
// debugger
// create Rings
ringx = createRing(2.00, 0xFF0000, 'x')
ringy = createRing(1.75, 0x00FF00, 'y')
ringz = createRing(1.50, 0x0000FF, 'z')
// set up rotation hierarchy - assuming x -> y -> z intrinsic
// ringy.add(ringx)
// ringz.add(ringy)
//
// parentObject.add(ringz)
ringy.add(ringz)
ringx.add(ringy)
parentObject.add(ringx)
}
const eulerRings = new THREE.Object3D()
scene.add(eulerRings)
createAllRings(eulerRings)
const control = new THREE.TransformControls(camera, renderer.domElement)
let disableUpdate = false
store.listen([() => store.getStore('Robot').getState().target, state => state], (targetT, state) => {
if (state.followTarget) {
state.position.x = targetT.position.x
state.position.y = targetT.position.y
state.position.z = targetT.position.z
state.rotation.x = targetT.rotation.x
state.rotation.y = targetT.rotation.y
state.rotation.z = targetT.rotation.z
}
target.position.x = state.position.x
target.position.y = state.position.y
target.position.z = state.position.z
target.rotation.x = state.rotation.x
target.rotation.y = state.rotation.y
target.rotation.z = state.rotation.z
if (true) { // loop - changing mode triggers change....
disableUpdate = true
control.setMode(state.controlMode)
control.setSpace(state.controlSpace)
disableUpdate = false
}
control.visible = state.controlVisible
eulerRings.visible = state.eulerRingsVisible
eulerRings.position.set(target.position.x, target.position.y, target.position.z)
ringx.rotation.x = target.rotation.x
ringy.rotation.y = target.rotation.y
ringz.rotation.z = target.rotation.z
// control.dispatchEvent({ type: 'change' })
})
const targetChangedAction = () => {
setTarget(target.position, target.rotation)
// bonus points: how to not fire an action from this reducer and still be able
// to call CHANGE_TARGET on Target and sync the ROBOT_TARGET
// state.dispatch('ROBOT_CHANGE_TARGET', {
// position: target.position,
// rotation: target.rotation,
// })
}
// control.rotation.x = 2
control.addEventListener('change', () => {
if (!disableUpdate) { // changing controlmode causes a loop
targetChangedAction()
}
})
control.attach(target)
scene.add(control)
eulerRings.visible = store.getState().eulerRingsVisible
control.visible = store.getState().controlVisible
window.addEventListener('keydown', (event) => {
switch (event.keyCode) {
case 82:
console.log('rotation mode')
setMode('rotate')
break
case 84:
console.log('translation mode')
setMode('translate')
break
default:
break
}
}, false)
store.action('CONTROL_SPACE_TOGGLE', state => state.controlSpace, controlSpace => ((controlSpace === 'local') ? 'world' : 'local'))
function toggleSpace() {
store.dispatch('CONTROL_SPACE_TOGGLE')
}
function getState() {
return store.getState()
}
// TODO change this to match the state first API
function setMode(mode) {
store.dispatch('CHANGE_CONTROL_MODE', mode)
}
store.action('CHANGE_CONTROL_MODE', (state, data) => ({ ...state,
controlMode: data,
}))
store.action('TARGET_CHANGE_TARGET', (state, data) => {
// + this function can be called from outside
// + may otherwise lead to inconsistent state, where followTarget: true, but pos of target and robot do not match (or not?, listen() will always be consistent)
// - action should only care about its own state
// - can lead to loop
// - need only one way to do it, UI may only need to update other modules state, so only update others sate is needed
// const pos = { ...state.rotation,
// ...data.rotation,
// }
//
// console.log(pos)
if (state.followTarget) {
store.getStore('Robot').dispatch('ROBOT_CHANGE_TARGET', {
position: { ...state.position, // allow for changing only one parameter (x,y,z)
...data.position,
},
rotation: { ...state.rotation,
...data.rotation,
},
})
}
return { ...state,
position: { ...state.position, // allow for changing only one parameter (x,y,z)
...data.position,
},
rotation: { ...state.rotation,
...data.rotation,
},
}
})
function setTarget(position, rotation) {
store.dispatch('TARGET_CHANGE_TARGET', {
position: {
x: position.x,
y: position.y,
z: position.z,
},
rotation: {
x: rotation.x,
y: rotation.y,
z: rotation.z,
},
})
}
module.exports = store
})

5
js/UiDat.js Normal file
View file

@ -0,0 +1,5 @@
define((require, exports, module) => {
const dat = require('dat.gui.min')
module.exports = new dat.GUI()
})

217
js/WorkingSpace.js Normal file
View file

@ -0,0 +1,217 @@
define((require, exports, module) => {
const storeManager = require('State')
const gui = require('UiDat')
const Kinematic = require('Kinematic')
const {
scene,
} = require('THREEScene')
const robotStore = require('Robot')
const workingSpaceStore = storeManager.createStore('WorkingSpace', {
step: 5.0,
directions: [{
rx: 0,
ry: 0,
rz: -Math.PI / 2,
color: 0x00ff00,
}, {
rx: Math.PI,
ry: 0,
rz: 0,
color: 0xff0000,
}, {
rx: 0,
ry: Math.PI / 2,
rz: 0,
color: 0x0000ff,
}],
show: false,
})
workingSpaceStore.action('CHANGE_STEP', (state, step) =>
Object.assign({}, state, {
step,
}),
)
workingSpaceStore.action('ADD_POSE_TO_EULER', state => state.directions, (directions, pose) => [...directions, pose])
workingSpaceStore.action('REMOVE_POSES', state => state.directions, (directions, pose) => [])
workingSpaceStore.action('CHANGE_VISIBILITY', (state, data) => Object.assign({}, state, {
show: data,
}))
const guiHelper = {
step: 5.0,
directions: [{
rx: 0,
ry: 0,
rz: -Math.PI / 2,
color: 0x00ff00,
}, {
rx: Math.PI,
ry: 0,
rz: 0,
color: 0xff0000,
}, {
rx: 0,
ry: Math.PI / 2,
rz: 0,
color: 0x0000ff,
}],
show: false,
}
const THREEGroup = new THREE.Group()
scene.add(THREEGroup)
robotStore.listen([() => workingSpaceStore.getState(), state => state.jointLimits, state => state.geometry], (state, jointLimits, geometry) => {
// gui
guiHelper.step = state.step
// romove all children before adding new ones
while (THREEGroup.children.length) {
THREEGroup.remove(THREEGroup.children[0])
}
if (state.show) {
// debugger
const geo = Object.values(geometry).map((val, i, array) => [val.x, val.y, val.z])
const IK = new Kinematic(geo, [ // todo remove when using new ik
[-360, 360],
[-360, 360],
[-360, 360],
[-360, 360],
[-360, 360],
[-360, 360],
[-360, 360],
])
const step = state.step
const euler = state.directions
const THREEgeo = new THREE.BoxBufferGeometry(0.1, 0.1, 0.1)
for (let j = 0; j < euler.length; j++) {
const {
rx,
ry,
rz,
color,
} = euler[j]
const size = 1.5
const transparent = true
const opacity = 0.9
const vertexColors = false
const sizeAttenuation = true
const rotateSystem = false
const geom = new THREE.Geometry()
const material = new THREE.PointCloudMaterial({
size,
transparent,
opacity,
vertexColors,
sizeAttenuation,
color,
})
let i = 0
let goOn = 8
while (goOn > 0) {
i += step
goOn--
for (let x = -i; x <= i; x += step) {
for (let y = -i; y <= i; y += step) {
for (let z = -i; z <= i; z += step) {
// not at the boundary
if (x < i && x > -i && y < i && y > -i && z < i && z > -i) continue
const angles = []
IK.calculateAngles(
x,
y,
z,
rx,
ry,
rz,
angles,
)
let inReach = true
Object.keys(jointLimits).forEach((key, i) => {
const jl0 = jointLimits[key][0]
const jl1 = jointLimits[key][1]
if (isNaN(angles[i]) || jointLimits[key][0] > angles[i] || jointLimits[key][1] < angles[i]) {
inReach = false
}
})
if (inReach) {
goOn = 3 // continue n more layers if at least one point was in reach
// const material = new THREE.MeshBasicMaterial({
// color,
// })
// const sphere = new THREE.Mesh(THREEgeo, material)
// sphere.position.set(x + 0.1 * j, y + 0.1 * j, z + 0.1 * j)
// THREEGroup.add(sphere)
const particle = new THREE.Vector3(x + 0.2 * size * j, y + 0.2 * size * j, z + 0.2 * size * j)
geom.vertices.push(particle)
// console.log(particle)
// var color = new THREE.Color(0x00ff00);
// color.setHSL(color.getHSL().h, color.getHSL().s, color.getHSL().l);
// geom.colors.push(color);
}
}
}
}
}
const cloud = new THREE.Points(geom, material)
THREEGroup.add(cloud)
}
}
})
const workingSpaceGUI = gui.addFolder('working space')
workingSpaceGUI.add(guiHelper, 'show').onChange(() => {
workingSpaceStore.dispatch('CHANGE_VISIBILITY', guiHelper.show)
})
workingSpaceGUI.add(guiHelper, 'step').min(0.1).max(5).step(0.1).onChange(() => {
workingSpaceStore.dispatch('CHANGE_STEP', guiHelper.step)
})
const fun = {
addPose() {
},
clearPoses() {
},
}
workingSpaceGUI.add(fun, 'addPose').onChange(() => {
workingSpaceStore.dispatch('ADD_POSE_TO_EULER', {
rx: robotStore.getState().target.rotation.x,
ry: robotStore.getState().target.rotation.y,
rz: robotStore.getState().target.rotation.z,
color: 0xffffff * (0.6 + 0.4 * Math.random()), // brighter colors
})
})
workingSpaceGUI.add(fun, 'clearPoses').onChange(() => {
workingSpaceStore.dispatch('REMOVE_POSES', {})
})
module.exports = function test() {
console.log('todo')
}
})
// todo -> get rid of scene injection using require scene -> threerobot handles 3d view

2
js/dat.gui.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2183
js/require.js Normal file

File diff suppressed because it is too large Load diff

27
package.json Normal file
View file

@ -0,0 +1,27 @@
{
"name": "Javascript Robot HMI",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"colors": "^1.1.2",
"commander": "^2.9.0",
"debug": "^2.2.0",
"redux": "^3.6.0",
"serialport": "^4.0.1",
"socketio": "^1.0.0"
},
"devDependencies": {
"eslint": "^3.8.0",
"eslint-config-airbnb": "^12.0.0",
"eslint-plugin-import": "^2.0.1",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.4.1",
"mocha": "3.2.0"
}
}

96
vendor/EventDispatcher.js vendored Normal file
View file

@ -0,0 +1,96 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
var EventDispatcher = function () {};
Object.assign( EventDispatcher.prototype, {
addEventListener: function ( type, listener ) {
if ( this._listeners === undefined ) this._listeners = {};
var listeners = this._listeners;
if ( listeners[ type ] === undefined ) {
listeners[ type ] = [];
}
if ( listeners[ type ].indexOf( listener ) === - 1 ) {
listeners[ type ].push( listener );
}
},
hasEventListener: function ( type, listener ) {
if ( this._listeners === undefined ) return false;
var listeners = this._listeners;
if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) {
return true;
}
return false;
},
removeEventListener: function ( type, listener ) {
if ( this._listeners === undefined ) return;
var listeners = this._listeners;
var listenerArray = listeners[ type ];
if ( listenerArray !== undefined ) {
var index = listenerArray.indexOf( listener );
if ( index !== - 1 ) {
listenerArray.splice( index, 1 );
}
}
},
dispatchEvent: function ( event ) {
if ( this._listeners === undefined ) return;
var listeners = this._listeners;
var listenerArray = listeners[ event.type ];
if ( listenerArray !== undefined ) {
event.target = this;
var array = [], i = 0;
var length = listenerArray.length;
for ( i = 0; i < length; i ++ ) {
array[ i ] = listenerArray[ i ];
}
for ( i = 0; i < length; i ++ ) {
array[ i ].call( this, event );
}
}
}
} );

262
vendor/state/State.js vendored Normal file
View file

@ -0,0 +1,262 @@
define((require, exports, module) => {
/**
* thoughts:
* - objects must not be added, items can only be added to arrays
* - -> initial data is the schema
*
* store.listen([(state, getStore) => getStore('Robot').getState().angles]) // only acces other stores in the listen method
* - only acces the state in the listen method and in actions
* store.action('NAME', (state, data, getStore) => {
* getStore('Robot').dispatch('SOME_ACTION', {data}) // do not get state from other stores?
* })
*
* - dispatching actions within actions may leed to false undo. Outer action causes inner action, so only outer action has to be called
* - -> catch this case like InnerFunction = true
*
* - disable listeners, when applying undo - redo actions
*/
class Store {
constructor(state, name, storeManager) {
this.state = state
this.name = name
this.storeManager = storeManager
this.actions = {}
this.listeners = {}
this.listenerId = 1
}
action(name, ...args) {
if (this.actions.hasOwnProperty(name)) {
console.warn(`action name in use: ${name}`)
}
let callback = args[0]
// selector given
if (args.length === 2) {
const selector = args[0]
const cb = args[1]
callback = (state, data) => {
const recursivelyAssignObjects = (object, selectedObj, newValue) => {
if (object === selectedObj) {
return newValue
}
for (const key in object) {
if (object.hasOwnProperty(key)) {
// key authors object book[0]
if (object[key] === selectedObj) {
return Object.assign({}, object, {
[key]: newValue,
})
}
// key 0 object books
if (Array.isArray(object[key]) || typeof (object[key]) === 'object') {
const newObject = recursivelyAssignObjects(object[key], selectedObj, newValue)
if (newObject) {
return Object.assign({}, object, {
[key]: newObject,
})
}
}
}
}
return false
}
const selectedObj = selector(state)
if (typeof selectedObj !== 'object') {
console.warn(`Action selector must select an object! (${selectedObj}) selected`)
}
const newState = recursivelyAssignObjects(state, selectedObj, cb(selectedObj, data))
if (!newState) {
console.warn('selector does not match any object', selector, state)
}
return newState
}
}
this.actions[name] = callback
}
listen(...args) {
let callback
// selectros given
if (args.length === 2) {
const selects = args[0]
const cb = args[1]
const currentStates = []
for (const select of selects) {
currentStates.push(select(this.state))
}
const handleChange = (state) => {
let changed = false
for (const i in selects) {
const newState = selects[i](state)
if (newState !== currentStates[i]) {
changed = true
currentStates[i] = newState
}
}
if (changed) {
cb.apply(this, currentStates)
}
}
callback = handleChange
// execute cb once on init
cb.apply(this, currentStates)
} else {
callback = args[0]
}
const id = this.listenerId++
this.listeners[id] = callback
// call once to init. Default state is already set
callback(this.state)
return id
}
unsubscribe(id) {
if (this.listeners[id]) {
delete this.listeners[id]
} else {
console.warn(`Could not find listener for id: ${id}`)
}
}
dispatch(action, data) {
this.storeManager.notify(action, data, this.name, this)
}
getState() {
return this.state
}
getStore(storeName) {
// console.log(`%cStore [${this.name}] requesting data from [${storeName}]`, 'font-weight:bold')
return this.storeManager.getStore(storeName)
}
}
class StoreManager {
constructor() {
this.state = {}
this.store = this
this.middlewares = []
this.stores = {}
}
getState() {
return this.state
}
getStore(storeName) {
return this.stores[storeName]
}
createStore(name, defaultState) {
this.state[name] = defaultState
if (this.stores[name]) {
console.error(`store ${name} already exists`)
}
const store = new Store(this.state[name], name, this)
this.stores[name] = store
return store
}
removeStore(name) {
if (!this.stores[name]) {
console.warn(`cannot find store with name: ${name}`)
} else {
delete this.stores[name]
}
}
notify(action, data, name, store) {
const newState = this.runMiddleware(action, data, store)
this.state = Object.assign({}, this.state, {
[name]: newState,
})
store.state = this.state[name]
// call listeners
for (const storeId in this.stores) {
if (this.stores[storeId]) {
for (const id in this.stores[storeId].listeners) {
if (this.stores[storeId].listeners[id]) {
this.stores[storeId].listeners[id](this.stores[storeId].state)
}
}
}
}
// todo check if state was changed in listeners
}
runMiddleware(action, data, store) {
// cant prechain the middleware, sonce the scope of getStae is matching the local store
const middlewareAPI = {
getState: store.getState.bind(store),
getGlobalState: this.getState.bind(this),
dispatch: (action, data) => store.dispatch(action, data), // allow for further dispatches in middleware //todo check this if we need to bind
}
// mid1,mid2,mid3
const chain = this.middlewares.map(middleware => middleware(middlewareAPI))
// mid1(mid2(mid3(dispatch))(name, data)
function executeAction(name, data) {
if (!this.actions.hasOwnProperty(name)) {
console.warn(`action not found: ${name}`)
}
return this.actions[name](this.state, data)
}
// mid1,mid2,mid3,dispatch
// (prev, current) (mid3, dispatch)
const runMiddleware = [...chain, executeAction.bind(store)].reduceRight((composed, f) => f(composed))
return runMiddleware(action, data)
}
applyMiddleware(...middlewares) {
this.middlewares = [...this.middlewares, ...middlewares]
}
}
const storeManager = new StoreManager()
module.exports = storeManager
})
// s.commit('CHANGE_CONTROL_MODE', mode, (state, data) => {
// return [
// ...state, {
// controlMode: data,
// },
// ]
// })
// // global state (app state)
// GlobalDataDomain.setMode(mode)
//
// function onChange(store, select, onChange) {
// let currentState;
//
// function handleChange() {
// let nextState = select(store.getState());
// if (nextState !== currentState) {
// currentState = nextState;
// onChange(currentState);
// }
// }
//
// let unsubscribe = store.subscribe(handleChange);
// handleChange();
// return unsubscribe;
// }
//
// store.onChange(store, [state, Module.getState(), Module.getClicked()](state) => {
//
// })

191
vendor/state/Test.js vendored Normal file
View file

@ -0,0 +1,191 @@
define((require, exports, module) => {
const storeManager = require('State')
class BooksModule {
constructor() {
const defaultState = {
highlight: 'abc',
books: [{
id: 1,
title: 'abc',
author: 'Erwin',
}, {
id: 2,
title: 'test',
author: 'Albert',
}, ],
}
//
this.store = storeManager.createStore('books', defaultState)
//
// + list possible actions
// + dispatch call from other module Module.getState().dispatch('add_book') withou module api (addBook())
// this.store.action('add_book', (state, data) => {
// // {
// // ...state,
// // books: {
// // ...state.books,
// // [data.id]: {
// // title: data.title,
// // author: data.title,
// // },
// // },
// // }
// return Object.assign({}, state, {
// books: [...state.books, {
// id: data.id,
// title: data.title,
// author: data.author,
// }, ],
// })
// })
this.store.action('add_book', state => state.books, (state, data) => {
return [...state, {
id: data.id,
title: data.title,
author: data.author,
}, ]
})
this.store.action('change_title', state => state.books, (books, data) => {
return books.map((book, index) => {
if (book.id === data.id) {
return Object.assign({}, book, {
title: data.title,
})
}
return book
})
})
this.store.action('change_highlight', (state, {
highlight,
}) => {
return Object.assign({}, state, {
highlight,
})
})
this.store.onChange([state => state.highlight], (state) => {
console.log('highlight changed')
})
this.store.onChange([state => state], (state) => {
console.log('state changed')
})
this.store.onChange([state => state.books], (state) => {
console.log('books changed')
})
// this.store.onChange([state => state.title, Module.getState, Module.getClicked], (state) => {
// console.log('title changed')
// })
this.store.listen((state) => {
// console.log(state)
})
}
addBook(title, author, id) {
this.store.dispatch('add_book', {
title,
author,
id,
})
}
changeTitle(id, title) {
this.store.dispatch('change_title', {
title,
id,
})
}
highlightBook(id) {
this.store.commit('highlight_book', {
id,
}, (state, data) => {
// return [
// ...state, {
// highlight: data.id,
// },
// ]
})
}
getState() {
this.store.getState()
}
}
const booksModule = new BooksModule()
booksModule.changeTitle(2, 'muh')
booksModule.addBook('Its Me, Frank', 'Mr T', 13)
booksModule.changeTitle(13, 'Its Me, Max')
booksModule.store.dispatch('change_highlight', {
highlight: '12',
})
const state1 = {
name: 'tim',
type: {
gender: {
a: 'm',
},
age: 34,
},
}
const state2 = Object.assign({}, state1, {
type: Object.assign({}, state1.type, {
age: 35,
}),
})
console.log(state1)
console.log(state2)
console.log(state2.type === state1.type) // false
console.log(state2.type.gender === state1.type.gender) // true
// test
const defaultData = {
propA: 'A',
propB: 'B',
lvl1: {
arr: [1, 2, 3],
objArr: [{
a: 'a',
b: 'b',
}, {
a: 1,
b: 2,
}],
a: 1,
b: 2,
lvl2: {
a: 3,
b: 4,
lvl3: {
a: 5,
b: 6,
},
},
},
}
const testStore = storeManager.createStore('test', defaultData)
const initialState = testStore.getState()
console.log(initialState)
testStore.action('change_state', state => state, (state, data) => {
return Object.assign({}, state, {
propA: 'C',
})
})
testStore.dispatch('change_state', {})
console.log(testStore.getState())
const newState = testStore.getState()
console.log(initialState !== newState)
console.log(initialState.propA !== newState.propA)
testStore.dispatch('change_state', {})
const newState2 = testStore.getState()
console.log(newState !== newState2)
console.log(newState.propA === newState2.propA) // same Value
})

33
vendor/state/test.html vendored Normal file
View file

@ -0,0 +1,33 @@
<!doctype html>
<html>
<head>
<title>learningthree.js boiler plate for three.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<script src="../../js/require.js" charset="utf-8"></script>
</head>
<body>
<!-- three.js container -->
<div id="container"></div>
<!-- info on screen display -->
<script type="text/javascript">
requirejs.config({
baseUrl: '',
// paths: {
// redux: '../node_modules/redux/dist/redux'
// }
});
require(['Test'], function(foo) {
});
</script>
</body>
</html>

459
vendor/state/test/State.test.js vendored Normal file
View file

@ -0,0 +1,459 @@
define((require, exports, module) => {
const assert = require('chai').assert
const m = require('mocha')
describe('State', () => {
const storeManager = require('State')
const logger = store => dispatch => (action, data) => {
console.group(`ACTION ${action}`)
console.log(`action: %c${action}`, 'color:green')
console.log('data: ', data)
console.log('%cstore before: ', 'color:orange', store.getState())
const newState = dispatch(action, data)
console.log('%cnew state: ', 'color:green', newState)
console.groupEnd()
return newState
}
const mid = store => dispatch => (action, data) => {
const oldState = store.getState()
const oldStateCopy = JSON.parse(JSON.stringify(oldState))
const newState = dispatch(action, data)
function compare(o, n, os) {
for (const i of Object.keys(o).concat(Object.keys(n))) {
if (!n[i]) {
if (os === n) {
console.warn('nooohohoohoh did not change state, bro!')
console.warn('element was removed, but parent not changed')
}
} else if (!o[i]) {
if (os === n) {
console.warn('nooohohoohoh did not change state, bro!')
console.warn('element was added, but parent not changed')
}
} else if (!!o[i] && typeof (o[i]) === 'object') {
// console.log('aaaa')
//
compare(o[i], n[i], os[i])
} else {
if (!n[i] || o[i] !== n[i]) { // el deleted, or value not same
// value has changed todo iter over newState (missing ones were deleted, dont matter. new ones dont matter either hm....)
// new state cant be old state, if a child changed
if (os === n) {
console.warn('nooohohoohoh did not change state, bro!')
console.group(`state ${action}`)
console.log(`oldStateCopy: ${o[i]}`)
console.log(`oldState: %c${os[i]}`, 'color: red')
console.log(`newState: ${n[i]}`)
console.groupEnd()
}
}
// console.log(i, o[i] === n[i])
}
}
}
compare(oldStateCopy, newState, oldState)
return newState
}
storeManager.applyMiddleware(logger, mid)
const defaultData = {
propA: 'A',
propB: 'B',
lvl1: {
arr: [1, 2, 3],
objArr: [{
a: 'a',
b: 'b',
}, {
a: 1,
b: 2,
}],
a: 1,
b: 2,
lvl2: {
a: 3,
b: 4,
lvl3: {
a: 5,
b: 6,
},
},
},
}
let testStore
beforeEach((done) => {
storeManager.removeStore('test')
testStore = storeManager.createStore('test', defaultData)
done()
})
describe('#createStore', () => {
it('create a store', () => {
assert.equal(testStore.getState(), defaultData)
})
})
describe('#listen', () => {
it('called with initial state when binding', () => {
testStore.listen((state) => {
assert.deepEqual(defaultData, state)
})
})
it('listen to changes', () => {
let calledTimes = 0
testStore.listen(() => {
calledTimes++
})
testStore.action('change_state', (state, data) => Object.assign({}, state, {
propA: 'C',
}))
testStore.dispatch('change_state', {})
assert.equal(calledTimes, 2)
})
it('called multiple times, when changes have the same value', () => {
let calledTimes = 0
testStore.listen(() => {
calledTimes++
})
testStore.action('change_state', (state, data) => Object.assign({}, state, {
propA: 'C',
}))
testStore.dispatch('change_state', {})
testStore.dispatch('change_state', {})
testStore.dispatch('change_state', {})
assert.equal(calledTimes, 4)
})
it('called with new state', () => {
let state = 0
testStore.listen((data) => {
state = data
})
testStore.action('change_state', (state, data) => Object.assign({}, state, {
propA: 'C',
}))
testStore.dispatch('change_state', {})
assert.notEqual(defaultData.propA, state.propA)
assert.equal(state.propA, 'C')
})
it('called with part of the state', () => {
let state = 0
testStore.listen([state => state.lvl1.lvl2.lvl3], (lvl3) => {
state = lvl3
})
testStore.action('change_state', state => state.lvl1.lvl2.lvl3, state => Object.assign({}, state, {
a: 11,
}))
testStore.dispatch('change_state', {})
assert.equal(state.a, 11)
assert.equal(state.b, 6)
})
it('only called when state changes', () => {
let calledTimesGlobalState = 0
let calledTimesLocalState = 0
testStore.listen([state => state.lvl1.lvl2.lvl3, state => state.lvl1, state => state], (lvl3, lvl1, state) => {
calledTimesGlobalState++
})
testStore.listen([state => state.lvl1.lvl2.lvl3, state => state.lvl1], (lvl3, lvl1) => {
calledTimesLocalState++
})
assert.equal(calledTimesGlobalState, 1)
assert.equal(calledTimesLocalState, 1)
testStore.action('change_state', state => state, state => Object.assign({}, state, {
propA: 'B',
}))
testStore.dispatch('change_state', {})
assert.equal(calledTimesGlobalState, 2)
assert.equal(calledTimesLocalState, 1)
})
it('unsubscribe', () => {
let calledTimes = 0
const unsubscribe = testStore.listen((state) => {
calledTimes++
})
assert.equal(calledTimes, 1)
testStore.action('change_state', state => state, state => Object.assign({}, state, {
propA: 'B',
}))
testStore.dispatch('change_state', {})
assert.equal(calledTimes, 2)
testStore.unsubscribe(unsubscribe)
testStore.dispatch('change_state', {})
assert.equal(calledTimes, 2)
})
it('call when child gets replaced', () => {
let calledTimes = 0
let aProp
const unsubscribe = testStore.listen([state => state.lvl1.a], (a) => {
calledTimes++
aProp = a
})
testStore.action('change_child_obj', state => Object.assign({}, state, {
lvl1: {
a: 'a',
b: 'b',
arr: [1, 2, 3],
},
}))
testStore.dispatch('change_child_obj')
assert.equal(calledTimes, 2)
assert.equal(aProp, 'a')
assert.equal(testStore.getState().lvl1.a, 'a')
})
})
describe('#dispatch', () => {
it('dispatch action and change state', () => {
const initialState = testStore.getState()
testStore.action('change_state', (state, data) => Object.assign({}, state, {
propA: 'C',
}))
testStore.dispatch('change_state', {})
const newState = testStore.getState()
assert.notEqual(initialState, newState)
assert.notEqual(initialState.propA, newState.propA)
testStore.dispatch('change_state', {})
const newState2 = testStore.getState()
assert.notEqual(newState, newState2)
assert.equal(newState.propA, newState2.propA) // same Value
})
it('pass parameters', () => {
const initialState = testStore.getState()
testStore.action('change_propA', (state, data) => Object.assign({}, state, {
propA: data,
}))
testStore.dispatch('change_propA', 'B')
const newState = testStore.getState()
assert.equal(newState.propA, 'B')
testStore.dispatch('change_propA', 'C')
assert.equal(testStore.getState().propA, 'C')
assert.equal(newState.propA, 'B')
})
it('pass object', () => {
const initialState = testStore.getState()
testStore.action('change_propA_to_obj', (state, data) => Object.assign({}, state, {
propA: object,
}))
const object = {
A: '2',
B: 'c',
}
testStore.dispatch('change_propA_to_obj', object)
const newState = testStore.getState()
assert.equal(newState.propA, object)
})
})
describe('#action', () => {
it('change array element', () => {
const initialState = testStore.getState()
testStore.action('change_array_element', (state, data) => Object.assign({}, state, {
lvl1: Object.assign({}, state.lvl1, {
t: 1,
arr: state.lvl1.arr.map((el, index) => {
if (index === data) {
return data
}
return el
}),
}),
}))
testStore.dispatch('change_array_element', 2)
assert.equal(testStore.getState().lvl1.arr[2], 2)
testStore.dispatch('change_array_element', 1)
assert.equal(testStore.getState().lvl1.arr[1], 1)
})
it('use state filters to change array element', () => {
const initialState = testStore.getState()
testStore.action('change_array_element_using_filter', state => state.lvl1.arr, (arr, data) => arr.map((el, index) => {
if (index === data) {
return data
}
return el
}))
testStore.dispatch('change_array_element_using_filter', 2)
assert.equal(testStore.getState().lvl1.arr[2], 2)
testStore.dispatch('change_array_element_using_filter', 1)
assert.equal(testStore.getState().lvl1.arr[1], 1)
})
it('use state filters to change nested object', () => {
const initialState = testStore.getState()
testStore.action('change_nested_object_using_filter', state => state.lvl1.lvl2.lvl3, (lvl3, data) => Object.assign({}, lvl3, {
c: 'C added',
}))
testStore.dispatch('change_nested_object_using_filter')
assert.equal(testStore.getState().lvl1.lvl2.lvl3.c, 'C added')
})
it('remove object from array', () => {
assert.isDefined(testStore.getState().lvl1.objArr[1])
testStore.action('remove_object_from_array', state => state.lvl1.objArr, (objArr, data) => objArr.filter((el, index) =>
index === 1,
))
testStore.dispatch('remove_object_from_array')
assert.isUndefined(testStore.getState().lvl1.objArr[1])
})
it('remove lvl2 object ', () => {
assert.isDefined(testStore.getState().lvl1.lvl2)
testStore.action('remove_object', state => state.lvl1, (lvl1, data) => {
const obj = Object.assign({}, lvl1)
delete obj.lvl2
return obj
})
testStore.dispatch('remove_object')
assert.isUndefined(testStore.getState().lvl1.lvl2)
})
it('add object', () => {
assert.isUndefined(testStore.getState().newProp)
testStore.action('add_object', state => state, (state, data) => Object.assign({}, state, {
newProp: 'yea',
}))
testStore.dispatch('add_object')
assert.isDefined(testStore.getState().newProp)
assert.equal(testStore.getState().newProp, 'yea')
})
it('change primitive propery using selector', () => {
const oldState = testStore.getState()
testStore.action('change_prop', state => state.propA, propA => 'B')
testStore.dispatch('change_prop')
assert.equal(oldState.propA, 'A')
assert.equal(testStore.getState().propA, 'B')
})
it('change child object', () => {
const oldState = testStore.getState()
testStore.action('change_child_obj', state => Object.assign({}, state, {
lvl1: {
a: 'a',
b: 'b',
arr: [1, 2, 3],
},
}))
testStore.dispatch('change_child_obj')
assert.equal(oldState.lvl1.a, 1)
assert.equal(testStore.getState().lvl1.a, 'a')
})
})
describe('cross module communication', () => {
it('communicate between stores', () => {
const books = storeManager.createStore('books', [{
title: 'Don`t make me think',
author: 'id1',
uid: '321312',
}, {
title: 'Loriot`s Dramatische Werke',
author: 'id2',
uid: '1232133',
}])
const authors = storeManager.createStore('authors', {
selected: 'id2',
list: {
id1: {
name: 'Steve Krug',
},
id2: {
name: 'Loriot',
},
},
})
authors.action('change_name', state => state.list, (state, data) => Object.assign({}, state, {
[data.id]: {
name: data.name,
},
}))
authors.action('change_selected', (state, data) => Object.assign({}, state, {
selected: data.selected,
}))
books.action('change_title', (state, data) => state.map((el, i) => {
if (el.uid === data.uid) {
return Object.assign({}, el, {
title: data.title,
})
}
return el
}))
const getAuthorList = () => authors.getState().list
books.listen([state => state, getAuthorList], (state, authors) => {
console.group('render')
for (book of state) {
console.log(`title:%c ${book.title}`, 'color: blue')
console.log(`author:%c ${authors[book.author].name}`, 'color: lightblue')
}
console.groupEnd()
})
authors.dispatch('change_name', {
id: 'id1',
name: 'Steve',
})
books.dispatch('change_title', {
uid: '321312',
title: 'Make me think!',
})
authors.dispatch('change_selected', {
selected: 'id1',
})
})
})
})
module.exports = {}
})

103
vendor/state/test/index.html vendored Normal file
View file

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cow tests</title>
<script src="/js/require.js" charset="utf-8"></script>
</head>
<body>
<div class="books">
<h1>Books</h1>
<div id="container">
</div>
</div>
<script>
requirejs.config({
baseUrl: '/vendor/state/',
});
let books, authors
require(['State'], function(storeManager) {
books = storeManager.createStore('books', [{
title: 'Don`t make me think',
author: 'id1',
uid: '321312',
}, {
title: 'Loriot`s Dramatische Werke',
author: 'id2',
uid: '1232133',
}])
authors = storeManager.createStore('authors', {
selected: 'id2',
list: {
id1: {
name: 'Steve Krug',
},
id2: {
name: 'Loriot',
},
},
})
authors.action('change_name', state => state.list, (state, data) => {
return Object.assign({}, state, {
[data.id]: {
name: data.name,
},
})
})
authors.action('change_selected', (state, data) => {
return Object.assign({}, state, {
selected: data.selected,
})
})
books.action('change_title', (state, data) => {
return state.map((el, i) => {
if (el.uid === data.uid) {
return Object.assign({}, el, {
title: data.title,
})
}
return el
})
})
const getAuthorList = () => authors.getState().list
books.listen([state => state, getAuthorList], (state, authors) => {
console.group('render')
for (book of state) {
console.log(`title:%c ${book.title}`, 'color: blue')
console.log(`author:%c ${authors[book.author].name}`, 'color: lightblue')
}
console.groupEnd()
let html = '<ul>'
for (book of state) {
html += `<li><b>${book.title}</b> - <small>${authors[book.author].name}</small></li>`
}
html += '</ul>'
document.getElementById("container").innerHTML = html
})
authors.dispatch('change_name', {
id: 'id1',
name: 'Steve',
})
books.dispatch('change_title', {
uid: '321312',
title: 'Make me think!',
})
authors.dispatch('change_selected', {
selected: 'id1',
})
})
</script>
</body>
</html>

46
vendor/state/test/test.html vendored Normal file
View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cow tests</title>
<link rel="stylesheet" media="all" href="../../../../node_modules/mocha/mocha.css">
</head>
<body>
<div id="mocha">
<p><a href=".">Index</a></p>
</div>
<div id="messages"></div>
<div id="fixtures"></div>
<script src="../../../js/require.js" charset="utf-8"></script>
<script>
requirejs.config({
baseUrl: '/vendor/state/',
paths: {
mocha: '/node_modules/mocha/mocha',
chai: '/node_modules/chai/chai'
},
shim: {
'mocha': {
init: function() {
this.mocha.setup('bdd');
return this.mocha;
}
}
}
});
require(['mocha'], function(m) {
require(['test/State.test'], function(test) {
mocha.setup('bdd')
mocha.run();
});
});
</script>
</body>
</html>

230
vendor/three.js/CombinedCamera.js vendored Normal file
View file

@ -0,0 +1,230 @@
/**
* @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
*
* A general perpose camera, for setting FOV, Lens Focal Length,
* and switching between perspective and orthographic views easily.
* Use this only if you do not wish to manage
* both a Orthographic and Perspective Camera
*
*/
THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) {
THREE.Camera.call( this );
this.fov = fov;
this.left = - width / 2;
this.right = width / 2;
this.top = height / 2;
this.bottom = - height / 2;
// We could also handle the projectionMatrix internally, but just wanted to test nested camera objects
this.cameraO = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, orthoNear, orthoFar );
this.cameraP = new THREE.PerspectiveCamera( fov, width / height, near, far );
this.zoom = 1;
this.toPerspective();
};
THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype );
THREE.CombinedCamera.prototype.constructor = THREE.CombinedCamera;
THREE.CombinedCamera.prototype.toPerspective = function () {
// Switches to the Perspective Camera
this.near = this.cameraP.near;
this.far = this.cameraP.far;
this.cameraP.fov = this.fov / this.zoom ;
this.cameraP.updateProjectionMatrix();
this.projectionMatrix = this.cameraP.projectionMatrix;
this.inPerspectiveMode = true;
this.inOrthographicMode = false;
};
THREE.CombinedCamera.prototype.toOrthographic = function () {
// Switches to the Orthographic camera estimating viewport from Perspective
var fov = this.fov;
var aspect = this.cameraP.aspect;
var near = this.cameraP.near;
var far = this.cameraP.far;
// The size that we set is the mid plane of the viewing frustum
var hyperfocus = ( near + far ) / 2;
var halfHeight = Math.tan( fov * Math.PI / 180 / 2 ) * hyperfocus;
var halfWidth = halfHeight * aspect;
halfHeight /= this.zoom;
halfWidth /= this.zoom;
this.cameraO.left = - halfWidth;
this.cameraO.right = halfWidth;
this.cameraO.top = halfHeight;
this.cameraO.bottom = - halfHeight;
// this.cameraO.left = -farHalfWidth;
// this.cameraO.right = farHalfWidth;
// this.cameraO.top = farHalfHeight;
// this.cameraO.bottom = -farHalfHeight;
// this.cameraO.left = this.left / this.zoom;
// this.cameraO.right = this.right / this.zoom;
// this.cameraO.top = this.top / this.zoom;
// this.cameraO.bottom = this.bottom / this.zoom;
this.cameraO.updateProjectionMatrix();
this.near = this.cameraO.near;
this.far = this.cameraO.far;
this.projectionMatrix = this.cameraO.projectionMatrix;
this.inPerspectiveMode = false;
this.inOrthographicMode = true;
};
THREE.CombinedCamera.prototype.setSize = function( width, height ) {
this.cameraP.aspect = width / height;
this.left = - width / 2;
this.right = width / 2;
this.top = height / 2;
this.bottom = - height / 2;
};
THREE.CombinedCamera.prototype.setFov = function( fov ) {
this.fov = fov;
if ( this.inPerspectiveMode ) {
this.toPerspective();
} else {
this.toOrthographic();
}
};
// For maintaining similar API with PerspectiveCamera
THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {
if ( this.inPerspectiveMode ) {
this.toPerspective();
} else {
this.toPerspective();
this.toOrthographic();
}
};
/*
* Uses Focal Length (in mm) to estimate and set FOV
* 35mm (full frame) camera is used if frame size is not specified;
* Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
*/
THREE.CombinedCamera.prototype.setLens = function ( focalLength, filmGauge ) {
if ( filmGauge === undefined ) filmGauge = 35;
var vExtentSlope = 0.5 * filmGauge /
( focalLength * Math.max( this.cameraP.aspect, 1 ) );
var fov = THREE.Math.RAD2DEG * 2 * Math.atan( vExtentSlope );
this.setFov( fov );
return fov;
};
THREE.CombinedCamera.prototype.setZoom = function( zoom ) {
this.zoom = zoom;
if ( this.inPerspectiveMode ) {
this.toPerspective();
} else {
this.toOrthographic();
}
};
THREE.CombinedCamera.prototype.toFrontView = function() {
this.rotation.x = 0;
this.rotation.y = 0;
this.rotation.z = 0;
// should we be modifing the matrix instead?
};
THREE.CombinedCamera.prototype.toBackView = function() {
this.rotation.x = 0;
this.rotation.y = Math.PI;
this.rotation.z = 0;
};
THREE.CombinedCamera.prototype.toLeftView = function() {
this.rotation.x = 0;
this.rotation.y = - Math.PI / 2;
this.rotation.z = 0;
};
THREE.CombinedCamera.prototype.toRightView = function() {
this.rotation.x = 0;
this.rotation.y = Math.PI / 2;
this.rotation.z = 0;
};
THREE.CombinedCamera.prototype.toTopView = function() {
this.rotation.x = - Math.PI / 2;
this.rotation.y = 0;
this.rotation.z = 0;
};
THREE.CombinedCamera.prototype.toBottomView = function() {
this.rotation.x = Math.PI / 2;
this.rotation.y = 0;
this.rotation.z = 0;
};

59
vendor/three.js/Detector.js vendored Normal file
View file

@ -0,0 +1,59 @@
/**
* @author alteredq / http://alteredqualia.com/
* @author mr.doob / http://mrdoob.com/
*/
var Detector = {
canvas: !! window.CanvasRenderingContext2D,
webgl: ( function () { try { var canvas = document.createElement( 'canvas' ); return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); } catch( e ) { return false; } } )(),
workers: !! window.Worker,
fileapi: window.File && window.FileReader && window.FileList && window.Blob,
getWebGLErrorMessage: function () {
var element = document.createElement( 'div' );
element.id = 'webgl-error-message';
element.style.fontFamily = 'monospace';
element.style.fontSize = '13px';
element.style.fontWeight = 'normal';
element.style.textAlign = 'center';
element.style.background = '#fff';
element.style.color = '#000';
element.style.padding = '1.5em';
element.style.width = '400px';
element.style.margin = '5em auto 0';
if ( ! this.webgl ) {
element.innerHTML = window.WebGLRenderingContext ? [
'Your graphics card does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br />',
'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'
].join( '\n' ) : [
'Your browser does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">WebGL</a>.<br/>',
'Find out how to get it <a href="http://get.webgl.org/" style="color:#000">here</a>.'
].join( '\n' );
}
return element;
},
addGetWebGLMessage: function ( parameters ) {
var parent, id, element;
parameters = parameters || {};
parent = parameters.parent !== undefined ? parameters.parent : document.body;
id = parameters.id !== undefined ? parameters.id : 'oldie';
element = Detector.getWebGLErrorMessage();
element.id = id;
parent.appendChild( element );
}
};

1035
vendor/three.js/OrbitControls.js vendored Normal file

File diff suppressed because it is too large Load diff

6
vendor/three.js/Stats.js vendored Normal file
View file

@ -0,0 +1,6 @@
// stats.js - http://github.com/mrdoob/stats.js
var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";
i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div");
k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=
"block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:11,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=
a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};

41763
vendor/three.js/Three.js vendored Normal file

File diff suppressed because one or more lines are too long

599
vendor/three.js/TrackballControls.js vendored Normal file
View file

@ -0,0 +1,599 @@
/**
* @author Eberhard Graether / http://egraether.com/
* @author Mark Lundin / http://mark-lundin.com
*/
THREE.TrackballControls = function ( object, domElement ) {
var _this = this;
var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM: 4, TOUCH_PAN: 5 };
this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document;
// API
this.enabled = true;
this.screen = { left: 0, top: 0, width: 0, height: 0 };
this.rotateSpeed = 1.0;
this.zoomSpeed = 1.2;
this.panSpeed = 0.3;
this.noRotate = false;
this.noZoom = false;
this.noPan = false;
this.noRoll = false;
this.staticMoving = false;
this.dynamicDampingFactor = 0.2;
this.minDistance = 0;
this.maxDistance = Infinity;
this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
// internals
this.target = new THREE.Vector3();
var EPS = 0.000001;
var lastPosition = new THREE.Vector3();
var _state = STATE.NONE,
_prevState = STATE.NONE,
_eye = new THREE.Vector3(),
_rotateStart = new THREE.Vector3(),
_rotateEnd = new THREE.Vector3(),
_zoomStart = new THREE.Vector2(),
_zoomEnd = new THREE.Vector2(),
_touchZoomDistanceStart = 0,
_touchZoomDistanceEnd = 0,
_panStart = new THREE.Vector2(),
_panEnd = new THREE.Vector2();
// for reset
this.target0 = this.target.clone();
this.position0 = this.object.position.clone();
this.up0 = this.object.up.clone();
// events
var changeEvent = { type: 'change' };
var startEvent = { type: 'start'};
var endEvent = { type: 'end'};
// methods
this.handleResize = function () {
if ( this.domElement === document ) {
this.screen.left = 0;
this.screen.top = 0;
this.screen.width = window.innerWidth;
this.screen.height = window.innerHeight;
} else {
var box = this.domElement.getBoundingClientRect();
// adjustments come from similar code in the jquery offset() function
var d = this.domElement.ownerDocument.documentElement;
this.screen.left = box.left + window.pageXOffset - d.clientLeft;
this.screen.top = box.top + window.pageYOffset - d.clientTop;
this.screen.width = box.width;
this.screen.height = box.height;
}
};
this.handleEvent = function ( event ) {
if ( typeof this[ event.type ] == 'function' ) {
this[ event.type ]( event );
}
};
this.getMouseOnScreen = function ( pageX, pageY, vector ) {
return vector.set(
( pageX - _this.screen.left ) / _this.screen.width,
( pageY - _this.screen.top ) / _this.screen.height
);
};
this.getMouseProjectionOnBall = (function(){
var objectUp = new THREE.Vector3(),
mouseOnBall = new THREE.Vector3();
return function ( pageX, pageY, projection ) {
mouseOnBall.set(
( pageX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5),
( _this.screen.height * 0.5 + _this.screen.top - pageY ) / (_this.screen.height*.5),
0.0
);
var length = mouseOnBall.length();
if ( _this.noRoll ) {
if ( length < Math.SQRT1_2 ) {
mouseOnBall.z = Math.sqrt( 1.0 - length*length );
} else {
mouseOnBall.z = .5 / length;
}
} else if ( length > 1.0 ) {
mouseOnBall.normalize();
} else {
mouseOnBall.z = Math.sqrt( 1.0 - length * length );
}
_eye.copy( _this.object.position ).sub( _this.target );
projection.copy( _this.object.up ).setLength( mouseOnBall.y )
projection.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
projection.add( _eye.setLength( mouseOnBall.z ) );
return projection;
}
}());
this.rotateCamera = (function(){
var axis = new THREE.Vector3(),
quaternion = new THREE.Quaternion();
return function () {
var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
if ( angle ) {
axis.crossVectors( _rotateStart, _rotateEnd ).normalize();
angle *= _this.rotateSpeed;
quaternion.setFromAxisAngle( axis, -angle );
_eye.applyQuaternion( quaternion );
_this.object.up.applyQuaternion( quaternion );
_rotateEnd.applyQuaternion( quaternion );
if ( _this.staticMoving ) {
_rotateStart.copy( _rotateEnd );
} else {
quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
_rotateStart.applyQuaternion( quaternion );
}
}
}
}());
this.zoomCamera = function () {
if ( _state === STATE.TOUCH_ZOOM ) {
var factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
_touchZoomDistanceStart = _touchZoomDistanceEnd;
_eye.multiplyScalar( factor );
} else {
var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
if ( factor !== 1.0 && factor > 0.0 ) {
_eye.multiplyScalar( factor );
if ( _this.staticMoving ) {
_zoomStart.copy( _zoomEnd );
} else {
_zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
}
}
}
};
this.panCamera = (function(){
var mouseChange = new THREE.Vector2(),
objectUp = new THREE.Vector3(),
pan = new THREE.Vector3();
return function () {
mouseChange.copy( _panEnd ).sub( _panStart );
if ( mouseChange.lengthSq() ) {
mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
pan.copy( _eye ).cross( _this.object.up ).setLength( mouseChange.x );
pan.add( objectUp.copy( _this.object.up ).setLength( mouseChange.y ) );
_this.object.position.add( pan );
_this.target.add( pan );
if ( _this.staticMoving ) {
_panStart.copy( _panEnd );
} else {
_panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
}
}
}
}());
this.checkDistances = function () {
if ( !_this.noZoom || !_this.noPan ) {
if ( _eye.lengthSq() > _this.maxDistance * _this.maxDistance ) {
_this.object.position.addVectors( _this.target, _eye.setLength( _this.maxDistance ) );
}
if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
_this.object.position.addVectors( _this.target, _eye.setLength( _this.minDistance ) );
}
}
};
this.update = function () {
_eye.subVectors( _this.object.position, _this.target );
if ( !_this.noRotate ) {
_this.rotateCamera();
}
if ( !_this.noZoom ) {
_this.zoomCamera();
}
if ( !_this.noPan ) {
_this.panCamera();
}
_this.object.position.addVectors( _this.target, _eye );
_this.checkDistances();
_this.object.lookAt( _this.target );
if ( lastPosition.distanceToSquared( _this.object.position ) > EPS ) {
_this.dispatchEvent( changeEvent );
lastPosition.copy( _this.object.position );
}
};
this.reset = function () {
_state = STATE.NONE;
_prevState = STATE.NONE;
_this.target.copy( _this.target0 );
_this.object.position.copy( _this.position0 );
_this.object.up.copy( _this.up0 );
_eye.subVectors( _this.object.position, _this.target );
_this.object.lookAt( _this.target );
_this.dispatchEvent( changeEvent );
lastPosition.copy( _this.object.position );
};
// listeners
function keydown( event ) {
if ( _this.enabled === false ) return;
window.removeEventListener( 'keydown', keydown );
_prevState = _state;
if ( _state !== STATE.NONE ) {
return;
} else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) {
_state = STATE.ROTATE;
} else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) {
_state = STATE.ZOOM;
} else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) {
_state = STATE.PAN;
}
}
function keyup( event ) {
if ( _this.enabled === false ) return;
_state = _prevState;
window.addEventListener( 'keydown', keydown, false );
}
function mousedown( event ) {
if ( _this.enabled === false ) return;
event.preventDefault();
event.stopPropagation();
if ( _state === STATE.NONE ) {
_state = event.button;
}
if ( _state === STATE.ROTATE && !_this.noRotate ) {
_this.getMouseProjectionOnBall( event.pageX, event.pageY, _rotateStart );
_rotateEnd.copy(_rotateStart)
} else if ( _state === STATE.ZOOM && !_this.noZoom ) {
_this.getMouseOnScreen( event.pageX, event.pageY, _zoomStart );
_zoomEnd.copy(_zoomStart);
} else if ( _state === STATE.PAN && !_this.noPan ) {
_this.getMouseOnScreen( event.pageX, event.pageY, _panStart );
_panEnd.copy(_panStart)
}
document.addEventListener( 'mousemove', mousemove, false );
document.addEventListener( 'mouseup', mouseup, false );
_this.dispatchEvent( startEvent );
}
function mousemove( event ) {
if ( _this.enabled === false ) return;
event.preventDefault();
event.stopPropagation();
if ( _state === STATE.ROTATE && !_this.noRotate ) {
_this.getMouseProjectionOnBall( event.pageX, event.pageY, _rotateEnd );
} else if ( _state === STATE.ZOOM && !_this.noZoom ) {
_this.getMouseOnScreen( event.pageX, event.pageY, _zoomEnd );
} else if ( _state === STATE.PAN && !_this.noPan ) {
_this.getMouseOnScreen( event.pageX, event.pageY, _panEnd );
}
}
function mouseup( event ) {
if ( _this.enabled === false ) return;
event.preventDefault();
event.stopPropagation();
_state = STATE.NONE;
document.removeEventListener( 'mousemove', mousemove );
document.removeEventListener( 'mouseup', mouseup );
_this.dispatchEvent( endEvent );
}
function mousewheel( event ) {
if ( _this.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;
_this.dispatchEvent( startEvent );
_this.dispatchEvent( endEvent );
}
function touchstart( event ) {
if ( _this.enabled === false ) return;
switch ( event.touches.length ) {
case 1:
_state = STATE.TOUCH_ROTATE;
_rotateEnd.copy( _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateStart ));
break;
case 2:
_state = STATE.TOUCH_ZOOM;
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 );
break;
case 3:
_state = STATE.TOUCH_PAN;
_panEnd.copy( _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panStart ));
break;
default:
_state = STATE.NONE;
}
_this.dispatchEvent( startEvent );
}
function touchmove( event ) {
if ( _this.enabled === false ) return;
event.preventDefault();
event.stopPropagation();
switch ( event.touches.length ) {
case 1:
_this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateEnd );
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 )
break;
case 3:
_this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panEnd );
break;
default:
_state = STATE.NONE;
}
}
function touchend( event ) {
if ( _this.enabled === false ) return;
switch ( event.touches.length ) {
case 1:
_rotateStart.copy( _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _rotateEnd ));
break;
case 2:
_touchZoomDistanceStart = _touchZoomDistanceEnd = 0;
break;
case 3:
_panStart.copy( _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY, _panEnd ));
break;
}
_state = STATE.NONE;
_this.dispatchEvent( endEvent );
}
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
this.domElement.addEventListener( 'mousedown', mousedown, false );
this.domElement.addEventListener( 'mousewheel', mousewheel, false );
this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
this.domElement.addEventListener( 'touchstart', touchstart, false );
this.domElement.addEventListener( 'touchend', touchend, false );
this.domElement.addEventListener( 'touchmove', touchmove, false );
window.addEventListener( 'keydown', keydown, false );
window.addEventListener( 'keyup', keyup, false );
this.handleResize();
// force an update at start
this.update();
};
THREE.TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );

1138
vendor/three.js/TransformControls.js vendored Normal file

File diff suppressed because it is too large Load diff

69
vendor/threex.dragpancontrols.js vendored Normal file
View file

@ -0,0 +1,69 @@
/** @namespace */
var THREEx = THREEx || {};
THREEx.DragPanControls = function(object, domElement)
{
this._object = object;
this._domElement= domElement || document;
// parameters that you can change after initialisation
this.target = new THREE.Vector3(0, 0, 0);
this.speedX = 0.03;
this.speedY = 0.03;
this.rangeX = -40;
this.rangeY = +40;
// private variables
this._mouseX = 0;
this._mouseY = 0;
var _this = this;
this._$onMouseMove = function(){ _this._onMouseMove.apply(_this, arguments); };
this._$onTouchStart = function(){ _this._onTouchStart.apply(_this, arguments); };
this._$onTouchMove = function(){ _this._onTouchMove.apply(_this, arguments); };
this._domElement.addEventListener( 'mousemove', this._$onMouseMove, false );
this._domElement.addEventListener( 'touchstart', this._$onTouchStart,false );
this._domElement.addEventListener( 'touchmove', this._$onTouchMove, false );
}
THREEx.DragPanControls.prototype.destroy = function()
{
this._domElement.removeEventListener( 'mousemove', this._$onMouseMove, false );
this._domElement.removeEventListener( 'touchstart', this._$onTouchStart,false );
this._domElement.removeEventListener( 'touchmove', this._$onTouchMove, false );
}
THREEx.DragPanControls.prototype.update = function(event)
{
this._object.position.x += ( this._mouseX * this.rangeX - this._object.position.x ) * this.speedX;
this._object.position.y += ( this._mouseY * this.rangeY - this._object.position.y ) * this.speedY;
this._object.lookAt( this.target );
}
THREEx.DragPanControls.prototype._onMouseMove = function(event)
{
this._mouseX = ( event.clientX / window.innerWidth ) - 0.5;
this._mouseY = ( event.clientY / window.innerHeight) - 0.5;
}
THREEx.DragPanControls.prototype._onTouchStart = function(event)
{
if( event.touches.length != 1 ) return;
// no preventDefault to get click event on ios
this._mouseX = ( event.touches[ 0 ].pageX / window.innerWidth ) - 0.5;
this._mouseY = ( event.touches[ 0 ].pageY / window.innerHeight) - 0.5;
}
THREEx.DragPanControls.prototype._onTouchMove = function(event)
{
if( event.touches.length != 1 ) return;
event.preventDefault();
this._mouseX = ( event.touches[ 0 ].pageX / window.innerWidth ) - 0.5;
this._mouseY = ( event.touches[ 0 ].pageY / window.innerHeight) - 0.5;
}

18
vendor/threex/Makefile vendored Normal file
View file

@ -0,0 +1,18 @@
# simple makefile to avoid repeatitive tasks
buildDoc:
docco *.js
monitorDoc: build
(while inotifywait -r -e modify,attrib,create . ; do make build; done)
server:
python -m SimpleHTTPServer
deploy:
# assume there is something to commit
# use "git diff --exit-code HEAD" to know if there is something to commit
# so two lines: one if no commit, one if something to commit
git commit -a -m "New deploy" && git push -f origin HEAD:gh-pages && git reset HEAD~

19
vendor/threex/README.md vendored Normal file
View file

@ -0,0 +1,19 @@
* This should be the root of a git repository but i dunno how to handle submodule
# TODO
* document those
* you write a lot of code but not a lot of doc
* all that could go in learningthreejs
* what about anotated source.
* easy to write.
* how to present it in the blog
* currently anotated source is isnt too embedable
* should it be a blocker ?
* likely not
* make a super simple post for each
* they need example and all
* how to handle this ?
* an examples directory like three.js ?
* why not ?
* how to handle the maturity of it ?
* many arent too finished

70
vendor/threex/THREEx.CelShader.js vendored Normal file
View file

@ -0,0 +1,70 @@
// define namespaces
var THREEx = THREEx || {};
THREEx.ShaderLib = THREEx.ShaderLib || {};
THREEx.UniformsLib = THREEx.UniformsLib || {};
// cel shader from ro.me - http://www.ro.me/tech/cel-shader - Apache License 2.0
THREEx.UniformsLib['cel'] = {
"uDirLightPos" : { type: "v3", value: new THREE.Vector3(1,0,0) },
"uDirLightColor" : { type: "c" , value: new THREE.Color( 0xeeeeee ) },
"uAmbientLightColor" : { type: "c" , value: new THREE.Color( 0x050505 ) },
"uBaseColor" : { type: "c" , value: new THREE.Color( 0xff0000 ) }
};
THREEx.ShaderLib['cel'] = {
vertexShader: [
"varying vec3 vNormal;",
"varying vec3 vRefract;",
"void main() {",
"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
"vec3 nWorld = normalize ( mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal );",
"vNormal = normalize( normalMatrix * normal );",
"vec3 I = mPosition.xyz - cameraPosition;",
"vRefract = refract( normalize( I ), nWorld, 1.02 );",
"gl_Position = projectionMatrix * mvPosition;",
"}"
].join( "\n" ),
fragmentShader: [
"uniform vec3 uBaseColor;",
"uniform vec3 uDirLightPos;",
"uniform vec3 uDirLightColor;",
"uniform vec3 uAmbientLightColor;",
"varying vec3 vNormal;",
"varying vec3 vRefract;",
"void main() {",
"float directionalLightWeighting = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);",
"vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;",
"float intensity = smoothstep( - 0.5, 1.0, pow( length(lightWeighting), 20.0 ) );",
"intensity += length(lightWeighting) * 0.2;",
"float cameraWeighting = dot( normalize( vNormal ), vRefract );",
"intensity += pow( 1.0 - length( cameraWeighting ), 6.0 );",
"intensity = intensity * 0.2 + 0.3;",
"if ( intensity < 0.50 ) {",
"gl_FragColor = vec4( 2.0 * intensity * uBaseColor, 1.0 );",
"} else {",
"gl_FragColor = vec4( 1.0 - 2.0 * ( 1.0 - intensity ) * ( 1.0 - uBaseColor ), 1.0 );",
"}",
"}"
].join( "\n" )
};

View file

@ -0,0 +1,50 @@
/** @namespace */
var THREEx = THREEx || {};
THREEx.DeviceOrientationState = function()
{
// to store the current state
this._state = { x: 0, y: 0, z: 0 };
this._$callback = function(event){ this._onDeviceOrientation(event); }.bind(this);
// bind events
// - spec http://dev.w3.org/geo/api/spec-source-orientation.html
window.addEventListener('deviceorientation', this._$callback);
}
/**
* To stop listening of the keyboard events
*/
THREEx.DeviceOrientationState.prototype.destroy = function()
{
// unbind events
window.removeEventListener('deviceorientation', this._$callback);
}
/**
* to process the keyboard dom event
*/
THREEx.DeviceOrientationState.prototype._onDeviceOrientation = function(event)
{
this._state.x = (!event.alpha ? 0 : event.alpha) * Math.PI / 180;
this._state.y = (!event.beta ? 0 : event.beta ) * Math.PI / 180;
this._state.z = (!event.gamma ? 0 : event.gamma) * Math.PI / 180;
}
THREEx.DeviceOrientationState.prototype.angleX = function()
{
return this._state.x;
}
THREEx.DeviceOrientationState.prototype.angleY = function()
{
return this._state.y;
}
THREEx.DeviceOrientationState.prototype.angleZ = function()
{
return this._state.z;
}

117
vendor/threex/THREEx.FullScreen.js vendored Normal file
View file

@ -0,0 +1,117 @@
// This THREEx helper makes it easy to handle the fullscreen API
// * it hides the prefix for each browser
// * it hides the little discrepencies of the various vendor API
// * at the time of this writing (nov 2011) it is available in
// [firefox nightly](http://blog.pearce.org.nz/2011/11/firefoxs-html-full-screen-api-enabled.html),
// [webkit nightly](http://peter.sh/2011/01/javascript-full-screen-api-navigation-timing-and-repeating-css-gradients/) and
// [chrome stable](http://updates.html5rocks.com/2011/10/Let-Your-Content-Do-the-Talking-Fullscreen-API).
//
// # Code
//
/** @namespace */
var THREEx = THREEx || {};
THREEx.FullScreen = THREEx.FullScreen || {};
/**
* test if it is possible to have fullscreen
*
* @returns {Boolean} true if fullscreen API is available, false otherwise
*/
THREEx.FullScreen.available = function()
{
return this._hasWebkitFullScreen || this._hasMozFullScreen;
}
/**
* test if fullscreen is currently activated
*
* @returns {Boolean} true if fullscreen is currently activated, false otherwise
*/
THREEx.FullScreen.activated = function()
{
if( this._hasWebkitFullScreen ){
return document.webkitIsFullScreen;
}else if( this._hasMozFullScreen ){
return document.mozFullScreen;
}else{
console.assert(false);
}
}
/**
* Request fullscreen on a given element
* @param {DomElement} element to make fullscreen. optional. default to document.body
*/
THREEx.FullScreen.request = function(element)
{
element = element || document.body;
if( this._hasWebkitFullScreen ){
element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}else if( this._hasMozFullScreen ){
element.mozRequestFullScreen();
}else{
console.assert(false);
}
}
/**
* Cancel fullscreen
*/
THREEx.FullScreen.cancel = function()
{
if( this._hasWebkitFullScreen ){
document.webkitCancelFullScreen();
}else if( this._hasMozFullScreen ){
document.mozCancelFullScreen();
}else{
console.assert(false);
}
}
// internal functions to know which fullscreen API implementation is available
THREEx.FullScreen._hasWebkitFullScreen = 'webkitCancelFullScreen' in document ? true : false;
THREEx.FullScreen._hasMozFullScreen = 'mozCancelFullScreen' in document ? true : false;
/**
* Bind a key to renderer screenshot
*/
THREEx.FullScreen.bindKey = function(opts){
opts = opts || {};
var charCode = opts.charCode || 'f'.charCodeAt(0);
var dblclick = opts.dblclick !== undefined ? opts.dblclick : false;
var element = opts.element
var toggle = function(){
if( THREEx.FullScreen.activated() ){
THREEx.FullScreen.cancel();
}else{
THREEx.FullScreen.request(element);
}
}
// callback to handle keypress
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
var onKeyPress = __bind(function(event){
// return now if the KeyPress isnt for the proper charCode
if( event.which !== charCode ) return;
// toggle fullscreen
toggle();
}, this);
// listen to keypress
// NOTE: for firefox it seems mandatory to listen to document directly
document.addEventListener('keypress', onKeyPress, false);
// listen to dblclick
dblclick && document.addEventListener('dblclick', toggle, false);
return {
unbind : function(){
document.removeEventListener('keypress', onKeyPress, false);
dblclick && document.removeEventListener('dblclick', toggle, false);
}
};
}

139
vendor/threex/THREEx.GeometryUtils.js vendored Normal file
View file

@ -0,0 +1,139 @@
// This THREEx helper provide various basic functions for ```THREE.Geometry```.
// It is able to scale, translate, center a geometry. Other functions may be
// added soon.
// The API is chained for convenience.
//
// ## Scale
// To make the geometry twice larger in ```y```
// ```
// var scale = new THREE.Vector3(1,2,1);
// THREEx.GeometryUtils.scale(geometry, scale);
// ```
// ## Translate
// To make the geometry move 100 further in ```x```
// ```
// var translation = new THREE.Vector3(100,0,0);
// THREEx.GeometryUtils.translate(geometry, translation);
// ```
// ## Center
// To center the geometry on its middle point
// ```
// THREEx.GeometryUtils.center(geometry);
// ```
// ## middlePoint
// To compute the middle point of a geometry
// ```
// THREEx.GeometryUtils.middlePoint(geometry);
// ```
// # Code
//
/** @namespace */
var THREEx = THREEx || {};
THREEx.GeometryUtils = THREEx.GeometryUtils || {};
// TODO
// - chained API
// - possibility a matrix to reduce computation ?
/**
* Change the scale of a geometry
*
* @params {THREE.Geometry} geometry the geometry to compute on
* @params {THREE.Vector3} scale the middlepoint of the geometry
*/
THREEx.GeometryUtils.scale = function(geometry, scale)
{
// change all geometry.vertices
for(var i = 0; i < geometry.vertices.length; i++) {
var vertex = geometry.vertices[i];
vertex.position.multiplySelf(scale);
}
// mark the vertices as dirty
geometry.__dirtyVertices = true;
// return this, to get chained API
return this;
}
THREEx.GeometryUtils.translate = function(geometry, delta)
{
// change all geometry.vertices
for(var i = 0; i < geometry.vertices.length; i++) {
var vertex = geometry.vertices[i];
vertex.position.addSelf(delta);
}
// mark the vertices as dirty
geometry.__dirtyVertices = true;
// return this, to get chained API
return this;
}
/**
* Compute the "middlePoint" aka the point at the middle of the boundingBox
*
* @params {THREE.Geometry} the geometry to compute on
* @returns {THREE.Vector3} the middlepoint of the geometry
*/
THREEx.GeometryUtils.middlePoint = function(geometry)
{
// compute bounding box
geometry.computeBoundingBox();
// compute middle
var middle = new THREE.Vector3()
middle.x = ( geometry.boundingBox.x[ 1 ] + geometry.boundingBox.x[ 0 ] ) / 2;
middle.y = ( geometry.boundingBox.y[ 1 ] + geometry.boundingBox.y[ 0 ] ) / 2;
middle.z = ( geometry.boundingBox.z[ 1 ] + geometry.boundingBox.z[ 0 ] ) / 2;
// return the just computed middle
return middle;
}
/**
* Center the geometry on its middlepoint
*/
THREEx.GeometryUtils.center = function(geometry, noX, noY, noZ)
{
// compute delta
var delta = this.middlePoint(geometry).negate();
if( noX ) delta.x = 0;
if( noY ) delta.y = 0;
if( noZ ) delta.z = 0;
return this.translate(geometry, delta)
}
/**
* Initial version of attachement
* - geometry2 is the one which is moved
* - TODO make something more flexible... especially on the attachement config
*/
THREEx.GeometryUtils.attachRightLeft = function(geometry1, geometry2, delta)
{
if( delta === undefined ) delta = 0;
// compute bounding box
geometry1.computeBoundingBox();
geometry2.computeBoundingBox();
var maxX1 = geometry1.boundingBox.x[ 1 ]
var minX2 = geometry2.boundingBox.x[ 0 ];
var vector = new THREE.Vector3();
vector.x = maxX1+ (-minX2) + delta;
this.translate(geometry2, vector);
return this;
}

54
vendor/threex/THREEx.GeometryWobble.js vendored Normal file
View file

@ -0,0 +1,54 @@
var THREEx = THREEx || {};
THREEx.GeometryWobble = {};
// Geometry Wobble
// based on paul lewis / areotwist - http://lab.aerotwist.com/webgl/undulating-monkey/
THREEx.GeometryWobble.init = function(geometry)
{
for(var i = 0; i < geometry.vertices.length; i++){
var vertex = geometry.vertices[i];
vertex.originalPosition = vertex.position.clone();
vertex.dirVector = vertex.position.clone().normalize();
}
geometry.dynamic = true;
this.cpuAxis(geometry, 'y')
}
THREEx.GeometryWobble.cpuAxis = function(geometry, type, factor)
{
if( type === undefined ) type = 'x';
if( factor === undefined ) factor = 0.2;
for(var i = 0; i < geometry.vertices.length; i++) {
var vertex = geometry.vertices[i];
// Note: may need more axis ?
if( type === 'x' ) vertex.axisValue = vertex.originalPosition.x * factor;
else if( type === 'y' ) vertex.axisValue = vertex.originalPosition.y * factor;
else if( type === 'z' ) vertex.axisValue = vertex.originalPosition.z * factor;
else console.assert(false);
}
}
THREEx.GeometryWobble.Animate = function(geometry, phase, magnitude)
{
if( phase === undefined ) phase = 0;
if( magnitude === undefined ) magnitude = 0.2;
if( typeof magnitude === "number" ) magnitude = new THREE.Vector3(magnitude, magnitude, magnitude)
for(var i = 0; i < geometry.vertices.length; i++) {
var vertex = geometry.vertices[i];
var vertexPhase = Math.cos(phase + vertex.axisValue);
vertex.position.x = vertex.originalPosition.x + vertexPhase * vertex.dirVector.x * magnitude.x;
vertex.position.y = vertex.originalPosition.y + vertexPhase * vertex.dirVector.y * magnitude.y;
vertex.position.z = vertex.originalPosition.z + vertexPhase * vertex.dirVector.z * magnitude.z;
}
geometry.__dirtyVertices = true;
}

116
vendor/threex/THREEx.KeyboardState.js vendored Normal file
View file

@ -0,0 +1,116 @@
// THREEx.KeyboardState.js keep the current state of the keyboard.
// It is possible to query it at any time. No need of an event.
// This is particularly convenient in loop driven case, like in
// 3D demos or games.
//
// # Usage
//
// **Step 1**: Create the object
//
// ```var keyboard = new THREEx.KeyboardState();```
//
// **Step 2**: Query the keyboard state
//
// This will return true if shift and A are pressed, false otherwise
//
// ```keyboard.pressed("shift+A")```
//
// **Step 3**: Stop listening to the keyboard
//
// ```keyboard.destroy()```
//
// NOTE: this library may be nice as standaline. independant from three.js
// - rename it keyboardForGame
//
// # Code
//
/** @namespace */
var THREEx = THREEx || {};
/**
* - NOTE: it would be quite easy to push event-driven too
* - microevent.js for events handling
* - in this._onkeyChange, generate a string from the DOM event
* - use this as event name
*/
THREEx.KeyboardState = function()
{
// to store the current state
this.keyCodes = {};
this.modifiers = {};
// create callback to bind/unbind keyboard events
var self = this;
this._onKeyDown = function(event){ self._onKeyChange(event, true); };
this._onKeyUp = function(event){ self._onKeyChange(event, false);};
// bind keyEvents
document.addEventListener("keydown", this._onKeyDown, false);
document.addEventListener("keyup", this._onKeyUp, false);
}
/**
* To stop listening of the keyboard events
*/
THREEx.KeyboardState.prototype.destroy = function()
{
// unbind keyEvents
document.removeEventListener("keydown", this._onKeyDown, false);
document.removeEventListener("keyup", this._onKeyUp, false);
}
THREEx.KeyboardState.MODIFIERS = ['shift', 'ctrl', 'alt', 'meta'];
THREEx.KeyboardState.ALIAS = {
'left' : 37,
'up' : 38,
'right' : 39,
'down' : 40,
'space' : 32,
'pageup' : 33,
'pagedown' : 34,
'tab' : 9
};
/**
* to process the keyboard dom event
*/
THREEx.KeyboardState.prototype._onKeyChange = function(event, pressed)
{
// log to debug
//console.log("onKeyChange", event, pressed, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)
// update this.keyCodes
var keyCode = event.keyCode;
this.keyCodes[keyCode] = pressed;
// update this.modifiers
this.modifiers['shift']= event.shiftKey;
this.modifiers['ctrl'] = event.ctrlKey;
this.modifiers['alt'] = event.altKey;
this.modifiers['meta'] = event.metaKey;
}
/**
* query keyboard state to know if a key is pressed of not
*
* @param {String} keyDesc the description of the key. format : modifiers+key e.g shift+A
* @returns {Boolean} true if the key is pressed, false otherwise
*/
THREEx.KeyboardState.prototype.pressed = function(keyDesc)
{
var keys = keyDesc.split("+");
for(var i = 0; i < keys.length; i++){
var key = keys[i];
var pressed;
if( THREEx.KeyboardState.MODIFIERS.indexOf( key ) !== -1 ){
pressed = this.modifiers[key];
}else if( Object.keys(THREEx.KeyboardState.ALIAS).indexOf( key ) != -1 ){
pressed = this.keyCodes[ THREEx.KeyboardState.ALIAS[key] ];
}else {
pressed = this.keyCodes[key.toUpperCase().charCodeAt(0)]
}
if( !pressed) return false;
};
return true;
}

46
vendor/threex/THREEx.LogoTurtle.js vendored Normal file
View file

@ -0,0 +1,46 @@
/** @namespace */
var THREEx = THREEx || {};
// TODO should those relative polar coord function be INSIDE path already ?
THREEx.LogoTurtle = function()
{
this._penX = 0;
this._penY = 0;
this._angle = 0;
this._vectors = [];
}
THREEx.LogoTurtle.create = function()
{
return new THREEx.LogoTurtle()
}
THREEx.LogoTurtle.prototype.turn = function(rotation)
{
this._angle += rotation;
return this;
}
THREEx.LogoTurtle.prototype.moveTo = function(x, y)
{
this._penX = x * Math.cos(this._angle) - y * Math.sin(this._angle);
this._penY = x * Math.sin(this._angle) + y * Math.cos(this._angle);
this._vectors.push( new THREE.Vector2(this._penX, this._penY) );
return this;
}
THREEx.LogoTurtle.prototype.forward = function(distance)
{
this._penX += Math.cos(this._angle) * distance;
this._penY += Math.sin(this._angle) * distance;
this._vectors.push( new THREE.Vector2(this._penX, this._penY) );
return this;
}
THREEx.LogoTurtle.prototype.points = function()
{
return this._vectors;
}

104
vendor/threex/THREEx.PlasmaShader.js vendored Normal file
View file

@ -0,0 +1,104 @@
// define namespaces
var THREEx = THREEx || {};
THREEx.ShaderLib = THREEx.ShaderLib || {};
THREEx.UniformsLib = THREEx.UniformsLib || {};
THREEx.UniformsLib['plasma'] = {
time : { type : "f", value: 0.0 },
scale : { type : "f", value: 1.0 },
rotation: { type : "f", value: 0.0 },
opacity : { type : "f", value: 1.0 },
c0 : { type : "f", value: 5.0 },
c1 : { type : "f", value: 3.0 },
c2 : { type : "f", value: 11.0 },
c3 : { type : "f", value: 7.0 },
c4 : { type : "f", value: 9.0 },
c5 : { type : "f", value: 3.0 }
};
THREEx.ShaderLib['plasma'] = {
vertexShader: [
"#ifdef GL_ES",
"precision highp float;",
"#endif",
"varying vec2 vUv;",
"void main(){",
"vUv = uv;",
"gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);",
"}"
].join( "\n" ),
fragmentShader: [
"#ifdef GL_ES",
"precision highp float;",
"#endif",
"varying vec2 vUv;",
"uniform float time;",
"uniform float scale;",
"uniform float rotation;",
"uniform float opacity;",
"uniform float c0, c1, c2, c3, c4, c5;",
// todo zoom and rotation of vec2 point
"vec2 rotoZoom(const vec2 point, const float scale, const float rotation){",
"vec2 tmp;",
"tmp.x = point.x * cos(rotation) - point.y * sin(rotation);",
"tmp.y = point.x * sin(rotation) + point.y * cos(rotation);",
"tmp = tmp * scale;",
"return tmp;",
"}",
// based on THREE.Color.setHSV()
// based on Mads Elvheim / Madsy http://code.google.com/p/opengl3-freenode/wiki/ColorSpaceConversions
"vec3 HSVtoRGB(const vec3 color){",
"float h = color.r;",
"float s = color.g;",
"float v = color.b;",
"float i = floor(h * 6.0);",
"float f = (h * 6.0) - i;",
"float p = v * (1.0 - s);",
"float q = v * (1.0 - f * s);",
"float t = v * (1.0 - (1.0 - f) * s);",
"vec3 result;",
"if( i < 1.0 ) result = vec3(v,t,p);",
"else if( i < 2.0 ) result = vec3(q,v,p);",
"else if( i < 3.0 ) result = vec3(p,v,t);",
"else if( i < 4.0 ) result = vec3(p,q,v);",
"else if( i < 5.0 ) result = vec3(t,p,v);",
"else if( i < 6.0 ) result = vec3(v,p,q);",
"else result = vec3(v,t,p);",
"return result;",
"}",
// default value
"#ifndef ROTOZOOM",
"#define ROTOZOOM 1",
"#endif",
"#ifndef USEHSV",
"#define USEHSV 1",
"#endif",
"void main(){",
"vec2 p = -1.0 + 2.0 * vUv;",
"#if ROTOZOOM",
"p = rotoZoom(p, scale, rotation);",
"#endif",
"float cossin1 = cos(p.x*c0+sin(time*1.3)) - sin(p.y*c3-cos(time)) + sin(time);",
"float cossin2 = cos(p.y*c1+cos(c1*time/c4)) * sin(p.x*c4*sin(time)) - cos(time);",
"float cossin3 = cos(p.x*c2+sin(c2*time/c5)) + sin(p.y*c5+cos(time)) + cos(time);",
//"vec3 color = vec3(abs(cossin1*sin(p.x)), cossin2*sin(p.y), cossin3*sin(p.x));",
"vec3 color = vec3(abs(cossin1*sin(p.x)), 0.6 - 0.4* abs(cossin2*sin(p.y)), 0.5 - 0.3*(cossin3*sin(p.x)));",
"#if USEHSV",
"color = HSVtoRGB(color);",
"#endif",
"gl_FragColor = vec4(color, opacity);",
//"gl_FragColor = vec4(cossin1*sin(p.x), cossin2*sin(p.y), cossin3*sin(p.x), opacity);",
"}"
].join( "\n" )
};

62
vendor/threex/THREEx.SkyMap.js vendored Normal file
View file

@ -0,0 +1,62 @@
var THREEx = THREEx || {};
THREEx.SkyMap = {};
THREEx.SkyMap.buildMesh = function(urls, opts)
{
// get parameters
opts = opts || {}
var cubeSize = opts.cubeSize !== undefined ? opts.cubeSize : 100000;
// load the cube textures
var texture = THREE.ImageUtils.loadTextureCube( urls );
// init the cube shadder
var shader = THREE.ShaderUtils.lib["cube"];
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
uniforms['tCube'].texture= textureCube;
var material = new THREE.MeshShaderMaterial({
fragmentShader : shader.fragmentShader,
vertexShader : shader.vertexShader,
uniforms : uniforms
});
// build the geometry
var geometry = new THREE.CubeGeometry( cubeSize, cubeSize, cubeSize, 1, 1, 1, null, true );
// build the skybox Mesh
var mesh = new THREE.Mesh( geometry, material );
return mesh;
}
/**
* Build the urls array for THREEx.SkyMap.buildMesh()
*/
THREEx.SkyMap.UrlsPosx = function(prefix, extension)
{
return [
prefix + "posx" + extension,
prefix + "negx" + extension,
prefix + "posy" + extension,
prefix + "negy" + extension,
prefix + "posz" + extension,
prefix + "negz" + extension
];
return urls;
}
/**
* Build the urls array for THREEx.SkyMap.buildMesh()
*/
THREEx.SkyMap.UrlsPx = function(prefix, extension)
{
return [
prefix + "px" + extension,
prefix + "nx" + extension,
prefix + "py" + extension,
prefix + "ny" + extension,
prefix + "pz" + extension,
prefix + "nz" + extension
];
return urls;
}

49
vendor/threex/THREEx.WindowResize.js vendored Normal file
View file

@ -0,0 +1,49 @@
// This THREEx helper makes it easy to handle window resize.
// It will update renderer and camera when window is resized.
//
// # Usage
//
// **Step 1**: Start updating renderer and camera
//
// ```var windowResize = THREEx.WindowResize(aRenderer, aCamera)```
//
// **Step 2**: Start updating renderer and camera
//
// ```windowResize.stop()```
// # Code
//
/** @namespace */
var THREEx = THREEx || {};
/**
* Update renderer and camera when the window is resized
*
* @param {Object} renderer the renderer to update
* @param {Object} Camera the camera to update
*/
THREEx.WindowResize = function(renderer, camera){
var callback = function(){
// notify the renderer of the size change
renderer.setSize( window.innerWidth, window.innerHeight );
// update the camera
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
// bind the resize event
window.addEventListener('resize', callback, false);
// return .stop() the function to stop watching window resize
return {
/**
* Stop watching window resize
*/
stop : function(){
window.removeEventListener('resize', callback);
}
};
}
THREEx.WindowResize.bind = function(renderer, camera){
return THREEx.WindowResize(renderer, camera);
}

52
vendor/threex/THREEx.glCapability.js vendored Normal file
View file

@ -0,0 +1,52 @@
/**
* Define namespace
*/
if(typeof THREEx === "undefined") var THREEx = {};
/**
* return the capability of a WebGl context
*
* TODO to rewrite
* - heavily wased on webglreport on sourceforge
* - is there other/better properties
* - should i get a more readable output ?
* - another function ?
*
* @param {WebGLRenderingContext} webgl context
* @returns {Object} capabilities
*/
THREEx.glCapability = function(gl)
{
// sanity check - gl context MUST BE WebGLRenderingContext
console.assert(gl instanceof WebGLRenderingContext)
// TODO find better names
var prout = ['VERSION', 'SHADING_LANGUAGE_VERSION', 'VENDOR', 'RENDERER'];
var pixDepth = ['RED_BITS', 'GREEN_BITS', 'BLUE_BITS', 'ALPHA_BITS', 'DEPTH_BITS', 'STENCIL_BITS'];
var slota = ['MAX_RENDERBUFFER_SIZE', 'MAX_COMBINED_TEXTURE_IMAGE_UNITS', 'MAX_CUBE_MAP_TEXTURE_SIZE'
, 'MAX_FRAGMENT_UNIFORM_VECTORS', 'MAX_TEXTURE_IMAGE_UNITS'
, 'MAX_TEXTURE_SIZE', 'MAX_VERTEX_ATTRIBS'
, 'MAX_VERTEX_ATTRIBS', 'MAX_VERTEX_TEXTURE_IMAGE_UNITS'
, 'MAX_VERTEX_UNIFORM_VECTORS'];
var sloti = ['ALIASED_LINE_WIDTH_RANGE', 'ALIASED_POINT_SIZE_RANGE', 'MAX_VIEWPORT_DIMS'];
var info = {};
var collect = function(arr){
arr.forEach(function(parameter){
//console.log('parameter', parameter)
info[parameter] = gl.getParameter(gl[parameter])
})
}
collect(prout);
collect(pixDepth);
collect(slota);
collect(sloti)
// special case to get the extensions
info['SUPPORTED_EXTENSIONS'] = gl.getSupportedExtensions()
//console.log("info");
//console.dir(info)
return info;
}

View file

@ -0,0 +1,38 @@
/**
* Provides requestAnimationFrame/cancelRequestAnimation in a cross browser way.
* from paul irish + jerome etienne
* - http://paulirish.com/2011/requestanimationframe-for-smart-animating/
* - http://notes.jetienne.com/2011/05/18/cancelRequestAnimFrame-for-paul-irish-requestAnimFrame.html
*/
if ( !window.requestAnimationFrame ) {
window.requestAnimationFrame = ( function() {
return window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
return window.setTimeout( callback, 1000 / 60 );
};
} )();
}
if ( !window.cancelRequestAnimationFrame ) {
window.cancelRequestAnimationFrame = ( function() {
return window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
clearTimeout
} )();
}

132
vendor/threex/THREEx.screenshot.js vendored Normal file
View file

@ -0,0 +1,132 @@
/** @namespace */
var THREEx = THREEx || {};
// TODO http://29a.ch/2011/9/11/uploading-from-html5-canvas-to-imgur-data-uri
// able to upload your screenshot without running servers
// forced closure
(function(){
/**
* Take a screenshot of a renderer
* - require WebGLRenderer to have "preserveDrawingBuffer: true" to be set
* - TODO is it possible to check if this variable is set ? if so check it
* and make advice in the console.log
* - maybe with direct access to the gl context...
*
* @param {Object} renderer to use
* @param {String} mimetype of the output image. default to "image/png"
* @param {String} dataUrl of the image
*/
var toDataURL = function(renderer, mimetype)
{
mimetype = mimetype || "image/png";
var dataUrl = renderer.domElement.toDataURL(mimetype);
return dataUrl;
}
/**
* resize an image to another resolution while preserving aspect
*
* @param {String} srcUrl the url of the image to resize
* @param {Number} dstWidth the destination width of the image
* @param {Number} dstHeight the destination height of the image
* @param {Number} callback the callback to notify once completed with callback(newImageUrl)
*/
var _aspectResize = function(srcUrl, dstW, dstH, callback){
// to compute the width/height while keeping aspect
var cpuScaleAspect = function(maxW, maxH, curW, curH){
var ratio = curH / curW;
if( curW >= maxW && ratio <= 1 ){
curW = maxW;
curH = maxW * ratio;
}else if(curH >= maxH){
curH = maxH;
curW = maxH / ratio;
}
return { width: curW, height: curH };
}
// callback once the image is loaded
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
var onLoad = __bind(function(){
// init the canvas
var canvas = document.createElement('canvas');
canvas.width = dstW; canvas.height = dstH;
var ctx = canvas.getContext('2d');
// TODO is this needed
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// scale the image while preserving the aspect
var scaled = cpuScaleAspect(canvas.width, canvas.height, image.width, image.height);
// actually draw the image on canvas
var offsetX = (canvas.width - scaled.width )/2;
var offsetY = (canvas.height - scaled.height)/2;
ctx.drawImage(image, offsetX, offsetY, scaled.width, scaled.height);
// dump the canvas to an URL
var mimetype = "image/png";
var newDataUrl = canvas.toDataURL(mimetype);
// notify the url to the caller
callback && callback(newDataUrl)
}, this);
// Create new Image object
var image = new Image();
image.onload = onLoad;
image.src = srcUrl;
}
// Super cooked function: THREEx.Screenshot.bindKey(renderer)
// and you are done to get screenshot on your demo
/**
* Bind a key to renderer screenshot
*/
var bindKey = function(renderer, opts){
// handle parameters
opts = opts || {};
var charCode = opts.charCode || 'p'.charCodeAt(0);
var width = opts.width;
var height = opts.height;
var callback = opts.callback || function(url){
window.open(url, "name-"+Math.random());
};
// callback to handle keypress
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
var onKeyPress = __bind(function(event){
// return now if the KeyPress isnt for the proper charCode
if( event.which !== charCode ) return;
// get the renderer output
var dataUrl = this.toDataURL(renderer);
if( width === undefined && height === undefined ){
callback( dataUrl )
}else{
// resize it and notify the callback
// * resize == async so if callback is a window open, it triggers the pop blocker
_aspectResize(dataUrl, width, height, callback);
}
}, this);
// listen to keypress
// NOTE: for firefox it seems mandatory to listen to document directly
document.addEventListener('keypress', onKeyPress, false);
return {
unbind : function(){
document.removeEventListener('keypress', onKeyPress, false);
}
};
}
// export it
THREEx.Screenshot = {
toDataURL : toDataURL,
bindKey : bindKey
};
})();

View file

@ -0,0 +1,68 @@
<!DOCTYPE html> <html> <head> <title>THREEx.CelShader.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.CelShader.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>define namespaces</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">ShaderLib</span> <span class="o">=</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">ShaderLib</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">UniformsLib</span> <span class="o">=</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">UniformsLib</span> <span class="o">||</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>cel shader from ro.me - http://www.ro.me/tech/cel-shader - Apache License 2.0</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">THREEx</span><span class="p">.</span><span class="nx">UniformsLib</span><span class="p">[</span><span class="s1">&#39;cel&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;uDirLightPos&quot;</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;v3&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Vector3</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span> <span class="p">},</span>
<span class="s2">&quot;uDirLightColor&quot;</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;c&quot;</span> <span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Color</span><span class="p">(</span> <span class="mh">0xeeeeee</span> <span class="p">)</span> <span class="p">},</span>
<span class="s2">&quot;uAmbientLightColor&quot;</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;c&quot;</span> <span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Color</span><span class="p">(</span> <span class="mh">0x050505</span> <span class="p">)</span> <span class="p">},</span>
<span class="s2">&quot;uBaseColor&quot;</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span><span class="o">:</span> <span class="s2">&quot;c&quot;</span> <span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Color</span><span class="p">(</span> <span class="mh">0xff0000</span> <span class="p">)</span> <span class="p">}</span>
<span class="p">};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">ShaderLib</span><span class="p">[</span><span class="s1">&#39;cel&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">vertexShader</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;varying vec3 vNormal;&quot;</span><span class="p">,</span>
<span class="s2">&quot;varying vec3 vRefract;&quot;</span><span class="p">,</span>
<span class="s2">&quot;void main() {&quot;</span><span class="p">,</span>
<span class="s2">&quot;vec4 mPosition = objectMatrix * vec4( position, 1.0 );&quot;</span><span class="p">,</span>
<span class="s2">&quot;vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );&quot;</span><span class="p">,</span>
<span class="s2">&quot;vec3 nWorld = normalize ( mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal );&quot;</span><span class="p">,</span>
<span class="s2">&quot;vNormal = normalize( normalMatrix * normal );&quot;</span><span class="p">,</span>
<span class="s2">&quot;vec3 I = mPosition.xyz - cameraPosition;&quot;</span><span class="p">,</span>
<span class="s2">&quot;vRefract = refract( normalize( I ), nWorld, 1.02 );&quot;</span><span class="p">,</span>
<span class="s2">&quot;gl_Position = projectionMatrix * mvPosition;&quot;</span><span class="p">,</span>
<span class="s2">&quot;}&quot;</span>
<span class="p">].</span><span class="nx">join</span><span class="p">(</span> <span class="s2">&quot;\n&quot;</span> <span class="p">),</span>
<span class="nx">fragmentShader</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;uniform vec3 uBaseColor;&quot;</span><span class="p">,</span>
<span class="s2">&quot;uniform vec3 uDirLightPos;&quot;</span><span class="p">,</span>
<span class="s2">&quot;uniform vec3 uDirLightColor;&quot;</span><span class="p">,</span>
<span class="s2">&quot;uniform vec3 uAmbientLightColor;&quot;</span><span class="p">,</span>
<span class="s2">&quot;varying vec3 vNormal;&quot;</span><span class="p">,</span>
<span class="s2">&quot;varying vec3 vRefract;&quot;</span><span class="p">,</span>
<span class="s2">&quot;void main() {&quot;</span><span class="p">,</span>
<span class="s2">&quot;float directionalLightWeighting = max( dot( normalize( vNormal ), uDirLightPos ), 0.0);&quot;</span><span class="p">,</span>
<span class="s2">&quot;vec3 lightWeighting = uAmbientLightColor + uDirLightColor * directionalLightWeighting;&quot;</span><span class="p">,</span>
<span class="s2">&quot;float intensity = smoothstep( - 0.5, 1.0, pow( length(lightWeighting), 20.0 ) );&quot;</span><span class="p">,</span>
<span class="s2">&quot;intensity += length(lightWeighting) * 0.2;&quot;</span><span class="p">,</span>
<span class="s2">&quot;float cameraWeighting = dot( normalize( vNormal ), vRefract );&quot;</span><span class="p">,</span>
<span class="s2">&quot;intensity += pow( 1.0 - length( cameraWeighting ), 6.0 );&quot;</span><span class="p">,</span>
<span class="s2">&quot;intensity = intensity * 0.2 + 0.3;&quot;</span><span class="p">,</span>
<span class="s2">&quot;if ( intensity &lt; 0.50 ) {&quot;</span><span class="p">,</span>
<span class="s2">&quot;gl_FragColor = vec4( 2.0 * intensity * uBaseColor, 1.0 );&quot;</span><span class="p">,</span>
<span class="s2">&quot;} else {&quot;</span><span class="p">,</span>
<span class="s2">&quot;gl_FragColor = vec4( 1.0 - 2.0 * ( 1.0 - intensity ) * ( 1.0 - uBaseColor ), 1.0 );&quot;</span><span class="p">,</span>
<span class="s2">&quot;}&quot;</span><span class="p">,</span>
<span class="s2">&quot;}&quot;</span>
<span class="p">].</span><span class="nx">join</span><span class="p">(</span> <span class="s2">&quot;\n&quot;</span> <span class="p">)</span>
<span class="p">};</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,9 @@
<!DOCTYPE html> <html> <head> <title>THREEx.CubeMap.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.CubeMap.html"> THREEx.CubeMap.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.CubeMap.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">Cubemap</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">Cubemap</span><span class="p">.</span><span class="nx">center</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="nx">noX</span><span class="p">,</span> <span class="nx">noY</span><span class="p">,</span> <span class="nx">noZ</span><span class="p">)</span>
<span class="p">{</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,45 @@
<!DOCTYPE html> <html> <head> <title>THREEx.DeviceOrientationState.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.DeviceOrientationState.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/** @namespace */</span>
<span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">DeviceOrientationState</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>to store the current state</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">_state</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">x</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">z</span><span class="o">:</span> <span class="mi">0</span> <span class="p">};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_$callback</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">){</span> <span class="k">this</span><span class="p">.</span><span class="nx">_onDeviceOrientation</span><span class="p">(</span><span class="nx">event</span><span class="p">);</span> <span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>bind events
- spec http://dev.w3.org/geo/api/spec-source-orientation.html</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">&#39;deviceorientation&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_$callback</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * To stop listening of the keyboard events</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">DeviceOrientationState</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">destroy</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>unbind events</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">window</span><span class="p">.</span><span class="nx">removeEventListener</span><span class="p">(</span><span class="s1">&#39;deviceorientation&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_$callback</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * to process the keyboard dom event</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">DeviceOrientationState</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_onDeviceOrientation</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_state</span><span class="p">.</span><span class="nx">x</span> <span class="o">=</span> <span class="p">(</span><span class="o">!</span><span class="nx">event</span><span class="p">.</span><span class="nx">alpha</span> <span class="o">?</span> <span class="mi">0</span> <span class="o">:</span> <span class="nx">event</span><span class="p">.</span><span class="nx">alpha</span><span class="p">)</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span> <span class="o">/</span> <span class="mi">180</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_state</span><span class="p">.</span><span class="nx">y</span> <span class="o">=</span> <span class="p">(</span><span class="o">!</span><span class="nx">event</span><span class="p">.</span><span class="nx">beta</span> <span class="o">?</span> <span class="mi">0</span> <span class="o">:</span> <span class="nx">event</span><span class="p">.</span><span class="nx">beta</span> <span class="p">)</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span> <span class="o">/</span> <span class="mi">180</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_state</span><span class="p">.</span><span class="nx">z</span> <span class="o">=</span> <span class="p">(</span><span class="o">!</span><span class="nx">event</span><span class="p">.</span><span class="nx">gamma</span> <span class="o">?</span> <span class="mi">0</span> <span class="o">:</span> <span class="nx">event</span><span class="p">.</span><span class="nx">gamma</span><span class="p">)</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">PI</span> <span class="o">/</span> <span class="mi">180</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">DeviceOrientationState</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">angleX</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_state</span><span class="p">.</span><span class="nx">x</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">DeviceOrientationState</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">angleY</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_state</span><span class="p">.</span><span class="nx">y</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">DeviceOrientationState</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">angleZ</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_state</span><span class="p">.</span><span class="nx">z</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,68 @@
<!DOCTYPE html> <html> <head> <title>THREEx.FullScreen.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.FullScreen.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>This THREEx helper makes it easy to handle the fullscreen API
* it hides the prefix for each browser
* it hides the little discrepencies of the various vendor API
* at the time of this writing (nov 2011) it is available in
<a href="http://blog.pearce.org.nz/2011/11/firefoxs-html-full-screen-api-enabled.html">firefox nightly</a>,
<a href="http://peter.sh/2011/01/javascript-full-screen-api-navigation-timing-and-repeating-css-gradients/">webkit nightly</a> and
<a href="http://updates.html5rocks.com/2011/10/Let-Your-Content-Do-the-Talking-Fullscreen-API">chrome stable</a>.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <h1>Code</h1> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/** @namespace */</span>
<span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">FullScreen</span> <span class="o">=</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">FullScreen</span> <span class="o">||</span> <span class="p">{};</span>
<span class="cm">/**</span>
<span class="cm"> * test if it is possible to have fullscreen</span>
<span class="cm"> * </span>
<span class="cm"> * @returns {Boolean} true if fullscreen API is available, false otherwise</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">FullScreen</span><span class="p">.</span><span class="nx">available</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hasWebkitFullScreen</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hasMozFullScreen</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * test if fullscreen is currently activated</span>
<span class="cm"> * </span>
<span class="cm"> * @returns {Boolean} true if fullscreen is currently activated, false otherwise</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">FullScreen</span><span class="p">.</span><span class="nx">activated</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hasWebkitFullScreen</span> <span class="p">){</span>
<span class="k">return</span> <span class="nb">document</span><span class="p">.</span><span class="nx">webkitIsFullScreen</span><span class="p">;</span>
<span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hasMozFullScreen</span> <span class="p">){</span>
<span class="k">return</span> <span class="nb">document</span><span class="p">.</span><span class="nx">mozFullScreen</span><span class="p">;</span>
<span class="p">}</span><span class="k">else</span><span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Request fullscreen on a given element</span>
<span class="cm"> * @param {DomElement} element to make fullscreen. optional. default to document.body</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">FullScreen</span><span class="p">.</span><span class="nx">request</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">element</span><span class="p">)</span>
<span class="p">{</span>
<span class="nx">element</span> <span class="o">=</span> <span class="nx">element</span> <span class="o">||</span> <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hasWebkitFullScreen</span> <span class="p">){</span>
<span class="nx">element</span><span class="p">.</span><span class="nx">webkitRequestFullScreen</span><span class="p">();</span>
<span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hasMozFullScreen</span> <span class="p">){</span>
<span class="nx">element</span><span class="p">.</span><span class="nx">mozRequestFullScreen</span><span class="p">();</span>
<span class="p">}</span><span class="k">else</span><span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Cancel fullscreen</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">FullScreen</span><span class="p">.</span><span class="nx">cancel</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hasWebkitFullScreen</span> <span class="p">){</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">webkitCancelFullScreen</span><span class="p">();</span>
<span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="k">this</span><span class="p">.</span><span class="nx">_hasMozFullScreen</span> <span class="p">){</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">mozCancelFullScreen</span><span class="p">();</span>
<span class="p">}</span><span class="k">else</span><span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>internal functions to know which fullscreen API implementation is available</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">THREEx</span><span class="p">.</span><span class="nx">FullScreen</span><span class="p">.</span><span class="nx">_hasWebkitFullScreen</span> <span class="o">=</span> <span class="s1">&#39;webkitCancelFullScreen&#39;</span> <span class="k">in</span> <span class="nb">document</span> <span class="o">?</span> <span class="kc">true</span> <span class="o">:</span> <span class="kc">false</span><span class="p">;</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">FullScreen</span><span class="p">.</span><span class="nx">_hasMozFullScreen</span> <span class="o">=</span> <span class="s1">&#39;mozCancelFullScreen&#39;</span> <span class="k">in</span> <span class="nb">document</span> <span class="o">?</span> <span class="kc">true</span> <span class="o">:</span> <span class="kc">false</span><span class="p">;</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,95 @@
<!DOCTYPE html> <html> <head> <title>THREEx.GeometryUtils.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.GeometryUtils.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>This THREEx helper provide various basic functions for <code>THREE.Geometry</code>.
It is able to scale, translate, center a geometry. Other functions may be
added soon.
The API is chained for convenience.</p>
<h2>Scale</h2>
<p>To make the geometry twice larger in <code>y</code></p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p><code>
var scale = new THREE.Vector3(1,2,1);
THREEx.GeometryUtils.scale(geometry, scale);
</code></p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <h2>Translate</h2>
<p>To make the geometry move 100 further in <code>x</code></p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p><code>
var translation = new THREE.Vector3(100,0,0);
THREEx.GeometryUtils.translate(geometry, translation);
</code></p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <h2>Center</h2>
<p>To center the geometry on its middle point</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p><code>
THREEx.GeometryUtils.center(geometry);
</code></p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <h2>middlePoint</h2>
<p>To compute the middle point of a geometry</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p><code>
THREEx.GeometryUtils.middlePoint(geometry);
</code></p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <h1>Code</h1> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/** @namespace */</span>
<span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryUtils</span> <span class="o">=</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryUtils</span> <span class="o">||</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>TODO
- chained API
- possibility a matrix to reduce computation ?</p> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/**</span>
<span class="cm"> * Change the scale of a geometry</span>
<span class="cm"> * </span>
<span class="cm"> * @params {THREE.Geometry} geometry the geometry to compute on</span>
<span class="cm"> * @params {THREE.Vector3} scale the middlepoint of the geometry</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryUtils</span><span class="p">.</span><span class="nx">scale</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="nx">scale</span><span class="p">)</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>change all geometry.vertices</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">vertex</span> <span class="o">=</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="nx">vertex</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nx">multiplySelf</span><span class="p">(</span><span class="nx">scale</span><span class="p">);</span>
<span class="p">}</span>
</pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>mark the vertices as dirty</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">geometry</span><span class="p">.</span><span class="nx">__dirtyVertices</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>return this, to get chained API </p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryUtils</span><span class="p">.</span><span class="nx">translate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="nx">delta</span><span class="p">)</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>change all geometry.vertices</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">vertex</span> <span class="o">=</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="nx">vertex</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nx">addSelf</span><span class="p">(</span><span class="nx">delta</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>mark the vertices as dirty</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">geometry</span><span class="p">.</span><span class="nx">__dirtyVertices</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>return this, to get chained API </p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Compute the &quot;middlePoint&quot; aka the point at the middle of the boundingBox</span>
<span class="cm"> * </span>
<span class="cm"> * @params {THREE.Geometry} the geometry to compute on</span>
<span class="cm"> * @returns {THREE.Vector3} the middlepoint of the geometry</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryUtils</span><span class="p">.</span><span class="nx">middlePoint</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry</span><span class="p">)</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>compute bounding box</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">geometry</span><span class="p">.</span><span class="nx">computeBoundingBox</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>compute middle</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">middle</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Vector3</span><span class="p">()</span>
<span class="nx">middle</span><span class="p">.</span><span class="nx">x</span> <span class="o">=</span> <span class="p">(</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">boundingBox</span><span class="p">.</span><span class="nx">x</span><span class="p">[</span> <span class="mi">1</span> <span class="p">]</span> <span class="o">+</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">boundingBox</span><span class="p">.</span><span class="nx">x</span><span class="p">[</span> <span class="mi">0</span> <span class="p">]</span> <span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span>
<span class="nx">middle</span><span class="p">.</span><span class="nx">y</span> <span class="o">=</span> <span class="p">(</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">boundingBox</span><span class="p">.</span><span class="nx">y</span><span class="p">[</span> <span class="mi">1</span> <span class="p">]</span> <span class="o">+</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">boundingBox</span><span class="p">.</span><span class="nx">y</span><span class="p">[</span> <span class="mi">0</span> <span class="p">]</span> <span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span>
<span class="nx">middle</span><span class="p">.</span><span class="nx">z</span> <span class="o">=</span> <span class="p">(</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">boundingBox</span><span class="p">.</span><span class="nx">z</span><span class="p">[</span> <span class="mi">1</span> <span class="p">]</span> <span class="o">+</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">boundingBox</span><span class="p">.</span><span class="nx">z</span><span class="p">[</span> <span class="mi">0</span> <span class="p">]</span> <span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>return the just computed middle</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">middle</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Center the geometry on its middlepoint</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryUtils</span><span class="p">.</span><span class="nx">center</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="nx">noX</span><span class="p">,</span> <span class="nx">noY</span><span class="p">,</span> <span class="nx">noZ</span><span class="p">)</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>compute delta</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">delta</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">middlePoint</span><span class="p">(</span><span class="nx">geometry</span><span class="p">).</span><span class="nx">negate</span><span class="p">();</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">noX</span> <span class="p">)</span> <span class="nx">delta</span><span class="p">.</span><span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">noY</span> <span class="p">)</span> <span class="nx">delta</span><span class="p">.</span><span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">noZ</span> <span class="p">)</span> <span class="nx">delta</span><span class="p">.</span><span class="nx">z</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">translate</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="nx">delta</span><span class="p">)</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Initial version of attachement</span>
<span class="cm"> * - geometry2 is the one which is moved</span>
<span class="cm"> * - TODO make something more flexible... especially on the attachement config</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryUtils</span><span class="p">.</span><span class="nx">attachRightLeft</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry1</span><span class="p">,</span> <span class="nx">geometry2</span><span class="p">,</span> <span class="nx">delta</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">delta</span> <span class="o">===</span> <span class="kc">undefined</span> <span class="p">)</span> <span class="nx">delta</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">&#182;</a> </div> <p>compute bounding box</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">geometry1</span><span class="p">.</span><span class="nx">computeBoundingBox</span><span class="p">();</span>
<span class="nx">geometry2</span><span class="p">.</span><span class="nx">computeBoundingBox</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">maxX1</span> <span class="o">=</span> <span class="nx">geometry1</span><span class="p">.</span><span class="nx">boundingBox</span><span class="p">.</span><span class="nx">x</span><span class="p">[</span> <span class="mi">1</span> <span class="p">]</span>
<span class="kd">var</span> <span class="nx">minX2</span> <span class="o">=</span> <span class="nx">geometry2</span><span class="p">.</span><span class="nx">boundingBox</span><span class="p">.</span><span class="nx">x</span><span class="p">[</span> <span class="mi">0</span> <span class="p">];</span>
<span class="kd">var</span> <span class="nx">vector</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Vector3</span><span class="p">();</span>
<span class="nx">vector</span><span class="p">.</span><span class="nx">x</span> <span class="o">=</span> <span class="nx">maxX1</span><span class="o">+</span> <span class="p">(</span><span class="o">-</span><span class="nx">minX2</span><span class="p">)</span> <span class="o">+</span> <span class="nx">delta</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">translate</span><span class="p">(</span><span class="nx">geometry2</span><span class="p">,</span> <span class="nx">vector</span><span class="p">);</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,49 @@
<!DOCTYPE html> <html> <head> <title>THREEx.GeometryWobble.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.GeometryWobble.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryWobble</span> <span class="o">=</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>Geometry Wobble
based on paul lewis / areotwist - http://lab.aerotwist.com/webgl/undulating-monkey/</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryWobble</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
<span class="kd">var</span> <span class="nx">vertex</span> <span class="o">=</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="nx">vertex</span><span class="p">.</span><span class="nx">originalPosition</span> <span class="o">=</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nx">clone</span><span class="p">();</span>
<span class="nx">vertex</span><span class="p">.</span><span class="nx">dirVector</span> <span class="o">=</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nx">clone</span><span class="p">().</span><span class="nx">normalize</span><span class="p">();</span>
<span class="p">}</span>
<span class="nx">geometry</span><span class="p">.</span><span class="nx">dynamic</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">cpuAxis</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="s1">&#39;y&#39;</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryWobble</span><span class="p">.</span><span class="nx">cpuAxis</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="nx">type</span><span class="p">,</span> <span class="nx">factor</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">type</span> <span class="o">===</span> <span class="kc">undefined</span> <span class="p">)</span> <span class="nx">type</span> <span class="o">=</span> <span class="s1">&#39;x&#39;</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">factor</span> <span class="o">===</span> <span class="kc">undefined</span> <span class="p">)</span> <span class="nx">factor</span> <span class="o">=</span> <span class="mf">0.2</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">vertex</span> <span class="o">=</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>Note: may need more axis ?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span> <span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;x&#39;</span> <span class="p">)</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">axisValue</span> <span class="o">=</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">originalPosition</span><span class="p">.</span><span class="nx">x</span> <span class="o">*</span> <span class="nx">factor</span><span class="p">;</span>
<span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;y&#39;</span> <span class="p">)</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">axisValue</span> <span class="o">=</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">originalPosition</span><span class="p">.</span><span class="nx">y</span> <span class="o">*</span> <span class="nx">factor</span><span class="p">;</span>
<span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;z&#39;</span> <span class="p">)</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">axisValue</span> <span class="o">=</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">originalPosition</span><span class="p">.</span><span class="nx">z</span> <span class="o">*</span> <span class="nx">factor</span><span class="p">;</span>
<span class="k">else</span> <span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">GeometryWobble</span><span class="p">.</span><span class="nx">Animate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="nx">phase</span><span class="p">,</span> <span class="nx">magnitude</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">phase</span> <span class="o">===</span> <span class="kc">undefined</span> <span class="p">)</span> <span class="nx">phase</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">magnitude</span> <span class="o">===</span> <span class="kc">undefined</span> <span class="p">)</span> <span class="nx">magnitude</span> <span class="o">=</span> <span class="mf">0.2</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span> <span class="k">typeof</span> <span class="nx">magnitude</span> <span class="o">===</span> <span class="s2">&quot;number&quot;</span> <span class="p">)</span> <span class="nx">magnitude</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Vector3</span><span class="p">(</span><span class="nx">magnitude</span><span class="p">,</span> <span class="nx">magnitude</span><span class="p">,</span> <span class="nx">magnitude</span><span class="p">)</span>
<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">vertex</span> <span class="o">=</span> <span class="nx">geometry</span><span class="p">.</span><span class="nx">vertices</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">vertexPhase</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">cos</span><span class="p">(</span><span class="nx">phase</span> <span class="o">+</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">axisValue</span><span class="p">);</span>
<span class="nx">vertex</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nx">x</span> <span class="o">=</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">originalPosition</span><span class="p">.</span><span class="nx">x</span> <span class="o">+</span> <span class="nx">vertexPhase</span> <span class="o">*</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">dirVector</span><span class="p">.</span><span class="nx">x</span> <span class="o">*</span> <span class="nx">magnitude</span><span class="p">.</span><span class="nx">x</span><span class="p">;</span>
<span class="nx">vertex</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nx">y</span> <span class="o">=</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">originalPosition</span><span class="p">.</span><span class="nx">y</span> <span class="o">+</span> <span class="nx">vertexPhase</span> <span class="o">*</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">dirVector</span><span class="p">.</span><span class="nx">y</span> <span class="o">*</span> <span class="nx">magnitude</span><span class="p">.</span><span class="nx">y</span><span class="p">;</span>
<span class="nx">vertex</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nx">z</span> <span class="o">=</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">originalPosition</span><span class="p">.</span><span class="nx">z</span> <span class="o">+</span> <span class="nx">vertexPhase</span> <span class="o">*</span> <span class="nx">vertex</span><span class="p">.</span><span class="nx">dirVector</span><span class="p">.</span><span class="nx">z</span> <span class="o">*</span> <span class="nx">magnitude</span><span class="p">.</span><span class="nx">z</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">geometry</span><span class="p">.</span><span class="nx">__dirtyVertices</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,99 @@
<!DOCTYPE html> <html> <head> <title>THREEx.KeyboardState.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.KeyboardState.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>THREEx.KeyboardState.js keep the current state of the keyboard.
It is possible to query it at any time. No need of an event.
This is particularly convenient in loop driven case, like in
3D demos or games.</p>
<h1>Usage</h1>
<p><strong>Step 1</strong>: Create the object</p>
<p><code>var keyboard = new THREEx.KeyboardState();</code></p>
<p><strong>Step 2</strong>: Query the keyboard state</p>
<p>This will return true if shift and A are pressed, false otherwise</p>
<p><code>keyboard.pressed("shift+A")</code></p>
<p><strong>Step 3</strong>: Stop listening to the keyboard</p>
<p><code>keyboard.destroy()</code></p>
<p>NOTE: this library may be nice as standaline. independant from three.js
- rename it keyboardForGame</p>
<h1>Code</h1> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/** @namespace */</span>
<span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="cm">/**</span>
<span class="cm"> * - NOTE: it would be quite easy to push event-driven too</span>
<span class="cm"> * - microevent.js for events handling</span>
<span class="cm"> * - in this._onkeyChange, generate a string from the DOM event</span>
<span class="cm"> * - use this as event name</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>to store the current state</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">keyCodes</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">modifiers</span> <span class="o">=</span> <span class="p">{};</span>
</pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>create callback to bind/unbind keyboard events</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">self</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_onKeyDown</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">){</span> <span class="nx">self</span><span class="p">.</span><span class="nx">_onKeyChange</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span> <span class="p">};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_onKeyUp</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">){</span> <span class="nx">self</span><span class="p">.</span><span class="nx">_onKeyChange</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="kc">false</span><span class="p">);};</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>bind keyEvents</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">document</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">&quot;keydown&quot;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_onKeyDown</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">&quot;keyup&quot;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_onKeyUp</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * To stop listening of the keyboard events</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">destroy</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>unbind keyEvents</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">document</span><span class="p">.</span><span class="nx">removeEventListener</span><span class="p">(</span><span class="s2">&quot;keydown&quot;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_onKeyDown</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">removeEventListener</span><span class="p">(</span><span class="s2">&quot;keyup&quot;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_onKeyUp</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span><span class="p">.</span><span class="nx">MODIFIERS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;shift&#39;</span><span class="p">,</span> <span class="s1">&#39;ctrl&#39;</span><span class="p">,</span> <span class="s1">&#39;alt&#39;</span><span class="p">,</span> <span class="s1">&#39;meta&#39;</span><span class="p">];</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span><span class="p">.</span><span class="nx">ALIAS</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">&#39;left&#39;</span> <span class="o">:</span> <span class="mi">37</span><span class="p">,</span>
<span class="s1">&#39;up&#39;</span> <span class="o">:</span> <span class="mi">38</span><span class="p">,</span>
<span class="s1">&#39;right&#39;</span> <span class="o">:</span> <span class="mi">39</span><span class="p">,</span>
<span class="s1">&#39;down&#39;</span> <span class="o">:</span> <span class="mi">40</span><span class="p">,</span>
<span class="s1">&#39;space&#39;</span> <span class="o">:</span> <span class="mi">32</span><span class="p">,</span>
<span class="s1">&#39;pageup&#39;</span> <span class="o">:</span> <span class="mi">33</span><span class="p">,</span>
<span class="s1">&#39;pagedown&#39;</span> <span class="o">:</span> <span class="mi">34</span><span class="p">,</span>
<span class="s1">&#39;tab&#39;</span> <span class="o">:</span> <span class="mi">9</span>
<span class="p">};</span>
<span class="cm">/**</span>
<span class="cm"> * to process the keyboard dom event</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">_onKeyChange</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">pressed</span><span class="p">)</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>log to debug
console.log("onKeyChange", event, pressed, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>update this.keyCodes</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">keyCode</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">keyCodes</span><span class="p">[</span><span class="nx">keyCode</span><span class="p">]</span> <span class="o">=</span> <span class="nx">pressed</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>update this.modifiers</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">modifiers</span><span class="p">[</span><span class="s1">&#39;shift&#39;</span><span class="p">]</span><span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">shiftKey</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">modifiers</span><span class="p">[</span><span class="s1">&#39;ctrl&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">ctrlKey</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">modifiers</span><span class="p">[</span><span class="s1">&#39;alt&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">altKey</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">modifiers</span><span class="p">[</span><span class="s1">&#39;meta&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">metaKey</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * query keyboard state to know if a key is pressed of not</span>
<span class="cm"> *</span>
<span class="cm"> * @param {String} keyDesc the description of the key. format : modifiers+key e.g shift+A</span>
<span class="cm"> * @returns {Boolean} true if the key is pressed, false otherwise</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">pressed</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">keyDesc</span><span class="p">)</span>
<span class="p">{</span>
<span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="nx">keyDesc</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s2">&quot;+&quot;</span><span class="p">);</span>
<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">keys</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
<span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="nx">keys</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">pressed</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span><span class="p">.</span><span class="nx">MODIFIERS</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span> <span class="nx">key</span> <span class="p">)</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span> <span class="p">){</span>
<span class="nx">pressed</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">modifiers</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
<span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span><span class="p">.</span><span class="nx">ALIAS</span><span class="p">).</span><span class="nx">indexOf</span><span class="p">(</span> <span class="nx">key</span> <span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span> <span class="p">){</span>
<span class="nx">pressed</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">keyCodes</span><span class="p">[</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">KeyboardState</span><span class="p">.</span><span class="nx">ALIAS</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="p">];</span>
<span class="p">}</span><span class="k">else</span> <span class="p">{</span>
<span class="nx">pressed</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">keyCodes</span><span class="p">[</span><span class="nx">key</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">().</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="mi">0</span><span class="p">)]</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="nx">pressed</span><span class="p">)</span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html> <html> <head> <title>THREEx.LogoTurtle.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.LogoTurtle.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/** @namespace */</span>
<span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>TODO should those relative polar coord function be INSIDE path already ?</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">THREEx</span><span class="p">.</span><span class="nx">LogoTurtle</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_penX</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_penY</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_angle</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_vectors</span> <span class="o">=</span> <span class="p">[];</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">LogoTurtle</span><span class="p">.</span><span class="nx">create</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">LogoTurtle</span><span class="p">()</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">LogoTurtle</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">turn</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">rotation</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_angle</span> <span class="o">+=</span> <span class="nx">rotation</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">LogoTurtle</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">moveTo</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_penX</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">cos</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_angle</span><span class="p">)</span> <span class="o">-</span> <span class="nx">y</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">sin</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_angle</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_penY</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">sin</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_angle</span><span class="p">)</span> <span class="o">+</span> <span class="nx">y</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">cos</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_angle</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_vectors</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Vector2</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_penX</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_penY</span><span class="p">)</span> <span class="p">);</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">LogoTurtle</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">forward</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">distance</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_penX</span> <span class="o">+=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">cos</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_angle</span><span class="p">)</span> <span class="o">*</span> <span class="nx">distance</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_penY</span> <span class="o">+=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">sin</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_angle</span><span class="p">)</span> <span class="o">*</span> <span class="nx">distance</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_vectors</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Vector2</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">_penX</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">_penY</span><span class="p">)</span> <span class="p">);</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">LogoTurtle</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">points</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_vectors</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,94 @@
<!DOCTYPE html> <html> <head> <title>THREEx.PlasmaShader.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.PlasmaShader.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>define namespaces</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">ShaderLib</span> <span class="o">=</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">ShaderLib</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">UniformsLib</span> <span class="o">=</span> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">UniformsLib</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">UniformsLib</span><span class="p">[</span><span class="s1">&#39;plasma&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">time</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">0.0</span> <span class="p">},</span>
<span class="nx">scale</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">1.0</span> <span class="p">},</span>
<span class="nx">rotation</span><span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">0.0</span> <span class="p">},</span>
<span class="nx">opacity</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">1.0</span> <span class="p">},</span>
<span class="nx">c0</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">5.0</span> <span class="p">},</span>
<span class="nx">c1</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">3.0</span> <span class="p">},</span>
<span class="nx">c2</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">11.0</span> <span class="p">},</span>
<span class="nx">c3</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">7.0</span> <span class="p">},</span>
<span class="nx">c4</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">9.0</span> <span class="p">},</span>
<span class="nx">c5</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">type</span> <span class="o">:</span> <span class="s2">&quot;f&quot;</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mf">3.0</span> <span class="p">}</span>
<span class="p">};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">ShaderLib</span><span class="p">[</span><span class="s1">&#39;plasma&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">vertexShader</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;#ifdef GL_ES&quot;</span><span class="p">,</span>
<span class="s2">&quot;precision highp float;&quot;</span><span class="p">,</span>
<span class="s2">&quot;#endif&quot;</span><span class="p">,</span>
<span class="s2">&quot;varying vec2 vUv;&quot;</span><span class="p">,</span>
<span class="s2">&quot;void main(){&quot;</span><span class="p">,</span>
<span class="s2">&quot;vUv = uv;&quot;</span><span class="p">,</span>
<span class="s2">&quot;gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);&quot;</span><span class="p">,</span>
<span class="s2">&quot;}&quot;</span>
<span class="p">].</span><span class="nx">join</span><span class="p">(</span> <span class="s2">&quot;\n&quot;</span> <span class="p">),</span>
<span class="nx">fragmentShader</span><span class="o">:</span> <span class="p">[</span>
<span class="s2">&quot;#ifdef GL_ES&quot;</span><span class="p">,</span>
<span class="s2">&quot;precision highp float;&quot;</span><span class="p">,</span>
<span class="s2">&quot;#endif&quot;</span><span class="p">,</span>
<span class="s2">&quot;varying vec2 vUv;&quot;</span><span class="p">,</span>
<span class="s2">&quot;uniform float time;&quot;</span><span class="p">,</span>
<span class="s2">&quot;uniform float scale;&quot;</span><span class="p">,</span>
<span class="s2">&quot;uniform float rotation;&quot;</span><span class="p">,</span>
<span class="s2">&quot;uniform float opacity;&quot;</span><span class="p">,</span>
<span class="s2">&quot;uniform float c0, c1, c2, c3, c4, c5;&quot;</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>todo zoom and rotation of vec2 point</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;vec2 rotoZoom(const vec2 point, const float scale, const float rotation){&quot;</span><span class="p">,</span>
<span class="s2">&quot;vec2 tmp;&quot;</span><span class="p">,</span>
<span class="s2">&quot;tmp.x = point.x * cos(rotation) - point.y * sin(rotation);&quot;</span><span class="p">,</span>
<span class="s2">&quot;tmp.y = point.x * sin(rotation) + point.y * cos(rotation);&quot;</span><span class="p">,</span>
<span class="s2">&quot;tmp = tmp * scale;&quot;</span><span class="p">,</span>
<span class="s2">&quot;return tmp;&quot;</span><span class="p">,</span>
<span class="s2">&quot;}&quot;</span><span class="p">,</span>
</pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>based on THREE.Color.setHSV()
based on Mads Elvheim / Madsy http://code.google.com/p/opengl3-freenode/wiki/ColorSpaceConversions</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;vec3 HSVtoRGB(const vec3 color){&quot;</span><span class="p">,</span>
<span class="s2">&quot;float h = color.r;&quot;</span><span class="p">,</span>
<span class="s2">&quot;float s = color.g;&quot;</span><span class="p">,</span>
<span class="s2">&quot;float v = color.b;&quot;</span><span class="p">,</span>
<span class="s2">&quot;float i = floor(h * 6.0);&quot;</span><span class="p">,</span>
<span class="s2">&quot;float f = (h * 6.0) - i;&quot;</span><span class="p">,</span>
<span class="s2">&quot;float p = v * (1.0 - s);&quot;</span><span class="p">,</span>
<span class="s2">&quot;float q = v * (1.0 - f * s);&quot;</span><span class="p">,</span>
<span class="s2">&quot;float t = v * (1.0 - (1.0 - f) * s);&quot;</span><span class="p">,</span>
<span class="s2">&quot;vec3 result;&quot;</span><span class="p">,</span>
<span class="s2">&quot;if( i &lt; 1.0 ) result = vec3(v,t,p);&quot;</span><span class="p">,</span>
<span class="s2">&quot;else if( i &lt; 2.0 ) result = vec3(q,v,p);&quot;</span><span class="p">,</span>
<span class="s2">&quot;else if( i &lt; 3.0 ) result = vec3(p,v,t);&quot;</span><span class="p">,</span>
<span class="s2">&quot;else if( i &lt; 4.0 ) result = vec3(p,q,v);&quot;</span><span class="p">,</span>
<span class="s2">&quot;else if( i &lt; 5.0 ) result = vec3(t,p,v);&quot;</span><span class="p">,</span>
<span class="s2">&quot;else if( i &lt; 6.0 ) result = vec3(v,p,q);&quot;</span><span class="p">,</span>
<span class="s2">&quot;else result = vec3(v,t,p);&quot;</span><span class="p">,</span>
<span class="s2">&quot;return result;&quot;</span><span class="p">,</span>
<span class="s2">&quot;}&quot;</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>default value</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;#ifndef ROTOZOOM&quot;</span><span class="p">,</span>
<span class="s2">&quot;#define ROTOZOOM 1&quot;</span><span class="p">,</span>
<span class="s2">&quot;#endif&quot;</span><span class="p">,</span>
<span class="s2">&quot;#ifndef USEHSV&quot;</span><span class="p">,</span>
<span class="s2">&quot;#define USEHSV 1&quot;</span><span class="p">,</span>
<span class="s2">&quot;#endif&quot;</span><span class="p">,</span>
<span class="s2">&quot;void main(){&quot;</span><span class="p">,</span>
<span class="s2">&quot;vec2 p = -1.0 + 2.0 * vUv;&quot;</span><span class="p">,</span>
<span class="s2">&quot;#if ROTOZOOM&quot;</span><span class="p">,</span>
<span class="s2">&quot;p = rotoZoom(p, scale, rotation);&quot;</span><span class="p">,</span>
<span class="s2">&quot;#endif&quot;</span><span class="p">,</span>
<span class="s2">&quot;float cossin1 = cos(p.x*c0+sin(time*1.3)) - sin(p.y*c3-cos(time)) + sin(time);&quot;</span><span class="p">,</span>
<span class="s2">&quot;float cossin2 = cos(p.y*c1+cos(c1*time/c4)) * sin(p.x*c4*sin(time)) - cos(time);&quot;</span><span class="p">,</span>
<span class="s2">&quot;float cossin3 = cos(p.x*c2+sin(c2*time/c5)) + sin(p.y*c5+cos(time)) + cos(time);&quot;</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>"vec3 color = vec3(abs(cossin1<em>sin(p.x)), cossin2</em>sin(p.y), cossin3*sin(p.x));",</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;vec3 color = vec3(abs(cossin1*sin(p.x)), 0.6 - 0.4* abs(cossin2*sin(p.y)), 0.5 - 0.3*(cossin3*sin(p.x)));&quot;</span><span class="p">,</span>
<span class="s2">&quot;#if USEHSV&quot;</span><span class="p">,</span>
<span class="s2">&quot;color = HSVtoRGB(color);&quot;</span><span class="p">,</span>
<span class="s2">&quot;#endif&quot;</span><span class="p">,</span>
<span class="s2">&quot;gl_FragColor = vec4(color, opacity);&quot;</span><span class="p">,</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>"gl_FragColor = vec4(cossin1<em>sin(p.x), cossin2</em>sin(p.y), cossin3*sin(p.x), opacity);",</p> </td> <td class="code"> <div class="highlight"><pre> <span class="s2">&quot;}&quot;</span>
<span class="p">].</span><span class="nx">join</span><span class="p">(</span> <span class="s2">&quot;\n&quot;</span> <span class="p">)</span>
<span class="p">};</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

51
vendor/threex/docs/THREEx.SkyMap.html vendored Normal file
View file

@ -0,0 +1,51 @@
<!DOCTYPE html> <html> <head> <title>THREEx.SkyMap.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.SkyMap.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">SkyMap</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">SkyMap</span><span class="p">.</span><span class="nx">buildMesh</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">urls</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>get parameters</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">opts</span> <span class="o">=</span> <span class="nx">opts</span> <span class="o">||</span> <span class="p">{}</span>
<span class="kd">var</span> <span class="nx">cubeSize</span> <span class="o">=</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">cubeSize</span> <span class="o">!==</span> <span class="kc">undefined</span> <span class="o">?</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">cubeSize</span> <span class="o">:</span> <span class="mi">100000</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>load the cube textures</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">texture</span> <span class="o">=</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">ImageUtils</span><span class="p">.</span><span class="nx">loadTextureCube</span><span class="p">(</span> <span class="nx">urls</span> <span class="p">);</span>
</pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>init the cube shadder</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">shader</span> <span class="o">=</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">ShaderUtils</span><span class="p">.</span><span class="nx">lib</span><span class="p">[</span><span class="s2">&quot;cube&quot;</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">uniforms</span> <span class="o">=</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">UniformsUtils</span><span class="p">.</span><span class="nx">clone</span><span class="p">(</span> <span class="nx">shader</span><span class="p">.</span><span class="nx">uniforms</span> <span class="p">);</span>
<span class="nx">uniforms</span><span class="p">[</span><span class="s1">&#39;tCube&#39;</span><span class="p">].</span><span class="nx">texture</span><span class="o">=</span> <span class="nx">textureCube</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">material</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">MeshShaderMaterial</span><span class="p">({</span>
<span class="nx">fragmentShader</span> <span class="o">:</span> <span class="nx">shader</span><span class="p">.</span><span class="nx">fragmentShader</span><span class="p">,</span>
<span class="nx">vertexShader</span> <span class="o">:</span> <span class="nx">shader</span><span class="p">.</span><span class="nx">vertexShader</span><span class="p">,</span>
<span class="nx">uniforms</span> <span class="o">:</span> <span class="nx">uniforms</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>build the geometry</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">geometry</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">CubeGeometry</span><span class="p">(</span> <span class="nx">cubeSize</span><span class="p">,</span> <span class="nx">cubeSize</span><span class="p">,</span> <span class="nx">cubeSize</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">true</span> <span class="p">);</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>build the skybox Mesh</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">mesh</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nx">Mesh</span><span class="p">(</span> <span class="nx">geometry</span><span class="p">,</span> <span class="nx">material</span> <span class="p">);</span>
<span class="k">return</span> <span class="nx">mesh</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Build the urls array for THREEx.SkyMap.buildMesh()</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">SkyMap</span><span class="p">.</span><span class="nx">UrlsPosx</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">prefix</span><span class="p">,</span> <span class="nx">extension</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="p">[</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;posx&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;negx&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;posy&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;negy&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;posz&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;negz&quot;</span> <span class="o">+</span> <span class="nx">extension</span>
<span class="p">];</span>
<span class="k">return</span> <span class="nx">urls</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Build the urls array for THREEx.SkyMap.buildMesh()</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">SkyMap</span><span class="p">.</span><span class="nx">UrlsPx</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">prefix</span><span class="p">,</span> <span class="nx">extension</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="p">[</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;px&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;nx&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;py&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;ny&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;pz&quot;</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">,</span>
<span class="nx">prefix</span> <span class="o">+</span> <span class="s2">&quot;nz&quot;</span> <span class="o">+</span> <span class="nx">extension</span>
<span class="p">];</span>
<span class="k">return</span> <span class="nx">urls</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html> <html> <head> <title>THREEx.WindowResize.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.WindowResize.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> <p>This THREEx helper makes it easy to handle window resize.
It will update renderer and camera when window is resized.</p>
<h1>Usage</h1>
<p><strong>Step 1</strong>: Start updating renderer and camera</p>
<p><code>var windowResize = THREEx.WindowResize(aRenderer, aCamera)</code></p>
<p><strong>Step 2</strong>: Start updating renderer and camera</p>
<p><code>windowResize.stop()</code></p>
<h1>Code</h1> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/** @namespace */</span>
<span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span>
<span class="cm">/**</span>
<span class="cm"> * Update renderer and camera when the window is resized</span>
<span class="cm"> * </span>
<span class="cm"> * @param {Object} renderer the renderer to update</span>
<span class="cm"> * @param {Object} Camera the camera to update</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">WindowResize</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">renderer</span><span class="p">,</span> <span class="nx">camera</span><span class="p">){</span>
<span class="kd">var</span> <span class="nx">callback</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>notify the renderer of the size change</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">renderer</span><span class="p">.</span><span class="nx">setSize</span><span class="p">(</span> <span class="nb">window</span><span class="p">.</span><span class="nx">innerWidth</span><span class="p">,</span> <span class="nb">window</span><span class="p">.</span><span class="nx">innerHeight</span> <span class="p">);</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>update the camera</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">camera</span><span class="p">.</span><span class="nx">aspect</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">innerWidth</span> <span class="o">/</span> <span class="nb">window</span><span class="p">.</span><span class="nx">innerHeight</span><span class="p">;</span>
<span class="nx">camera</span><span class="p">.</span><span class="nx">updateProjectionMatrix</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>bind the resize event</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">&#39;resize&#39;</span><span class="p">,</span> <span class="nx">callback</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>return .stop() the function to stop watching window resize</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="p">{</span>
<span class="cm">/**</span>
<span class="cm"> * Stop watching window resize</span>
<span class="cm"> */</span>
<span class="nx">stop</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">removeEventListener</span><span class="p">(</span><span class="s1">&#39;resize&#39;</span><span class="p">,</span> <span class="nx">callback</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,44 @@
<!DOCTYPE html> <html> <head> <title>THREEx.glCapability.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.glCapability.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/**</span>
<span class="cm"> * Define namespace</span>
<span class="cm">*/</span>
<span class="k">if</span><span class="p">(</span><span class="k">typeof</span> <span class="nx">THREEx</span> <span class="o">===</span> <span class="s2">&quot;undefined&quot;</span><span class="p">)</span> <span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="p">{};</span>
<span class="cm">/**</span>
<span class="cm"> * return the capability of a WebGl context</span>
<span class="cm"> *</span>
<span class="cm"> * TODO to rewrite</span>
<span class="cm"> * - heavily wased on webglreport on sourceforge</span>
<span class="cm"> * - is there other/better properties</span>
<span class="cm"> * - should i get a more readable output ?</span>
<span class="cm"> * - another function ?</span>
<span class="cm"> *</span>
<span class="cm"> * @param {WebGLRenderingContext} webgl context</span>
<span class="cm"> * @returns {Object} capabilities</span>
<span class="cm">*/</span>
<span class="nx">THREEx</span><span class="p">.</span><span class="nx">glCapability</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">gl</span><span class="p">)</span>
<span class="p">{</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>sanity check - gl context MUST BE WebGLRenderingContext</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">console</span><span class="p">.</span><span class="nx">assert</span><span class="p">(</span><span class="nx">gl</span> <span class="k">instanceof</span> <span class="nx">WebGLRenderingContext</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>TODO find better names</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">prout</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;VERSION&#39;</span><span class="p">,</span> <span class="s1">&#39;SHADING_LANGUAGE_VERSION&#39;</span><span class="p">,</span> <span class="s1">&#39;VENDOR&#39;</span><span class="p">,</span> <span class="s1">&#39;RENDERER&#39;</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">pixDepth</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;RED_BITS&#39;</span><span class="p">,</span> <span class="s1">&#39;GREEN_BITS&#39;</span><span class="p">,</span> <span class="s1">&#39;BLUE_BITS&#39;</span><span class="p">,</span> <span class="s1">&#39;ALPHA_BITS&#39;</span><span class="p">,</span> <span class="s1">&#39;DEPTH_BITS&#39;</span><span class="p">,</span> <span class="s1">&#39;STENCIL_BITS&#39;</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">slota</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;MAX_RENDERBUFFER_SIZE&#39;</span><span class="p">,</span> <span class="s1">&#39;MAX_COMBINED_TEXTURE_IMAGE_UNITS&#39;</span><span class="p">,</span> <span class="s1">&#39;MAX_CUBE_MAP_TEXTURE_SIZE&#39;</span>
<span class="p">,</span> <span class="s1">&#39;MAX_FRAGMENT_UNIFORM_VECTORS&#39;</span><span class="p">,</span> <span class="s1">&#39;MAX_TEXTURE_IMAGE_UNITS&#39;</span>
<span class="p">,</span> <span class="s1">&#39;MAX_TEXTURE_SIZE&#39;</span><span class="p">,</span> <span class="s1">&#39;MAX_VERTEX_ATTRIBS&#39;</span>
<span class="p">,</span> <span class="s1">&#39;MAX_VERTEX_ATTRIBS&#39;</span><span class="p">,</span> <span class="s1">&#39;MAX_VERTEX_TEXTURE_IMAGE_UNITS&#39;</span>
<span class="p">,</span> <span class="s1">&#39;MAX_VERTEX_UNIFORM_VECTORS&#39;</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">sloti</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;ALIASED_LINE_WIDTH_RANGE&#39;</span><span class="p">,</span> <span class="s1">&#39;ALIASED_POINT_SIZE_RANGE&#39;</span><span class="p">,</span> <span class="s1">&#39;MAX_VIEWPORT_DIMS&#39;</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">info</span> <span class="o">=</span> <span class="p">{};</span>
<span class="kd">var</span> <span class="nx">collect</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">arr</span><span class="p">){</span>
<span class="nx">arr</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">parameter</span><span class="p">){</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>console.log('parameter', parameter)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">info</span><span class="p">[</span><span class="nx">parameter</span><span class="p">]</span> <span class="o">=</span> <span class="nx">gl</span><span class="p">.</span><span class="nx">getParameter</span><span class="p">(</span><span class="nx">gl</span><span class="p">[</span><span class="nx">parameter</span><span class="p">])</span>
<span class="p">})</span>
<span class="p">}</span>
<span class="nx">collect</span><span class="p">(</span><span class="nx">prout</span><span class="p">);</span>
<span class="nx">collect</span><span class="p">(</span><span class="nx">pixDepth</span><span class="p">);</span>
<span class="nx">collect</span><span class="p">(</span><span class="nx">slota</span><span class="p">);</span>
<span class="nx">collect</span><span class="p">(</span><span class="nx">sloti</span><span class="p">)</span>
</pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>special case to get the extensions</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">info</span><span class="p">[</span><span class="s1">&#39;SUPPORTED_EXTENSIONS&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nx">gl</span><span class="p">.</span><span class="nx">getSupportedExtensions</span><span class="p">()</span>
</pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>console.log("info");
console.dir(info)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">return</span> <span class="nx">info</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,40 @@
<!DOCTYPE html> <html> <head> <title>THREEx.requestAnimationFrame.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.requestAnimationFrame.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/**</span>
<span class="cm"> * Provides requestAnimationFrame/cancelRequestAnimation in a cross browser way.</span>
<span class="cm"> * from paul irish + jerome etienne</span>
<span class="cm"> * - http://paulirish.com/2011/requestanimationframe-for-smart-animating/</span>
<span class="cm"> * - http://notes.jetienne.com/2011/05/18/cancelRequestAnimFrame-for-paul-irish-requestAnimFrame.html</span>
<span class="cm"> */</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span><span class="nb">window</span><span class="p">.</span><span class="nx">requestAnimationFrame</span> <span class="p">)</span> <span class="p">{</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">requestAnimationFrame</span> <span class="o">=</span> <span class="p">(</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">window</span><span class="p">.</span><span class="nx">webkitRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">mozRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">oRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">msRequestAnimationFrame</span> <span class="o">||</span>
<span class="kd">function</span><span class="p">(</span> <span class="cm">/* function FrameRequestCallback */</span> <span class="nx">callback</span><span class="p">,</span> <span class="cm">/* DOMElement Element */</span> <span class="nx">element</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">window</span><span class="p">.</span><span class="nx">setTimeout</span><span class="p">(</span> <span class="nx">callback</span><span class="p">,</span> <span class="mi">1000</span> <span class="o">/</span> <span class="mi">60</span> <span class="p">);</span>
<span class="p">};</span>
<span class="p">}</span> <span class="p">)();</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span><span class="nb">window</span><span class="p">.</span><span class="nx">cancelRequestAnimationFrame</span> <span class="p">)</span> <span class="p">{</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">cancelRequestAnimationFrame</span> <span class="o">=</span> <span class="p">(</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">window</span><span class="p">.</span><span class="nx">webkitCancelRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">mozCancelRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">oCancelRequestAnimationFrame</span> <span class="o">||</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">msCancelRequestAnimationFrame</span> <span class="o">||</span>
<span class="nx">clearTimeout</span>
<span class="p">}</span> <span class="p">)();</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View file

@ -0,0 +1,78 @@
<!DOCTYPE html> <html> <head> <title>THREEx.screenshot.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="THREEx.CelShader.html"> THREEx.CelShader.js </a> <a class="source" href="THREEx.DeviceOrientationState.html"> THREEx.DeviceOrientationState.js </a> <a class="source" href="THREEx.FullScreen.html"> THREEx.FullScreen.js </a> <a class="source" href="THREEx.GeometryUtils.html"> THREEx.GeometryUtils.js </a> <a class="source" href="THREEx.GeometryWobble.html"> THREEx.GeometryWobble.js </a> <a class="source" href="THREEx.KeyboardState.html"> THREEx.KeyboardState.js </a> <a class="source" href="THREEx.LogoTurtle.html"> THREEx.LogoTurtle.js </a> <a class="source" href="THREEx.PlasmaShader.html"> THREEx.PlasmaShader.js </a> <a class="source" href="THREEx.SkyMap.html"> THREEx.SkyMap.js </a> <a class="source" href="THREEx.WindowResize.html"> THREEx.WindowResize.js </a> <a class="source" href="THREEx.glCapability.html"> THREEx.glCapability.js </a> <a class="source" href="THREEx.requestAnimationFrame.html"> THREEx.requestAnimationFrame.js </a> <a class="source" href="THREEx.screenshot.html"> THREEx.screenshot.js </a> <a class="source" href="threex.embedded.html"> threex.embedded.js </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> THREEx.screenshot.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre><span class="cm">/** @namespace */</span>
<span class="kd">var</span> <span class="nx">THREEx</span> <span class="o">=</span> <span class="nx">THREEx</span> <span class="o">||</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <p>TODO http://29a.ch/2011/9/11/uploading-from-html5-canvas-to-imgur-data-uri
able to upload your screenshot without running servers</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <p>forced closure</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="cm">/**</span>
<span class="cm"> * Take a screenshot of a renderer</span>
<span class="cm"> * - require WebGLRenderer to have &quot;preserveDrawingBuffer: true&quot; to be set</span>
<span class="cm"> * - TODO is it possible to check if this variable is set ? if so check it</span>
<span class="cm"> * and make advice in the console.log</span>
<span class="cm"> * - maybe with direct access to the gl context...</span>
<span class="cm"> * </span>
<span class="cm"> * @param {Object} renderer to use</span>
<span class="cm"> * @param {String} mimetype of the output image. default to &quot;image/png&quot;</span>
<span class="cm"> * @param {String} dataUrl of the image</span>
<span class="cm"> */</span>
<span class="kd">var</span> <span class="nx">toDataURL</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">renderer</span><span class="p">,</span> <span class="nx">mimetype</span><span class="p">)</span>
<span class="p">{</span>
<span class="nx">mimetype</span> <span class="o">=</span> <span class="nx">mimetype</span> <span class="o">||</span> <span class="s2">&quot;image/png&quot;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">dataUrl</span> <span class="o">=</span> <span class="nx">renderer</span><span class="p">.</span><span class="nx">domElement</span><span class="p">.</span><span class="nx">toDataURL</span><span class="p">(</span><span class="nx">mimetype</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">dataUrl</span><span class="p">;</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * resize an image to another resolution while preserving aspect</span>
<span class="cm"> *</span>
<span class="cm"> * @param {String} srcUrl the url of the image to resize</span>
<span class="cm"> * @param {Number} dstWidth the destination width of the image</span>
<span class="cm"> * @param {Number} dstHeight the destination height of the image</span>
<span class="cm"> * @param {Number} callback the callback to notify once completed with callback(newImageUrl)</span>
<span class="cm"> */</span>
<span class="kd">var</span> <span class="nx">_aspectResize</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">srcUrl</span><span class="p">,</span> <span class="nx">dstW</span><span class="p">,</span> <span class="nx">dstH</span><span class="p">,</span> <span class="nx">callback</span><span class="p">){</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>to compute the width/height while keeping aspect</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">cpuScaleAspect</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">maxW</span><span class="p">,</span> <span class="nx">maxH</span><span class="p">,</span> <span class="nx">curW</span><span class="p">,</span> <span class="nx">curH</span><span class="p">){</span>
<span class="kd">var</span> <span class="nx">ratio</span> <span class="o">=</span> <span class="nx">curH</span> <span class="o">/</span> <span class="nx">curW</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span> <span class="nx">curW</span> <span class="o">&gt;=</span> <span class="nx">maxW</span> <span class="o">&amp;&amp;</span> <span class="nx">ratio</span> <span class="o">&lt;=</span> <span class="mi">1</span> <span class="p">){</span>
<span class="nx">curW</span> <span class="o">=</span> <span class="nx">maxW</span><span class="p">;</span>
<span class="nx">curH</span> <span class="o">=</span> <span class="nx">maxW</span> <span class="o">*</span> <span class="nx">ratio</span><span class="p">;</span>
<span class="p">}</span><span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nx">curH</span> <span class="o">&gt;=</span> <span class="nx">maxH</span><span class="p">){</span>
<span class="nx">curH</span> <span class="o">=</span> <span class="nx">maxH</span><span class="p">;</span>
<span class="nx">curW</span> <span class="o">=</span> <span class="nx">maxH</span> <span class="o">/</span> <span class="nx">ratio</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="p">{</span> <span class="nx">width</span><span class="o">:</span> <span class="nx">curW</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span> <span class="nx">curH</span> <span class="p">};</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <p>callback once the image is loaded</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">onLoad</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>init the canvas</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">canvas</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">&#39;canvas&#39;</span><span class="p">);</span>
<span class="nx">canvas</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">dstW</span><span class="p">;</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">dstH</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">ctx</span> <span class="o">=</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">getContext</span><span class="p">(</span><span class="s1">&#39;2d&#39;</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <p>TODO is this needed</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">ctx</span><span class="p">.</span><span class="nx">fillStyle</span> <span class="o">=</span> <span class="s2">&quot;black&quot;</span><span class="p">;</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nx">fillRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>scale the image while preserving the aspect</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">scaled</span> <span class="o">=</span> <span class="nx">cpuScaleAspect</span><span class="p">(</span><span class="nx">canvas</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">height</span><span class="p">,</span> <span class="nx">image</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="nx">image</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>actually draw the image on canvas</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">offsetX</span> <span class="o">=</span> <span class="p">(</span><span class="nx">canvas</span><span class="p">.</span><span class="nx">width</span> <span class="o">-</span> <span class="nx">scaled</span><span class="p">.</span><span class="nx">width</span> <span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">offsetY</span> <span class="o">=</span> <span class="p">(</span><span class="nx">canvas</span><span class="p">.</span><span class="nx">height</span> <span class="o">-</span> <span class="nx">scaled</span><span class="p">.</span><span class="nx">height</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nx">drawImage</span><span class="p">(</span><span class="nx">image</span><span class="p">,</span> <span class="nx">offsetX</span><span class="p">,</span> <span class="nx">offsetY</span><span class="p">,</span> <span class="nx">scaled</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="nx">scaled</span><span class="p">.</span><span class="nx">height</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>dump the canvas to an URL </p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">mimetype</span> <span class="o">=</span> <span class="s2">&quot;image/png&quot;</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">newDataUrl</span> <span class="o">=</span> <span class="nx">canvas</span><span class="p">.</span><span class="nx">toDataURL</span><span class="p">(</span><span class="nx">mimetype</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>notify the url to the caller</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">callback</span> <span class="o">&amp;&amp;</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">newDataUrl</span><span class="p">)</span>
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <p>Create new Image object</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">image</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Image</span><span class="p">();</span>
<span class="nx">image</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="nx">onLoad</span><span class="p">;</span>
<span class="nx">image</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="nx">srcUrl</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <p>Super cooked function: THREEx.Screenshot.bindKey(renderer)
and you are done to get screenshot on your demo</p> </td> <td class="code"> <div class="highlight"><pre> <span class="cm">/**</span>
<span class="cm"> * Bind a key to renderer screenshot</span>
<span class="cm"> */</span>
<span class="kd">var</span> <span class="nx">bindKey</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">renderer</span><span class="p">,</span> <span class="nx">opts</span><span class="p">){</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <p>handle parameters</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">opts</span> <span class="o">=</span> <span class="nx">opts</span> <span class="o">||</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">&#182;</a> </div> <p>FIXME this modification of opts parameters is a bug. remove it</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">opts</span><span class="p">.</span><span class="nx">charCode</span> <span class="o">=</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">charCode</span> <span class="o">||</span> <span class="s1">&#39;p&#39;</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="nx">opts</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">width</span> <span class="o">||</span> <span class="mi">640</span><span class="p">;</span>
<span class="nx">opts</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">height</span> <span class="o">||</span> <span class="mi">480</span><span class="p">;</span>
<span class="nx">opts</span><span class="p">.</span><span class="nx">callback</span> <span class="o">=</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">callback</span> <span class="o">||</span> <span class="kd">function</span><span class="p">(</span><span class="nx">url</span><span class="p">){</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>
<span class="p">};</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">&#182;</a> </div> <p>callback to handle keypress</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">onKeyPress</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">){</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">&#182;</a> </div> <p>return now if the KeyPress isnt for the proper charCode</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span> <span class="nx">event</span><span class="p">.</span><span class="nx">which</span> <span class="o">!==</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">charCode</span> <span class="p">)</span> <span class="k">return</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">&#182;</a> </div> <p>get the renderer output</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">dataUrl</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">toDataURL</span><span class="p">(</span><span class="nx">renderer</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">&#182;</a> </div> <p>FIXME dont resize if not explicitly asked
* resize == async so if callback is a window open, it triggers the pop blocker
resize it and notify the callback</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_aspectResize</span><span class="p">(</span><span class="nx">dataUrl</span><span class="p">,</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">width</span><span class="p">,</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">height</span><span class="p">,</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">callback</span><span class="p">);</span>
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">&#182;</a> </div> <p>listen to keypress
NOTE: for firefox it seems mandatory to listen to document directly</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">document</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">&#39;keypress&#39;</span><span class="p">,</span> <span class="nx">onKeyPress</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="k">return</span> <span class="p">{</span>
<span class="nx">unbind</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">removeEventListener</span><span class="p">(</span><span class="s1">&#39;keypress&#39;</span><span class="p">,</span> <span class="nx">onKeyPress</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">&#182;</a> </div> <p>export it </p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">THREEx</span><span class="p">.</span><span class="nx">Screenshot</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">toDataURL</span> <span class="o">:</span> <span class="nx">toDataURL</span><span class="p">,</span>
<span class="nx">bindKey</span> <span class="o">:</span> <span class="nx">bindKey</span>
<span class="p">};</span>
<span class="p">})();</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

186
vendor/threex/docs/docco.css vendored Normal file
View file

@ -0,0 +1,186 @@
/*--------------------- Layout and Typography ----------------------------*/
body {
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
font-size: 15px;
line-height: 22px;
color: #252519;
margin: 0; padding: 0;
}
a {
color: #261a3b;
}
a:visited {
color: #261a3b;
}
p {
margin: 0 0 15px 0;
}
h1, h2, h3, h4, h5, h6 {
margin: 0px 0 15px 0;
}
h1 {
margin-top: 40px;
}
#container {
position: relative;
}
#background {
position: fixed;
top: 0; left: 525px; right: 0; bottom: 0;
background: #f5f5ff;
border-left: 1px solid #e5e5ee;
z-index: -1;
}
#jump_to, #jump_page {
background: white;
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
font: 10px Arial;
text-transform: uppercase;
cursor: pointer;
text-align: right;
}
#jump_to, #jump_wrapper {
position: fixed;
right: 0; top: 0;
padding: 5px 10px;
}
#jump_wrapper {
padding: 0;
display: none;
}
#jump_to:hover #jump_wrapper {
display: block;
}
#jump_page {
padding: 5px 0 3px;
margin: 0 0 25px 25px;
}
#jump_page .source {
display: block;
padding: 5px 10px;
text-decoration: none;
border-top: 1px solid #eee;
}
#jump_page .source:hover {
background: #f5f5ff;
}
#jump_page .source:first-child {
}
table td {
border: 0;
outline: 0;
}
td.docs, th.docs {
max-width: 450px;
min-width: 450px;
min-height: 5px;
padding: 10px 25px 1px 50px;
overflow-x: hidden;
vertical-align: top;
text-align: left;
}
.docs pre {
margin: 15px 0 15px;
padding-left: 15px;
}
.docs p tt, .docs p code {
background: #f8f8ff;
border: 1px solid #dedede;
font-size: 12px;
padding: 0 0.2em;
}
.pilwrap {
position: relative;
}
.pilcrow {
font: 12px Arial;
text-decoration: none;
color: #454545;
position: absolute;
top: 3px; left: -20px;
padding: 1px 2px;
opacity: 0;
-webkit-transition: opacity 0.2s linear;
}
td.docs:hover .pilcrow {
opacity: 1;
}
td.code, th.code {
padding: 14px 15px 16px 25px;
width: 100%;
vertical-align: top;
background: #f5f5ff;
border-left: 1px solid #e5e5ee;
}
pre, tt, code {
font-size: 12px; line-height: 18px;
font-family: Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0;
}
/*---------------------- Syntax Highlighting -----------------------------*/
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
body .hll { background-color: #ffffcc }
body .c { color: #408080; font-style: italic } /* Comment */
body .err { border: 1px solid #FF0000 } /* Error */
body .k { color: #954121 } /* Keyword */
body .o { color: #666666 } /* Operator */
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
body .cp { color: #BC7A00 } /* Comment.Preproc */
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
body .cs { color: #408080; font-style: italic } /* Comment.Special */
body .gd { color: #A00000 } /* Generic.Deleted */
body .ge { font-style: italic } /* Generic.Emph */
body .gr { color: #FF0000 } /* Generic.Error */
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
body .gi { color: #00A000 } /* Generic.Inserted */
body .go { color: #808080 } /* Generic.Output */
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
body .gs { font-weight: bold } /* Generic.Strong */
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
body .gt { color: #0040D0 } /* Generic.Traceback */
body .kc { color: #954121 } /* Keyword.Constant */
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
body .kp { color: #954121 } /* Keyword.Pseudo */
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
body .kt { color: #B00040 } /* Keyword.Type */
body .m { color: #666666 } /* Literal.Number */
body .s { color: #219161 } /* Literal.String */
body .na { color: #7D9029 } /* Name.Attribute */
body .nb { color: #954121 } /* Name.Builtin */
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
body .no { color: #880000 } /* Name.Constant */
body .nd { color: #AA22FF } /* Name.Decorator */
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
body .nf { color: #0000FF } /* Name.Function */
body .nl { color: #A0A000 } /* Name.Label */
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
body .nv { color: #19469D } /* Name.Variable */
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
body .w { color: #bbbbbb } /* Text.Whitespace */
body .mf { color: #666666 } /* Literal.Number.Float */
body .mh { color: #666666 } /* Literal.Number.Hex */
body .mi { color: #666666 } /* Literal.Number.Integer */
body .mo { color: #666666 } /* Literal.Number.Oct */
body .sb { color: #219161 } /* Literal.String.Backtick */
body .sc { color: #219161 } /* Literal.String.Char */
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
body .s2 { color: #219161 } /* Literal.String.Double */
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
body .sh { color: #219161 } /* Literal.String.Heredoc */
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
body .sx { color: #954121 } /* Literal.String.Other */
body .sr { color: #BB6688 } /* Literal.String.Regex */
body .s1 { color: #219161 } /* Literal.String.Single */
body .ss { color: #19469D } /* Literal.String.Symbol */
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
body .vc { color: #19469D } /* Name.Variable.Class */
body .vg { color: #19469D } /* Name.Variable.Global */
body .vi { color: #19469D } /* Name.Variable.Instance */
body .il { color: #666666 } /* Literal.Number.Integer.Long */

View file

@ -0,0 +1,19 @@
<html>
<body>
angleX: <span id="angleX"></span><br/>
angleY: <span id="angleY"></span><br/>
angleZ: <span id="angleZ"></span><br/>
<script src="../THREEx.DeviceOrientationState.js"></script>
<script>
var deviceOrientation = new THREEx.DeviceOrientationState();
var elementX = document.getElementById('angleX');
var elementY = document.getElementById('angleY');
var elementZ = document.getElementById('angleZ');
setInterval(function(){
elementX.innerHTML = deviceOrientation.angleX();
elementY.innerHTML = deviceOrientation.angleY();
elementZ.innerHTML = deviceOrientation.angleZ();
}, 100);
</script>
</body>
</html>

View file

@ -0,0 +1,14 @@
<html>
<body>
<script src="../THREEx.KeyboardState.js"></script>
<script>
var keyboard = new THREEx.KeyboardState();
setInterval(function(){
var key = "alt+left";
var pressed = keyboard.pressed(key);
console.log("key", key, "pressed", pressed);
}, 100);
</script>
</body>
</html>

View file

@ -0,0 +1,9 @@
<html>
<body>
<iframe src="noshield-iframe.html"width='320' height='240'></iframe>
<div style="height:1024px; background-color: lightyellow">
dummy div 1024px height to create a scrollable page
</div>
</body>
</html>

View file

@ -0,0 +1,22 @@
<html>
<head>
<style>
body .noFocusMessage { display : block; }
body .withFocusMessage { display : none; }
body:focus .noFocusMessage { display : none; }
body:focus .withFocusMessage { display : block; }
body { background-color: #DC143C; }
body:focus { background-color: lightgreen; }
body .title { font-size : 120%; }
</style>
</head>
<body tabindex=1>
<span class='title'>WITHOUT shielding events<br></span>
<span class="noFocusMessage"><b>Click</b> to get focus</span>
<span class="withFocusMessage">
Got Focus!<br>
Now <b>use arrow UP/DOWN</b> and the host page will scroll as events are not shielded.
</span>
</script>
</body>
</html>

View file

@ -0,0 +1,9 @@
<html>
<body>
<iframe src="withshield-iframe.html" width='320' height='240'></iframe>
<div style="height:1024px; background-color: lightyellow">
dummy div 1024px height to create a scrollable page
</div>
</body>
</html>

View file

@ -0,0 +1,28 @@
<html>
<head>
<style>
body .noFocusMessage { display : block; }
body .withFocusMessage { display : none; }
body:focus .noFocusMessage { display : none; }
body:focus .withFocusMessage { display : block; }
body { background-color: #DC143C; }
body:focus { background-color: lightgreen; }
body .title { font-size : 120%; }
</style>
<script src="../../threex.embedded.js"></script>
</head>
<body tabindex=1>
<span class='title'>WITH shielding events<br></span>
<span class="noFocusMessage"><b>Click</b> to get focus</span>
<span class="withFocusMessage">
Got Focus!<br>
now <b>use arrow UP/DOWN</b> and the host page won't scroll as events are shielded.
</span>
<script>
if( THREEx.Embedded.inIFrame() ){
THREEx.Embedded.shieldArrowKeys();
}
</script>
</body>
</html>

View file

@ -0,0 +1,36 @@
<html>
<body>
<h1>threex.fullscreen.js demo</h1>
<a href="https://github.com/jeromeetienne/threex">threex.js</a> - helpers for three.js
<hr/>
<!-- DOM declaration -->
<span class="available">fullscreen available ? <span class="value"></span></span>
<br/>
<span class="activated">fullscreen activated ? <span class="value"></span></span>
<br/>
<button class="button request">request fullscreen</button>
<br/>
<button class="button cancel">cancel fullscreen</button>
<script src="../threex.fullscreen.js"></script>
<script>
document.querySelector(".available .value").innerHTML = THREEx.FullScreen.available() ? "yes" : "no";
document.querySelector(".activated .value").innerHTML = THREEx.FullScreen.activated() ? "yes" : "no";
THREEx.FullScreen.bindKey({
dblclick : true
});
document.querySelector(".button.request").addEventListener('click', function(){
THREEx.FullScreen.request();
document.querySelector(".activated .value").innerHTML = THREEx.FullScreen.activated() ? "yes" : "no";
}, false);
document.querySelector(".button.cancel").addEventListener('click', function(){
THREEx.FullScreen.cancel();
document.querySelector(".activated .value").innerHTML = THREEx.FullScreen.activated() ? "yes" : "no";
}, false);
</script>
</body>
</html>

View file

@ -0,0 +1,45 @@
// This THREEx helper makes it easy to handle chrome.webstore.install API.
// * api description http://code.google.com/chrome/webstore/docs/inline_installation.html
// * paul kinlan post on g+ https://plus.google.com/116059998563577101552/posts/c9zYiA9RdC5
//
// # Code
//
/** @namespace */
var THREEx = THREEx || {};
THREEx.ChromeWebStoreInstall = THREEx.ChromeWebStoreInstall || {};
/**
* test if the API is available
* @returns {Boolean} true if the API is available, false otherwise
*/
THREEx.ChromeWebStoreInstall.apiAvailable = function()
{
var available = typeof chrome !== 'undefined' && chrome.webstore && chrome.webstore.install;
return available ? true : false;
}
/**
* Test if the application is already installed
*
* @returns {Boolean} true if the application is installed, false otherwise
*/
THREEx.ChromeWebStoreInstall.isInstalled = function()
{
if( !this.apiAvailable() ) return false;
return chrome.app.isInstalled ? true : false;
}
/**
* Trigger an installation
* @param {String} url of the application (optional)
* @param {Function} callback called if installation succeed
* @param {Function} callback called if installation failed
*/
THREEx.ChromeWebStoreInstall.install = function(url, successCallback, failureCallback)
{
console.assert( this.apiAvailable() )
chrome.webstore.install(url, successCallback, failureCallback);
}

24
vendor/threex/threex.embedded.js vendored Normal file
View file

@ -0,0 +1,24 @@
/** @namespace */
var THREEx = THREEx || {};
THREEx.Embedded = THREEx.Embedded || {};
/**
* @returns {Boolean} return true if we are in a iframe, false otherwise
*/
THREEx.Embedded.inIFrame = function()
{
return window != window.top ? true : false;
}
/**
* Prevent Arrows key event from going out of the iframe
*/
THREEx.Embedded.shieldArrowKeys = function()
{
document.addEventListener('keydown', function(event){
// if it is keydown on a arrow, prevent default
if( event.keyCode >= 37 && event.keyCode <= 40 ){
event.preventDefault();
}
}, true);
}

237
vendor/threex/threex.sparks.js vendored Normal file
View file

@ -0,0 +1,237 @@
// This THREEx helper makes it even easier to use spark.js with three.js
// * FIXME This is currently only with WebGL
//
// # Code
//
var THREEx = THREEx || {};
THREEx.Sparks = function(opts)
{
opts = opts || {};
this._maxParticles = opts.maxParticles || console.assert(false);
this._texture = opts.texture || this._buildDefaultTexture();
var counter = opts.counter || console.assert(false);
var vertexIndexPool = {
__pools: [],
// Get a new Vector
get: function() {
if( this.__pools.length > 0 ) return this.__pools.pop();
console.assert(false, "pool ran out!")
return null;
},
// Release a vector back into the pool
add: function(v){ this.__pools.push(v); }
};
var particles = new THREE.Geometry();
var vertices = particles.vertices;
for ( i = 0; i < this._maxParticles; i++ ) {
var position = new THREE.Vector3(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
vertices.push(new THREE.Vertex(position));
vertexIndexPool.add(i);
}
// to handle window resize
this._$onWindowResize = this._onWindowResize.bind(this);
window.addEventListener('resize', this._$onWindowResize, false);
var attributes = this._attributes = {
size : { type: 'f', value: [] },
aColor : { type: 'c', value: [] }
};
var uniforms = this._uniforms = {
texture : { type: "t", texture: this._texture },
color : { type: "c", value: new THREE.Color(0xffffff) },
sizeRatio : { type: "f", value: this._computeSizeRatio() }
};
// fill attributes array
var valuesSize = this._attributes.size.value;
var valuesColor = this._attributes.aColor.value;
for(var v = 0; v < particles.vertices.length; v++ ){
valuesSize[v] = 99;
valuesColor[v] = new THREE.Color( 0x000000 );
}
var material = new THREE.ShaderMaterial( {
uniforms : this._uniforms,
attributes : this._attributes,
vertexShader : THREEx.Sparks.vertexShaderText,
fragmentShader : THREEx.Sparks.fragmentShaderText,
blending : THREE.AdditiveBlending,
depthWrite : false,
transparent : true
});
this._group = new THREE.ParticleSystem( particles, material );
//this._group.dynamic = true;
//this._group.sortParticles = true; // TODO is this needed ?
//// EMITTER STUFF
var setTargetParticle = function() {
var vertexIdx = vertexIndexPool.get();
var target = {
vertexIdx : vertexIdx,
size : function(value){ valuesSize[vertexIdx] = value; },
color : function(){ return valuesColor[vertexIdx]; }
};
return target;
};
var onParticleCreated = function(particle) {
var vertexIdx = particle.target.vertexIdx;
// copy particle position into three.js geometry
vertices[vertexIdx].position = particle.position;
};
var onParticleDead = function(particle) {
var vertexIdx = particle.target.vertexIdx;
// Hide the particle
valuesColor[vertexIdx].setHex( 0x000000 );
vertices[vertexIdx].position.set(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);
// Mark particle system as available by returning to pool
vertexIndexPool.add( vertexIdx );
};
var emitter = this._emitter = new SPARKS.Emitter(counter);
emitter.addInitializer(new SPARKS.Target(null, setTargetParticle));
emitter.addCallback("created" , onParticleCreated );
emitter.addCallback("dead" , onParticleDead );
}
THREEx.Sparks.prototype.destroy = function()
{
window.removeEventListener('resize', this._$onWindowResize);
if( this._emitter.isRunning() ) this._emitter.stop();
}
//////////////////////////////////////////////////////////////////////////////////
// //
//////////////////////////////////////////////////////////////////////////////////
THREEx.Sparks.prototype.container = function()
{
return this._group;
}
THREEx.Sparks.prototype.emitter = function()
{
return this._emitter;
}
THREEx.Sparks.prototype.update = function()
{
this._group.geometry.__dirtyVertices = true;
this._group.geometry.__dirtyColors = true;
this._attributes.size.needsUpdate = true;
this._attributes.aColor.needsUpdate = true;
}
//////////////////////////////////////////////////////////////////////////////////
// handle window resize //
//////////////////////////////////////////////////////////////////////////////////
THREEx.Sparks.prototype._onWindowResize = function()
{
this._uniforms.sizeRatio.value = this._computeSizeRatio();
this._uniforms.sizeRatio.needsUpdate = true;
}
THREEx.Sparks.prototype._computeSizeRatio = function()
{
return window.innerHeight / 1024;
}
//////////////////////////////////////////////////////////////////////////////////
// Shader Text //
//////////////////////////////////////////////////////////////////////////////////
THREEx.Sparks.vertexShaderText = [
"attribute float size;",
"attribute vec4 aColor;",
"uniform float sizeRatio;",
"varying vec4 vColor;",
"void main() {",
"vec4 mvPosition= modelViewMatrix * vec4( position, 1.0 );",
"gl_PointSize = size * sizeRatio * ( 150.0 / length( mvPosition.xyz ) );",
"gl_Position = projectionMatrix * mvPosition;",
"vColor = aColor;",
"}"
].join('\n');
THREEx.Sparks.fragmentShaderText = [
"uniform vec3 color;",
"uniform sampler2D texture;",
"varying vec4 vColor;",
"void main() {",
"vec4 outColor = texture2D( texture, gl_PointCoord );",
"gl_FragColor = outColor * vec4( color * vColor.xyz, 1.0 );",
"}"
].join('\n');
//////////////////////////////////////////////////////////////////////////////////
// Texture //
//////////////////////////////////////////////////////////////////////////////////
THREEx.Sparks.prototype._buildDefaultTexture = function(size)
{
size = size || 128;
var canvas = document.createElement( 'canvas' );
var context = canvas.getContext( '2d' );
canvas.width = canvas.height = size;
var gradient = context.createRadialGradient( canvas.width/2, canvas.height /2, 0, canvas.width /2, canvas.height /2, canvas.width /2 );
gradient.addColorStop( 0 , 'rgba(255,255,255,1)' );
gradient.addColorStop( 0.2, 'rgba(255,255,255,1)' );
gradient.addColorStop( 0.4, 'rgba(128,128,128,1)' );
gradient.addColorStop( 1 , 'rgba(0,0,0,1)' );
context.beginPath();
context.arc(size/2, size/2, size/2, 0, Math.PI*2, false);
context.closePath();
context.fillStyle = gradient;
//context.fillStyle = 'rgba(128,128,128,1)';
context.fill();
var texture = new THREE.Texture( canvas );
texture.needsUpdate = true;
return texture;
}
//////////////////////////////////////////////////////////////////////////////////
// Custom initializer TODO put it elsewhere //
//////////////////////////////////////////////////////////////////////////////////
THREEx.Sparks.ColorSizeInitializer = function(color, size){
this._color = color;
this._size = size;
}
THREEx.Sparks.ColorSizeInitializer.prototype.initialize = function(emitter, particle)
{
if( this._color !== undefined ) particle.target.color().copy(this._color);
if( this._size !== undefined ) particle.target.size(this._size);
}

78
vendor/threex/threex.texturePoolBall.js vendored Normal file
View file

@ -0,0 +1,78 @@
// NOTE: this match THREE namespace on purpose
if(typeof THREEx === "undefined") var THREEx = {};
if(typeof THREEx.Texture === "undefined") THREEx.Texture = {};
/**
*/
THREEx.Texture.PoolBall = {
clear : function(canvas){
var w = canvas.width;
var ctx = canvas.getContext( '2d' );
clearRect(0, 0, w, w);
},
/**
* display the shaddow of the smiley in a texture
*
* @param {canvasElement} the canvas where we draw
*/
draw : function(canvas, textData, stripped, color){
var ctx = canvas.getContext( '2d' );
var w = canvas.width;
var h = canvas.height;
// base color is white
ctx.save();
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0,0, w, h);
ctx.restore();
ctx.save();
ctx.translate(w/2, h/2)
var rectH = stripped ? h/2 : h;
ctx.fillStyle = color.getContextStyle();
ctx.fillRect(-w/2,-rectH/2, w, rectH);
ctx.restore();
ctx.save();
ctx.translate(w/2, h/2)
ctx.fillStyle = "#FFFFFF";
var radiusW = 0.7 * w/4;
var radiusH = 1.2 * h/4;
ctx.fillEllipse( -radiusW/2, -radiusH/2, radiusW, radiusH);
ctx.restore();
ctx.save();
ctx.translate(w/2, h/2)
var textH = w/4;
ctx.font = "bolder "+textH+"px Arial";
ctx.fillStyle = "#000000";
var textW = ctx.measureText(textData).width;
ctx.fillText(textData, -textW/2, 0.8*textH/2);
ctx.restore();
},
//////////////////////////////////////////////////////////////////////////////////
// texture helper //
//////////////////////////////////////////////////////////////////////////////////
ballTexture: function( textData, stripped, color, canvasW, mapping, callback ) {
var canvasDrawer = function(canvas){
THREEx.Texture.PoolBall.draw(canvas, textData, stripped, color);
}
return THREEx.Texture.PoolBall._buildTexture( canvasW, mapping, callback, canvasDrawer );
},
_buildTexture: function( canvasW, mapping, callback, canvasDrawer ) {
canvasW = typeof canvasW !== 'undefined' ? canvasW : 64;
var canvas = document.createElement('canvas');
canvas.width = canvas.height = canvasW;
var texture = new THREE.Texture(canvas, mapping);
canvasDrawer(canvas);
texture.needsUpdate = true;
if( callback ) callback( this );
return texture;
},
}