├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── dist ├── aframe-teleport-controls.js └── aframe-teleport-controls.min.js ├── examples ├── basic │ ├── floor.jpg │ └── index.html ├── common │ ├── mappings.js │ ├── pavement.jpg │ └── shaders │ │ └── skyGradient.js ├── custom │ └── index.html ├── dynamic │ ├── floor.jpg │ ├── index.html │ └── recording.json ├── mesh │ ├── asphalt.jpg │ ├── floor.obj │ └── index.html ├── multiple │ ├── floor.jpg │ ├── index.html │ └── recording.json └── shots │ ├── basic.png │ ├── custom.png │ ├── mesh.png │ └── multiple.png ├── index.html ├── index.js ├── lib ├── ParabolicCurve.js ├── RayCurve.js └── cylinderTexture.js ├── package-lock.json ├── package.json ├── teleport.png └── tests ├── __init.test.js ├── helpers.js ├── index.test.js └── karma.conf.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .sw[ponm] 3 | examples/build.js 4 | gh-pages 5 | node_modules/ 6 | npm-debug.log 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .sw[ponm] 2 | examples/build.js 3 | examples/node_modules/ 4 | gh-pages 5 | node_modules/ 6 | npm-debug.log 7 | .component 8 | package-lock.json 9 | yarn.lock 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | addons: 3 | firefox: 'latest' 4 | node_js: 5 | - '6.9' 6 | 7 | install: 8 | - npm install 9 | - ./node_modules/.bin/mozilla-download ./firefox/ --product firefox --branch mozilla-aurora 10 | - export FIREFOX_NIGHTLY_BIN="./firefox/firefox/firefox-bin" 11 | 12 | before_script: 13 | - export DISPLAY=:99.0 14 | - sh -e /etc/init.d/xvfb start 15 | 16 | script: 17 | - $CI_ACTION 18 | 19 | env: 20 | global: 21 | - TEST_SUITE=unit 22 | matrix: 23 | - CI_ACTION="npm run test" 24 | - CI_ACTION="npm run dist" 25 | # - CI_ACTION="npm run lint" 26 | 27 | branches: 28 | only: 29 | - master 30 | 31 | cache: 32 | directories: 33 | - node_modules 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Fernando Serrano <fernandojsg@gmail.com> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # aframe-teleport-controls 2 | 3 | Teleport component 4 | 5 | ![Screenshot](https://github.com/fernandojsg/aframe-teleport-controls/raw/master/teleport.png) 6 | 7 | ## Properties 8 | 9 | | Property | Description | Default Value | 10 | | -------- | ----------- | ------------- | 11 | | cameraRig | Selector of the camera Rig to teleport | | 12 | | teleportOrigin | Selector of the child of cameraRig to use as the center point for teleporting, typically the camera. If set teleporting will position the cameraRig such that this element ends up above the teleport location (rather than the center of the camreaRig) | | 13 | | type | Type of teleport: line or parabolic | parabolic | 14 | | button | Button used to launch the teleport: trackpad, trigger, grip, menu | trackpad | 15 | | collisionEntities | Selector of the meshes used to check the collisions. If no value provided a plane Y=0 is used | | 16 | | endEvents | Paired with `startEvents`, list of events to listen for to finish teleporting.| [] | 17 | | hitEntity | Entity used to show at the hitting position. If no value provided a cylinder will be used as default. | | 18 | | hitCylinderColor | Color used for the default `hitEntity` primitives | #99ff99 | 19 | | hitCylinderRadius | Radius used for the default `hitEntity` primitives | 0.25 | 20 | | hitCylinderHeight | Height used for the default `hitEntity` primitives | 0.3 | 21 | | interval | Number of milliseconds to wait in between each intersection test. Lower number is better for faster updates. Higher number is better for performance. | 0 | 22 | | curveHitColor | Color used for the curve when hit the mesh | #99ff99 | 23 | | curveMissColor | Color used for the curve when it doesn't hit anything | #ff0000 | 24 | | curveNumberPoints | Number of points used in the curve | 30 | 25 | | curveLineWidth | Line width of the curve | 0.025 | 26 | | curveShootingSpeed | Curve shooting speed, as bigger value, farther distance. | 5 | 27 | | defaultPlaneSize | Default plane size | 100 | 28 | | maxLength | Max length of the ray when using type=line teleport | 10 | 29 | | landingNormal | Normal vector to detect collisions with the `collisionEntity` | (0, 1, 0) | 30 | | landingMaxAngle | Angle threshold (in degrees) used together with `landingNormal` to detect if the mesh is so steep to jump to it. | 45 | 31 | | startEvents | Alternative to `button`, list of events to listen to start teleporting.| [] | 32 | 33 | ### Usage 34 | 35 | #### Browser Installation 36 | 37 | Install and use by directly including the [browser files](dist): 38 | 39 | There are two ways to use it: using a camera rig or not. I strongly recommend using a camera rig as the following example: 40 | 41 | ```html 42 | 43 | My A-Frame Scene 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | ``` 60 | 61 | To use this component with Gear VR, you need to add `gearvr-controls`: 62 | 63 | ```html 64 | 65 | 66 | 67 | 71 | 72 | 73 | ``` 74 | 75 | You can also use the trigger button instead of trackpad button by adding `button: trigger`. 76 | 77 | For Daydream, replace `gearvr-controls` by `daydream-controls`. 78 | 79 | If you use [aframe-environment-component](https://github.com/feiss/aframe-environment-component) > 1.0.0 80 | and want to teleport on the generated ground, on the hills, you can 81 | specify `collisionEntities: .environmentGround`. You can also add `.environmentDressing` if you want to teleport on the dressing like the mushrooms. 82 | On Gear VR, it can be very slow with the curved line. Use `maxLength: 200; type: line;` in this case. 83 | 84 | 85 | #### NPM Installation 86 | 87 | Install via NPM: 88 | 89 | ```bash 90 | npm install aframe-teleport-controls 91 | ``` 92 | 93 | Then register and use. 94 | 95 | ```js 96 | require('aframe-teleport-controls'); 97 | ``` 98 | 99 | ### Events 100 | 101 | | Event | Properties of `event.detail` | Description | 102 | |------------|------------------------------------------|----------------------------------| 103 | | `teleported` | `oldPosition`, `newPosition`, `hitPoint` | Fires when teleportation begins. | 104 | -------------------------------------------------------------------------------- /dist/aframe-teleport-controls.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) 10 | /******/ return installedModules[moduleId].exports; 11 | 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ exports: {}, 15 | /******/ id: moduleId, 16 | /******/ loaded: false 17 | /******/ }; 18 | 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | 22 | /******/ // Flag the module as loaded 23 | /******/ module.loaded = true; 24 | 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | 29 | 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | 36 | /******/ // __webpack_public_path__ 37 | /******/ __webpack_require__.p = ""; 38 | 39 | /******/ // Load entry module and return exports 40 | /******/ return __webpack_require__(0); 41 | /******/ }) 42 | /************************************************************************/ 43 | /******/ ([ 44 | /* 0 */ 45 | /***/ (function(module, exports, __webpack_require__) { 46 | 47 | /* global THREE, AFRAME, Element */ 48 | var cylinderTexture = __webpack_require__(1); 49 | var parabolicCurve = __webpack_require__(2); 50 | var RayCurve = __webpack_require__(3); 51 | 52 | if (typeof AFRAME === 'undefined') { 53 | throw new Error('Component attempted to register before AFRAME was available.'); 54 | } 55 | 56 | if (!Element.prototype.matches) { 57 | Element.prototype.matches = 58 | Element.prototype.matchesSelector || 59 | Element.prototype.mozMatchesSelector || 60 | Element.prototype.msMatchesSelector || 61 | Element.prototype.oMatchesSelector || 62 | Element.prototype.webkitMatchesSelector || 63 | function (s) { 64 | var matches = (this.document || this.ownerDocument).querySelectorAll(s); 65 | var i = matches.length; 66 | while (--i >= 0 && matches.item(i) !== this) { /* no-op */ } 67 | return i > -1; 68 | }; 69 | } 70 | 71 | AFRAME.registerComponent('teleport-controls', { 72 | schema: { 73 | type: {default: 'parabolic', oneOf: ['parabolic', 'line']}, 74 | button: {default: 'trackpad', oneOf: ['trackpad', 'trigger', 'grip', 'menu']}, 75 | startEvents: {type: 'array'}, 76 | endEvents: {type: 'array'}, 77 | collisionEntities: {default: ''}, 78 | hitEntity: {type: 'selector'}, 79 | cameraRig: {type: 'selector'}, 80 | teleportOrigin: {type: 'selector'}, 81 | hitCylinderColor: {type: 'color', default: '#99ff99'}, 82 | hitCylinderRadius: {default: 0.25, min: 0}, 83 | hitCylinderHeight: {default: 0.3, min: 0}, 84 | interval: {default: 0}, 85 | maxLength: {default: 10, min: 0, if: {type: ['line']}}, 86 | curveNumberPoints: {default: 30, min: 2, if: {type: ['parabolic']}}, 87 | curveLineWidth: {default: 0.025}, 88 | curveHitColor: {type: 'color', default: '#99ff99'}, 89 | curveMissColor: {type: 'color', default: '#ff0000'}, 90 | curveShootingSpeed: {default: 5, min: 0, if: {type: ['parabolic']}}, 91 | defaultPlaneSize: { default: 100 }, 92 | landingNormal: {type: 'vec3', default: '0 1 0'}, 93 | landingMaxAngle: {default: '45', min: 0, max: 360}, 94 | drawIncrementally: {default: false}, 95 | incrementalDrawMs: {default: 700}, 96 | missOpacity: {default: 1.0}, 97 | hitOpacity: {default: 1.0} 98 | }, 99 | 100 | init: function () { 101 | var data = this.data; 102 | var el = this.el; 103 | var teleportEntity; 104 | var i; 105 | 106 | this.active = false; 107 | this.obj = el.object3D; 108 | this.hitPoint = new THREE.Vector3(); 109 | this.rigWorldPosition = new THREE.Vector3(); 110 | this.newRigWorldPosition = new THREE.Vector3(); 111 | this.teleportEventDetail = { 112 | oldPosition: this.rigWorldPosition, 113 | newPosition: this.newRigWorldPosition, 114 | hitPoint: this.hitPoint 115 | }; 116 | 117 | this.hit = false; 118 | this.prevCheckTime = undefined; 119 | this.prevHitHeight = 0; 120 | this.referenceNormal = new THREE.Vector3(); 121 | this.curveMissColor = new THREE.Color(); 122 | this.curveHitColor = new THREE.Color(); 123 | this.raycaster = new THREE.Raycaster(); 124 | 125 | this.defaultPlane = createDefaultPlane(this.data.defaultPlaneSize); 126 | this.defaultCollisionMeshes = [this.defaultPlane]; 127 | 128 | teleportEntity = this.teleportEntity = document.createElement('a-entity'); 129 | teleportEntity.classList.add('teleportRay'); 130 | teleportEntity.setAttribute('visible', false); 131 | el.sceneEl.appendChild(this.teleportEntity); 132 | 133 | this.onButtonDown = this.onButtonDown.bind(this); 134 | this.onButtonUp = this.onButtonUp.bind(this); 135 | if (this.data.startEvents.length && this.data.endEvents.length) { 136 | 137 | for (i = 0; i < this.data.startEvents.length; i++) { 138 | el.addEventListener(this.data.startEvents[i], this.onButtonDown); 139 | } 140 | for (i = 0; i < this.data.endEvents.length; i++) { 141 | el.addEventListener(this.data.endEvents[i], this.onButtonUp); 142 | } 143 | } else { 144 | el.addEventListener(data.button + 'down', this.onButtonDown); 145 | el.addEventListener(data.button + 'up', this.onButtonUp); 146 | } 147 | 148 | this.queryCollisionEntities(); 149 | }, 150 | 151 | update: function (oldData) { 152 | var data = this.data; 153 | var diff = AFRAME.utils.diff(data, oldData); 154 | 155 | // Update normal. 156 | this.referenceNormal.copy(data.landingNormal); 157 | 158 | // Update colors. 159 | this.curveMissColor.set(data.curveMissColor); 160 | this.curveHitColor.set(data.curveHitColor); 161 | 162 | 163 | // Create or update line mesh. 164 | if (!this.line || 165 | 'curveLineWidth' in diff || 'curveNumberPoints' in diff || 'type' in diff) { 166 | 167 | this.line = createLine(data); 168 | this.line.material.opacity = this.data.hitOpacity; 169 | this.line.material.transparent = this.data.hitOpacity < 1; 170 | this.numActivePoints = data.curveNumberPoints; 171 | this.teleportEntity.setObject3D('mesh', this.line.mesh); 172 | } 173 | 174 | // Create or update hit entity. 175 | if (data.hitEntity) { 176 | this.hitEntity = data.hitEntity; 177 | } else if (!this.hitEntity || 'hitCylinderColor' in diff || 'hitCylinderHeight' in diff || 178 | 'hitCylinderRadius' in diff) { 179 | // Remove previous entity, create new entity (could be more performant). 180 | if (this.hitEntity) { this.hitEntity.parentNode.removeChild(this.hitEntity); } 181 | this.hitEntity = createHitEntity(data); 182 | this.el.sceneEl.appendChild(this.hitEntity); 183 | } 184 | this.hitEntity.setAttribute('visible', false); 185 | 186 | if ('collisionEntities' in diff) { this.queryCollisionEntities(); } 187 | }, 188 | 189 | remove: function () { 190 | var el = this.el; 191 | var hitEntity = this.hitEntity; 192 | var teleportEntity = this.teleportEntity; 193 | 194 | if (hitEntity) { hitEntity.parentNode.removeChild(hitEntity); } 195 | if (teleportEntity) { teleportEntity.parentNode.removeChild(teleportEntity); } 196 | 197 | el.sceneEl.removeEventListener('child-attached', this.childAttachHandler); 198 | el.sceneEl.removeEventListener('child-detached', this.childDetachHandler); 199 | }, 200 | 201 | tick: (function () { 202 | var p0 = new THREE.Vector3(); 203 | var v0 = new THREE.Vector3(); 204 | var g = -9.8; 205 | var a = new THREE.Vector3(0, g, 0); 206 | var next = new THREE.Vector3(); 207 | var last = new THREE.Vector3(); 208 | var quaternion = new THREE.Quaternion(); 209 | var translation = new THREE.Vector3(); 210 | var scale = new THREE.Vector3(); 211 | var shootAngle = new THREE.Vector3(); 212 | var lastNext = new THREE.Vector3(); 213 | var auxDirection = new THREE.Vector3(); 214 | var timeSinceDrawStart = 0; 215 | 216 | return function (time, delta) { 217 | if (!this.active) { return; } 218 | if (this.data.drawIncrementally && this.redrawLine){ 219 | this.redrawLine = false; 220 | timeSinceDrawStart = 0; 221 | } 222 | timeSinceDrawStart += delta; 223 | this.numActivePoints = this.data.curveNumberPoints*timeSinceDrawStart/this.data.incrementalDrawMs; 224 | if (this.numActivePoints > this.data.curveNumberPoints){ 225 | this.numActivePoints = this.data.curveNumberPoints; 226 | } 227 | 228 | // Only check for intersection if interval time has passed. 229 | if (this.prevCheckTime && (time - this.prevCheckTime < this.data.interval)) { return; } 230 | // Update check time. 231 | this.prevCheckTime = time; 232 | 233 | var matrixWorld = this.obj.matrixWorld; 234 | matrixWorld.decompose(translation, quaternion, scale); 235 | 236 | var direction = shootAngle.set(0, 0, -1) 237 | .applyQuaternion(quaternion).normalize(); 238 | this.line.setDirection(auxDirection.copy(direction)); 239 | this.obj.getWorldPosition(p0); 240 | 241 | last.copy(p0); 242 | 243 | // Set default status as non-hit 244 | this.teleportEntity.setAttribute('visible', true); 245 | this.line.material.color.set(this.curveMissColor); 246 | this.line.material.opacity = this.data.missOpacity; 247 | this.line.material.transparent = this.data.missOpacity < 1; 248 | this.hitEntity.setAttribute('visible', false); 249 | this.hit = false; 250 | 251 | if (this.data.type === 'parabolic') { 252 | v0.copy(direction).multiplyScalar(this.data.curveShootingSpeed); 253 | 254 | this.lastDrawnIndex = 0; 255 | const numPoints = this.data.drawIncrementally ? this.numActivePoints : this.line.numPoints; 256 | for (var i = 0; i < numPoints+1; i++) { 257 | var t; 258 | if (i == Math.floor(numPoints+1)){ 259 | t = numPoints / (this.line.numPoints - 1); 260 | } 261 | else { 262 | t = i / (this.line.numPoints - 1); 263 | } 264 | parabolicCurve(p0, v0, a, t, next); 265 | // Update the raycaster with the length of the current segment last->next 266 | var dirLastNext = lastNext.copy(next).sub(last).normalize(); 267 | this.raycaster.far = dirLastNext.length(); 268 | this.raycaster.set(last, dirLastNext); 269 | 270 | this.lastDrawnPoint = next; 271 | this.lastDrawnIndex = i; 272 | if (this.checkMeshCollisions(i, next)) { break; } 273 | 274 | last.copy(next); 275 | } 276 | for (var j = this.lastDrawnIndex+1; j < this.line.numPoints; j++) { 277 | this.line.setPoint(j, this.lastDrawnPoint); 278 | } 279 | } else if (this.data.type === 'line') { 280 | next.copy(last).add(auxDirection.copy(direction).multiplyScalar(this.data.maxLength)); 281 | this.raycaster.far = this.data.maxLength; 282 | this.raycaster.set(p0, direction); 283 | this.line.setPoint(0, p0); 284 | 285 | this.checkMeshCollisions(1, next); 286 | } 287 | }; 288 | })(), 289 | 290 | /** 291 | * Run `querySelectorAll` for `collisionEntities` and maintain it with `child-attached` 292 | * and `child-detached` events. 293 | */ 294 | queryCollisionEntities: function () { 295 | var collisionEntities; 296 | var data = this.data; 297 | var el = this.el; 298 | 299 | if (!data.collisionEntities) { 300 | this.collisionEntities = []; 301 | return; 302 | } 303 | 304 | collisionEntities = [].slice.call(el.sceneEl.querySelectorAll(data.collisionEntities)); 305 | this.collisionEntities = collisionEntities; 306 | 307 | // Update entity list on attach. 308 | this.childAttachHandler = function childAttachHandler (evt) { 309 | if (!evt.detail.el.matches(data.collisionEntities)) { return; } 310 | collisionEntities.push(evt.detail.el); 311 | }; 312 | el.sceneEl.addEventListener('child-attached', this.childAttachHandler); 313 | 314 | // Update entity list on detach. 315 | this.childDetachHandler = function childDetachHandler (evt) { 316 | var index; 317 | if (!evt.detail.el.matches(data.collisionEntities)) { return; } 318 | index = collisionEntities.indexOf(evt.detail.el); 319 | if (index === -1) { return; } 320 | collisionEntities.splice(index, 1); 321 | }; 322 | el.sceneEl.addEventListener('child-detached', this.childDetachHandler); 323 | }, 324 | 325 | onButtonDown: function () { 326 | this.active = true; 327 | this.redrawLine = true; 328 | }, 329 | 330 | /** 331 | * Jump! 332 | */ 333 | onButtonUp: (function () { 334 | const teleportOriginWorldPosition = new THREE.Vector3(); 335 | const newRigLocalPosition = new THREE.Vector3(); 336 | const newHandPosition = [new THREE.Vector3(), new THREE.Vector3()]; // Left and right 337 | const handPosition = new THREE.Vector3(); 338 | 339 | return function (evt) { 340 | if (!this.active) { return; } 341 | 342 | // Hide the hit point and the curve 343 | this.active = false; 344 | this.hitEntity.setAttribute('visible', false); 345 | this.teleportEntity.setAttribute('visible', false); 346 | 347 | if (!this.hit) { 348 | // Button released but not hit point 349 | return; 350 | } 351 | 352 | const rig = this.data.cameraRig || this.el.sceneEl.camera.el; 353 | rig.object3D.getWorldPosition(this.rigWorldPosition); 354 | this.newRigWorldPosition.copy(this.hitPoint); 355 | 356 | // If a teleportOrigin exists, offset the rig such that the teleportOrigin is above the hitPoint 357 | const teleportOrigin = this.data.teleportOrigin; 358 | if (teleportOrigin) { 359 | teleportOrigin.object3D.getWorldPosition(teleportOriginWorldPosition); 360 | this.newRigWorldPosition.sub(teleportOriginWorldPosition).add(this.rigWorldPosition); 361 | } 362 | 363 | // Always keep the rig at the same offset off the ground after teleporting 364 | this.newRigWorldPosition.y = this.rigWorldPosition.y + this.hitPoint.y - this.prevHitHeight; 365 | this.prevHitHeight = this.hitPoint.y; 366 | 367 | // Finally update the rigs position 368 | newRigLocalPosition.copy(this.newRigWorldPosition); 369 | if (rig.object3D.parent) { 370 | rig.object3D.parent.worldToLocal(newRigLocalPosition); 371 | } 372 | rig.setAttribute('position', newRigLocalPosition); 373 | 374 | // If a rig was not explicitly declared, look for hands and mvoe them proportionally as well 375 | if (!this.data.cameraRig) { 376 | var hands = document.querySelectorAll('a-entity[tracked-controls]'); 377 | for (var i = 0; i < hands.length; i++) { 378 | hands[i].object3D.getWorldPosition(handPosition); 379 | 380 | // diff = rigWorldPosition - handPosition 381 | // newPos = newRigWorldPosition - diff 382 | newHandPosition[i].copy(this.newRigWorldPosition).sub(this.rigWorldPosition).add(handPosition); 383 | hands[i].setAttribute('position', newHandPosition[i]); 384 | } 385 | } 386 | 387 | this.el.emit('teleported', this.teleportEventDetail); 388 | }; 389 | })(), 390 | 391 | /** 392 | * Check for raycaster intersection. 393 | * 394 | * @param {number} Line fragment point index. 395 | * @param {number} Next line fragment point index. 396 | * @returns {boolean} true if there's an intersection. 397 | */ 398 | checkMeshCollisions: function (i, next) { 399 | // @todo We should add a property to define if the collisionEntity is dynamic or static 400 | // If static we should do the map just once, otherwise we're recreating the array in every 401 | // loop when aiming. 402 | var meshes; 403 | if (!this.data.collisionEntities) { 404 | meshes = this.defaultCollisionMeshes; 405 | } else { 406 | meshes = this.collisionEntities.map(function (entity) { 407 | return entity.getObject3D('mesh'); 408 | }).filter(function (n) { return n; }); 409 | meshes = meshes.length ? meshes : this.defaultCollisionMeshes; 410 | } 411 | 412 | var intersects = this.raycaster.intersectObjects(meshes, true); 413 | if (intersects.length > 0 && !this.hit && 414 | this.isValidNormalsAngle(intersects[0].face.normal)) { 415 | var point = intersects[0].point; 416 | 417 | this.line.material.color.set(this.curveHitColor); 418 | this.line.material.opacity = this.data.hitOpacity; 419 | this.line.material.transparent= this.data.hitOpacity < 1; 420 | this.hitEntity.setAttribute('position', point); 421 | this.hitEntity.setAttribute('visible', true); 422 | 423 | this.hit = true; 424 | this.hitPoint.copy(intersects[0].point); 425 | 426 | // If hit, just fill the rest of the points with the hit point and break the loop 427 | for (var j = i; j < this.line.numPoints; j++) { 428 | this.line.setPoint(j, this.hitPoint); 429 | } 430 | return true; 431 | } else { 432 | this.line.setPoint(i, next); 433 | return false; 434 | } 435 | }, 436 | 437 | isValidNormalsAngle: function (collisionNormal) { 438 | var angleNormals = this.referenceNormal.angleTo(collisionNormal); 439 | return (THREE.Math.RAD2DEG * angleNormals <= this.data.landingMaxAngle); 440 | }, 441 | }); 442 | 443 | 444 | function createLine (data) { 445 | var numPoints = data.type === 'line' ? 2 : data.curveNumberPoints; 446 | return new RayCurve(numPoints, data.curveLineWidth); 447 | } 448 | 449 | /** 450 | * Create mesh to represent the area of intersection. 451 | * Default to a combination of torus and cylinder. 452 | */ 453 | function createHitEntity (data) { 454 | var cylinder; 455 | var hitEntity; 456 | var torus; 457 | 458 | // Parent. 459 | hitEntity = document.createElement('a-entity'); 460 | hitEntity.className = 'hitEntity'; 461 | 462 | // Torus. 463 | torus = document.createElement('a-entity'); 464 | torus.setAttribute('geometry', { 465 | primitive: 'torus', 466 | radius: data.hitCylinderRadius, 467 | radiusTubular: 0.01 468 | }); 469 | torus.setAttribute('rotation', {x: 90, y: 0, z: 0}); 470 | torus.setAttribute('material', { 471 | shader: 'flat', 472 | color: data.hitCylinderColor, 473 | side: 'double', 474 | depthTest: false 475 | }); 476 | hitEntity.appendChild(torus); 477 | 478 | // Cylinder. 479 | cylinder = document.createElement('a-entity'); 480 | cylinder.setAttribute('position', {x: 0, y: data.hitCylinderHeight / 2, z: 0}); 481 | cylinder.setAttribute('geometry', { 482 | primitive: 'cylinder', 483 | segmentsHeight: 1, 484 | radius: data.hitCylinderRadius, 485 | height: data.hitCylinderHeight, 486 | openEnded: true 487 | }); 488 | cylinder.setAttribute('material', { 489 | shader: 'flat', 490 | color: data.hitCylinderColor, 491 | side: 'double', 492 | src: cylinderTexture, 493 | transparent: true, 494 | depthTest: false 495 | }); 496 | hitEntity.appendChild(cylinder); 497 | 498 | return hitEntity; 499 | } 500 | 501 | function createDefaultPlane (size) { 502 | var geometry; 503 | var material; 504 | 505 | geometry = new THREE.PlaneBufferGeometry(100, 100); 506 | geometry.rotateX(-Math.PI / 2); 507 | material = new THREE.MeshBasicMaterial({color: 0xffff00}); 508 | return new THREE.Mesh(geometry, material); 509 | } 510 | 511 | 512 | /***/ }), 513 | /* 1 */ 514 | /***/ (function(module, exports) { 515 | 516 | module.exports = 'url(data:image/png;base64,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)'; 517 | 518 | 519 | /***/ }), 520 | /* 2 */ 521 | /***/ (function(module, exports) { 522 | 523 | /* global THREE */ 524 | // Parabolic motion equation, y = p0 + v0*t + 1/2at^2 525 | function parabolicCurveScalar (p0, v0, a, t) { 526 | return p0 + v0 * t + 0.5 * a * t * t; 527 | } 528 | 529 | // Parabolic motion equation applied to 3 dimensions 530 | function parabolicCurve (p0, v0, a, t, out) { 531 | out.x = parabolicCurveScalar(p0.x, v0.x, a.x, t); 532 | out.y = parabolicCurveScalar(p0.y, v0.y, a.y, t); 533 | out.z = parabolicCurveScalar(p0.z, v0.z, a.z, t); 534 | return out; 535 | } 536 | 537 | module.exports = parabolicCurve; 538 | 539 | 540 | /***/ }), 541 | /* 3 */ 542 | /***/ (function(module, exports) { 543 | 544 | /* global THREE */ 545 | var RayCurve = function (numPoints, width) { 546 | this.geometry = new THREE.BufferGeometry(); 547 | this.vertices = new Float32Array(numPoints * 3 * 2); 548 | this.uvs = new Float32Array(numPoints * 2 * 2); 549 | this.width = width; 550 | 551 | this.geometry.addAttribute('position', new THREE.BufferAttribute(this.vertices, 3).setDynamic(true)); 552 | 553 | this.material = new THREE.MeshBasicMaterial({ 554 | side: THREE.DoubleSide, 555 | color: 0xff0000 556 | }); 557 | 558 | this.mesh = new THREE.Mesh(this.geometry, this.material); 559 | this.mesh.drawMode = THREE.TriangleStripDrawMode; 560 | 561 | this.mesh.frustumCulled = false; 562 | this.mesh.vertices = this.vertices; 563 | 564 | this.direction = new THREE.Vector3(); 565 | this.numPoints = numPoints; 566 | }; 567 | 568 | RayCurve.prototype = { 569 | setDirection: function (direction) { 570 | var UP = new THREE.Vector3(0, 1, 0); 571 | this.direction 572 | .copy(direction) 573 | .cross(UP) 574 | .normalize() 575 | .multiplyScalar(this.width / 2); 576 | }, 577 | 578 | setWidth: function (width) { 579 | this.width = width; 580 | }, 581 | 582 | setPoint: (function () { 583 | var posA = new THREE.Vector3(); 584 | var posB = new THREE.Vector3(); 585 | 586 | return function (i, point) { 587 | posA.copy(point).add(this.direction); 588 | posB.copy(point).sub(this.direction); 589 | 590 | var idx = 2 * 3 * i; 591 | this.vertices[idx++] = posA.x; 592 | this.vertices[idx++] = posA.y; 593 | this.vertices[idx++] = posA.z; 594 | 595 | this.vertices[idx++] = posB.x; 596 | this.vertices[idx++] = posB.y; 597 | this.vertices[idx++] = posB.z; 598 | 599 | this.geometry.attributes.position.needsUpdate = true; 600 | }; 601 | })() 602 | }; 603 | 604 | module.exports = RayCurve; 605 | 606 | 607 | /***/ }) 608 | /******/ ]); -------------------------------------------------------------------------------- /dist/aframe-teleport-controls.min.js: -------------------------------------------------------------------------------- 1 | !function(t){function e(n){if(i[n])return i[n].exports;var s=i[n]={exports:{},id:n,loaded:!1};return t[n].call(s.exports,s,s.exports,e),s.loaded=!0,s.exports}var i={};return e.m=t,e.c=i,e.p="",e(0)}([function(t,e,i){function n(t){var e="line"===t.type?2:t.curveNumberPoints;return new h(e,t.curveLineWidth)}function s(t){var e,i,n;return i=document.createElement("a-entity"),i.className="hitEntity",n=document.createElement("a-entity"),n.setAttribute("geometry",{primitive:"torus",radius:t.hitCylinderRadius,radiusTubular:.01}),n.setAttribute("rotation",{x:90,y:0,z:0}),n.setAttribute("material",{shader:"flat",color:t.hitCylinderColor,side:"double",depthTest:!1}),i.appendChild(n),e=document.createElement("a-entity"),e.setAttribute("position",{x:0,y:t.hitCylinderHeight/2,z:0}),e.setAttribute("geometry",{primitive:"cylinder",segmentsHeight:1,radius:t.hitCylinderRadius,height:t.hitCylinderHeight,openEnded:!0}),e.setAttribute("material",{shader:"flat",color:t.hitCylinderColor,side:"double",src:r,transparent:!0,depthTest:!1}),i.appendChild(e),i}function o(t){var e,i;return e=new THREE.PlaneBufferGeometry(100,100),e.rotateX(-Math.PI/2),i=new THREE.MeshBasicMaterial({color:16776960}),new THREE.Mesh(e,i)}var r=i(3),a=i(1),h=i(2);if("undefined"==typeof AFRAME)throw new Error("Component attempted to register before AFRAME was available.");Element.prototype.matches||(Element.prototype.matches=Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector||function(t){for(var e=(this.document||this.ownerDocument).querySelectorAll(t),i=e.length;--i>=0&&e.item(i)!==this;);return i>-1}),AFRAME.registerComponent("teleport-controls",{schema:{type:{default:"parabolic",oneOf:["parabolic","line"]},button:{default:"trackpad",oneOf:["trackpad","trigger","grip","menu"]},startEvents:{type:"array"},endEvents:{type:"array"},collisionEntities:{default:""},hitEntity:{type:"selector"},cameraRig:{type:"selector"},teleportOrigin:{type:"selector"},hitCylinderColor:{type:"color",default:"#99ff99"},hitCylinderRadius:{default:.25,min:0},hitCylinderHeight:{default:.3,min:0},interval:{default:0},maxLength:{default:10,min:0,if:{type:["line"]}},curveNumberPoints:{default:30,min:2,if:{type:["parabolic"]}},curveLineWidth:{default:.025},curveHitColor:{type:"color",default:"#99ff99"},curveMissColor:{type:"color",default:"#ff0000"},curveShootingSpeed:{default:5,min:0,if:{type:["parabolic"]}},defaultPlaneSize:{default:100},landingNormal:{type:"vec3",default:"0 1 0"},landingMaxAngle:{default:"45",min:0,max:360},drawIncrementally:{default:!1},incrementalDrawMs:{default:700},missOpacity:{default:1},hitOpacity:{default:1}},init:function(){var t,e,i=this.data,n=this.el;if(this.active=!1,this.obj=n.object3D,this.hitPoint=new THREE.Vector3,this.rigWorldPosition=new THREE.Vector3,this.newRigWorldPosition=new THREE.Vector3,this.teleportEventDetail={oldPosition:this.rigWorldPosition,newPosition:this.newRigWorldPosition,hitPoint:this.hitPoint},this.hit=!1,this.prevCheckTime=void 0,this.prevHitHeight=0,this.referenceNormal=new THREE.Vector3,this.curveMissColor=new THREE.Color,this.curveHitColor=new THREE.Color,this.raycaster=new THREE.Raycaster,this.defaultPlane=o(this.data.defaultPlaneSize),this.defaultCollisionMeshes=[this.defaultPlane],t=this.teleportEntity=document.createElement("a-entity"),t.classList.add("teleportRay"),t.setAttribute("visible",!1),n.sceneEl.appendChild(this.teleportEntity),this.onButtonDown=this.onButtonDown.bind(this),this.onButtonUp=this.onButtonUp.bind(this),this.data.startEvents.length&&this.data.endEvents.length){for(e=0;ethis.data.curveNumberPoints&&(this.numActivePoints=this.data.curveNumberPoints),!(this.prevCheckTime&&i-this.prevCheckTime0&&!this.hit&&this.isValidNormalsAngle(n[0].face.normal)){var s=n[0].point;this.line.material.color.set(this.curveHitColor),this.line.material.opacity=this.data.hitOpacity,this.line.material.transparent=this.data.hitOpacity<1,this.hitEntity.setAttribute("position",s),this.hitEntity.setAttribute("visible",!0),this.hit=!0,this.hitPoint.copy(n[0].point);for(var o=t;o 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 20 | 21 | 22 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /examples/common/mappings.js: -------------------------------------------------------------------------------- 1 | var mappings = { 2 | mappings: { 3 | default: { 4 | common: { 5 | trackpaddown: 'teleportstart', 6 | trackpadup: 'teleportend' 7 | }, 8 | 'oculus-touch-controls': { 9 | thumbstickdown: 'teleportstart', 10 | thumbstickup: 'teleportend' 11 | }, 12 | keyboard: { 13 | 't_down': 'teleportstart', 14 | 't_up': 'teleportend' 15 | } 16 | } 17 | } 18 | }; 19 | 20 | AFRAME.registerInputMappings(mappings); 21 | -------------------------------------------------------------------------------- /examples/common/pavement.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/examples/common/pavement.jpg -------------------------------------------------------------------------------- /examples/common/shaders/skyGradient.js: -------------------------------------------------------------------------------- 1 | /* global AFRAME */ 2 | AFRAME.registerShader('skyGradient', { 3 | schema: { 4 | colorTop: { type: 'color', default: 'black', is: 'uniform' }, 5 | colorBottom: { type: 'color', default: 'red', is: 'uniform' } 6 | }, 7 | 8 | vertexShader: [ 9 | 'varying vec3 vWorldPosition;', 10 | 11 | 'void main() {', 12 | 13 | 'vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', 14 | 'vWorldPosition = worldPosition.xyz;', 15 | 16 | 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', 17 | 18 | '}' 19 | 20 | ].join('\n'), 21 | 22 | fragmentShader: [ 23 | 'uniform vec3 colorTop;', 24 | 'uniform vec3 colorBottom;', 25 | 26 | 'varying vec3 vWorldPosition;', 27 | 28 | 'void main()', 29 | 30 | '{', 31 | 'vec3 pointOnSphere = normalize(vWorldPosition.xyz);', 32 | 'float f = 1.0;', 33 | 'if(pointOnSphere.y > - 0.2){', 34 | 35 | 'f = sin(pointOnSphere.y * 2.0);', 36 | 37 | '}', 38 | 'gl_FragColor = vec4(mix(colorBottom,colorTop, f ), 1.0);', 39 | 40 | '}' 41 | ].join('\n') 42 | }); 43 | -------------------------------------------------------------------------------- /examples/custom/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 23 | 24 | 28 | 29 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 51 | 52 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /examples/dynamic/floor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/examples/dynamic/floor.jpg -------------------------------------------------------------------------------- /examples/dynamic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Teleport Controls - Dynamic 5 | 6 | 7 | 8 | 9 | 10 | 11 | 42 | 43 | 44 | 45 | 49 | 53 | 54 | 55 | 56 | 60 | 65 | 66 | 67 | 68 | 69 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /examples/mesh/asphalt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/examples/mesh/asphalt.jpg -------------------------------------------------------------------------------- /examples/mesh/floor.obj: -------------------------------------------------------------------------------- 1 | # 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware 2 | # File Created: 28.10.2016 11:22:31 3 | 4 | mtllib floor.mtl 5 | 6 | # 7 | # object Box001 8 | # 9 | 10 | v -5.2726 -1.6981 9.5368 11 | v -7.9080 -1.6981 9.5368 12 | v -7.9080 -1.6981 7.2657 13 | v -5.2726 -1.6981 7.2657 14 | v -2.6372 -1.6981 9.5368 15 | v -2.6372 -1.6981 7.2657 16 | v -0.0018 -1.6981 9.5368 17 | v -0.0018 -1.6981 7.2657 18 | v 2.6337 -1.6981 9.5368 19 | v 2.6337 -1.6981 7.2657 20 | v 5.2691 -1.6981 9.5368 21 | v 5.2759 -1.6960 7.2657 22 | v 7.9660 -1.6981 7.2657 23 | v 10.5399 -1.6981 9.5368 24 | v 7.9045 -1.6981 9.5368 25 | v 7.8956 -1.6981 7.2657 26 | v -8.0452 -1.6981 7.1522 27 | v -10.5434 -1.6981 7.1522 28 | v -10.5434 -1.6981 4.7675 29 | v -8.0452 -1.6981 4.7675 30 | v 7.9660 -1.6981 7.1522 31 | v 7.9660 -1.6981 4.7675 32 | v 10.5399 -1.6981 4.7675 33 | v 10.5399 -1.6981 7.1522 34 | v -7.9080 -1.6981 2.3829 35 | v -7.9080 -1.6981 4.6918 36 | v -8.0452 -1.6981 4.6918 37 | v -10.5434 -1.6981 2.3829 38 | v -2.6372 -1.6981 4.6918 39 | v -5.2726 -1.6981 4.6918 40 | v -5.2726 -1.6981 2.3829 41 | v -2.6372 -1.6981 2.3829 42 | v -0.0018 -1.6981 2.3829 43 | v 2.6337 -1.6981 2.3829 44 | v 0.7055 -1.6981 3.9889 45 | v 7.9045 -1.6981 2.3829 46 | v 7.8974 -1.6981 4.6918 47 | v 7.8903 -1.6981 2.3829 48 | v 7.9655 -1.6981 4.6918 49 | v 10.5399 -1.6981 2.3829 50 | v -7.9080 -1.6981 -0.0018 51 | v -10.5434 -1.6981 -0.0018 52 | v -5.2726 -1.6981 -0.0018 53 | v -2.6372 -1.6981 -0.0018 54 | v -0.0018 -1.6981 -0.0018 55 | v 2.6337 -1.6981 -0.0018 56 | v 5.2691 -1.6981 -0.0018 57 | v 5.2691 -1.6981 2.3829 58 | v 7.8903 -1.6981 -0.0018 59 | v 7.9045 -1.6981 -0.0018 60 | v 10.5399 -1.6981 -0.0018 61 | v -7.9080 -1.6981 -2.3864 62 | v -10.5434 -1.6981 -2.3864 63 | v -5.2726 -1.6981 -2.3864 64 | v -2.6372 -1.6981 -2.3864 65 | v -0.0018 -1.6981 -2.3864 66 | v 2.6337 -1.6981 -2.3864 67 | v 5.2691 -1.6981 -2.3864 68 | v 5.2785 -1.6981 -0.0018 69 | v 7.9045 -1.6981 -2.3864 70 | v 10.5399 -1.6981 -2.3864 71 | v -7.9080 -1.6981 -4.7711 72 | v -10.5434 -1.6981 -4.7711 73 | v -5.2726 -1.6981 -2.4243 74 | v -2.6703 -1.6981 -2.4243 75 | v -0.0018 -1.6981 -4.7711 76 | v -2.6372 -1.6981 -4.7711 77 | v 2.6337 -1.6981 -4.7711 78 | v 5.2691 -1.6981 -4.7711 79 | v 7.9045 -1.6981 -4.7711 80 | v 10.5399 -1.6981 -4.7711 81 | v -7.9080 -1.6981 -7.1557 82 | v -10.5434 -1.6981 -7.1557 83 | v -2.6703 -1.6981 -4.7711 84 | v -2.6703 -1.6981 -7.1557 85 | v -2.6372 -1.6981 -7.1557 86 | v -0.0018 -1.6981 -7.1557 87 | v 2.6337 -1.6981 -7.1557 88 | v 5.2691 -1.6981 -7.1557 89 | v 7.9045 -1.6981 -7.1557 90 | v 10.5399 -1.6981 -7.1557 91 | v -7.9080 -1.6981 -9.5404 92 | v -10.5434 -1.6981 -9.5404 93 | v -7.8560 -1.6981 -7.1557 94 | v -5.2726 -1.6981 -9.5404 95 | v -5.2726 -1.6981 -7.1557 96 | v -2.6372 -1.6981 -9.5404 97 | v -0.0018 -1.6981 -9.5404 98 | v 2.6337 -1.6981 -9.5404 99 | v 5.2691 -1.6981 -9.5404 100 | v 7.9045 -1.6981 -9.5404 101 | v 10.5399 -1.6981 -9.5404 102 | v -8.0452 -0.0326 7.2657 103 | v -10.5434 -0.0326 9.5368 104 | v -7.9080 -0.0326 9.5368 105 | v -7.9080 -0.0326 7.2657 106 | v -5.2726 1.1052 7.2657 107 | v -5.2726 1.1052 9.5368 108 | v -2.6372 1.1052 9.5368 109 | v -2.6372 1.1052 7.2657 110 | v -0.0018 2.0350 7.2657 111 | v -0.0018 2.0350 9.5368 112 | v 2.6337 2.0350 9.5368 113 | v 2.6337 2.0350 7.2657 114 | v -10.5434 -0.0326 4.7675 115 | v -10.5434 -0.0326 7.1522 116 | v -8.0452 -0.0326 7.1522 117 | v -8.0452 -0.0326 4.7675 118 | v 7.9660 -0.0326 4.7675 119 | v 7.9660 -0.0326 7.1522 120 | v 10.5399 -0.0326 7.1522 121 | v 10.5399 -0.0326 4.7675 122 | v -7.9080 -0.0326 4.6918 123 | v -5.2726 -0.0326 4.6918 124 | v -5.2726 -0.0326 2.3829 125 | v -7.9080 -0.0326 2.3829 126 | v -2.6372 -0.0326 4.6918 127 | v -2.6372 -0.0326 2.3829 128 | v -0.0018 -0.0326 4.6918 129 | v -0.0018 -0.0326 2.3829 130 | v 2.6337 -0.0326 4.6918 131 | v 2.6337 -0.0326 2.3829 132 | v 3.3457 -0.0292 3.9889 133 | v 7.9045 -0.0326 2.3829 134 | v 7.8903 -0.0326 2.3829 135 | v 7.8938 -0.0326 4.6918 136 | v 7.9660 -0.0326 4.6918 137 | v 10.5399 -0.0326 2.3829 138 | v -7.9080 5.3704 -0.0018 139 | v -10.5434 5.3704 -0.0018 140 | v -10.5434 -0.0326 2.3829 141 | v -5.2726 -0.0326 -0.0018 142 | v -2.6372 -0.0326 -0.0018 143 | v -0.0018 -0.0326 -0.0018 144 | v 2.6337 -0.0326 -0.0018 145 | v 5.2691 -0.0326 -0.0018 146 | v 5.2691 -0.0326 2.3829 147 | v 7.9045 -0.0326 -0.0018 148 | v 7.8903 -0.0326 -0.0018 149 | v 10.5399 -0.0326 -0.0018 150 | v -7.9080 5.3704 -2.3864 151 | v -10.5434 5.3704 -2.3864 152 | v -5.2726 -0.0326 -2.3864 153 | v -2.6372 -0.0326 -2.3864 154 | v -0.0018 -0.0326 -2.3864 155 | v 2.6337 -0.0326 -2.3864 156 | v 5.2691 -0.0326 -2.3864 157 | v 10.5399 -0.0326 -2.3864 158 | v 7.9045 -0.0326 -2.3864 159 | v -7.9080 -0.0326 -4.7711 160 | v -10.5434 -0.0326 -4.7711 161 | v -7.8560 -0.0326 -2.4243 162 | v -5.2726 -0.0326 -2.4243 163 | v -0.0018 -0.0326 -4.7711 164 | v -2.6372 -0.0326 -4.7711 165 | v 2.6337 -0.0326 -4.7711 166 | v 5.2691 1.2554 -4.7711 167 | v 7.9045 1.2554 -4.7711 168 | v 10.5399 1.2554 -4.7711 169 | v -7.9080 -0.0326 -7.1557 170 | v -10.5434 -0.0326 -7.1557 171 | v -7.8560 -0.0326 -4.7711 172 | v -7.8560 -0.0326 -7.1557 173 | v -2.6703 -0.0326 -7.1557 174 | v -2.6703 -0.0326 -4.7711 175 | v -2.6372 -0.0326 -7.1557 176 | v -0.0018 -0.0326 -7.1557 177 | v 2.6337 -0.0326 -7.1557 178 | v 5.2691 1.2554 -7.1557 179 | v 7.9045 1.2554 -7.1557 180 | v 10.5399 1.2554 -7.1557 181 | v -7.9080 -0.0326 -9.5404 182 | v -10.5434 -0.0326 -9.5404 183 | v -2.6372 -0.0326 -9.5404 184 | v -5.2726 -0.0326 -9.5404 185 | v -5.2726 -0.0326 -7.1557 186 | v -0.0018 -0.0326 -9.5404 187 | v 2.6337 -0.0326 -9.5404 188 | v 5.2691 1.2554 -9.5404 189 | v 7.9045 1.2554 -9.5404 190 | v 10.5399 2.0576 -9.5404 191 | v 7.9045 2.0576 -9.5404 192 | v 7.9045 2.0576 -7.1557 193 | v 10.5399 2.0576 -7.1557 194 | v -7.9080 -0.8653 9.5368 195 | v -10.5434 -0.8653 9.5368 196 | v -10.5434 -1.6981 9.5368 197 | v -5.2726 -0.8653 9.5368 198 | v -2.6372 -0.8653 9.5368 199 | v -0.0018 -0.8653 9.5368 200 | v 2.6337 -0.8653 9.5368 201 | v 5.2691 -0.8653 9.5368 202 | v 7.9045 -0.8653 9.5368 203 | v 10.5399 -0.8653 9.5368 204 | v -5.2726 -0.0326 9.5368 205 | v -2.6372 -0.0326 9.5368 206 | v -0.0018 -0.0326 9.5368 207 | v 2.6337 -0.0326 9.5368 208 | v 5.2691 -0.0326 9.5368 209 | v 7.9045 -0.0326 9.5368 210 | v 10.5399 -0.0326 9.5368 211 | v 10.5399 -0.8653 7.1522 212 | v 10.5399 -0.8653 4.7675 213 | v 10.5399 -0.8653 2.3829 214 | v 10.5399 -0.8653 -0.0018 215 | v 10.5399 -0.8653 -2.3864 216 | v 10.5399 -0.8653 -4.7711 217 | v 10.5399 -0.8653 -7.1557 218 | v 10.5399 -0.8653 -9.5404 219 | v 10.5399 1.2554 -9.5404 220 | v 7.9045 -0.8653 -9.5404 221 | v 5.2691 -0.8653 -9.5404 222 | v 2.6337 -0.8653 -9.5404 223 | v -0.0018 -0.8653 -9.5404 224 | v -2.6372 -0.8653 -9.5404 225 | v -5.2726 -0.8653 -9.5404 226 | v -7.9080 -0.8653 -9.5404 227 | v -10.5434 -0.8653 -9.5404 228 | v -10.5434 -0.8653 -7.1557 229 | v -10.5434 -0.8653 -4.7711 230 | v -10.5434 -0.8653 -2.3864 231 | v -10.5434 -0.8653 -0.0018 232 | v -10.5434 -0.8653 2.3829 233 | v -10.5434 -0.8653 4.7675 234 | v -10.5434 -0.8653 7.1522 235 | v -7.8560 -1.6981 -4.7711 236 | v -7.8560 -1.6981 -2.4243 237 | v -2.6703 -0.0326 -2.4243 238 | v 5.2785 -1.6981 7.3415 239 | v 7.8903 -0.0326 7.3415 240 | v 7.8956 -0.0360 7.2657 241 | v 5.2785 -1.6981 2.3829 242 | v 3.3469 -1.6986 3.9889 243 | v 5.2785 -0.0326 2.3829 244 | v 5.2785 -0.0326 -0.0018 245 | v 5.2785 -0.0326 7.3415 246 | v 5.2750 0.6469 7.2657 247 | v 7.8903 -1.6981 7.3415 248 | v 7.9045 0.4848 9.5368 249 | v 7.8903 0.4848 7.3415 250 | v 5.2785 0.4848 7.3415 251 | v 5.2691 0.4848 9.5368 252 | v -8.0452 -1.6981 7.2657 253 | v -5.2726 0.4164 7.2657 254 | v -7.9080 0.4164 7.2657 255 | v -7.9080 0.4164 9.5368 256 | v -5.2726 0.4164 9.5368 257 | v -0.0018 1.6100 7.2657 258 | v -2.6372 1.6100 7.2657 259 | v -2.6372 1.6100 9.5368 260 | v -0.0018 1.6100 9.5368 261 | v 5.2745 1.4649 7.2663 262 | v 2.6332 1.4632 7.2663 263 | v 2.6332 1.0925 9.5374 264 | v 5.2686 1.0925 9.5374 265 | v 7.9660 -0.0326 7.2657 266 | v -0.0018 -1.6981 5.6317 267 | v -8.0452 -0.0326 4.6918 268 | v -5.2726 -0.0326 7.2657 269 | v -2.6372 -0.0326 7.2657 270 | v -0.0018 -0.0326 7.2657 271 | v 2.6337 0.6452 7.2657 272 | v 2.6332 1.4665 1.7703 273 | v 5.2745 1.4682 1.7703 274 | v 5.2750 -0.0285 -1.0039 275 | v 2.6337 -0.0302 -1.0039 276 | v 5.2745 1.8384 2.3272 277 | v 2.6332 1.8367 2.3272 278 | v 2.6337 0.6470 2.3266 279 | v 5.2750 0.6487 2.3266 280 | v 3.7006 1.0360 -10.0756 281 | v 3.7006 1.0360 -12.4224 282 | v 6.1231 1.0360 -12.4224 283 | v 6.1231 1.0360 -10.0756 284 | v 3.7006 2.5500 -10.0756 285 | v 6.1231 2.5500 -10.0756 286 | v 6.1231 2.5500 -12.4224 287 | v 3.7006 2.5500 -12.4224 288 | v -3.2647 2.4873 -10.6517 289 | v -3.2647 2.4873 -12.9985 290 | v -0.8422 2.4873 -12.9985 291 | v -0.8422 2.4873 -10.6517 292 | v -3.2647 4.0013 -10.6517 293 | v -0.8422 4.0013 -10.6517 294 | v -0.8422 4.0013 -12.9985 295 | v -3.2647 4.0013 -12.9985 296 | v 1.1804 1.8731 -12.7041 297 | v 1.1804 1.8731 -15.0509 298 | v 3.6029 1.8731 -15.0509 299 | v 3.6029 1.8731 -12.7041 300 | v 1.1804 3.3872 -12.7041 301 | v 3.6029 3.3872 -12.7041 302 | v 3.6029 3.3872 -15.0509 303 | v 1.1804 3.3872 -15.0509 304 | # 294 vertices 305 | 306 | vn 0.0000 -1.0000 -0.0000 307 | vn 0.0000 -1.0000 0.0000 308 | vn 0.0002 -1.0000 -0.0002 309 | vn -0.0001 -1.0000 -0.0003 310 | vn -0.0159 -0.9999 -0.0010 311 | vn -0.0000 -1.0000 0.0000 312 | vn -0.0000 -1.0000 -0.0000 313 | vn -0.0000 -1.0000 -0.0002 314 | vn 0.0000 1.0000 -0.0000 315 | vn 0.1500 0.8919 0.4266 316 | vn -0.0016 1.0000 -0.0000 317 | vn -0.0003 1.0000 -0.0004 318 | vn -0.0029 1.0000 -0.0009 319 | vn 0.4466 0.7656 0.4630 320 | vn 0.0000 0.8378 0.5460 321 | vn 0.3947 0.9054 0.1566 322 | vn 0.0000 1.0000 -0.0011 323 | vn 0.4667 0.7410 -0.4829 324 | vn 0.0000 0.8378 -0.5460 325 | vn 0.2510 0.9479 -0.1963 326 | vn -0.0625 0.9962 0.0609 327 | vn 0.0000 0.9695 0.2451 328 | vn 0.2043 0.9441 -0.2588 329 | vn 0.7036 0.0279 -0.7101 330 | vn -0.2253 0.9743 -0.0000 331 | vn -0.1692 0.9670 0.1903 332 | vn 0.0000 0.0000 1.0000 333 | vn 1.0000 0.0000 -0.0000 334 | vn 0.0000 0.0000 -1.0000 335 | vn -1.0000 0.0000 -0.0000 336 | vn -0.3985 -0.9171 -0.0017 337 | vn 0.4999 0.8661 -0.0032 338 | vn -0.0000 1.0000 -0.0000 339 | vn -0.0194 0.9998 -0.0014 340 | vn 0.0000 -1.0000 -0.0001 341 | vn -0.0002 -1.0000 -0.0006 342 | vn 0.0000 1.0000 -0.0006 343 | vn 0.9991 0.0004 -0.0433 344 | vn 0.9994 0.0000 -0.0351 345 | vn 0.9994 0.0000 -0.0354 346 | vn 0.9991 0.0004 -0.0434 347 | vn -0.9975 0.0000 -0.0701 348 | vn -0.0003 -1.0000 0.0000 349 | vn 1.0000 0.0057 0.0043 350 | vn -0.0003 0.9869 0.1615 351 | vn -0.0006 0.9869 0.1611 352 | vn -0.0003 0.9869 0.1614 353 | vn 0.0000 0.9868 0.1618 354 | vn -0.0156 0.9999 -0.0004 355 | vn -1.0000 -0.0004 0.0012 356 | vn -1.0000 0.0000 0.0015 357 | vn -1.0000 -0.0013 0.0021 358 | vn -1.0000 -0.0021 0.0015 359 | vn 0.6392 0.0003 0.7690 360 | vn 0.6393 0.0005 0.7690 361 | vn 0.9053 0.0001 0.4248 362 | vn 0.9052 0.0000 0.4250 363 | vn -0.0614 0.0971 0.9934 364 | vn -1.0000 0.0000 0.0002 365 | vn -1.0000 0.0003 0.0064 366 | vn -1.0000 0.0001 0.0031 367 | vn 0.0000 -0.0005 1.0000 368 | vn 1.0000 0.0004 0.0027 369 | vn 1.0000 0.0006 0.0028 370 | vn -0.0006 0.8801 -0.4748 371 | vn -1.0000 -0.0006 -0.0001 372 | vn -1.0000 -0.0004 -0.0001 373 | vn 1.0000 0.0000 -0.0065 374 | vn -1.0000 0.0000 -0.0043 375 | vn -0.0006 0.9972 0.0754 376 | vn 0.0006 -1.0000 -0.0004 377 | vn 1.0000 0.0004 0.0000 378 | vn 1.0000 0.0006 -0.0000 379 | vn -1.0000 -0.0004 0.0000 380 | vn -1.0000 -0.0006 -0.0000 381 | vn 0.0006 -0.9799 0.1993 382 | vn -1.0000 -0.0004 0.0003 383 | vn -0.0005 0.8328 -0.5536 384 | vn 1.0000 0.0005 -0.0001 385 | vn 0.4388 -0.1813 0.8801 386 | vn 0.2621 -0.4147 0.8714 387 | vn 0.3582 -0.6833 0.6363 388 | vn 0.1807 0.0847 0.9799 389 | vn 0.2981 0.4691 0.8313 390 | vn -1.0000 -0.0005 0.0001 391 | vn 1.0000 0.0004 -0.0003 392 | # 86 vertex normals 393 | 394 | vt 0.7500 0.0000 0.0001 395 | vt 0.8750 0.0000 0.0001 396 | vt 0.8750 0.0924 0.0001 397 | vt 0.7500 0.0924 0.0001 398 | vt 0.6250 0.0000 0.0001 399 | vt 0.6250 0.0924 0.0001 400 | vt 0.5000 0.0000 0.0001 401 | vt 0.5000 0.0924 0.0001 402 | vt 0.3750 0.0000 0.0001 403 | vt 0.3750 0.0924 0.0001 404 | vt 0.2500 0.0000 0.0001 405 | vt 0.2497 0.0924 0.0004 406 | vt 0.1221 0.0924 0.0001 407 | vt 0.0000 0.0000 0.0001 408 | vt 0.1250 0.0000 0.0001 409 | vt 0.1254 0.0924 0.0001 410 | vt 0.8815 0.0970 0.0001 411 | vt 1.0000 0.0970 0.0001 412 | vt 1.0000 0.1940 0.0001 413 | vt 0.8815 0.1940 0.0001 414 | vt 0.1221 0.0970 0.0001 415 | vt 0.1221 0.1940 0.0001 416 | vt 0.0000 0.1940 0.0001 417 | vt 0.0000 0.0970 0.0001 418 | vt 0.8750 0.2910 0.0001 419 | vt 0.8750 0.1971 0.0001 420 | vt 0.8815 0.1971 0.0001 421 | vt 1.0000 0.2910 0.0001 422 | vt 0.6250 0.1971 0.0001 423 | vt 0.7500 0.1971 0.0001 424 | vt 0.7500 0.2910 0.0001 425 | vt 0.6250 0.2910 0.0001 426 | vt 0.5000 0.2910 0.0001 427 | vt 0.3750 0.2910 0.0001 428 | vt 0.4665 0.2257 0.0001 429 | vt 0.1250 0.2910 0.0001 430 | vt 0.1253 0.1971 0.0001 431 | vt 0.1257 0.2910 0.0001 432 | vt 0.1221 0.1971 0.0001 433 | vt 0.0000 0.2910 0.0001 434 | vt 0.8750 0.3880 0.0001 435 | vt 1.0000 0.3880 0.0001 436 | vt 0.7500 0.3880 0.0001 437 | vt 0.6250 0.3880 0.0001 438 | vt 0.5000 0.3880 0.0001 439 | vt 0.3750 0.3880 0.0001 440 | vt 0.2500 0.3880 0.0001 441 | vt 0.2500 0.2910 0.0001 442 | vt 0.1257 0.3880 0.0001 443 | vt 0.1250 0.3880 0.0001 444 | vt 0.0000 0.3880 0.0001 445 | vt 0.8750 0.4849 0.0001 446 | vt 1.0000 0.4849 0.0001 447 | vt 0.7500 0.4849 0.0001 448 | vt 0.6250 0.4849 0.0001 449 | vt 0.5000 0.4849 0.0001 450 | vt 0.3750 0.4849 0.0001 451 | vt 0.2500 0.4849 0.0001 452 | vt 0.2496 0.3880 0.0001 453 | vt 0.1250 0.4849 0.0001 454 | vt 0.0000 0.4849 0.0001 455 | vt 0.8750 0.5819 0.0001 456 | vt 1.0000 0.5819 0.0001 457 | vt 0.7500 0.4865 0.0001 458 | vt 0.6266 0.4865 0.0001 459 | vt 0.5000 0.5819 0.0001 460 | vt 0.6250 0.5819 0.0001 461 | vt 0.3750 0.5819 0.0001 462 | vt 0.2500 0.5819 0.0001 463 | vt 0.1250 0.5819 0.0001 464 | vt 0.0000 0.5819 0.0001 465 | vt 0.8750 0.6789 0.0001 466 | vt 1.0000 0.6789 0.0001 467 | vt 0.6266 0.5819 0.0001 468 | vt 0.6266 0.6789 0.0001 469 | vt 0.6250 0.6789 0.0001 470 | vt 0.5000 0.6789 0.0001 471 | vt 0.3750 0.6789 0.0001 472 | vt 0.2500 0.6789 0.0001 473 | vt 0.1250 0.6789 0.0001 474 | vt 0.0000 0.6789 0.0001 475 | vt 0.8750 0.7759 0.0001 476 | vt 1.0000 0.7759 0.0001 477 | vt 0.8725 0.6789 0.0001 478 | vt 0.7500 0.7759 0.0001 479 | vt 0.7500 0.6789 0.0001 480 | vt 0.6250 0.7759 0.0001 481 | vt 0.5000 0.7759 0.0001 482 | vt 0.3750 0.7759 0.0001 483 | vt 0.2500 0.7759 0.0001 484 | vt 0.1250 0.7759 0.0001 485 | vt 0.0000 0.7759 0.0001 486 | vt 0.1185 0.0924 0.2357 487 | vt -0.0000 0.0000 0.2357 488 | vt 0.1250 0.0000 0.2357 489 | vt 0.1250 0.0924 0.2357 490 | vt 0.2500 0.0924 0.3966 491 | vt 0.2500 0.0000 0.3966 492 | vt 0.3750 0.0000 0.3966 493 | vt 0.3750 0.0924 0.3966 494 | vt 0.5000 0.0924 0.5282 495 | vt 0.5000 0.0000 0.5282 496 | vt 0.6250 0.0000 0.5282 497 | vt 0.6250 0.0924 0.5282 498 | vt 0.0000 0.1940 0.2357 499 | vt 0.0000 0.0970 0.2357 500 | vt 0.1185 0.0970 0.2357 501 | vt 0.1185 0.1940 0.2357 502 | vt 0.8779 0.1940 0.2357 503 | vt 0.8779 0.0970 0.2357 504 | vt 1.0000 0.0970 0.2357 505 | vt 1.0000 0.1940 0.2357 506 | vt 0.1250 0.1971 0.2357 507 | vt 0.2500 0.1971 0.2357 508 | vt 0.2500 0.2910 0.2357 509 | vt 0.1250 0.2910 0.2357 510 | vt 0.3750 0.1971 0.2357 511 | vt 0.3750 0.2910 0.2357 512 | vt 0.5000 0.1971 0.2357 513 | vt 0.5000 0.2910 0.2357 514 | vt 0.6250 0.1971 0.2357 515 | vt 0.6250 0.2910 0.2357 516 | vt 0.6588 0.2257 0.2362 517 | vt 0.8750 0.2910 0.2357 518 | vt 0.8743 0.2910 0.2357 519 | vt 0.8745 0.1971 0.2357 520 | vt 0.8779 0.1971 0.2357 521 | vt 1.0000 0.2910 0.2357 522 | vt 0.1250 0.3880 1.0000 523 | vt 0.0000 0.3880 1.0000 524 | vt 0.0000 0.2910 0.2357 525 | vt 0.2500 0.3880 0.2357 526 | vt 0.3750 0.3880 0.2357 527 | vt 0.5000 0.3880 0.2357 528 | vt 0.6250 0.3880 0.2357 529 | vt 0.7500 0.3880 0.2357 530 | vt 0.7500 0.2910 0.2357 531 | vt 0.8750 0.3880 0.2357 532 | vt 0.8743 0.3880 0.2357 533 | vt 1.0000 0.3880 0.2357 534 | vt 0.1250 0.4849 1.0000 535 | vt 0.0000 0.4849 1.0000 536 | vt 0.2500 0.4849 0.2357 537 | vt 0.3750 0.4849 0.2357 538 | vt 0.5000 0.4849 0.2357 539 | vt 0.6250 0.4849 0.2357 540 | vt 0.7500 0.4849 0.2357 541 | vt 1.0000 0.4849 0.2357 542 | vt 0.8750 0.4849 0.2357 543 | vt 0.1250 0.5819 0.2357 544 | vt 0.0000 0.5819 0.2357 545 | vt 0.8725 0.2357 0.4865 546 | vt 0.8750 1.0000 0.4849 547 | vt 0.7500 0.2357 0.4849 548 | vt 0.2500 0.4865 0.2357 549 | vt 0.1275 0.4865 0.2357 550 | vt 0.5000 0.5819 0.2357 551 | vt 0.3750 0.5819 0.2357 552 | vt 0.6250 0.5819 0.2357 553 | vt 0.7500 0.5819 0.4179 554 | vt 0.8750 0.5819 0.4179 555 | vt 1.0000 0.5819 0.4179 556 | vt 0.1250 0.6789 0.2357 557 | vt 0.0000 0.6789 0.2357 558 | vt 0.1275 0.5819 0.2357 559 | vt 0.1275 0.6789 0.2357 560 | vt 0.3734 0.6789 0.2357 561 | vt 0.3734 0.5819 0.2357 562 | vt 0.3750 0.6789 0.2357 563 | vt 0.5000 0.6789 0.2357 564 | vt 0.6250 0.6789 0.2357 565 | vt 0.7500 0.6789 0.4179 566 | vt 0.8750 0.6789 0.4179 567 | vt 1.0000 0.6789 0.4179 568 | vt 0.1250 0.7759 0.2357 569 | vt 0.0000 0.7759 0.2357 570 | vt 0.3750 0.7759 0.2357 571 | vt 0.2500 0.7759 0.2357 572 | vt 0.2500 0.6789 0.2357 573 | vt 0.5000 0.7759 0.2357 574 | vt 0.6250 0.7759 0.2357 575 | vt 0.7500 0.7759 0.4179 576 | vt 0.8750 0.7759 0.4179 577 | vt 1.0000 0.7759 0.5314 578 | vt 0.8750 0.7759 0.5314 579 | vt 0.8750 0.6789 0.5314 580 | vt 1.0000 0.6789 0.5314 581 | vt 0.1250 0.1179 0.0000 582 | vt -0.0000 0.1179 0.0000 583 | vt -0.0000 0.0001 0.0000 584 | vt 0.1250 0.0001 0.0000 585 | vt 0.2500 0.1179 0.0000 586 | vt 0.2500 0.0001 0.0000 587 | vt 0.3750 0.1179 0.0000 588 | vt 0.3750 0.0001 0.0000 589 | vt 0.5000 0.1179 0.0000 590 | vt 0.5000 0.0001 0.0000 591 | vt 0.6250 0.1179 0.0000 592 | vt 0.6250 0.0001 0.0000 593 | vt 0.7500 0.1179 0.0000 594 | vt 0.7500 0.0001 0.0000 595 | vt 0.8750 0.1179 0.0000 596 | vt 0.8750 0.0001 0.0000 597 | vt 1.0000 0.1179 0.0000 598 | vt 1.0000 0.0001 0.0000 599 | vt 0.1250 0.2357 0.0000 600 | vt -0.0000 0.2357 0.0000 601 | vt 0.2500 0.2357 0.0000 602 | vt 0.3750 0.2357 0.0000 603 | vt 0.5000 0.2357 0.0000 604 | vt 0.6250 0.2357 0.0000 605 | vt 0.7500 0.2357 0.0000 606 | vt 0.8750 0.2357 0.0000 607 | vt 1.0000 0.2357 0.0000 608 | vt 0.0970 0.1179 1.0000 609 | vt 0.0000 0.1179 1.0000 610 | vt 0.0000 0.0001 1.0000 611 | vt 0.0970 0.0001 1.0000 612 | vt 0.1940 0.1179 1.0000 613 | vt 0.1940 0.0001 1.0000 614 | vt 0.2910 0.1179 1.0000 615 | vt 0.2910 0.0001 1.0000 616 | vt 0.3880 0.1179 1.0000 617 | vt 0.3880 0.0001 1.0000 618 | vt 0.4849 0.1179 1.0000 619 | vt 0.4849 0.0001 1.0000 620 | vt 0.5819 0.1179 1.0000 621 | vt 0.5819 0.0001 1.0000 622 | vt 0.6789 0.1179 1.0000 623 | vt 0.6789 0.0001 1.0000 624 | vt 0.7759 0.1179 1.0000 625 | vt 0.7759 0.0001 1.0000 626 | vt 0.0970 0.2357 1.0000 627 | vt 0.0000 0.2357 1.0000 628 | vt 0.1940 0.2357 1.0000 629 | vt 0.2910 0.2357 1.0000 630 | vt 0.3880 0.2357 1.0000 631 | vt 0.4849 0.2357 1.0000 632 | vt 0.5819 0.4179 1.0000 633 | vt 0.6789 0.4179 1.0000 634 | vt 0.7759 0.4179 1.0000 635 | vt 0.1250 0.1179 0.7759 636 | vt 0.0000 0.1179 0.7759 637 | vt 0.0000 0.0001 0.7759 638 | vt 0.1250 0.0001 0.7759 639 | vt 0.2500 0.1179 0.7759 640 | vt 0.2500 0.0001 0.7759 641 | vt 0.3750 0.1179 0.7759 642 | vt 0.3750 0.0001 0.7759 643 | vt 0.5000 0.1179 0.7759 644 | vt 0.5000 0.0001 0.7759 645 | vt 0.6250 0.1179 0.7759 646 | vt 0.6250 0.0001 0.7759 647 | vt 0.7500 0.1179 0.7759 648 | vt 0.7500 0.0001 0.7759 649 | vt 0.8750 0.1179 0.7759 650 | vt 0.8750 0.0001 0.7759 651 | vt 1.0000 0.1179 0.7759 652 | vt 1.0000 0.0001 0.7759 653 | vt 0.1250 0.4179 0.7759 654 | vt 0.0000 0.4179 0.7759 655 | vt 0.2500 0.4179 0.7759 656 | vt 0.3750 0.2357 0.7759 657 | vt 0.5000 0.2357 0.7759 658 | vt 0.6250 0.2357 0.7759 659 | vt 0.7500 0.2357 0.7759 660 | vt 0.8750 0.2357 0.7759 661 | vt 1.0000 0.2357 0.7759 662 | vt 0.3211 0.1179 0.0000 663 | vt 0.2241 0.1179 0.0000 664 | vt 0.2241 0.0001 0.0000 665 | vt 0.3211 0.0001 0.0000 666 | vt 0.4181 0.1179 0.0000 667 | vt 0.4181 0.0001 0.0000 668 | vt 0.5151 0.1179 0.0000 669 | vt 0.5151 0.0001 0.0000 670 | vt 0.6120 0.1179 0.0000 671 | vt 0.6120 0.0001 0.0000 672 | vt 0.7090 0.1179 0.0000 673 | vt 0.7090 0.0001 0.0000 674 | vt 0.8060 0.1179 0.0000 675 | vt 0.8060 0.0001 0.0000 676 | vt 0.9030 0.1179 0.0000 677 | vt 0.9030 0.0001 0.0000 678 | vt 1.0000 0.1179 -0.0000 679 | vt 1.0000 0.0001 -0.0000 680 | vt 0.3211 0.2357 0.0000 681 | vt 0.2241 0.2357 0.0000 682 | vt 0.4181 0.2357 0.0000 683 | vt 0.5151 1.0000 0.0000 684 | vt 0.6120 1.0000 0.0000 685 | vt 0.7090 0.2357 0.0000 686 | vt 0.8060 0.2357 0.0000 687 | vt 0.9030 0.2357 0.0000 688 | vt 1.0000 0.2357 -0.0000 689 | vt 0.8725 0.5819 0.0001 690 | vt 0.8725 0.4865 0.0001 691 | vt 0.3734 0.4865 0.2357 692 | vt 0.5819 0.0001 0.1275 693 | vt 0.6789 0.0001 0.1275 694 | vt 0.6789 0.2357 0.1275 695 | vt 0.5819 0.2357 0.1275 696 | vt 0.4865 0.2357 0.1275 697 | vt 0.4865 0.0001 0.1275 698 | vt 0.2500 0.0001 0.6789 699 | vt 0.3734 0.0001 0.6789 700 | vt 0.3734 0.2357 0.6789 701 | vt 0.2500 0.2357 0.6789 702 | vt 0.1275 0.2357 0.6789 703 | vt 0.1275 0.0001 0.6789 704 | vt 0.4181 0.0001 0.3734 705 | vt 0.5135 0.0001 0.3734 706 | vt 0.5135 0.2357 0.3734 707 | vt 0.4181 0.2357 0.3734 708 | vt 0.3211 0.2357 0.3734 709 | vt 0.3211 0.0001 0.3734 710 | vt 0.7500 0.2357 0.4865 711 | vt 0.6266 0.2357 0.4865 712 | vt 0.6266 0.0001 0.4865 713 | vt 0.7500 0.0001 0.4865 714 | vt 0.8725 0.0001 0.4865 715 | vt 0.5819 0.2357 0.1250 716 | vt 0.4849 1.0000 0.1250 717 | vt 0.2496 0.0893 0.0001 718 | vt 0.8743 0.0893 0.2357 719 | vt 0.8750 0.0000 0.2357 720 | vt 0.8746 0.0924 0.2352 721 | vt 0.2496 0.2910 0.0001 722 | vt 0.3412 0.2257 -0.0000 723 | vt 0.7504 0.2910 0.2357 724 | vt 0.7504 0.3880 0.2357 725 | vt 0.0893 0.2357 0.7504 726 | vt 0.0893 0.0001 0.7504 727 | vt 0.0924 0.0004 0.7503 728 | vt 0.0924 0.3318 0.7503 729 | vt 0.7504 0.2357 0.3880 730 | vt 0.7504 0.0001 0.3880 731 | vt 0.8743 0.0001 0.3880 732 | vt 0.8743 0.2357 0.3880 733 | vt 0.1257 0.2357 0.0893 734 | vt 0.1257 0.0001 0.0893 735 | vt 0.2496 0.0001 0.0893 736 | vt 0.2496 0.2357 0.0893 737 | vt 0.9107 0.0001 0.8743 738 | vt 0.9107 0.2357 0.8743 739 | vt 0.9076 0.2352 0.8746 740 | vt 0.9076 0.0001 0.8746 741 | vt 0.1257 0.0893 0.0001 742 | vt 0.8750 0.0000 0.3089 743 | vt 0.8743 0.0893 0.3089 744 | vt 0.7504 0.0893 0.3089 745 | vt 0.7500 0.0000 0.3089 746 | vt 0.0000 0.2357 0.7500 747 | vt 0.8815 0.0924 0.0001 748 | vt 1.0000 0.0000 0.0001 749 | vt 0.2500 0.0924 0.2992 750 | vt 0.1250 0.0924 0.2992 751 | vt 0.1250 0.0000 0.2992 752 | vt 0.2500 0.0000 0.2992 753 | vt 0.5000 0.0924 0.4680 754 | vt 0.3750 0.0924 0.4680 755 | vt 0.3750 0.0000 0.4680 756 | vt 0.5000 0.0000 0.4680 757 | vt 0.7503 0.0924 0.4475 758 | vt 0.6250 0.0924 0.4473 759 | vt 0.6250 -0.0000 0.3948 760 | vt 0.7500 -0.0000 0.3948 761 | vt 0.8779 0.0924 0.2357 762 | vt 1.0000 0.0000 0.2357 763 | vt 0.5000 0.1588 0.0001 764 | vt 0.1185 0.1971 0.2357 765 | vt 0.7090 0.2357 0.8743 766 | vt 0.6120 0.2357 0.8743 767 | vt 0.6120 0.0001 0.8743 768 | vt 0.7090 0.0001 0.8743 769 | vt 0.8029 0.0001 0.8747 770 | vt 0.8029 0.2357 0.8745 771 | vt 0.6588 0.2362 0.2257 772 | vt 0.6588 -0.0000 0.2257 773 | vt 0.7504 0.0001 0.2910 774 | vt 0.7504 0.2357 0.2910 775 | vt 0.1940 0.0001 0.1185 776 | vt 0.1971 0.0001 0.1185 777 | vt 0.1971 0.2357 0.1185 778 | vt 0.1940 0.2357 0.1185 779 | vt 0.0924 0.2357 0.1185 780 | vt 0.0924 0.0001 0.1185 781 | vt 0.0970 0.0001 0.1185 782 | vt 0.0970 0.2357 0.1185 783 | vt 0.1185 0.2357 0.1971 784 | vt 0.1185 0.0001 0.1971 785 | vt 0.1250 0.0001 0.1971 786 | vt 0.1250 0.2357 0.1971 787 | vt 0.2500 0.2357 0.1971 788 | vt 0.2500 0.0001 0.1971 789 | vt 0.3750 0.2357 0.1971 790 | vt 0.3750 0.0001 0.1971 791 | vt 0.8779 0.2357 0.1971 792 | vt 0.8745 0.2357 0.1971 793 | vt 0.8747 0.0001 0.1971 794 | vt 0.8779 0.0001 0.1971 795 | vt 0.9030 0.0001 0.8779 796 | vt 0.9076 0.0001 0.8779 797 | vt 0.9076 0.2357 0.8779 798 | vt 0.9030 0.2357 0.8779 799 | vt 0.8029 0.2357 0.8779 800 | vt 0.8029 0.0001 0.8779 801 | vt 0.8060 0.0001 0.8779 802 | vt 0.8060 0.2357 0.8779 803 | vt 0.8815 0.0001 0.0924 804 | vt 0.8815 0.2357 0.0924 805 | vt 0.8750 0.2357 0.0924 806 | vt 0.8750 0.0001 0.0924 807 | vt 0.7500 0.2357 0.0924 808 | vt 0.7500 0.0001 0.0924 809 | vt 0.6250 0.2357 0.0924 810 | vt 0.6250 0.0001 0.0924 811 | vt 0.5000 0.2357 0.0924 812 | vt 0.1254 0.2352 0.0924 813 | vt 0.1221 0.2357 0.0924 814 | vt 0.1221 0.0001 0.0924 815 | vt 0.1254 0.0001 0.0924 816 | vt 1.0000 0.5314 0.6789 817 | vt 0.8750 0.5314 0.6789 818 | vt 0.8750 0.4179 0.6789 819 | vt 1.0000 0.4179 0.6789 820 | vt 0.3211 0.5314 0.8750 821 | vt 0.2241 0.5314 0.8750 822 | vt 0.2241 0.4179 0.8750 823 | vt 0.3211 0.4179 0.8750 824 | vt 0.7759 0.5314 1.0000 825 | vt 0.6789 0.5314 1.0000 826 | vt 0.1250 0.5314 0.7759 827 | vt 0.0000 0.5314 0.7759 828 | vt 1.0000 0.2992 0.1250 829 | vt 0.9076 0.2992 0.1250 830 | vt 0.9076 0.2357 0.1250 831 | vt 1.0000 0.2357 0.1250 832 | vt 0.0924 0.2992 0.2500 833 | vt 0.0000 0.2992 0.2500 834 | vt 0.0000 0.2357 0.2500 835 | vt 0.0924 0.2357 0.2500 836 | vt 0.2500 0.2992 0.0000 837 | vt 0.1250 0.2992 0.0000 838 | vt 0.8750 0.2992 0.0924 839 | vt 0.7500 0.2992 0.0924 840 | vt 0.0924 0.3966 0.3750 841 | vt 0.0000 0.3966 0.3750 842 | vt 0.0000 0.2357 0.3750 843 | vt 0.0924 0.2357 0.3750 844 | vt 0.7500 0.3966 0.0924 845 | vt 0.6250 0.3966 0.0924 846 | vt 1.0000 0.3966 0.2500 847 | vt 0.9076 0.3966 0.2500 848 | vt 0.9076 0.2357 0.2500 849 | vt 1.0000 0.2357 0.2500 850 | vt 0.3750 0.3966 0.0000 851 | vt 0.2500 0.3966 0.0000 852 | vt 0.0924 0.4680 0.5000 853 | vt 0.0000 0.4680 0.5000 854 | vt 0.0000 0.2357 0.5000 855 | vt 0.0924 0.2357 0.5000 856 | vt 0.5000 0.4680 0.0000 857 | vt 0.3750 0.4680 0.0000 858 | vt 0.6250 0.4680 0.0924 859 | vt 0.5000 0.4680 0.0924 860 | vt 1.0000 0.4680 0.3750 861 | vt 0.9076 0.4680 0.3750 862 | vt 0.9076 0.2357 0.3750 863 | vt 1.0000 0.2357 0.3750 864 | vt 0.0924 0.5282 0.6250 865 | vt 0.0000 0.5282 0.6250 866 | vt 0.0000 0.2357 0.6250 867 | vt 0.0924 0.3316 0.6250 868 | vt 0.5000 0.5282 0.0924 869 | vt 0.3750 0.5282 0.0924 870 | vt 0.3750 0.3316 0.0924 871 | vt 1.0000 0.5282 0.5000 872 | vt 0.9076 0.5282 0.5000 873 | vt 0.9076 0.2357 0.5000 874 | vt 1.0000 0.2357 0.5000 875 | vt 0.6250 0.5282 0.0000 876 | vt 0.5000 0.5282 0.0000 877 | vt 0.7500 0.3948 -0.0000 878 | vt 0.6250 0.3948 -0.0000 879 | vt 0.0924 0.4475 0.7503 880 | vt -0.0000 0.3948 0.7500 881 | vt 0.6250 0.3159 0.4477 882 | vt 0.7503 0.3159 0.4480 883 | vt 0.7503 0.4287 0.2363 884 | vt 0.6250 0.4287 0.2360 885 | vt 1.0000 0.3948 0.6250 886 | vt 0.9076 0.4473 0.6250 887 | vt 0.9076 0.3316 0.6250 888 | vt 1.0000 0.2357 0.6250 889 | vt 0.8750 0.3089 0.0000 890 | vt 0.7500 0.3089 0.0000 891 | vt 0.0893 0.3089 0.8743 892 | vt 0.0000 0.3089 0.8750 893 | vt 0.0000 0.2357 0.8750 894 | vt 0.0893 0.2357 0.8743 895 | vt 0.2496 0.3089 0.0893 896 | vt 0.1257 0.3089 0.0893 897 | vt 1.0000 0.3089 0.7500 898 | vt 0.9107 0.3089 0.7504 899 | vt 0.9107 0.2357 0.7504 900 | vt 1.0000 0.2357 0.7500 901 | vt 0.7503 0.2932 0.5004 902 | vt 0.6250 0.2932 0.5001 903 | vt 0.3750 0.2933 0.3318 904 | vt 0.2497 0.2933 0.3321 905 | vt 0.2497 0.0924 0.3318 906 | vt 0.3750 0.0924 0.3316 907 | vt 0.2933 0.3321 0.7503 908 | vt 0.2932 0.5004 0.7503 909 | vt 0.7068 0.5001 0.6250 910 | vt 0.7067 0.3318 0.6250 911 | vt 0.3750 0.4287 0.2360 912 | vt 0.2497 0.4287 0.2363 913 | vt 0.6841 0.4477 0.6250 914 | vt 0.4287 0.2363 0.7503 915 | vt 0.3159 0.4480 0.7503 916 | vt 0.3880 0.2357 0.7504 917 | vt 0.2910 0.2357 0.7504 918 | vt 0.2910 0.0001 0.7504 919 | vt 0.3880 0.0001 0.7504 920 | vt 0.5335 0.0001 0.2257 921 | vt 0.3412 0.2257 0.2362 922 | vt 0.1588 0.0001 0.5000 923 | vt 0.2257 0.0001 0.5335 924 | vt 0.1971 0.2357 0.5000 925 | vt 0.5000 0.2357 0.1971 926 | vt 0.3750 0.1971 0.0001 927 | vt 0.2497 0.3318 0.0924 928 | vt 0.2497 0.0004 0.0924 929 | vt 0.3750 0.0001 0.0924 930 | vt 0.5000 0.0001 0.0924 931 | vt 0.5713 0.2360 0.6250 932 | vt 0.3244 0.7977 0.3868 933 | vt 0.3244 0.8931 0.3868 934 | vt 0.2095 0.8931 0.3868 935 | vt 0.2095 0.7977 0.3868 936 | vt 0.6756 0.7977 0.6010 937 | vt 0.7905 0.7977 0.6010 938 | vt 0.7905 0.8931 0.6010 939 | vt 0.6756 0.8931 0.6010 940 | vt 0.6756 0.3868 0.7977 941 | vt 0.7905 0.3868 0.7977 942 | vt 0.7905 0.6010 0.7977 943 | vt 0.6756 0.6010 0.7977 944 | vt 0.7977 0.3868 0.7905 945 | vt 0.8931 0.3868 0.7905 946 | vt 0.8931 0.6010 0.7905 947 | vt 0.7977 0.6010 0.7905 948 | vt 0.2095 0.3868 0.8931 949 | vt 0.3244 0.3868 0.8931 950 | vt 0.3244 0.6010 0.8931 951 | vt 0.2095 0.6010 0.8931 952 | vt 0.1069 0.3868 0.6756 953 | vt 0.2023 0.3868 0.6756 954 | vt 0.2023 0.6010 0.6756 955 | vt 0.1069 0.6010 0.6756 956 | vt 0.6548 0.8211 0.5921 957 | vt 0.6548 0.9165 0.5921 958 | vt 0.5399 0.9165 0.5921 959 | vt 0.5399 0.8211 0.5921 960 | vt 0.3452 0.8211 0.8063 961 | vt 0.4601 0.8211 0.8063 962 | vt 0.4601 0.9165 0.8063 963 | vt 0.3452 0.9165 0.8063 964 | vt 0.3452 0.5921 0.8211 965 | vt 0.4601 0.5921 0.8211 966 | vt 0.4601 0.8063 0.8211 967 | vt 0.3452 0.8063 0.8211 968 | vt 0.8211 0.5921 0.4601 969 | vt 0.9165 0.5921 0.4601 970 | vt 0.9165 0.8063 0.4601 971 | vt 0.8211 0.8063 0.4601 972 | vt 0.5399 0.5921 0.9165 973 | vt 0.6548 0.5921 0.9165 974 | vt 0.6548 0.8063 0.9165 975 | vt 0.5399 0.8063 0.9165 976 | vt 0.0835 0.5921 0.3452 977 | vt 0.1789 0.5921 0.3452 978 | vt 0.1789 0.8063 0.3452 979 | vt 0.0835 0.8063 0.3452 980 | vt 0.4439 0.9046 0.5053 981 | vt 0.4439 1.0000 0.5053 982 | vt 0.3290 1.0000 0.5053 983 | vt 0.3290 0.9046 0.5053 984 | vt 0.5561 0.9046 0.7194 985 | vt 0.6710 0.9046 0.7194 986 | vt 0.6710 1.0000 0.7194 987 | vt 0.5561 1.0000 0.7194 988 | vt 0.5561 0.5053 0.9046 989 | vt 0.6710 0.5053 0.9046 990 | vt 0.6710 0.7194 0.9046 991 | vt 0.5561 0.7194 0.9046 992 | vt 0.9046 0.5053 0.6710 993 | vt 1.0000 0.5053 0.6710 994 | vt 1.0000 0.7194 0.6710 995 | vt 0.9046 0.7194 0.6710 996 | vt 0.3290 0.5053 1.0000 997 | vt 0.4439 0.5053 1.0000 998 | vt 0.4439 0.7194 1.0000 999 | vt 0.3290 0.7194 1.0000 1000 | vt -0.0000 0.5053 0.5561 1001 | vt 0.0954 0.5053 0.5561 1002 | vt 0.0954 0.7194 0.5561 1003 | vt -0.0000 0.7194 0.5561 1004 | # 610 texture coords 1005 | 1006 | g Box001 1007 | usemtl wire_086086086 1008 | f 1/1/1 2/2/2 3/3/1 1009 | f 3/3/1 4/4/1 1/1/1 1010 | f 5/5/1 1/1/1 4/4/1 1011 | f 4/4/1 6/6/1 5/5/1 1012 | f 7/7/1 5/5/1 6/6/1 1013 | f 6/6/1 8/8/1 7/7/1 1014 | f 9/9/1 7/7/1 8/8/1 1015 | f 8/8/1 10/10/3 9/9/1 1016 | f 11/11/4 9/9/1 10/10/3 1017 | f 10/10/3 12/12/5 11/11/4 1018 | f 13/13/2 14/14/2 15/15/6 1019 | f 15/15/6 16/16/2 13/13/2 1020 | f 17/17/1 18/18/7 19/19/6 1021 | f 19/19/6 20/20/2 17/17/1 1022 | f 21/21/1 22/22/2 23/23/2 1023 | f 23/23/2 24/24/1 21/21/1 1024 | f 25/25/1 26/26/1 27/27/2 1025 | f 27/27/2 28/28/7 25/25/1 1026 | f 29/29/1 30/30/1 31/31/1 1027 | f 31/31/1 32/32/1 29/29/1 1028 | f 33/33/1 34/34/1 35/35/7 1029 | f 36/36/7 37/37/7 38/38/2 1030 | f 23/23/2 22/22/2 39/39/6 1031 | f 39/39/6 40/40/1 23/23/2 1032 | f 41/41/1 25/25/1 28/28/7 1033 | f 28/28/7 42/42/1 41/41/1 1034 | f 43/43/1 31/31/1 25/25/1 1035 | f 25/25/1 41/41/1 43/43/1 1036 | f 44/44/1 32/32/1 31/31/1 1037 | f 31/31/1 43/43/1 44/44/1 1038 | f 45/45/1 33/33/1 32/32/1 1039 | f 32/32/1 44/44/1 45/45/1 1040 | f 46/46/1 34/34/1 33/33/1 1041 | f 33/33/1 45/45/1 46/46/1 1042 | f 47/47/1 48/48/8 34/34/1 1043 | f 34/34/1 46/46/1 47/47/1 1044 | f 38/38/2 49/49/1 50/50/2 1045 | f 50/50/2 36/36/7 38/38/2 1046 | f 51/51/1 40/40/1 36/36/7 1047 | f 36/36/7 50/50/2 51/51/1 1048 | f 52/52/1 41/41/1 42/42/1 1049 | f 42/42/1 53/53/1 52/52/1 1050 | f 54/54/1 43/43/1 41/41/1 1051 | f 41/41/1 52/52/1 54/54/1 1052 | f 55/55/1 44/44/1 43/43/1 1053 | f 43/43/1 54/54/1 55/55/1 1054 | f 56/56/1 45/45/1 44/44/1 1055 | f 44/44/1 55/55/1 56/56/1 1056 | f 57/57/1 46/46/1 45/45/1 1057 | f 45/45/1 56/56/1 57/57/1 1058 | f 58/58/1 47/47/1 46/46/1 1059 | f 46/46/1 57/57/1 58/58/1 1060 | f 59/59/7 47/47/1 58/58/1 1061 | f 59/59/7 58/58/1 60/60/1 1062 | f 60/60/1 50/50/2 49/49/1 1063 | f 59/59/7 60/60/1 49/49/1 1064 | f 61/61/1 51/51/1 50/50/2 1065 | f 50/50/2 60/60/1 61/61/1 1066 | f 62/62/1 52/52/1 53/53/1 1067 | f 53/53/1 63/63/1 62/62/1 1068 | f 55/55/1 54/54/1 64/64/1 1069 | f 64/64/1 65/65/1 55/55/1 1070 | f 66/66/1 56/56/1 55/55/1 1071 | f 55/55/1 67/67/1 66/66/1 1072 | f 68/68/1 57/57/1 56/56/1 1073 | f 56/56/1 66/66/1 68/68/1 1074 | f 69/69/1 58/58/1 57/57/1 1075 | f 57/57/1 68/68/1 69/69/1 1076 | f 70/70/1 60/60/1 58/58/1 1077 | f 58/58/1 69/69/1 70/70/1 1078 | f 71/71/1 61/61/1 60/60/1 1079 | f 60/60/1 70/70/1 71/71/1 1080 | f 72/72/1 62/62/1 63/63/1 1081 | f 63/63/1 73/73/1 72/72/1 1082 | f 74/74/1 75/75/1 76/76/1 1083 | f 76/76/1 67/67/1 74/74/1 1084 | f 77/77/1 66/66/1 67/67/1 1085 | f 67/67/1 76/76/1 77/77/1 1086 | f 78/78/1 68/68/1 66/66/1 1087 | f 66/66/1 77/77/1 78/78/1 1088 | f 79/79/1 69/69/1 68/68/1 1089 | f 68/68/1 78/78/1 79/79/1 1090 | f 80/80/1 70/70/1 69/69/1 1091 | f 69/69/1 79/79/1 80/80/1 1092 | f 81/81/1 71/71/1 70/70/1 1093 | f 70/70/1 80/80/1 81/81/1 1094 | f 82/82/1 72/72/1 73/73/1 1095 | f 73/73/1 83/83/1 82/82/1 1096 | f 84/84/1 72/72/1 82/82/1 1097 | f 84/84/1 82/82/1 85/85/1 1098 | f 84/84/1 85/85/1 86/86/1 1099 | f 87/87/1 76/76/1 75/75/1 1100 | f 87/87/1 75/75/1 86/86/1 1101 | f 87/87/1 86/86/1 85/85/1 1102 | f 88/88/1 77/77/1 76/76/1 1103 | f 76/76/1 87/87/1 88/88/1 1104 | f 89/89/1 78/78/1 77/77/1 1105 | f 77/77/1 88/88/1 89/89/1 1106 | f 90/90/1 79/79/1 78/78/1 1107 | f 78/78/1 89/89/1 90/90/1 1108 | f 91/91/1 80/80/1 79/79/1 1109 | f 79/79/1 90/90/1 91/91/1 1110 | f 92/92/1 81/81/1 80/80/1 1111 | f 80/80/1 91/91/1 92/92/1 1112 | f 93/93/9 94/94/9 95/95/9 1113 | f 95/95/9 96/96/9 93/93/9 1114 | f 97/97/9 98/98/9 99/99/9 1115 | f 99/99/9 100/100/9 97/97/9 1116 | f 101/101/9 102/102/9 103/103/9 1117 | f 103/103/9 104/104/9 101/101/9 1118 | f 105/105/9 106/106/9 107/107/9 1119 | f 107/107/9 108/108/9 105/105/9 1120 | f 109/109/9 110/110/9 111/111/9 1121 | f 111/111/9 112/112/9 109/109/9 1122 | f 113/113/9 114/114/9 115/115/9 1123 | f 115/115/9 116/116/10 113/113/9 1124 | f 114/114/9 117/117/9 118/118/9 1125 | f 118/118/9 115/115/9 114/114/9 1126 | f 117/117/9 119/119/9 120/120/9 1127 | f 120/120/9 118/118/9 117/117/9 1128 | f 119/119/9 121/121/11 122/122/12 1129 | f 122/122/12 120/120/9 119/119/9 1130 | f 122/122/12 121/121/11 123/123/13 1131 | f 124/124/9 125/125/9 126/126/9 1132 | f 124/124/9 126/126/9 127/127/9 1133 | f 127/127/9 128/128/9 124/124/9 1134 | f 129/129/14 130/130/15 131/131/15 1135 | f 131/131/15 116/116/10 129/129/14 1136 | f 132/132/16 129/129/14 116/116/10 1137 | f 116/116/10 115/115/9 132/132/16 1138 | f 133/133/9 132/132/16 115/115/9 1139 | f 115/115/9 118/118/9 133/133/9 1140 | f 134/134/9 133/133/9 118/118/9 1141 | f 118/118/9 120/120/9 134/134/9 1142 | f 135/135/9 134/134/9 120/120/9 1143 | f 120/120/9 122/122/12 135/135/9 1144 | f 136/136/9 135/135/9 122/122/12 1145 | f 122/122/12 137/137/17 136/136/9 1146 | f 138/138/9 139/139/9 125/125/9 1147 | f 125/125/9 124/124/9 138/138/9 1148 | f 140/140/9 138/138/9 124/124/9 1149 | f 124/124/9 128/128/9 140/140/9 1150 | f 141/141/18 142/142/19 130/130/15 1151 | f 130/130/15 129/129/14 141/141/18 1152 | f 143/143/20 141/141/18 129/129/14 1153 | f 129/129/14 132/132/16 143/143/20 1154 | f 144/144/9 143/143/20 132/132/16 1155 | f 132/132/16 133/133/9 144/144/9 1156 | f 145/145/9 144/144/9 133/133/9 1157 | f 133/133/9 134/134/9 145/145/9 1158 | f 146/146/21 145/145/9 134/134/9 1159 | f 134/134/9 135/135/9 146/146/21 1160 | f 147/147/22 146/146/21 135/135/9 1161 | f 135/135/9 136/136/9 147/147/22 1162 | f 148/148/22 149/149/22 138/138/9 1163 | f 138/138/9 140/140/9 148/148/22 1164 | f 150/150/23 151/151/19 142/142/19 1165 | f 142/142/19 141/141/18 150/150/23 1166 | f 152/152/24 141/153/18 143/154/20 1167 | f 143/143/20 153/155/9 152/156/24 1168 | f 154/157/9 155/158/9 144/144/9 1169 | f 144/144/9 145/145/9 154/157/9 1170 | f 156/159/25 154/157/9 145/145/9 1171 | f 145/145/9 146/146/21 156/159/25 1172 | f 157/160/26 156/159/25 146/146/21 1173 | f 146/146/21 147/147/22 157/160/26 1174 | f 158/161/22 157/160/26 147/147/22 1175 | f 147/147/22 149/149/22 158/161/22 1176 | f 159/162/22 158/161/22 149/149/22 1177 | f 149/149/22 148/148/22 159/162/22 1178 | f 160/163/9 161/164/9 151/151/19 1179 | f 151/151/19 150/150/23 160/163/9 1180 | f 150/150/23 162/165/9 163/166/9 1181 | f 163/166/9 160/163/9 150/150/23 1182 | f 164/167/9 165/168/9 155/158/9 1183 | f 155/158/9 166/169/9 164/167/9 1184 | f 167/170/9 166/169/9 155/158/9 1185 | f 155/158/9 154/157/9 167/170/9 1186 | f 168/171/25 167/170/9 154/157/9 1187 | f 154/157/9 156/159/25 168/171/25 1188 | f 169/172/25 168/171/25 156/159/25 1189 | f 156/159/25 157/160/26 169/172/25 1190 | f 170/173/9 169/172/25 157/160/26 1191 | f 157/160/26 158/161/22 170/173/9 1192 | f 171/174/9 170/173/9 158/161/22 1193 | f 158/161/22 159/162/22 171/174/9 1194 | f 172/175/9 173/176/9 161/164/9 1195 | f 161/164/9 160/163/9 172/175/9 1196 | f 164/167/9 166/169/9 174/177/9 1197 | f 174/177/9 175/178/9 176/179/9 1198 | f 164/167/9 174/177/9 176/179/9 1199 | f 177/180/9 174/177/9 166/169/9 1200 | f 166/169/9 167/170/9 177/180/9 1201 | f 178/181/25 177/180/9 167/170/9 1202 | f 167/170/9 168/171/25 178/181/25 1203 | f 179/182/25 178/181/25 168/171/25 1204 | f 168/171/25 169/172/25 179/182/25 1205 | f 180/183/9 179/182/25 169/172/25 1206 | f 169/172/25 170/173/9 180/183/9 1207 | f 181/184/9 182/185/9 183/186/9 1208 | f 183/186/9 184/187/9 181/184/9 1209 | f 185/188/27 186/189/27 187/190/27 1210 | f 187/190/27 2/191/27 185/188/27 1211 | f 188/192/27 185/188/27 2/191/27 1212 | f 2/191/27 1/193/27 188/192/27 1213 | f 189/194/27 188/192/27 1/193/27 1214 | f 1/193/27 5/195/27 189/194/27 1215 | f 190/196/27 189/194/27 5/195/27 1216 | f 5/195/27 7/197/27 190/196/27 1217 | f 191/198/27 190/196/27 7/197/27 1218 | f 7/197/27 9/199/27 191/198/27 1219 | f 192/200/27 191/198/27 9/199/27 1220 | f 9/199/27 11/201/27 192/200/27 1221 | f 193/202/27 192/200/27 11/201/27 1222 | f 11/201/27 15/203/27 193/202/27 1223 | f 194/204/27 193/202/27 15/203/27 1224 | f 15/203/27 14/205/27 194/204/27 1225 | f 95/206/27 94/207/27 186/189/27 1226 | f 186/189/27 185/188/27 95/206/27 1227 | f 195/208/27 95/206/27 185/188/27 1228 | f 185/188/27 188/192/27 195/208/27 1229 | f 196/209/27 195/208/27 188/192/27 1230 | f 188/192/27 189/194/27 196/209/27 1231 | f 197/210/27 196/209/27 189/194/27 1232 | f 189/194/27 190/196/27 197/210/27 1233 | f 198/211/27 197/210/27 190/196/27 1234 | f 190/196/27 191/198/27 198/211/27 1235 | f 199/212/27 198/211/27 191/198/27 1236 | f 191/198/27 192/200/27 199/212/27 1237 | f 200/213/27 199/212/27 192/200/27 1238 | f 192/200/27 193/202/27 200/213/27 1239 | f 201/214/27 200/213/27 193/202/27 1240 | f 193/202/27 194/204/27 201/214/27 1241 | f 202/215/28 194/216/28 14/217/28 1242 | f 14/217/28 24/218/28 202/215/28 1243 | f 203/219/28 202/215/28 24/218/28 1244 | f 24/218/28 23/220/28 203/219/28 1245 | f 204/221/28 203/219/28 23/220/28 1246 | f 23/220/28 40/222/28 204/221/28 1247 | f 205/223/28 204/221/28 40/222/28 1248 | f 40/222/28 51/224/28 205/223/28 1249 | f 206/225/28 205/223/28 51/224/28 1250 | f 51/224/28 61/226/28 206/225/28 1251 | f 207/227/28 206/225/28 61/226/28 1252 | f 61/226/28 71/228/28 207/227/28 1253 | f 208/229/28 207/227/28 71/228/28 1254 | f 71/228/28 81/230/28 208/229/28 1255 | f 209/231/28 208/229/28 81/230/28 1256 | f 81/230/28 92/232/28 209/231/28 1257 | f 111/233/28 201/234/28 194/216/28 1258 | f 194/216/28 202/215/28 111/233/28 1259 | f 112/235/28 111/233/28 202/215/28 1260 | f 202/215/28 203/219/28 112/235/28 1261 | f 128/236/28 112/235/28 203/219/28 1262 | f 203/219/28 204/221/28 128/236/28 1263 | f 140/237/28 128/236/28 204/221/28 1264 | f 204/221/28 205/223/28 140/237/28 1265 | f 148/238/28 140/237/28 205/223/28 1266 | f 205/223/28 206/225/28 148/238/28 1267 | f 159/239/28 148/238/28 206/225/28 1268 | f 206/225/28 207/227/28 159/239/28 1269 | f 171/240/28 159/239/28 207/227/28 1270 | f 207/227/28 208/229/28 171/240/28 1271 | f 210/241/28 171/240/28 208/229/28 1272 | f 208/229/28 209/231/28 210/241/28 1273 | f 211/242/29 209/243/29 92/244/29 1274 | f 92/244/29 91/245/29 211/242/29 1275 | f 212/246/29 211/242/29 91/245/29 1276 | f 91/245/29 90/247/29 212/246/29 1277 | f 213/248/29 212/246/29 90/247/29 1278 | f 90/247/29 89/249/29 213/248/29 1279 | f 214/250/29 213/248/29 89/249/29 1280 | f 89/249/29 88/251/29 214/250/29 1281 | f 215/252/29 214/250/29 88/251/29 1282 | f 88/251/29 87/253/29 215/252/29 1283 | f 216/254/29 215/252/29 87/253/29 1284 | f 87/253/29 85/255/29 216/254/29 1285 | f 217/256/29 216/254/29 85/255/29 1286 | f 85/255/29 82/257/29 217/256/29 1287 | f 218/258/29 217/256/29 82/257/29 1288 | f 82/257/29 83/259/29 218/258/29 1289 | f 180/260/29 210/261/29 209/243/29 1290 | f 209/243/29 211/242/29 180/260/29 1291 | f 179/262/29 180/260/29 211/242/29 1292 | f 211/242/29 212/246/29 179/262/29 1293 | f 178/263/29 179/262/29 212/246/29 1294 | f 212/246/29 213/248/29 178/263/29 1295 | f 177/264/29 178/263/29 213/248/29 1296 | f 213/248/29 214/250/29 177/264/29 1297 | f 174/265/29 177/264/29 214/250/29 1298 | f 214/250/29 215/252/29 174/265/29 1299 | f 175/266/29 174/265/29 215/252/29 1300 | f 215/252/29 216/254/29 175/266/29 1301 | f 172/267/29 175/266/29 216/254/29 1302 | f 216/254/29 217/256/29 172/267/29 1303 | f 173/268/29 172/267/29 217/256/29 1304 | f 217/256/29 218/258/29 173/268/29 1305 | f 219/269/30 218/270/30 83/271/30 1306 | f 83/271/30 73/272/30 219/269/30 1307 | f 220/273/30 219/269/30 73/272/30 1308 | f 73/272/30 63/274/30 220/273/30 1309 | f 221/275/30 220/273/30 63/274/30 1310 | f 63/274/30 53/276/30 221/275/30 1311 | f 222/277/30 221/275/30 53/276/30 1312 | f 53/276/30 42/278/30 222/277/30 1313 | f 223/279/30 222/277/30 42/278/30 1314 | f 42/278/30 28/280/30 223/279/30 1315 | f 224/281/30 223/279/30 28/280/30 1316 | f 28/280/30 19/282/30 224/281/30 1317 | f 225/283/30 224/281/30 19/282/30 1318 | f 19/282/30 18/284/30 225/283/30 1319 | f 186/285/30 225/283/30 18/284/30 1320 | f 18/284/30 187/286/30 186/285/30 1321 | f 161/287/30 173/288/30 218/270/30 1322 | f 218/270/30 219/269/30 161/287/30 1323 | f 151/289/30 161/287/30 219/269/30 1324 | f 219/269/30 220/273/30 151/289/30 1325 | f 142/290/30 151/289/30 220/273/30 1326 | f 220/273/30 221/275/30 142/290/30 1327 | f 130/291/30 142/290/30 221/275/30 1328 | f 221/275/30 222/277/30 130/291/30 1329 | f 131/292/30 130/291/30 222/277/30 1330 | f 222/277/30 223/279/30 131/292/30 1331 | f 105/293/30 131/292/30 223/279/30 1332 | f 223/279/30 224/281/30 105/293/30 1333 | f 106/294/30 105/293/30 224/281/30 1334 | f 224/281/30 225/283/30 106/294/30 1335 | f 94/295/30 106/294/30 225/283/30 1336 | f 225/283/30 186/285/30 94/295/30 1337 | f 62/62/1 226/296/1 227/297/1 1338 | f 227/297/1 52/52/1 62/62/1 1339 | f 155/158/9 165/168/9 228/298/9 1340 | f 228/298/9 144/144/9 155/158/9 1341 | f 62/62/1 72/72/1 84/84/1 1342 | f 84/84/1 226/296/1 62/62/1 1343 | f 163/166/9 176/179/9 175/178/9 1344 | f 163/166/9 175/178/9 172/175/9 1345 | f 163/166/9 172/175/9 160/163/9 1346 | f 226/299/28 84/300/28 163/301/28 1347 | f 226/299/28 163/301/28 162/302/28 1348 | f 226/299/28 162/302/28 152/303/28 1349 | f 226/299/28 152/303/28 227/304/28 1350 | f 86/305/27 75/306/27 164/307/27 1351 | f 86/305/27 164/307/27 176/308/27 1352 | f 86/305/27 176/308/27 163/309/27 1353 | f 86/305/27 163/309/27 84/310/27 1354 | f 74/311/30 65/312/30 228/313/30 1355 | f 74/311/30 228/313/30 165/314/30 1356 | f 74/311/30 165/314/30 164/315/30 1357 | f 74/311/30 164/315/30 75/316/30 1358 | f 153/317/29 228/318/29 65/319/29 1359 | f 153/317/29 65/319/29 64/320/29 1360 | f 153/317/29 64/320/29 227/321/29 1361 | f 153/317/29 227/321/29 152/152/29 1362 | f 67/67/1 55/55/1 65/65/1 1363 | f 65/65/1 74/74/1 67/67/1 1364 | f 150/322/23 141/323/18 152/303/24 1365 | f 152/156/24 162/165/9 150/150/23 1366 | f 54/54/1 52/52/1 227/297/1 1367 | f 227/297/1 64/64/1 54/54/1 1368 | f 144/144/9 228/298/9 153/155/9 1369 | f 153/155/9 143/143/20 144/144/9 1370 | f 229/324/31 11/11/4 12/12/5 1371 | f 230/325/32 200/326/33 231/327/34 1372 | f 48/48/8 232/328/35 233/329/36 1373 | f 234/330/37 137/137/17 123/123/13 1374 | f 137/137/17 234/330/37 235/331/9 1375 | f 235/331/9 136/136/9 137/137/17 1376 | f 139/139/9 138/138/9 149/149/22 1377 | f 139/139/9 149/149/22 147/147/22 1378 | f 147/147/22 136/136/9 235/331/9 1379 | f 139/139/9 147/147/22 235/331/9 1380 | f 48/48/8 47/47/1 59/59/7 1381 | f 59/59/7 232/328/35 48/48/8 1382 | f 236/332/38 229/333/39 12/334/40 1383 | f 12/334/40 237/335/41 236/332/38 1384 | f 235/336/27 59/337/27 49/338/27 1385 | f 49/338/27 139/339/27 235/336/27 1386 | f 230/340/29 238/341/29 229/342/29 1387 | f 229/342/29 236/343/29 230/340/29 1388 | f 238/344/42 230/345/42 231/346/42 1389 | f 231/346/42 16/347/42 238/344/42 1390 | f 15/15/6 11/11/4 229/324/31 1391 | f 229/324/31 238/348/43 15/15/6 1392 | f 239/349/9 240/350/9 241/351/9 1393 | f 241/351/9 242/352/9 239/349/9 1394 | f 236/332/44 237/335/44 199/353/44 1395 | f 18/18/7 17/17/1 243/354/1 1396 | f 243/354/1 187/355/6 18/18/7 1397 | f 15/15/6 238/348/43 16/16/2 1398 | f 244/356/9 245/357/9 246/358/9 1399 | f 246/358/9 247/359/9 244/356/9 1400 | f 248/360/9 249/361/9 250/362/9 1401 | f 250/362/9 251/363/9 248/360/9 1402 | f 252/364/45 253/365/46 254/366/47 1403 | f 254/366/47 255/367/48 252/364/45 1404 | f 111/111/9 110/110/9 256/368/49 1405 | f 256/368/49 201/369/9 111/111/9 1406 | f 31/31/1 30/30/1 26/26/1 1407 | f 26/26/1 25/25/1 31/31/1 1408 | f 33/33/1 257/370/1 29/29/1 1409 | f 29/29/1 32/32/1 33/33/1 1410 | f 48/48/8 233/329/36 35/35/7 1411 | f 35/35/7 34/34/1 48/48/8 1412 | f 105/105/9 108/108/9 258/371/9 1413 | f 258/371/9 131/131/15 105/105/9 1414 | f 125/372/50 139/373/30 49/374/30 1415 | f 125/372/50 49/374/30 38/375/51 1416 | f 125/372/50 38/375/51 37/376/52 1417 | f 125/372/50 37/376/52 126/377/53 1418 | f 123/378/54 233/379/55 232/380/56 1419 | f 232/380/56 234/381/57 123/378/54 1420 | f 20/382/28 27/383/28 258/384/28 1421 | f 20/382/28 258/384/28 108/385/28 1422 | f 93/386/28 243/387/28 17/388/28 1423 | f 107/389/28 93/386/28 17/388/28 1424 | f 108/385/28 107/389/28 17/388/28 1425 | f 20/382/28 108/385/28 17/388/28 1426 | f 258/390/27 27/391/27 26/392/27 1427 | f 113/393/27 258/390/27 26/392/27 1428 | f 114/394/27 113/393/27 26/392/27 1429 | f 114/394/27 26/392/27 30/395/27 1430 | f 117/396/27 114/394/27 30/395/27 1431 | f 117/396/27 30/395/27 29/397/58 1432 | f 127/398/27 126/399/27 37/400/27 1433 | f 37/400/27 39/401/27 127/398/27 1434 | f 21/402/30 13/403/30 256/404/30 1435 | f 21/402/30 256/404/30 110/405/30 1436 | f 127/406/59 39/407/60 22/408/61 1437 | f 109/409/30 127/406/59 22/408/61 1438 | f 110/405/30 109/409/30 22/408/61 1439 | f 21/402/30 110/405/30 22/408/61 1440 | f 243/410/29 93/411/29 96/412/29 1441 | f 3/413/29 243/410/29 96/412/29 1442 | f 3/413/29 96/412/29 259/414/29 1443 | f 4/415/29 3/413/29 259/414/29 1444 | f 4/415/29 259/414/29 260/416/29 1445 | f 6/417/29 4/415/29 260/416/29 1446 | f 6/417/29 260/416/29 261/418/29 1447 | f 231/419/29 256/420/29 13/421/29 1448 | f 13/421/29 16/422/29 231/419/29 1449 | f 184/423/27 183/424/27 170/425/27 1450 | f 170/425/27 171/426/27 184/423/27 1451 | f 183/427/30 182/428/30 180/429/30 1452 | f 180/429/30 170/430/30 183/427/30 1453 | f 181/431/28 184/432/28 171/240/28 1454 | f 171/240/28 210/241/28 181/431/28 1455 | f 182/433/29 181/434/29 210/261/29 1456 | f 210/261/29 180/260/29 182/433/29 1457 | f 246/435/30 245/436/30 96/437/30 1458 | f 96/437/30 95/438/30 246/435/30 1459 | f 244/439/28 247/440/28 195/441/28 1460 | f 195/441/28 259/442/28 244/439/28 1461 | f 247/443/27 246/444/27 95/206/27 1462 | f 95/206/27 195/208/27 247/443/27 1463 | f 245/445/29 244/446/29 259/414/29 1464 | f 259/414/29 96/412/29 245/445/29 1465 | f 100/447/28 99/448/28 196/449/28 1466 | f 196/449/28 260/450/28 100/447/28 1467 | f 97/451/29 100/452/29 260/416/29 1468 | f 260/416/29 259/414/29 97/451/29 1469 | f 98/453/30 97/454/30 259/455/30 1470 | f 259/455/30 195/456/30 98/453/30 1471 | f 99/457/27 98/458/27 195/208/27 1472 | f 195/208/27 196/209/27 99/457/27 1473 | f 248/459/28 251/460/28 197/461/28 1474 | f 197/461/28 261/462/28 248/459/28 1475 | f 251/463/27 250/464/27 196/209/27 1476 | f 196/209/27 197/210/27 251/463/27 1477 | f 249/465/29 248/466/29 261/418/29 1478 | f 261/418/29 260/416/29 249/465/29 1479 | f 250/467/30 249/468/30 260/469/30 1480 | f 260/469/30 196/470/30 250/467/30 1481 | f 104/471/28 103/472/28 198/473/28 1482 | f 198/473/28 262/474/28 104/471/28 1483 | f 101/475/29 104/476/29 262/477/29 1484 | f 262/477/29 261/418/29 101/475/29 1485 | f 102/478/30 101/479/30 261/480/30 1486 | f 261/480/30 197/481/30 102/478/30 1487 | f 103/482/27 102/483/27 197/210/27 1488 | f 197/210/27 198/211/27 103/482/27 1489 | f 255/484/62 254/485/62 198/211/62 1490 | f 198/211/62 199/212/62 255/484/62 1491 | f 252/486/63 255/487/63 199/353/63 1492 | f 199/353/64 237/335/64 252/486/64 1493 | f 263/488/65 264/489/65 265/490/65 1494 | f 265/490/65 266/491/65 263/488/65 1495 | f 254/492/66 253/493/66 262/494/66 1496 | f 262/494/67 198/495/67 254/492/67 1497 | f 239/496/27 242/497/27 199/212/27 1498 | f 199/212/27 200/213/27 239/496/27 1499 | f 240/498/68 239/499/68 200/500/68 1500 | f 200/500/68 230/501/68 240/498/68 1501 | f 241/502/29 240/503/29 230/340/29 1502 | f 230/340/29 236/343/29 241/502/29 1503 | f 242/504/69 241/505/69 236/506/69 1504 | f 236/506/69 199/507/69 242/504/69 1505 | f 267/508/70 268/509/70 253/365/70 1506 | f 253/365/70 252/364/70 267/508/70 1507 | f 269/510/71 270/511/71 237/512/71 1508 | f 237/512/71 262/513/71 269/510/71 1509 | f 270/514/72 267/515/72 252/486/72 1510 | f 252/486/73 237/335/73 270/514/73 1511 | f 268/516/74 269/517/74 262/494/74 1512 | f 262/494/75 253/493/75 268/516/75 1513 | f 266/518/76 265/519/76 270/511/76 1514 | f 270/511/76 269/510/76 266/518/76 1515 | f 269/517/77 268/516/77 263/520/77 1516 | f 264/489/78 263/488/78 268/509/78 1517 | f 268/509/78 267/508/78 264/489/78 1518 | f 270/514/79 265/521/79 264/522/79 1519 | f 24/24/1 14/14/2 13/13/2 1520 | f 13/13/2 21/21/1 24/24/1 1521 | f 19/19/6 28/28/7 27/27/2 1522 | f 27/27/2 20/20/2 19/19/6 1523 | f 35/35/7 257/370/1 33/33/1 1524 | f 36/36/7 40/40/1 39/39/6 1525 | f 39/39/6 37/37/7 36/36/7 1526 | f 106/106/9 94/94/9 93/93/9 1527 | f 93/93/9 107/107/9 106/106/9 1528 | f 123/123/13 137/137/17 122/122/12 1529 | f 112/112/9 128/128/9 127/127/9 1530 | f 127/127/9 109/109/9 112/112/9 1531 | f 2/2/2 187/355/6 243/354/1 1532 | f 243/354/1 3/3/1 2/2/2 1533 | f 200/326/33 201/369/9 256/368/49 1534 | f 256/368/49 231/327/34 200/326/33 1535 | f 116/116/10 131/131/15 258/371/9 1536 | f 258/371/9 113/113/9 116/116/10 1537 | f 235/523/28 234/524/57 232/525/56 1538 | f 232/525/56 59/526/28 235/523/28 1539 | f 35/527/80 233/379/27 123/378/81 1540 | f 35/35/80 123/528/81 121/117/82 1541 | f 35/35/80 121/117/82 119/119/83 1542 | f 257/529/84 35/530/80 119/531/83 1543 | f 119/532/83 117/396/27 29/397/58 1544 | f 29/533/58 257/370/84 119/119/83 1545 | f 262/477/29 237/534/29 12/535/29 1546 | f 262/477/29 12/535/29 10/536/29 1547 | f 262/477/29 10/536/29 8/537/29 1548 | f 262/477/29 8/537/29 6/417/29 1549 | f 261/418/29 262/477/29 6/417/29 1550 | f 263/520/85 266/538/85 269/517/85 1551 | f 264/522/86 267/515/86 270/514/86 1552 | f 271/539/1 272/540/1 273/541/1 1553 | f 273/541/1 274/542/1 271/539/1 1554 | f 275/543/9 276/544/9 277/545/9 1555 | f 277/545/9 278/546/9 275/543/9 1556 | f 271/547/27 274/548/27 276/549/27 1557 | f 276/549/27 275/550/27 271/547/27 1558 | f 274/551/28 273/552/28 277/553/28 1559 | f 277/553/28 276/554/28 274/551/28 1560 | f 273/555/29 272/556/29 278/557/29 1561 | f 278/557/29 277/558/29 273/555/29 1562 | f 272/559/30 271/560/30 275/561/30 1563 | f 275/561/30 278/562/30 272/559/30 1564 | f 279/563/1 280/564/1 281/565/1 1565 | f 281/565/1 282/566/1 279/563/1 1566 | f 283/567/9 284/568/9 285/569/9 1567 | f 285/569/9 286/570/9 283/567/9 1568 | f 279/571/27 282/572/27 284/573/27 1569 | f 284/573/27 283/574/27 279/571/27 1570 | f 282/575/28 281/576/28 285/577/28 1571 | f 285/577/28 284/578/28 282/575/28 1572 | f 281/579/29 280/580/29 286/581/29 1573 | f 286/581/29 285/582/29 281/579/29 1574 | f 280/583/30 279/584/30 283/585/30 1575 | f 283/585/30 286/586/30 280/583/30 1576 | f 287/587/1 288/588/1 289/589/1 1577 | f 289/589/1 290/590/1 287/587/1 1578 | f 291/591/9 292/592/9 293/593/9 1579 | f 293/593/9 294/594/9 291/591/9 1580 | f 287/595/27 290/596/27 292/597/27 1581 | f 292/597/27 291/598/27 287/595/27 1582 | f 290/599/28 289/600/28 293/601/28 1583 | f 293/601/28 292/602/28 290/599/28 1584 | f 289/603/29 288/604/29 294/605/29 1585 | f 294/605/29 293/606/29 289/603/29 1586 | f 288/607/30 287/608/30 291/609/30 1587 | f 291/609/30 294/610/30 288/607/30 1588 | # 580 faces 1589 | 1590 | -------------------------------------------------------------------------------- /examples/mesh/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 24 | 25 | 29 | 30 | 34 | 35 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 47 | 53 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /examples/multiple/floor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/examples/multiple/floor.jpg -------------------------------------------------------------------------------- /examples/multiple/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 50 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /examples/shots/basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/examples/shots/basic.png -------------------------------------------------------------------------------- /examples/shots/custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/examples/shots/custom.png -------------------------------------------------------------------------------- /examples/shots/mesh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/examples/shots/mesh.png -------------------------------------------------------------------------------- /examples/shots/multiple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/examples/shots/multiple.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A-Frame Teleport Controls Component 6 | 7 | 48 | 49 | 50 |

A-Frame Teleport Controls Component

51 | 52 |
    53 |
  • 54 | 55 |

    Basic

    56 |

    This is a basic example.

    57 |
  • 58 |
59 | 60 |
    61 |
  • 62 | 63 |

    Mesh

    64 |

    An example using a OBJ model as collision mesh.

    65 |
  • 66 |
67 | 68 |
    69 |
  • 70 | 71 |

    Custom

    72 |

    Customized teleporter ray and target.

    73 |
  • 74 |
75 | 76 |
    77 |
  • 78 | 79 |

    Multiple

    80 |

    Select multiple groups of collision entities using selectors.

    81 |
  • 82 |
83 | 84 |
    85 |
  • 86 | 87 |

    Dynamic

    88 |

    Handles dynamically-appended entities.

    89 |
  • 90 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* global THREE, AFRAME, Element */ 2 | var cylinderTexture = require('./lib/cylinderTexture'); 3 | var parabolicCurve = require('./lib/ParabolicCurve'); 4 | var RayCurve = require('./lib/RayCurve'); 5 | 6 | if (typeof AFRAME === 'undefined') { 7 | throw new Error('Component attempted to register before AFRAME was available.'); 8 | } 9 | 10 | if (!Element.prototype.matches) { 11 | Element.prototype.matches = 12 | Element.prototype.matchesSelector || 13 | Element.prototype.mozMatchesSelector || 14 | Element.prototype.msMatchesSelector || 15 | Element.prototype.oMatchesSelector || 16 | Element.prototype.webkitMatchesSelector || 17 | function (s) { 18 | var matches = (this.document || this.ownerDocument).querySelectorAll(s); 19 | var i = matches.length; 20 | while (--i >= 0 && matches.item(i) !== this) { /* no-op */ } 21 | return i > -1; 22 | }; 23 | } 24 | 25 | AFRAME.registerComponent('teleport-controls', { 26 | schema: { 27 | type: {default: 'parabolic', oneOf: ['parabolic', 'line']}, 28 | button: {default: 'trackpad', oneOf: ['trackpad', 'trigger', 'grip', 'menu']}, 29 | startEvents: {type: 'array'}, 30 | endEvents: {type: 'array'}, 31 | collisionEntities: {default: ''}, 32 | hitEntity: {type: 'selector'}, 33 | cameraRig: {type: 'selector'}, 34 | teleportOrigin: {type: 'selector'}, 35 | hitCylinderColor: {type: 'color', default: '#99ff99'}, 36 | hitCylinderRadius: {default: 0.25, min: 0}, 37 | hitCylinderHeight: {default: 0.3, min: 0}, 38 | interval: {default: 0}, 39 | maxLength: {default: 10, min: 0, if: {type: ['line']}}, 40 | curveNumberPoints: {default: 30, min: 2, if: {type: ['parabolic']}}, 41 | curveLineWidth: {default: 0.025}, 42 | curveHitColor: {type: 'color', default: '#99ff99'}, 43 | curveMissColor: {type: 'color', default: '#ff0000'}, 44 | curveShootingSpeed: {default: 5, min: 0, if: {type: ['parabolic']}}, 45 | defaultPlaneSize: { default: 100 }, 46 | landingNormal: {type: 'vec3', default: { x: 0, y: 1, z: 0 }}, 47 | landingMaxAngle: {default: '45', min: 0, max: 360}, 48 | drawIncrementally: {default: false}, 49 | incrementalDrawMs: {default: 700}, 50 | missOpacity: {default: 1.0}, 51 | hitOpacity: {default: 1.0} 52 | }, 53 | 54 | init: function () { 55 | var data = this.data; 56 | var el = this.el; 57 | var teleportEntity; 58 | var i; 59 | 60 | this.active = false; 61 | this.obj = el.object3D; 62 | this.hitPoint = new THREE.Vector3(); 63 | this.rigWorldPosition = new THREE.Vector3(); 64 | this.newRigWorldPosition = new THREE.Vector3(); 65 | this.teleportEventDetail = { 66 | oldPosition: this.rigWorldPosition, 67 | newPosition: this.newRigWorldPosition, 68 | hitPoint: this.hitPoint 69 | }; 70 | 71 | this.hit = false; 72 | this.prevCheckTime = undefined; 73 | this.prevHitHeight = 0; 74 | this.referenceNormal = new THREE.Vector3(); 75 | this.curveMissColor = new THREE.Color(); 76 | this.curveHitColor = new THREE.Color(); 77 | this.raycaster = new THREE.Raycaster(); 78 | 79 | this.defaultPlane = createDefaultPlane(this.data.defaultPlaneSize); 80 | this.defaultCollisionMeshes = [this.defaultPlane]; 81 | 82 | teleportEntity = this.teleportEntity = document.createElement('a-entity'); 83 | teleportEntity.classList.add('teleportRay'); 84 | teleportEntity.setAttribute('visible', false); 85 | el.sceneEl.appendChild(this.teleportEntity); 86 | 87 | this.onButtonDown = this.onButtonDown.bind(this); 88 | this.onButtonUp = this.onButtonUp.bind(this); 89 | if (this.data.startEvents.length && this.data.endEvents.length) { 90 | 91 | for (i = 0; i < this.data.startEvents.length; i++) { 92 | el.addEventListener(this.data.startEvents[i], this.onButtonDown); 93 | } 94 | for (i = 0; i < this.data.endEvents.length; i++) { 95 | el.addEventListener(this.data.endEvents[i], this.onButtonUp); 96 | } 97 | } else { 98 | el.addEventListener(data.button + 'down', this.onButtonDown); 99 | el.addEventListener(data.button + 'up', this.onButtonUp); 100 | } 101 | 102 | this.queryCollisionEntities(); 103 | }, 104 | 105 | update: function (oldData) { 106 | var data = this.data; 107 | var diff = AFRAME.utils.diff(data, oldData); 108 | 109 | // Update normal. 110 | this.referenceNormal.copy(data.landingNormal); 111 | 112 | // Update colors. 113 | this.curveMissColor.set(data.curveMissColor); 114 | this.curveHitColor.set(data.curveHitColor); 115 | 116 | 117 | // Create or update line mesh. 118 | if (!this.line || 119 | 'curveLineWidth' in diff || 'curveNumberPoints' in diff || 'type' in diff) { 120 | 121 | this.line = createLine(data); 122 | this.line.material.opacity = this.data.hitOpacity; 123 | this.line.material.transparent = this.data.hitOpacity < 1; 124 | this.numActivePoints = data.curveNumberPoints; 125 | this.teleportEntity.setObject3D('mesh', this.line.mesh); 126 | } 127 | 128 | // Create or update hit entity. 129 | if (data.hitEntity) { 130 | this.hitEntity = data.hitEntity; 131 | } else if (!this.hitEntity || 'hitCylinderColor' in diff || 'hitCylinderHeight' in diff || 132 | 'hitCylinderRadius' in diff) { 133 | // Remove previous entity, create new entity (could be more performant). 134 | if (this.hitEntity) { this.hitEntity.parentNode.removeChild(this.hitEntity); } 135 | this.hitEntity = createHitEntity(data); 136 | this.el.sceneEl.appendChild(this.hitEntity); 137 | } 138 | this.hitEntity.setAttribute('visible', false); 139 | 140 | if ('collisionEntities' in diff) { this.queryCollisionEntities(); } 141 | }, 142 | 143 | remove: function () { 144 | var el = this.el; 145 | var hitEntity = this.hitEntity; 146 | var teleportEntity = this.teleportEntity; 147 | 148 | if (hitEntity) { hitEntity.parentNode.removeChild(hitEntity); } 149 | if (teleportEntity) { teleportEntity.parentNode.removeChild(teleportEntity); } 150 | 151 | el.sceneEl.removeEventListener('child-attached', this.childAttachHandler); 152 | el.sceneEl.removeEventListener('child-detached', this.childDetachHandler); 153 | }, 154 | 155 | tick: (function () { 156 | var p0 = new THREE.Vector3(); 157 | var v0 = new THREE.Vector3(); 158 | var g = -9.8; 159 | var a = new THREE.Vector3(0, g, 0); 160 | var next = new THREE.Vector3(); 161 | var last = new THREE.Vector3(); 162 | var quaternion = new THREE.Quaternion(); 163 | var translation = new THREE.Vector3(); 164 | var scale = new THREE.Vector3(); 165 | var shootAngle = new THREE.Vector3(); 166 | var lastNext = new THREE.Vector3(); 167 | var auxDirection = new THREE.Vector3(); 168 | var timeSinceDrawStart = 0; 169 | 170 | return function (time, delta) { 171 | if (!this.active) { return; } 172 | if (this.data.drawIncrementally && this.redrawLine){ 173 | this.redrawLine = false; 174 | timeSinceDrawStart = 0; 175 | } 176 | timeSinceDrawStart += delta; 177 | this.numActivePoints = this.data.curveNumberPoints*timeSinceDrawStart/this.data.incrementalDrawMs; 178 | if (this.numActivePoints > this.data.curveNumberPoints){ 179 | this.numActivePoints = this.data.curveNumberPoints; 180 | } 181 | 182 | // Only check for intersection if interval time has passed. 183 | if (this.prevCheckTime && (time - this.prevCheckTime < this.data.interval)) { return; } 184 | // Update check time. 185 | this.prevCheckTime = time; 186 | 187 | var matrixWorld = this.obj.matrixWorld; 188 | matrixWorld.decompose(translation, quaternion, scale); 189 | 190 | var direction = shootAngle.set(0, 0, -1) 191 | .applyQuaternion(quaternion).normalize(); 192 | this.line.setDirection(auxDirection.copy(direction)); 193 | this.obj.getWorldPosition(p0); 194 | 195 | last.copy(p0); 196 | 197 | // Set default status as non-hit 198 | this.teleportEntity.setAttribute('visible', true); 199 | this.line.material.color.set(this.curveMissColor); 200 | this.line.material.opacity = this.data.missOpacity; 201 | this.line.material.transparent = this.data.missOpacity < 1; 202 | this.hitEntity.setAttribute('visible', false); 203 | this.hit = false; 204 | 205 | if (this.data.type === 'parabolic') { 206 | v0.copy(direction).multiplyScalar(this.data.curveShootingSpeed); 207 | 208 | this.lastDrawnIndex = 0; 209 | const numPoints = this.data.drawIncrementally ? this.numActivePoints : this.line.numPoints; 210 | for (var i = 0; i < numPoints+1; i++) { 211 | var t; 212 | if (i == Math.floor(numPoints+1)){ 213 | t = numPoints / (this.line.numPoints - 1); 214 | } 215 | else { 216 | t = i / (this.line.numPoints - 1); 217 | } 218 | parabolicCurve(p0, v0, a, t, next); 219 | // Update the raycaster with the length of the current segment last->next 220 | var dirLastNext = lastNext.copy(next).sub(last).normalize(); 221 | this.raycaster.far = dirLastNext.length(); 222 | this.raycaster.set(last, dirLastNext); 223 | 224 | this.lastDrawnPoint = next; 225 | this.lastDrawnIndex = i; 226 | if (this.checkMeshCollisions(i, next)) { break; } 227 | 228 | last.copy(next); 229 | } 230 | for (var j = this.lastDrawnIndex+1; j < this.line.numPoints; j++) { 231 | this.line.setPoint(j, this.lastDrawnPoint); 232 | } 233 | } else if (this.data.type === 'line') { 234 | next.copy(last).add(auxDirection.copy(direction).multiplyScalar(this.data.maxLength)); 235 | this.raycaster.far = this.data.maxLength; 236 | this.raycaster.set(p0, direction); 237 | this.line.setPoint(0, p0); 238 | 239 | this.checkMeshCollisions(1, next); 240 | } 241 | }; 242 | })(), 243 | 244 | /** 245 | * Run `querySelectorAll` for `collisionEntities` and maintain it with `child-attached` 246 | * and `child-detached` events. 247 | */ 248 | queryCollisionEntities: function () { 249 | var collisionEntities; 250 | var data = this.data; 251 | var el = this.el; 252 | 253 | if (!data.collisionEntities) { 254 | this.collisionEntities = []; 255 | return; 256 | } 257 | 258 | collisionEntities = [].slice.call(el.sceneEl.querySelectorAll(data.collisionEntities)); 259 | this.collisionEntities = collisionEntities; 260 | 261 | // Update entity list on attach. 262 | this.childAttachHandler = function childAttachHandler (evt) { 263 | if (!evt.detail.el.matches(data.collisionEntities)) { return; } 264 | collisionEntities.push(evt.detail.el); 265 | }; 266 | el.sceneEl.addEventListener('child-attached', this.childAttachHandler); 267 | 268 | // Update entity list on detach. 269 | this.childDetachHandler = function childDetachHandler (evt) { 270 | var index; 271 | if (!evt.detail.el.matches(data.collisionEntities)) { return; } 272 | index = collisionEntities.indexOf(evt.detail.el); 273 | if (index === -1) { return; } 274 | collisionEntities.splice(index, 1); 275 | }; 276 | el.sceneEl.addEventListener('child-detached', this.childDetachHandler); 277 | }, 278 | 279 | onButtonDown: function () { 280 | this.active = true; 281 | this.redrawLine = true; 282 | }, 283 | 284 | /** 285 | * Jump! 286 | */ 287 | onButtonUp: (function () { 288 | const teleportOriginWorldPosition = new THREE.Vector3(); 289 | const newRigLocalPosition = new THREE.Vector3(); 290 | const newHandPosition = [new THREE.Vector3(), new THREE.Vector3()]; // Left and right 291 | const handPosition = new THREE.Vector3(); 292 | 293 | return function (evt) { 294 | if (!this.active) { return; } 295 | 296 | // Hide the hit point and the curve 297 | this.active = false; 298 | this.hitEntity.setAttribute('visible', false); 299 | this.teleportEntity.setAttribute('visible', false); 300 | 301 | if (!this.hit) { 302 | // Button released but not hit point 303 | return; 304 | } 305 | 306 | const rig = this.data.cameraRig || this.el.sceneEl.camera.el; 307 | rig.object3D.getWorldPosition(this.rigWorldPosition); 308 | this.newRigWorldPosition.copy(this.hitPoint); 309 | 310 | // If a teleportOrigin exists, offset the rig such that the teleportOrigin is above the hitPoint 311 | const teleportOrigin = this.data.teleportOrigin; 312 | if (teleportOrigin) { 313 | teleportOrigin.object3D.getWorldPosition(teleportOriginWorldPosition); 314 | this.newRigWorldPosition.sub(teleportOriginWorldPosition).add(this.rigWorldPosition); 315 | } 316 | 317 | // Always keep the rig at the same offset off the ground after teleporting 318 | this.newRigWorldPosition.y = this.rigWorldPosition.y + this.hitPoint.y - this.prevHitHeight; 319 | this.prevHitHeight = this.hitPoint.y; 320 | 321 | // Finally update the rigs position 322 | newRigLocalPosition.copy(this.newRigWorldPosition); 323 | if (rig.object3D.parent) { 324 | rig.object3D.parent.worldToLocal(newRigLocalPosition); 325 | } 326 | rig.setAttribute('position', newRigLocalPosition); 327 | 328 | // If a rig was not explicitly declared, look for hands and mvoe them proportionally as well 329 | if (!this.data.cameraRig) { 330 | var hands = document.querySelectorAll('a-entity[tracked-controls]'); 331 | for (var i = 0; i < hands.length; i++) { 332 | hands[i].object3D.getWorldPosition(handPosition); 333 | 334 | // diff = rigWorldPosition - handPosition 335 | // newPos = newRigWorldPosition - diff 336 | newHandPosition[i].copy(this.newRigWorldPosition).sub(this.rigWorldPosition).add(handPosition); 337 | hands[i].setAttribute('position', newHandPosition[i]); 338 | } 339 | } 340 | 341 | this.el.emit('teleported', this.teleportEventDetail); 342 | }; 343 | })(), 344 | 345 | /** 346 | * Check for raycaster intersection. 347 | * 348 | * @param {number} Line fragment point index. 349 | * @param {number} Next line fragment point index. 350 | * @returns {boolean} true if there's an intersection. 351 | */ 352 | checkMeshCollisions: function (i, next) { 353 | // @todo We should add a property to define if the collisionEntity is dynamic or static 354 | // If static we should do the map just once, otherwise we're recreating the array in every 355 | // loop when aiming. 356 | var meshes; 357 | if (!this.data.collisionEntities) { 358 | meshes = this.defaultCollisionMeshes; 359 | } else { 360 | meshes = this.collisionEntities.map(function (entity) { 361 | return entity.getObject3D('mesh'); 362 | }).filter(function (n) { return n; }); 363 | meshes = meshes.length ? meshes : this.defaultCollisionMeshes; 364 | } 365 | 366 | var intersects = this.raycaster.intersectObjects(meshes, true); 367 | if (intersects.length > 0 && !this.hit && 368 | this.isValidNormalsAngle(intersects[0].face.normal)) { 369 | var point = intersects[0].point; 370 | 371 | this.line.material.color.set(this.curveHitColor); 372 | this.line.material.opacity = this.data.hitOpacity; 373 | this.line.material.transparent= this.data.hitOpacity < 1; 374 | this.hitEntity.setAttribute('position', point); 375 | this.hitEntity.setAttribute('visible', true); 376 | 377 | this.hit = true; 378 | this.hitPoint.copy(intersects[0].point); 379 | 380 | // If hit, just fill the rest of the points with the hit point and break the loop 381 | for (var j = i; j < this.line.numPoints; j++) { 382 | this.line.setPoint(j, this.hitPoint); 383 | } 384 | return true; 385 | } else { 386 | this.line.setPoint(i, next); 387 | return false; 388 | } 389 | }, 390 | 391 | isValidNormalsAngle: function (collisionNormal) { 392 | var angleNormals = this.referenceNormal.angleTo(collisionNormal); 393 | return (THREE.Math.RAD2DEG * angleNormals <= this.data.landingMaxAngle); 394 | }, 395 | }); 396 | 397 | 398 | function createLine (data) { 399 | var numPoints = data.type === 'line' ? 2 : data.curveNumberPoints; 400 | return new RayCurve(numPoints, data.curveLineWidth); 401 | } 402 | 403 | /** 404 | * Create mesh to represent the area of intersection. 405 | * Default to a combination of torus and cylinder. 406 | */ 407 | function createHitEntity (data) { 408 | var cylinder; 409 | var hitEntity; 410 | var torus; 411 | 412 | // Parent. 413 | hitEntity = document.createElement('a-entity'); 414 | hitEntity.className = 'hitEntity'; 415 | 416 | // Torus. 417 | torus = document.createElement('a-entity'); 418 | torus.setAttribute('geometry', { 419 | primitive: 'torus', 420 | radius: data.hitCylinderRadius, 421 | radiusTubular: 0.01 422 | }); 423 | torus.setAttribute('rotation', {x: 90, y: 0, z: 0}); 424 | torus.setAttribute('material', { 425 | shader: 'flat', 426 | color: data.hitCylinderColor, 427 | side: 'double', 428 | depthTest: false 429 | }); 430 | hitEntity.appendChild(torus); 431 | 432 | // Cylinder. 433 | cylinder = document.createElement('a-entity'); 434 | cylinder.setAttribute('position', {x: 0, y: data.hitCylinderHeight / 2, z: 0}); 435 | cylinder.setAttribute('geometry', { 436 | primitive: 'cylinder', 437 | segmentsHeight: 1, 438 | radius: data.hitCylinderRadius, 439 | height: data.hitCylinderHeight, 440 | openEnded: true 441 | }); 442 | cylinder.setAttribute('material', { 443 | shader: 'flat', 444 | color: data.hitCylinderColor, 445 | side: 'double', 446 | src: cylinderTexture, 447 | transparent: true, 448 | depthTest: false 449 | }); 450 | hitEntity.appendChild(cylinder); 451 | 452 | return hitEntity; 453 | } 454 | 455 | function createDefaultPlane (size) { 456 | var geometry; 457 | var material; 458 | 459 | geometry = new THREE.PlaneBufferGeometry(size, size); 460 | geometry.rotateX(-Math.PI / 2); 461 | material = new THREE.MeshBasicMaterial({color: 0xffff00}); 462 | return new THREE.Mesh(geometry, material); 463 | } 464 | -------------------------------------------------------------------------------- /lib/ParabolicCurve.js: -------------------------------------------------------------------------------- 1 | /* global THREE */ 2 | // Parabolic motion equation, y = p0 + v0*t + 1/2at^2 3 | function parabolicCurveScalar (p0, v0, a, t) { 4 | return p0 + v0 * t + 0.5 * a * t * t; 5 | } 6 | 7 | // Parabolic motion equation applied to 3 dimensions 8 | function parabolicCurve (p0, v0, a, t, out) { 9 | out.x = parabolicCurveScalar(p0.x, v0.x, a.x, t); 10 | out.y = parabolicCurveScalar(p0.y, v0.y, a.y, t); 11 | out.z = parabolicCurveScalar(p0.z, v0.z, a.z, t); 12 | return out; 13 | } 14 | 15 | module.exports = parabolicCurve; 16 | -------------------------------------------------------------------------------- /lib/RayCurve.js: -------------------------------------------------------------------------------- 1 | /* global THREE */ 2 | var RayCurve = function (numPoints, width) { 3 | this.geometry = new THREE.BufferGeometry(); 4 | this.vertices = new Float32Array(numPoints * 3 * 2); 5 | this.uvs = new Float32Array(numPoints * 2 * 2); 6 | this.width = width; 7 | 8 | this.geometry.addAttribute('position', new THREE.BufferAttribute(this.vertices, 3).setDynamic(true)); 9 | 10 | this.material = new THREE.MeshBasicMaterial({ 11 | side: THREE.DoubleSide, 12 | color: 0xff0000 13 | }); 14 | 15 | this.mesh = new THREE.Mesh(this.geometry, this.material); 16 | this.mesh.drawMode = THREE.TriangleStripDrawMode; 17 | 18 | this.mesh.frustumCulled = false; 19 | this.mesh.vertices = this.vertices; 20 | 21 | this.direction = new THREE.Vector3(); 22 | this.numPoints = numPoints; 23 | }; 24 | 25 | RayCurve.prototype = { 26 | setDirection: function (direction) { 27 | var UP = new THREE.Vector3(0, 1, 0); 28 | this.direction 29 | .copy(direction) 30 | .cross(UP) 31 | .normalize() 32 | .multiplyScalar(this.width / 2); 33 | }, 34 | 35 | setWidth: function (width) { 36 | this.width = width; 37 | }, 38 | 39 | setPoint: (function () { 40 | var posA = new THREE.Vector3(); 41 | var posB = new THREE.Vector3(); 42 | 43 | return function (i, point) { 44 | posA.copy(point).add(this.direction); 45 | posB.copy(point).sub(this.direction); 46 | 47 | var idx = 2 * 3 * i; 48 | this.vertices[idx++] = posA.x; 49 | this.vertices[idx++] = posA.y; 50 | this.vertices[idx++] = posA.z; 51 | 52 | this.vertices[idx++] = posB.x; 53 | this.vertices[idx++] = posB.y; 54 | this.vertices[idx++] = posB.z; 55 | 56 | this.geometry.attributes.position.needsUpdate = true; 57 | }; 58 | })() 59 | }; 60 | 61 | module.exports = RayCurve; 62 | -------------------------------------------------------------------------------- /lib/cylinderTexture.js: -------------------------------------------------------------------------------- 1 | module.exports = 'url(data:image/png;base64,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)'; 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aframe-teleport-controls", 3 | "version": "0.3.2", 4 | "description": "A Teleport Controls component for A-Frame.", 5 | "main": "index.js", 6 | "unpkg": "dist/aframe-teleport-controls.min.js", 7 | "scripts": { 8 | "dev": "budo index.js:dist/aframe-teleport-controls.min.js --port 7000 --live --open --ssl", 9 | "dist": "webpack index.js dist/aframe-teleport-controls.js && webpack -p index.js dist/aframe-teleport-controls.min.js", 10 | "lint": "semistandard -v | snazzy", 11 | "prepublish": "npm run dist", 12 | "ghpages": "ghpages", 13 | "start": "npm run dev", 14 | "test": "karma start ./tests/karma.conf.js", 15 | "test:firefox": "karma start ./tests/karma.conf.js --browsers Firefox", 16 | "test:chrome": "karma start ./tests/karma.conf.js --browsers Chrome" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/fernandojsg/aframe-teleport-controls.git" 21 | }, 22 | "keywords": [ 23 | "aframe", 24 | "aframe-component", 25 | "aframe-vr", 26 | "vr", 27 | "mozvr", 28 | "webvr", 29 | "teleport-controls" 30 | ], 31 | "author": "Fernando Serrano ", 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/fernandojsg/aframe-teleport-controls/issues" 35 | }, 36 | "homepage": "https://github.com/fernandojsg/aframe-teleport-controls#readme", 37 | "devDependencies": { 38 | "aframe": "^1.0.4", 39 | "browserify": "^13.0.0", 40 | "budo": "^11.6.3", 41 | "chai": "^3.4.1", 42 | "chai-shallow-deep-equal": "^1.3.0", 43 | "ghpages": "^0.0.8", 44 | "karma": "^0.13.15", 45 | "karma-browserify": "^4.4.2", 46 | "karma-chai-shallow-deep-equal": "0.0.4", 47 | "karma-chrome-launcher": "2.0.0", 48 | "karma-env-preprocessor": "^0.1.1", 49 | "karma-firefox-launcher": "^0.1.7", 50 | "karma-mocha": "^0.2.1", 51 | "karma-mocha-reporter": "^1.1.3", 52 | "karma-sinon-chai": "^1.3.4", 53 | "mocha": "^2.3.4", 54 | "randomcolor": "^0.4.4", 55 | "semistandard": "^8.0.0", 56 | "shelljs": "^0.7.0", 57 | "shx": "^0.1.1", 58 | "sinon": "^1.17.5", 59 | "sinon-chai": "^2.8.0", 60 | "snazzy": "^4.0.0", 61 | "webpack": "^1.13.0" 62 | }, 63 | "semistandard": { 64 | "globals": [ 65 | "AFRAME", 66 | "THREE" 67 | ], 68 | "ignore": [ 69 | "examples/build.js", 70 | "dist/**" 71 | ] 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /teleport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fernandojsg/aframe-teleport-controls/941d4fd20c514f40ea3d81b246cdc1b6cccb3842/teleport.png -------------------------------------------------------------------------------- /tests/__init.test.js: -------------------------------------------------------------------------------- 1 | /* global sinon, setup, teardown */ 2 | 3 | /** 4 | * __init.test.js is run before every test case. 5 | */ 6 | window.debug = true; 7 | var AScene = require('aframe').AScene 8 | 9 | navigator.getVRDisplays = function () { 10 | var resolvePromise = Promise.resolve(); 11 | var mockVRDisplay = { 12 | requestPresent: resolvePromise, 13 | exitPresent: resolvePromise, 14 | getPose: function () { return {orientation: null, position: null}; }, 15 | requestAnimationFrame: function () { return 1; } 16 | }; 17 | return Promise.resolve([mockVRDisplay]); 18 | }; 19 | 20 | setup(function () { 21 | this.sinon = sinon.sandbox.create(); 22 | // Stubs to not create a WebGL context since Travis CI runs headless. 23 | this.sinon.stub(AScene.prototype, 'render'); 24 | this.sinon.stub(AScene.prototype, 'resize'); 25 | this.sinon.stub(AScene.prototype, 'setupRenderer'); 26 | }); 27 | 28 | teardown(function () { 29 | // Clean up any attached elements. 30 | var attachedEls = ['canvas', 'a-assets', 'a-scene']; 31 | var els = document.querySelectorAll(attachedEls.join(',')); 32 | for (var i = 0; i < els.length; i++) { 33 | els[i].parentNode.removeChild(els[i]); 34 | } 35 | this.sinon.restore(); 36 | }); 37 | -------------------------------------------------------------------------------- /tests/helpers.js: -------------------------------------------------------------------------------- 1 | /* global suite */ 2 | 3 | /** 4 | * Helper method to create a scene, create an entity, add entity to scene, 5 | * add scene to document. 6 | * 7 | * @returns {object} An `` element. 8 | */ 9 | module.exports.entityFactory = function (opts) { 10 | var scene = document.createElement('a-scene'); 11 | var assets = document.createElement('a-assets'); 12 | var entity = document.createElement('a-entity'); 13 | scene.appendChild(assets); 14 | scene.appendChild(entity); 15 | 16 | opts = opts || {}; 17 | 18 | if (opts.assets) { 19 | opts.assets.forEach(function (asset) { 20 | assets.appendChild(asset); 21 | }); 22 | } 23 | 24 | document.body.appendChild(scene); 25 | return entity; 26 | }; 27 | 28 | /** 29 | * Creates and attaches a mixin element (and an `` element if necessary). 30 | * 31 | * @param {string} id - ID of mixin. 32 | * @param {object} obj - Map of component names to attribute values. 33 | * @param {Element} scene - Indicate which scene to apply mixin to if necessary. 34 | * @returns {object} An attached `` element. 35 | */ 36 | module.exports.mixinFactory = function (id, obj, scene) { 37 | var mixinEl = document.createElement('a-mixin'); 38 | mixinEl.setAttribute('id', id); 39 | Object.keys(obj).forEach(function (componentName) { 40 | mixinEl.setAttribute(componentName, obj[componentName]); 41 | }); 42 | 43 | var assetsEl = scene ? scene.querySelector('a-assets') : document.querySelector('a-assets'); 44 | assetsEl.appendChild(mixinEl); 45 | 46 | return mixinEl; 47 | }; 48 | 49 | /** 50 | * Test that is only run locally and is skipped on CI. 51 | */ 52 | module.exports.getSkipCISuite = function () { 53 | if (window.__env__.TEST_ENV === 'ci') { 54 | return suite.skip; 55 | } else { 56 | return suite; 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /tests/index.test.js: -------------------------------------------------------------------------------- 1 | /* global assert, setup, suite, test */ 2 | require('aframe'); 3 | require('../index.js'); 4 | var entityFactory = require('./helpers').entityFactory; 5 | 6 | suite('teleport-controls component', function () { 7 | var component; 8 | var el; 9 | 10 | setup(function (done) { 11 | el = entityFactory(); 12 | el.addEventListener('componentinitialized', function (evt) { 13 | if (evt.detail.name !== 'teleport-controls') { return; } 14 | component = el.components['teleport-controls']; 15 | done(); 16 | }); 17 | el.setAttribute('teleport-controls', {}); 18 | }); 19 | 20 | suite('foo property', function () { 21 | test('is good', function () { 22 | assert.equal(1, 1); 23 | }); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /tests/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration. 2 | module.exports = function (config) { 3 | config.set({ 4 | basePath: '../', 5 | browserify: { 6 | debug: true, 7 | paths: ['./'] 8 | }, 9 | browsers: ['Firefox', 'Chrome'], 10 | client: { 11 | captureConsole: true, 12 | mocha: {ui: 'tdd'} 13 | }, 14 | envPreprocessor: ['TEST_ENV'], 15 | files: [ 16 | // Define test files. 17 | {pattern: 'tests/**/*.test.js'}, 18 | // Serve test assets. 19 | {pattern: 'tests/assets/**/*', included: false, served: true} 20 | ], 21 | frameworks: ['mocha', 'sinon-chai', 'chai-shallow-deep-equal', 'browserify'], 22 | preprocessors: {'tests/**/*.js': ['browserify', 'env']}, 23 | reporters: ['mocha'] 24 | }); 25 | }; 26 | --------------------------------------------------------------------------------