Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| playground:test_3js [2020/08/20 08:46] – hnagel | playground:test_3js [2020/08/20 10:17] (current) – hnagel | ||
|---|---|---|---|
| Line 5: | Line 5: | ||
| <!-- | <!-- | ||
| polymake for knusper | polymake for knusper | ||
| - | Thu Aug 20 12:35:04 2020 | + | Thu Aug 20 14:10:19 2020 |
| unnamed | unnamed | ||
| --> | --> | ||
| Line 33: | Line 33: | ||
| | | ||
| | | ||
| - | #model76216027194 | + | #model47529851256 |
| - | | + | |
| - | | + | |
| | | ||
| | | ||
| Line 177: | Line 177: | ||
| </ | </ | ||
| - | <img id=' | + | <img id=' |
| - | <img id=' | + | <img id=' |
| - | <div id="model76216027194"></ | + | <div id="model47529851256"></ |
| </ | </ | ||
| < | < | ||
| requirejs.config({ | requirejs.config({ | ||
| paths: { | paths: { | ||
| - | three: '/ | + | three: '/ |
| - | TrackballControls: | + | TrackballControls: |
| - | Projector: '/ | + | Projector: '/ |
| - | SVGRenderer: | + | SVGRenderer: |
| + | WEBGL: '/ | ||
| }, | }, | ||
| shim: { | shim: { | ||
| ' | ' | ||
| ' | ' | ||
| + | ' | ||
| ' | ' | ||
| ' | ' | ||
| Line 199: | Line 201: | ||
| require([' | require([' | ||
| window.THREE = THREE; | window.THREE = THREE; | ||
| - | require([' | + | require([' |
| THREE.TrackballControls = TrackballControls; | THREE.TrackballControls = TrackballControls; | ||
| THREE.Projector = Projector; | THREE.Projector = Projector; | ||
| THREE.SVGRenderer = SVGRenderer; | THREE.SVGRenderer = SVGRenderer; | ||
| + | THREE.WEBGL = WEBGL; | ||
| // COMMON_CODE_BLOCK_BEGIN | // COMMON_CODE_BLOCK_BEGIN | ||
| Line 211: | Line 214: | ||
| const foldables = []; | const foldables = []; | ||
| - | var three = document.getElementById(" | + | var three = document.getElementById(" |
| var scene = new THREE.Scene(); | var scene = new THREE.Scene(); | ||
| Line 273: | Line 276: | ||
| }; | }; | ||
| // select the target node | // select the target node | ||
| - | var target = document.querySelector('# | + | var target = document.querySelector('# |
| // create an observer instance | // create an observer instance | ||
| Line 323: | Line 326: | ||
| < | < | ||
| obj0.userData.facetmaterial = new THREE.MeshBasicMaterial( { color: 0x77EC9E, depthFunc: THREE.LessDepth, | obj0.userData.facetmaterial = new THREE.MeshBasicMaterial( { color: 0x77EC9E, depthFunc: THREE.LessDepth, | ||
| - | //init_object(obj0); | + | init_object(obj0); |
| scene.add(obj0); | scene.add(obj0); | ||
| // COMMON_CODE_BLOCK_BEGIN | // COMMON_CODE_BLOCK_BEGIN | ||
| Line 629: | Line 632: | ||
| }; | }; | ||
| - | render(); | + | if ( THREE.WEBGL.isWebGLAvailable() ) { |
| + | render(); | ||
| + | } else { | ||
| + | var warning = WEBGL.getWebGLErrorMessage(); | ||
| + | three.appendChild( warning ); | ||
| + | } | ||
| | | ||
| function changeTransparency() { | function changeTransparency() { | ||
| Line 1244: | Line 1252: | ||
| </ | </ | ||
| </ | </ | ||
| + | <code perl> | ||
| + | > fan:: | ||
| + | </ | ||
| + | < | ||
| + | <!-- | ||
| + | polymake for knusper | ||
| + | Thu Aug 20 14:10:19 2020 | ||
| + | planar_net_ | ||
| + | --> | ||
| + | |||
| + | |||
| + | < | ||
| + | < | ||
| + | <meta charset=utf-8> | ||
| + | < | ||
| + | < | ||
| + | /* | ||
| + | // COMMON_CODE_BLOCK_BEGIN | ||
| + | */ | ||
| + | html {overflow: scroll;} | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | # | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | /* | ||
| + | // COMMON_CODE_BLOCK_END | ||
| + | */ | ||
| + | </ | ||
| + | </ | ||
| + | < | ||
| + | < | ||
| + | <div id=' | ||
| + | <div class=group id=' | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | |||
| + | <div class=group id=' | ||
| + | < | ||
| + | <div class=indented> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | |||
| + | <div class=suboption> | ||
| + | < | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | <div class=group id=' | ||
| + | < | ||
| + | <div class=indented> | ||
| + | < | ||
| + | </ | ||
| + | <div class=suboption> | ||
| + | <div class=indented> | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | <div class=group id=' | ||
| + | < | ||
| + | <div class=indented> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | </ | ||
| + | <img id=' | ||
| + | <img id=' | ||
| + | <div id=" | ||
| + | </ | ||
| + | < | ||
| + | requirejs.config({ | ||
| + | paths: { | ||
| + | three: '/ | ||
| + | TrackballControls: | ||
| + | Projector: '/ | ||
| + | SVGRenderer: | ||
| + | WEBGL: '/ | ||
| + | }, | ||
| + | shim: { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | } | ||
| + | }); | ||
| + | | ||
| + | require([' | ||
| + | window.THREE = THREE; | ||
| + | require([' | ||
| + | THREE.TrackballControls = TrackballControls; | ||
| + | THREE.Projector = Projector; | ||
| + | THREE.SVGRenderer = SVGRenderer; | ||
| + | THREE.WEBGL = WEBGL; | ||
| + | |||
| + | // COMMON_CODE_BLOCK_BEGIN | ||
| + | |||
| + | const intervalLength = 25; // for automatic animations | ||
| + | const explodableModel = false; | ||
| + | const modelContains = { points: false, pointlabels: | ||
| + | const foldables = []; | ||
| + | |||
| + | var three = document.getElementById(" | ||
| + | var scene = new THREE.Scene(); | ||
| + | |||
| + | var camera = new THREE.PerspectiveCamera(75, | ||
| + | camera.position.set(0, | ||
| + | camera.lookAt(0, | ||
| + | camera.up.set(0, | ||
| + | |||
| + | var renderer = new THREE.WebGLRenderer( { antialias: true } ); | ||
| + | var svgRenderer = new THREE.SVGRenderer({antialias: | ||
| + | renderer.setPixelRatio( window.devicePixelRatio ); | ||
| + | renderer.setClearColor(0xFFFFFF, | ||
| + | svgRenderer.setClearColor(0xFFFFFF, | ||
| + | three.appendChild(renderer.domElement); | ||
| + | |||
| + | var control = new THREE.TrackballControls(camera, | ||
| + | control.zoomSpeed = 0.2; | ||
| + | control.rotateSpeed = 4; | ||
| + | |||
| + | function onWindowResize() { | ||
| + | var width = three.clientWidth; | ||
| + | var height = three.clientHeight; | ||
| + | renderer.setSize( width, height ); | ||
| + | svgRenderer.setSize( width, height ); | ||
| + | camera.aspect = width / height; | ||
| + | camera.updateProjectionMatrix(); | ||
| + | } | ||
| + | |||
| + | onWindowResize(); | ||
| + | window.addEventListener(' | ||
| + | |||
| + | // class to allow move points together with labels and spheres | ||
| + | var PMPoint = function (x,y,z) { | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.addLabel = function(labelsprite) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.addSphere = function(spheremesh) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | PMPoint.prototype.set = function(x, | ||
| + | | ||
| + | if (this.sprite) { | ||
| + | this.sprite.position.copy(this.vector); | ||
| + | } | ||
| + | if (this.sphere) { | ||
| + | this.sphere.position.copy(this.vector); | ||
| + | } | ||
| + | } | ||
| + | PMPoint.prototype.radius = function() { | ||
| + | if (this.sphere) { | ||
| + | return this.sphere.geometry.parameters.radius; | ||
| + | } else { | ||
| + | return 0; | ||
| + | } | ||
| + | }; | ||
| + | // select the target node | ||
| + | var target = document.querySelector('# | ||
| + | |||
| + | // create an observer instance | ||
| + | var observer = new MutationObserver(function(mutations) { | ||
| + | | ||
| + | if (mutation.removedNodes && mutation.removedNodes.length > 0) { | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | }); | ||
| + | }); | ||
| + | |||
| + | // configuration of the observer: | ||
| + | var config = { childList: true, characterData: | ||
| + | |||
| + | // pass in the target node, as well as the observer options | ||
| + | while (target) { | ||
| + | if (target.className==" | ||
| + | observer.observe(target, | ||
| + | break; | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | |||
| + | // COMMON_CODE_BLOCK_END | ||
| + | |||
| + | var obj0 = new THREE.Object3D(); | ||
| + | obj0.name = " | ||
| + | obj0.userData.explodable = 1; | ||
| + | obj0.userData.points = []; | ||
| + | obj0.userData.points.push(new PMPoint(0, 0, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, 0, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, 2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(0, 2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(0, -2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, -2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, 4, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(0, 4, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(-2, 2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(-2, 0, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(4, 0, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(4, 2, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(0, -4, 0)); | ||
| + | obj0.userData.points.push(new PMPoint(2, -4, 0)); | ||
| + | |||
| + | obj0.userData.pointradii = 0.02; | ||
| + | < | ||
| + | obj0.userData.pointmaterial = new THREE.MeshBasicMaterial( { color: 0xFF0000, side: THREE.DoubleSide, | ||
| + | obj0.userData.pointlabels = [" | ||
| + | obj0.userData.edgeindices = [0, 1, 1, 2, 0, 3, 2, 3, 0, 4, 1, 5, 4, 5, 2, 6, 3, 7, 6, 7, 3, 8, 0, 9, 8, 9, 1, 10, 2, 11, 10, 11, 4, 12, 5, 13, 12, 13]; | ||
| + | < | ||
| + | obj0.userData.edgematerial = new THREE.LineBasicMaterial( { color: 0x000000, depthTest: true, linewidth: 1.5, transparent: | ||
| + | obj0.userData.facets = [[0, 1, 2, 3], [13, 5, 4, 12], [5, 1, 0, 4], [3, 2, 6, 7], [0, 3, 8, 9], [2, 1, 10, 11]]; | ||
| + | < | ||
| + | obj0.userData.facetmaterial = new THREE.MeshBasicMaterial( { color: 0x77EC9E, depthFunc: THREE.LessDepth, | ||
| + | obj0.userData.axes = [[5,4], | ||
| + | [2,1], | ||
| + | [0,3], | ||
| + | [3,2], | ||
| + | [1,0]]; | ||
| + | |||
| + | obj0.userData.angles = [1.5707963267949, | ||
| + | 1.5707963267949, | ||
| + | 1.5707963267949, | ||
| + | 1.5707963267949, | ||
| + | 1.5707963267949]; | ||
| + | |||
| + | obj0.userData.subtrees = [[12,13], | ||
| + | [10,11], | ||
| + | [8,9], | ||
| + | [6,7], | ||
| + | [4, | ||
| + | |||
| + | obj0.userData.polytoperoot = [[-1, | ||
| + | [-1,0,0], | ||
| + | [0,2,0]]; | ||
| + | |||
| + | obj0.userData.oldscale = 0; | ||
| + | foldables.push(obj0); | ||
| + | init_object(obj0); | ||
| + | scene.add(obj0); | ||
| + | // COMMON_CODE_BLOCK_BEGIN | ||
| + | function textSpriteMaterial(message, | ||
| + | if ( parameters === undefined ) parameters = {}; | ||
| + | var fontface = " | ||
| + | var fontsize = parameters.hasOwnProperty(" | ||
| + | fontsize = fontsize*10; | ||
| + | var lines = message.split(' | ||
| + | var size = 512; | ||
| + | for(var i = 0; i< | ||
| + | var tmp = lines[i].length; | ||
| + | while(tmp*fontsize > size){ | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | var canvas = document.createElement(' | ||
| + | canvas.width = size; | ||
| + | canvas.height = size; | ||
| + | var context = canvas.getContext(' | ||
| + | context.fillStyle = " | ||
| + | context.fill(); | ||
| + | context.font = fontsize + "px " + fontface; | ||
| + | | ||
| + | // text color | ||
| + | context.fillStyle = " | ||
| + | | ||
| + | context.fillText(lines[i], | ||
| + | } | ||
| + | | ||
| + | // canvas contents will be used for a texture | ||
| + | var texture = new THREE.Texture(canvas); | ||
| + | texture.needsUpdate = true; | ||
| + | | ||
| + | var spriteMaterial = new THREE.SpriteMaterial({map: | ||
| + | return spriteMaterial; | ||
| + | } | ||
| + | |||
| + | |||
| + | // ---------------------- INITIALIZING OBJECTS-------------------------------------- | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | |||
| + | function init_object(obj) { | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_points(obj); | ||
| + | modelContains.points = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_pointlabels(obj); | ||
| + | modelContains.pointlabels = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_lines(obj); | ||
| + | modelContains.lines = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_edgelabels(obj); | ||
| + | modelContains.edgelabels = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_arrowheads(obj); | ||
| + | modelContains.arrowheads = true; | ||
| + | } | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | init_faces(obj); | ||
| + | modelContains.faces = true; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function init_points(obj) { | ||
| + | var pointgroup = new THREE.Group(); | ||
| + | | ||
| + | var points = obj.userData.points; | ||
| + | var radii = obj.userData.pointradii; | ||
| + | var materials = obj.userData.pointmaterial; | ||
| + | var geometry, | ||
| + | if (!Array.isArray(radii)) { | ||
| + | geometry = new THREE.SphereBufferGeometry(radii); | ||
| + | } | ||
| + | if (!Array.isArray(materials)) { | ||
| + | material = materials; | ||
| + | } | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | if (Array.isArray(radii)) { | ||
| + | if (radii[i] == 0) { | ||
| + | continue; | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | if (Array.isArray(materials)) { | ||
| + | | ||
| + | } | ||
| + | var sphere = new THREE.Mesh(geometry, | ||
| + | point.addSphere(sphere); | ||
| + | pointgroup.add(sphere); | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | |||
| + | function init_pointlabels(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var labels = obj.userData.pointlabels; | ||
| + | var pointlabels = new THREE.Group(); | ||
| + | | ||
| + | if (Array.isArray(labels)) { | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var spriteMaterial = textSpriteMaterial( labels[i] ); | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } else { | ||
| + | var spriteMaterial = textSpriteMaterial( labels ); | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | |||
| + | function init_lines(obj) { | ||
| + | var edgeindices = obj.userData.edgeindices; | ||
| + | var points = obj.userData.points; | ||
| + | var materials = obj.userData.edgematerial; | ||
| + | var geometry = new THREE.BufferGeometry(); | ||
| + | var bufarr = new Float32Array( obj.userData.edgeindices.length * 3 ); | ||
| + | var bufattr = new THREE.Float32BufferAttribute( bufarr, 3 ); | ||
| + | var geometry = new THREE.BufferGeometry(); | ||
| + | | ||
| + | if (Array.isArray(materials)) { | ||
| + | for (var i=0; i< | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | var lines = new THREE.LineSegments(geometry, | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | function init_edgelabels(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var edgeindices = obj.userData.edgeindices; | ||
| + | var labels = obj.userData.edgelabels; | ||
| + | var edgelabels = new THREE.Group(); | ||
| + | | ||
| + | if (Array.isArray(labels)) { | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var spriteMaterial = textSpriteMaterial( labels[i] ); | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } else { | ||
| + | var spriteMaterial = textSpriteMaterial( labels ); | ||
| + | for (var i=0; i< | ||
| + | var point = points[i]; | ||
| + | var sprite = new THREE.Sprite(spriteMaterial); | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | |||
| + | function init_arrowheads(obj) { | ||
| + | var arrowheads = new THREE.Group(); | ||
| + | arrowheads.name = " | ||
| + | var arrowstyle = obj.userData.arrowstyle; | ||
| + | var edgeindices = obj.userData.edgeindices; | ||
| + | var edgematerials = obj.userData.edgematerial; | ||
| + | var points = obj.userData.points; | ||
| + | var material; | ||
| + | if (!Array.isArray(edgematerials)) { | ||
| + | material = new THREE.MeshBasicMaterial( {color: edgematerials.color} ); | ||
| + | } | ||
| + | |||
| + | for (var i=0; i< | ||
| + | var start = points[edgeindices[i]]; | ||
| + | var end = points[edgeindices[i+1]]; | ||
| + | var dist = start.vector.distanceTo( end.vector ) - start.radius() - end.radius(); | ||
| + | if (dist <= 0) { | ||
| + | continue; | ||
| + | } | ||
| + | var dir = new THREE.Vector3().subVectors(end.vector, | ||
| + | dir.normalize(); | ||
| + | var axis = new THREE.Vector3().set(dir.z, | ||
| + | axis.normalize(); | ||
| + | var radians = Math.acos( dir.y ); | ||
| + | var radius = dist/25; | ||
| + | var height = dist/5; | ||
| + | var geometry = new THREE.ConeBufferGeometry(radius, | ||
| + | var position = new THREE.Vector3().addVectors(start.vector, | ||
| + | if (Array.isArray(edgematerials)) { | ||
| + | material = new THREE.MeshBasicMaterial( {color: edgematerials[i].color} ); | ||
| + | } | ||
| + | var cone = new THREE.Mesh( geometry, material ); | ||
| + | cone.quaternion.setFromAxisAngle(axis, | ||
| + | cone.position.copy(position);; | ||
| + | arrowheads.add(cone); | ||
| + | } | ||
| + | obj.add(arrowheads); | ||
| + | } | ||
| + | |||
| + | function init_faces(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var facets = obj.userData.facets; | ||
| + | | ||
| + | for (var i=0; i< | ||
| + | facet = facets[i]; | ||
| + | for (var t=0; t< | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | var bufarr = new Float32Array( obj.userData.triangleindices.length * 3 ); | ||
| + | var bufattr = new THREE.Float32BufferAttribute(bufarr, | ||
| + | |||
| + | var materials = obj.userData.facetmaterial; | ||
| + | var geometry = new THREE.BufferGeometry(); | ||
| + | | ||
| + | if (Array.isArray(materials)) { | ||
| + | var tricount = 0; | ||
| + | var facet; | ||
| + | for (var i=0; i< | ||
| + | facet = facets[i]; | ||
| + | | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | var mesh = new THREE.Mesh(geometry, | ||
| + | | ||
| + | | ||
| + | | ||
| + | } | ||
| + | // // | ||
| + | |||
| + | |||
| + | function updateFacesPosition(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var indices = obj.userData.triangleindices; | ||
| + | var faces = obj.getObjectByName(" | ||
| + | var ba = faces.geometry.getAttribute(" | ||
| + | for (var i=0; i< | ||
| + | ba.setXYZ(i, | ||
| + | } | ||
| + | | ||
| + | |||
| + | } | ||
| + | |||
| + | function updateEdgesPosition(obj) { | ||
| + | var points = obj.userData.points; | ||
| + | var indices = obj.userData.edgeindices; | ||
| + | var lines = obj.getObjectByName(" | ||
| + | var ba = lines.geometry.getAttribute(" | ||
| + | for (var i=0; i< | ||
| + | ba.setXYZ(i, | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | var xRotationEnabled = false; | ||
| + | var yRotationEnabled = false; | ||
| + | var zRotationEnabled = false; | ||
| + | var rotationSpeedFactor = 1; | ||
| + | var settingsShown = false; | ||
| + | var labelsShown = true; | ||
| + | var intervals = []; | ||
| + | var timeouts = []; | ||
| + | var explodingSpeed = 0.05; | ||
| + | var explodeScale = 0; | ||
| + | var XMLS = new XMLSerializer(); | ||
| + | var svgElement; | ||
| + | var renderId; | ||
| + | |||
| + | var render = function () { | ||
| + | |||
| + | renderId = requestAnimationFrame(render); | ||
| + | |||
| + | // comment in for automatic explosion | ||
| + | // | ||
| + | |||
| + | var phi = 0.02 * rotationSpeedFactor; | ||
| + | |||
| + | if (xRotationEnabled) { | ||
| + | scene.rotation.x += phi; | ||
| + | } | ||
| + | if (yRotationEnabled) { | ||
| + | scene.rotation.y += phi; | ||
| + | } | ||
| + | if (zRotationEnabled) { | ||
| + | scene.rotation.z += phi; | ||
| + | } | ||
| + | |||
| + | control.update(); | ||
| + | renderer.render(scene, | ||
| + | }; | ||
| + | |||
| + | if ( THREE.WEBGL.isWebGLAvailable() ) { | ||
| + | render(); | ||
| + | } else { | ||
| + | var warning = WEBGL.getWebGLErrorMessage(); | ||
| + | three.appendChild( warning ); | ||
| + | } | ||
| + | | ||
| + | function changeTransparency() { | ||
| + | var opacity = 1-Number(event.currentTarget.value); | ||
| + | for (var i=0; i< | ||
| + | child = scene.children[i]; | ||
| + | if ( child.userData.hasOwnProperty(" | ||
| + | if (Array.isArray(child.userData.facetmaterial)) { | ||
| + | for (var j=0; j< | ||
| + | child.userData.facetmaterial[j].opacity = opacity; | ||
| + | } | ||
| + | } else { | ||
| + | child.userData.facetmaterial.opacity = opacity; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function changeRotationX(event){ | ||
| + | xRotationEnabled = event.currentTarget.checked; | ||
| + | } | ||
| + | |||
| + | function changeRotationY(event){ | ||
| + | yRotationEnabled = event.currentTarget.checked; | ||
| + | } | ||
| + | |||
| + | function changeRotationZ(event){ | ||
| + | zRotationEnabled = event.currentTarget.checked; | ||
| + | } | ||
| + | |||
| + | |||
| + | function changeRotationSpeedFactor(event){ | ||
| + | rotationSpeedFactor = Number(event.currentTarget.value); | ||
| + | } | ||
| + | |||
| + | function resetScene(){ | ||
| + | scene.rotation.set(0, | ||
| + | camera.position.set(0, | ||
| + | camera.up.set(0, | ||
| + | } | ||
| + | |||
| + | function showSettings(event){ | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | settingsShown = true; | ||
| + | } | ||
| + | |||
| + | function hideSettings(event){ | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | settingsShown = false; | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | var pos = 150* Math.PI; | ||
| + | |||
| + | function updateFactor() { | ||
| + | pos++; | ||
| + | return Math.sin(.01*pos)+1; | ||
| + | } | ||
| + | |||
| + | // ------------------------ FOLDING ------------------------------------------------ | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | // rotate point p around axis defined by points p1 and p2 by given angle | ||
| + | function rotate(p, p1, p2, angle ){ | ||
| + | angle = -angle; | ||
| + | var x = p.x, y = p.y, z = p.z, | ||
| + | a = p1.x, b = p1.y, c = p1.z, | ||
| + | u = p2.x-p1.x, v = p2.y-p1.y, w = p2.z-p1.z; | ||
| + | var result = []; | ||
| + | var L = u*u + v*v + w*w; | ||
| + | var sqrt = Math.sqrt; | ||
| + | var cos = Math.cos; | ||
| + | var sin = Math.sin; | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | } | ||
| + | |||
| + | var fold = function(event){ | ||
| + | var obj = foldables[Number(event.currentTarget.name)]; | ||
| + | var foldvalue = Number(event.currentTarget.value); | ||
| + | var scale = foldvalue - obj.userData.oldscale; | ||
| + | |||
| + | for (var j=0; j< | ||
| + | rotateVertices(obj, | ||
| + | } | ||
| + | update(obj); | ||
| + | obj.userData.oldscale += scale; | ||
| + | lookAtBarycenter(obj); | ||
| + | } | ||
| + | |||
| + | function lookAtBarycenter(obj){ | ||
| + | control.target = barycenter(obj); | ||
| + | } | ||
| + | |||
| + | function barycenter(obj) { | ||
| + | var center = new THREE.Vector3(0, | ||
| + | var points = obj.userData.points; | ||
| + | for (var i=0; i< | ||
| + | center.add(points[i].vector); | ||
| + | } | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | function rotateVertices(obj, | ||
| + | var axes = obj.userData.axes; | ||
| + | var subtrees = obj.userData.subtrees; | ||
| + | var points = obj.userData.points; | ||
| + | var angles = obj.userData.angles; | ||
| + | if (edge < axes.length){ | ||
| + | for (var j=0; j< | ||
| + | var rotP = rotate(points[subtrees[edge][j]].vector, | ||
| + | | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function update(obj) { | ||
| + | | ||
| + | | ||
| + | } | ||
| + | |||
| + | if (foldables.length) { | ||
| + | var settings = document.getElementById(' | ||
| + | var foldDiv = document.createElement(' | ||
| + | foldDiv.id = ' | ||
| + | var title = document.createElement(' | ||
| + | title.innerHTML = ' | ||
| + | foldDiv.appendChild(title); | ||
| + | foldDiv.className = ' | ||
| + | for (var i=0; i< | ||
| + | var range = document.createElement(' | ||
| + | range.type = ' | ||
| + | range.min = 0; | ||
| + | range.max = 1; | ||
| + | range.value = 0; | ||
| + | range.step = 0.001; | ||
| + | range.name = String(i); | ||
| + | range.oninput = fold; | ||
| + | foldDiv.appendChild(range); | ||
| + | } | ||
| + | lookAtBarycenter(foldables[0]); | ||
| + | settings.insertBefore(foldDiv, | ||
| + | } | ||
| + | |||
| + | | ||
| + | // ---------------------- EXPLOSION ------------------------------------------------ | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | |||
| + | if (explodableModel) { | ||
| + | for (var i=0; i< | ||
| + | obj = scene.children[i]; | ||
| + | if ( obj.userData.explodable ) { | ||
| + | computeCentroid(obj); | ||
| + | } | ||
| + | } | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | |||
| + | function computeCentroid(obj) { | ||
| + | centroid = new THREE.Vector3(); | ||
| + | obj.userData.points.forEach(function(pmpoint) { | ||
| + | centroid.add(pmpoint.vector); | ||
| + | }); | ||
| + | centroid.divideScalar(obj.userData.points.length); | ||
| + | obj.userData.centroid = centroid; | ||
| + | } | ||
| + | |||
| + | function explode(factor) { | ||
| + | for (var i=0; i< | ||
| + | var obj = scene.children[i]; | ||
| + | if (obj.userData.hasOwnProperty(" | ||
| + | var c = obj.userData.centroid; | ||
| + | obj.position.set(c.x*factor, | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function triggerExplode(event){ | ||
| + | explodeScale = Number(event.currentTarget.value); | ||
| + | explode(explodeScale); | ||
| + | } | ||
| + | |||
| + | function setExplodingSpeed(event){ | ||
| + | explodingSpeed = Number(event.currentTarget.value); | ||
| + | } | ||
| + | |||
| + | function triggerAutomaticExplode(event){ | ||
| + | if (event.currentTarget.checked){ | ||
| + | startExploding(); | ||
| + | } else { | ||
| + | clearIntervals(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function startExploding(){ | ||
| + | intervals.push(setInterval(explodingInterval, | ||
| + | } | ||
| + | |||
| + | |||
| + | function explodingInterval(){ | ||
| + | explodeScale += explodingSpeed; | ||
| + | if (explodeScale <= 6){ | ||
| + | explode(explodeScale); | ||
| + | } | ||
| + | else{ | ||
| + | explode(6); | ||
| + | explodeScale = 6; | ||
| + | clearIntervals(); | ||
| + | timeouts.push(setTimeout(startUnexploding, | ||
| + | } | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | |||
| + | |||
| + | function startUnexploding(){ | ||
| + | intervals.push(setInterval(unexplodingInterval, | ||
| + | } | ||
| + | |||
| + | function unexplodingInterval(){ | ||
| + | explodeScale -= explodingSpeed; | ||
| + | if (explodeScale >= 0){ | ||
| + | explode(explodeScale); | ||
| + | } | ||
| + | else { | ||
| + | explode(0); | ||
| + | explodeScale = 0; | ||
| + | clearIntervals(); | ||
| + | timeouts.push(setTimeout(startExploding, | ||
| + | } | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | |||
| + | function clearIntervals(){ | ||
| + | intervals.forEach(function(interval){ | ||
| + | clearInterval(interval); | ||
| + | }); | ||
| + | intervals = []; | ||
| + | timeouts.forEach(function(timeout){ | ||
| + | clearTimeout(timeout); | ||
| + | }); | ||
| + | timeouts = []; | ||
| + | } | ||
| + | |||
| + | // ---------------------- DISPLAY -------------------------------------------------- | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | |||
| + | const objectTypeInnerHTMLs = { points: " | ||
| + | const objectTypeVisible = {}; | ||
| + | Object.assign(objectTypeVisible, | ||
| + | const sortedObjectTypeKeys = Object.keys(objectTypeInnerHTMLs).sort(); | ||
| + | const shownObjectTypesList = document.getElementById(' | ||
| + | |||
| + | function setVisibility(bool, | ||
| + | for (var i=0; i< | ||
| + | var obj = scene.children[i].getObjectByName(objname); | ||
| + | if (obj) { | ||
| + | obj.visible = bool; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function toggleObjectTypeVisibility(event){ | ||
| + | var name = event.currentTarget.name; | ||
| + | var checked = event.currentTarget.checked; | ||
| + | objectTypeVisible[name] = checked; | ||
| + | setVisibility(checked, | ||
| + | } | ||
| + | |||
| + | for (var i=0; i< | ||
| + | var key = sortedObjectTypeKeys[i]; | ||
| + | if (modelContains[key]) { | ||
| + | var objTypeNode = document.createElement(' | ||
| + | objTypeNode.innerHTML = objectTypeInnerHTMLs[key] + '< | ||
| + | var checkbox = document.createElement(' | ||
| + | checkbox.type = ' | ||
| + | checkbox.checked = true; | ||
| + | checkbox.name = key; | ||
| + | checkbox.onchange = toggleObjectTypeVisibility; | ||
| + | shownObjectTypesList.appendChild(checkbox); | ||
| + | shownObjectTypesList.appendChild(objTypeNode); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // ------------------------------------------------------ | ||
| + | |||
| + | function toggleObjectVisibility(event){ | ||
| + | var nr = Number(event.currentTarget.name); | ||
| + | scene.children[nr].visible = event.currentTarget.checked; | ||
| + | } | ||
| + | |||
| + | // append checkboxes for displaying or hiding objects | ||
| + | var shownObjectsList = document.getElementById(' | ||
| + | for (var i=0; i< | ||
| + | obj = scene.children[i]; | ||
| + | var objNode = document.createElement(' | ||
| + | objNode.innerHTML = obj.name + '< | ||
| + | var checkbox = document.createElement(' | ||
| + | checkbox.type = ' | ||
| + | checkbox.checked = true; | ||
| + | checkbox.name = String(i); | ||
| + | checkbox.onchange = toggleObjectVisibility; | ||
| + | shownObjectsList.appendChild(checkbox); | ||
| + | shownObjectsList.appendChild(objNode); | ||
| + | } | ||
| + | |||
| + | // ---------------------- SVG ------------------------------------------------------ | ||
| + | // --------------------------------------------------------------------------------- | ||
| + | |||
| + | function takeSvgScreenshot() { | ||
| + | if (objectTypeVisible[" | ||
| + | setVisibility(false," | ||
| + | } | ||
| + | if (objectTypeVisible[" | ||
| + | setVisibility(false," | ||
| + | } | ||
| + | svgRenderer.render(scene, | ||
| + | svgElement = XMLS.serializeToString(svgRenderer.domElement); | ||
| + | | ||
| + | if (objectTypeVisible[" | ||
| + | setVisibility(true," | ||
| + | } | ||
| + | if (objectTypeVisible[" | ||
| + | setVisibility(true," | ||
| + | } | ||
| + | |||
| + | if (document.getElementById(' | ||
| + | //show in new tab | ||
| + | var myWindow = window.open("","" | ||
| + | myWindow.document.body.innerHTML = svgElement; | ||
| + | } else{ | ||
| + | // download svg file | ||
| + | download(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function download(filename, | ||
| + | var element = document.createElement(' | ||
| + | element.setAttribute(' | ||
| + | element.setAttribute(' | ||
| + | |||
| + | element.style.display = ' | ||
| + | document.body.appendChild(element); | ||
| + | |||
| + | element.click(); | ||
| + | |||
| + | document.body.removeChild(element); | ||
| + | } | ||
| + | |||
| + | |||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | document.getElementById(' | ||
| + | |||
| + | |||
| + | // ------------------ SHORTCUTS -------------------------------------------- | ||
| + | // ------------------------------------------------------------------------- | ||
| + | |||
| + | /** | ||
| + | * http:// | ||
| + | * Version : 2.01.B | ||
| + | * By Binny V A | ||
| + | * License : BSD | ||
| + | */ | ||
| + | shortcut = { | ||
| + | ' | ||
| + | ' | ||
| + | //Provide a set of default options | ||
| + | var default_options = { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | } | ||
| + | if(!opt) opt = default_options; | ||
| + | else { | ||
| + | for(var dfo in default_options) { | ||
| + | if(typeof opt[dfo] == ' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | var ele = opt.target; | ||
| + | if(typeof opt.target == ' | ||
| + | var ths = this; | ||
| + | shortcut_combination = shortcut_combination.toLowerCase(); | ||
| + | |||
| + | //The function to be called at keypress | ||
| + | var func = function(e) { | ||
| + | e = e || window.event; | ||
| + | |||
| + | if(opt[' | ||
| + | var element; | ||
| + | if(e.target) element=e.target; | ||
| + | else if(e.srcElement) element=e.srcElement; | ||
| + | if(element.nodeType==3) element=element.parentNode; | ||
| + | |||
| + | if(element.tagName == ' | ||
| + | } | ||
| + | |||
| + | //Find Which key is pressed | ||
| + | if (e.keyCode) code = e.keyCode; | ||
| + | else if (e.which) code = e.which; | ||
| + | var character = String.fromCharCode(code).toLowerCase(); | ||
| + | |||
| + | if(code == 188) character=","; | ||
| + | if(code == 190) character=" | ||
| + | |||
| + | var keys = shortcut_combination.split(" | ||
| + | //Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked | ||
| + | var kp = 0; | ||
| + | |||
| + | //Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken | ||
| + | var shift_nums = { | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ";":":", | ||
| + | "'":" | ||
| + | ",":"<", | ||
| + | " | ||
| + | "/":"?", | ||
| + | " | ||
| + | } | ||
| + | // | ||
| + | var special_keys = { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | |||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | } | ||
| + | |||
| + | var modifiers = { | ||
| + | shift: { wanted: | ||
| + | ctrl : { wanted: | ||
| + | alt | ||
| + | meta : { wanted: | ||
| + | }; | ||
| + | | ||
| + | if(e.ctrlKey) modifiers.ctrl.pressed = true; | ||
| + | if(e.shiftKey) modifiers.shift.pressed = true; | ||
| + | if(e.altKey) modifiers.alt.pressed = true; | ||
| + | if(e.metaKey) | ||
| + | | ||
| + | for(var i=0; k=keys[i], | ||
| + | // | ||
| + | if(k == ' | ||
| + | kp++; | ||
| + | modifiers.ctrl.wanted = true; | ||
| + | |||
| + | } else if(k == ' | ||
| + | kp++; | ||
| + | modifiers.shift.wanted = true; | ||
| + | |||
| + | } else if(k == ' | ||
| + | kp++; | ||
| + | modifiers.alt.wanted = true; | ||
| + | } else if(k == ' | ||
| + | kp++; | ||
| + | modifiers.meta.wanted = true; | ||
| + | } else if(k.length > 1) { //If it is a special key | ||
| + | if(special_keys[k] == code) kp++; | ||
| + | |||
| + | } else if(opt[' | ||
| + | if(opt[' | ||
| + | |||
| + | } else { //The special keys did not match | ||
| + | if(character == k) kp++; | ||
| + | else { | ||
| + | if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase | ||
| + | character = shift_nums[character]; | ||
| + | if(character == k) kp++; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | if(kp == keys.length && | ||
| + | modifiers.ctrl.pressed == modifiers.ctrl.wanted && | ||
| + | modifiers.shift.pressed == modifiers.shift.wanted && | ||
| + | modifiers.alt.pressed == modifiers.alt.wanted && | ||
| + | modifiers.meta.pressed == modifiers.meta.wanted) { | ||
| + | callback(e); | ||
| + | |||
| + | if(!opt[' | ||
| + | // | ||
| + | e.cancelBubble = true; | ||
| + | e.returnValue = false; | ||
| + | |||
| + | // | ||
| + | if (e.stopPropagation) { | ||
| + | e.stopPropagation(); | ||
| + | e.preventDefault(); | ||
| + | } | ||
| + | return false; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | this.all_shortcuts[shortcut_combination] = { | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | }; | ||
| + | //Attach the function with the event | ||
| + | if(ele.addEventListener) ele.addEventListener(opt[' | ||
| + | else if(ele.attachEvent) ele.attachEvent(' | ||
| + | else ele[' | ||
| + | }, | ||
| + | |||
| + | //Remove the shortcut - just specify the shortcut and I will remove the binding | ||
| + | ' | ||
| + | shortcut_combination = shortcut_combination.toLowerCase(); | ||
| + | var binding = this.all_shortcuts[shortcut_combination]; | ||
| + | delete(this.all_shortcuts[shortcut_combination]) | ||
| + | if(!binding) return; | ||
| + | var type = binding[' | ||
| + | var ele = binding[' | ||
| + | var callback = binding[' | ||
| + | |||
| + | if(ele.detachEvent) ele.detachEvent(' | ||
| + | else if(ele.removeEventListener) ele.removeEventListener(type, | ||
| + | else ele[' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | shortcut.add(" | ||
| + | var event = new Event(' | ||
| + | if (settingsShown){ | ||
| + | document.getElementById(' | ||
| + | } else { | ||
| + | document.getElementById(' | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | |||
| + | // COMMON_CODE_BLOCK_END | ||
| + | |||
| + | });}); | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||