From cf94478142d8559260e193cbf816017c9d632ca3 Mon Sep 17 00:00:00 2001 From: Bart McLeod Date: Mon, 5 Dec 2016 22:16:36 +0100 Subject: [PATCH] deleted files that are now in the VrmlParser project --- examples/js/loaders/vrml/Console.js | 41 - examples/js/loaders/vrml/ThreeJs.js | 788 ------------------ examples/js/loaders/vrml/ThreeJs/Animation.js | 335 -------- .../Animation/OrientationInterpolator.js | 105 --- .../ThreeJs/Animation/PositionInterpolator.js | 96 --- examples/js/loaders/vrml/ThreeJs/VrmlNode.js | 1 - .../vrml/ThreeJs/VrmlNode/NavigationInfo.js | 67 -- .../vrml/ThreeJs/VrmlNode/Viewpoint.js | 60 -- 8 files changed, 1493 deletions(-) delete mode 100644 examples/js/loaders/vrml/Console.js delete mode 100644 examples/js/loaders/vrml/ThreeJs.js delete mode 100644 examples/js/loaders/vrml/ThreeJs/Animation.js delete mode 100644 examples/js/loaders/vrml/ThreeJs/Animation/OrientationInterpolator.js delete mode 100644 examples/js/loaders/vrml/ThreeJs/Animation/PositionInterpolator.js delete mode 100644 examples/js/loaders/vrml/ThreeJs/VrmlNode.js delete mode 100644 examples/js/loaders/vrml/ThreeJs/VrmlNode/NavigationInfo.js delete mode 100644 examples/js/loaders/vrml/ThreeJs/VrmlNode/Viewpoint.js diff --git a/examples/js/loaders/vrml/Console.js b/examples/js/loaders/vrml/Console.js deleted file mode 100644 index cf58e513a7..0000000000 --- a/examples/js/loaders/vrml/Console.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @author Bart McLeod, mcleod@spaceweb.nl - * @since 2016-05-10 - * - * The VrmlParser/Renderer/Console renders the node tree as text output to the console, - * so that one can see what it is parsing. - */ - -module.exports = { - depth: 0, - decoration: '', - /** - * Render method, that takes the output from the VrmlParser as input and - * writes a textual representation of the node tree to the console. - * - * @param nodeTree - */ - render: function (tree) { - - this.decoration = ''; - // determine decoration base on depth - for (var j = 0; j < this.depth; j++) { - this.decoration += '-'; - } - - for (var a in tree) { - if ('string' === typeof a) { - - var value = tree[a]; - if ('object' === typeof value) { - this.depth++; - console.log(this.decoration + a); - this.render(value); - this.depth--; - } else { - console.log(this.decoration + a + ': ' + tree[a]); - } - } - } - } -}; diff --git a/examples/js/loaders/vrml/ThreeJs.js b/examples/js/loaders/vrml/ThreeJs.js deleted file mode 100644 index 05292bb1c7..0000000000 --- a/examples/js/loaders/vrml/ThreeJs.js +++ /dev/null @@ -1,788 +0,0 @@ -/** - * Not written as a NodeJs module, because this would require to use browserify - * to make it available in the browser, while it is onlly useful in the browser anyway. - * - * @copyright Bart McLeod 2016, mcleod@spaceweb.nl - * @author Bart McLeod / http://spaceweb.nl/ - */ -window['VrmlParser'] = {}; - -VrmlParser['Renderer'] = {}; - -VrmlParser.Renderer['ThreeJs'] = function (debug) { - this.debug = debug ? true : false; -}; - -VrmlParser.Renderer.ThreeJs.prototype = { - debug: false, - REVISION: 1, - constructor: VrmlParser.Renderer.ThreeJs, - - log: function () { - console.log.apply(console, arguments); - }, - - warn: function () { - console.warn.apply(console, arguments); - }, - - error: function () { - console.error.apply(console, arguments); - }, - - /** - * @param Object nodeTree - * @param THREE.Scene scene - */ - render: function (nodeTree, scene) { - - var scope = this; - - console.log('VrmlParser.Renderer.ThreeJsRenderer ' + this.REVISION); - - /** - * Colors ar return by the parser as vector{x, y, z}. - * We want them as color{r, g, b}. - * @param vector - */ - var convertVectorToColor = function (vector) { - return {r: vector.x, g: vector.y, b: vector.z}; - } - - /** - * Interpolates colors a and b following their relative distance - * expressed by t. - * - * @param float a - * @param float b - * @param float t - * @returns {Color} - */ - var interpolateColors = function (a, b, t) { - a = convertVectorToColor(a); - b = convertVectorToColor(b); - var deltaR = a.r - b.r; - var deltaG = a.g - b.g; - var deltaB = a.b - b.b; - - var c = new THREE.Color(); - - c.r = a.r - t * deltaR; - c.g = a.g - t * deltaG; - c.b = a.b - t * deltaB; - - return c; - - }; - - /** - * Vertically paints the faces interpolating between the - * specified colors at the specified angels. This is used for the Background - * node, but could be applied to other nodes with multiple faces as well. - * - * When used with the Background node, default is directionIsDown is true if - * interpolating the skyColor down from the Zenith. When interpolationg up from - * the Nadir i.e. interpolating the groundColor, the directionIsDown is false. - * - * The first angle is never specified, it is the Zenith (0 rad). Angles are specified - * in radians. The geometry is thought a sphere, but could be anything. The color interpolation - * is linear along the Y axis in any case. - * - * You must specify one more color than you have angles at the beginning of the colors array. - * This is the color of the Zenith (the top of the shape). - * - * @param geometry - * @param radius - * @param angles - * @param colors - * @param boolean directionIsDown Whether to work bottom up or top down. - */ - var paintFaces = function (geometry, radius, angles, colors, directionIsDown) { - var f, n, p, vertexIndex, color; - - var direction = directionIsDown ? 1 : -1; - - var faceIndices = ['a', 'b', 'c', 'd']; - - var coord = [], aColor, bColor, t = 1, A = {}, B = {}, applyColor = false, colorIndex; - - for ( var k = 0; k < angles.length; k++ ) { - - var vec = {}; - - // push the vector at which the color changes - vec.y = direction * ( Math.cos(angles[k]) * radius ); - - vec.x = direction * ( Math.sin(angles[k]) * radius ); - - coord.push(vec); - - } - - // painting the colors on the faces - for ( var i = 0; i < geometry.faces.length; i++ ) { - - f = geometry.faces[i]; - - n = ( f instanceof THREE.Face3 ) ? 3 : 4; - - for ( var j = 0; j < n; j++ ) { - - vertexIndex = f[faceIndices[j]]; - - p = geometry.vertices[vertexIndex]; - - for ( var index = 0; index < colors.length; index++ ) { - - // linear interpolation between aColor and bColor, calculate proportion - // A is previous point (vertex) - if ( index === 0 ) { - - A.x = 0; - A.y = directionIsDown ? radius : -1 * radius; - - } else { - - A.x = coord[index - 1].x; - A.y = coord[index - 1].y; - - } - - // B is current point (angle) - B = coord[index]; - - if ( undefined !== B ) { - - // p has to be between the points A and B which we interpolate - applyColor = directionIsDown ? p.y <= A.y && p.y > B.y : p.y >= A.y && p.y < B.y; - - if ( applyColor ) { - - bColor = colors[index + 1]; - - aColor = colors[index]; - - // below is simple linear interpolation - t = Math.abs(p.y - A.y) / ( A.y - B.y ); - - // to make it faster, you can only calculate this if the y coord changes, the color is the same for points with the same y - color = interpolateColors(aColor, bColor, t); - - f.vertexColors[j] = color; - - } - - } else if ( undefined === f.vertexColors[j] ) { - - colorIndex = directionIsDown ? colors.length - 1 : 0; - f.vertexColors[j] = convertVectorToColor(colors[colorIndex]); - - } - - } - - } - - } - - }; - - /** - * Utility to quickly and safely check if a given property is - * present and set on a node. - * - * @param string property - * @return boolean - */ - var has = function (property) { - // note that this pull the object the 'has' method is assigned to into this functions scope - return ('undefined' !== typeof this[property] && null !== this[property]); - }; - - /** - * Convert VRML node representation into a ThreeJS 3D object. - * - * @param object node VRML node as parsed by the VrmlParser. - * @returns {THREE.Object3D} - */ - var parseNode = function (node) { - if ( undefined === node.node ) { - // not a node, for now, ignore it - return false; - } - - // for syntactic sugar only: - node.has = has; - - // this will be the returned ThreeJS object returned from parseNode, if not overwritten - var object = new THREE.Object3D(); - var surroundingGroup = false; - // @todo: WIP refactor the switch to a class name with parse method for each node: parse(writer, node) - switch ( node.node ) { - case 'NavigationInfo': - // no object needed, NavigationInfo initializes controls in the scene - object = false; - var navigationInfo = new VrmlParser.Renderer.ThreeJs.VrmlNode.NavigationInfo(node, scope.debug); - navigationInfo.parse(scene); - break; - - case 'Viewpoint': - //scope.log('Got a Viewpoint named ' + (node.name ? node.name : node.description)); - var viewpoint = new VrmlParser.Renderer.ThreeJs.VrmlNode.Viewpoint(node, scope.debug); - surroundingGroup = viewpoint.parse(scene); - // store the group with the camera in the list of cameras, by its name - object = surroundingGroup.getCamera(); - scope.viewpoints[object.name] = surroundingGroup; - break; - - case 'OrientationInterpolator': - case 'PositionInterpolator': - // only keeping the object, because we are interested in its original values - break; - - case 'Switch': - // Switch is a list of nodes from which is chosen based on whichChoice, which is the index. - if ( node.whichChoice >= 0 && node.whichChoice < node.choice.length ) { - object = parseNode(node.choice[node.whichChoice]); - } else { - object = false; - } - break; - - case 'Group': - case 'Transform': - // Group is basically the same as Object3D, only the type is set to Group - object = new THREE.Group; - if ( node.has('children') ) { - // sugar - node.children.has = has; - // children can be a node or an array - if ( node.children.has('node') ) { - // children is a node - var objects = parseNode(node.children); - if ( false !== objects ) { - object.add(objects); - } - } else if ( node.children.has('length') ) { - // children should be an array - for ( var i = 0; i < node.children.length; i++ ) { - - var child = node.children[i]; - child.has = has; - var threeJsObj = parseNode(child); - if ( false !== threeJsObj ) { - object.add(threeJsObj); - } - - } - } - } - - var t = {x: 0, y: 0, z: 0}; - - if ( node.has('translation') ) { - - t = node.translation; - object.position.set(t.x, t.y, t.z); - - } - - var r = {x: 0, y: 0, z: 0, radians: 0}; - - if ( node.has('rotation') ) { - - r = node.rotation; - // we no longer set it here, but in the surrounding group, otherwise rotation will no be relative when animated - //object.quaternion.setFromAxisAngle(new THREE.Vector3(r.x, r.y, r.z), r.radians); - } - - if ( node.has('scale') ) { - - var s = node.scale; - - object.scale.set(s.x, s.y, s.z); - - } - - // support for center requires an extra group, which we will add allways, to ensure predictable behavior - // the name of the surrounding group will later become the name of the object prefixed with 'surrounding_' - surroundingGroup = new THREE.Group(); - - if ( !node.has('center') ) { - // setup a default center - node.center = {x: 0, y: 0, z: 0}; - } - - var center = node.center; - // this will be the axis of rotation, how to apply? - // by creating a group around the group, setting its position to the center - // and then translate the innerGroup back to its original position - surroundingGroup.position.set(t.x + center.x, t.y + center.y, t.z + center.z); - object.position.set(0 - center.x, 0 - center.y, 0 - center.z); - - // we me must also rotate the surrounding group to any rotation that applies to the original object - surroundingGroup.quaternion.setFromAxisAngle(new THREE.Vector3(r.x, r.y, r.z), r.radians); - - surroundingGroup.add(object); - break; - - case 'Shape': - var isLine = node.has('geometry') && 'IndexedLineSet' === node.geometry.node; - var isPoint = node.has('geometry') && 'PointSet' === node.geometry.node; - - object = isLine ? new THREE.Line() : (isPoint ? new THREE.Points({size: 0.01}) : new THREE.Mesh()); - - if ( node.has('geometry') ) { - object.geometry = parseNode(node.geometry); - } - - if ( node.has('appearance') ) { - var appearance = node.appearance; - - // sugar - appearance.has = has; - - if ( appearance.has('material') ) { - var vrmlMaterial = appearance.material; - var material; - - // sugar - vrmlMaterial.has = has; - - if ( isLine ) { - //scope.log('Line object'); - // @todo: we use LineBasicMaterial, is this always appropriate for VRML? - material = new THREE.LineBasicMaterial(); - - if ( vrmlMaterial.has('color') ) { - - var materialColor = convertVectorToColor(vrmlMaterial.color); - - material.color.setRGB(materialColor.r, materialColor.g, materialColor.b); - - } - } else if ( isPoint ) { - // points in ThreeJS only support color - //scope.log('Points object'); - //scope.log(vrmlMaterial); - - // color - var c; - - if ( vrmlMaterial.has('diffuseColor') ) { - c = convertVectorToColor(vrmlMaterial.diffuseColor); - } - if ( vrmlMaterial.has('emissiveColor') ) { - c = convertVectorToColor(vrmlMaterial.emissiveColor); - } - - material = new THREE.ShaderMaterial({ - vertexShader: 'void main() {' + - '\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n' + - '\n\tgl_PointSize = 3.0;\n' + - '}', - fragmentShader: 'void main() {\n\tgl_FragColor = vec4( ' + c.r + ', ' + c.g + ', ' + c.b + ', 1.0 );\n}' - }); - - } else { - //scope.log('Mesh object'); - - // @todo: we use a MeshPhongMaterial for meshes, but is this always appropriate for VRML? - material = new THREE.MeshPhongMaterial(); - - if ( vrmlMaterial.has('diffuseColor') ) { - - var materialColor = convertVectorToColor(vrmlMaterial.diffuseColor); - - material.color.setRGB(materialColor.r, materialColor.g, materialColor.b); - - } - - if ( vrmlMaterial.has('emissiveColor') ) { - - var emissiveColor = convertVectorToColor(vrmlMaterial.emissiveColor); - - material.emissive.setRGB(emissiveColor.r, emissiveColor.g, emissiveColor.b); - - } - - if ( vrmlMaterial.has('specularColor') ) { - - var specularColor = convertVectorToColor(vrmlMaterial.specularColor); - - material.specular.setRGB(specularColor.r, specularColor.g, specularColor.b); - - } - - if ( vrmlMaterial.has('transparency') ) { - - // transparency is opposite of opacity - material.opacity = Math.abs(1 - vrmlMaterial.transparency); - - material.transparent = true; - - } - - if ( appearance.has('texture') ) { - - // ImageTexture node? - if ( undefined !== appearance.texture.node && appearance.texture.node === 'ImageTexture' ) { - - var imageUrl = appearance.texture.url[0]; - - if ( undefined != imageUrl && imageUrl ) { - scope.log('Loading image: ' + imageUrl); - - // @todo: support for repeatS and repeatT - - var texture = new THREE.TextureLoader().load(imageUrl, function (texture) { - if ( undefined !== texture.image ) { - texture.repeat.set(texture.image.height / texture.image.width * 2, 2); - } - }); - - texture.wrapS = THREE.ClampToEdgeWrapping; - texture.wrapT = THREE.ClampToEdgeWrapping; - scope.log(texture); - - material.map = texture; - } - - } - - } - - //@todo: support for TextureTransform - } - - } - - object.material = material; - - if ( 'IndexedFaceSet' === node.geometry.node ) { - //if ( false === node.geometry.node.solid ) { - - object.material.side = THREE.DoubleSide; - - //} - } - - } - - break; - - case 'Background': - object = false; - - var segments = 20; - - // sky (full sphere): - - var radius = 2e4; - - var skyGeometry = new THREE.SphereGeometry(radius, segments, segments); - var skyMaterial = new THREE.MeshBasicMaterial({fog: false, side: THREE.BackSide}); - - if ( node.skyColor.length > 1 ) { - - paintFaces(skyGeometry, radius, node.skyAngle, node.skyColor, true); - - skyMaterial.vertexColors = THREE.VertexColors; - - } else { - - var color = convertVectorToColor(node.skyColor[0]); - - skyMaterial.color.setRGB(color.r, color.g, color.b); - - } - - var sky = new THREE.Mesh(skyGeometry, skyMaterial); - sky.userData.originalVrmlNode = node; - scene.add(sky); - - // ground (half sphere): - - if ( node.has('groundColor') ) { - - radius = 1.2e4; - - var groundGeometry = new THREE.SphereGeometry(radius, segments, segments, 0, 2 * Math.PI, 0.5 * Math.PI, 1.5 * Math.PI); - var groundMaterial = new THREE.MeshBasicMaterial({ - fog: false, - side: THREE.BackSide, - vertexColors: THREE.VertexColors - }); - - paintFaces(groundGeometry, radius, node.groundAngle, node.groundColor, false); - - var ground = new THREE.Mesh(groundGeometry, groundMaterial); - ground.userData.originalVrmlNode = node; - ground.receiveShadow = true; - scene.add(ground); - } - - break; - - case 'Box': - var s = node.size; - object = new THREE.BoxGeometry(s.x, s.y, s.z); - object.shading = THREE.SmoothShading; - break; - - case 'Cylinder': - object = new THREE.CylinderGeometry(node.radius, node.radius, node.height); - break; - - case 'Cone': - object = new THREE.CylinderGeometry(node.topRadius, node.bottomRadius, node.height); - break; - - case 'Sphere': - object = new THREE.SphereGeometry(node.radius); - break; - - case 'IndexedFaceSet': - - object = new THREE.Geometry(); - object.shading = THREE.SmoothShading; - - var indexes, uvIndexes, uvs; - - var vec; - - if ( node.has('texCoord') ) { - - uvs = node.texCoord.point; - - } - - if ( node.has('coord') ) { - if ( !uvs ) { - uvs = node.coord.point; - } - - for ( var k = 0, l = node.coord.point.length; k < l; k++ ) { - - var point = node.coord.point[k]; - - vec = new THREE.Vector3(point.x, point.y, point.z); - - object.vertices.push(vec); - - } - - } - - var skip = 0; - - // some shapes only have vertices for use in other shapes - if ( node.has('coordIndex') ) { - - // read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html - for ( var i = 0, j = node.coordIndex.length; i < j; i++ ) { - - indexes = node.coordIndex[i]; - - if ( node.has('texCoordIndex') ) { - uvIndexes = node.texCoordIndex[i]; - } else { - // default texture coord index - uvIndexes = indexes; - } - - // vrml supports multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here - skip = 0; - - // Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles - while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) { - - var a = indexes[0]; - var b = indexes[skip + (node.ccw ? 1 : 2)]; - var c = indexes[skip + (node.ccw ? 2 : 1)]; - - var face = new THREE.Face3( - a, - b, - c, - null // normal, will be added later - // todo: pass in the color, if a color index is present - ); - - if ( uvs && uvIndexes ) { - object.faceVertexUvs [0].push([ - new THREE.Vector2( - uvs[uvIndexes[0]].x, - uvs[uvIndexes[0]].y - ), - new THREE.Vector2( - uvs[uvIndexes[skip + (node.ccw ? 1 : 2)]].x, - uvs[uvIndexes[skip + (node.ccw ? 1 : 2)]].y - ), - new THREE.Vector2( - uvs[uvIndexes[skip + (node.ccw ? 2 : 1)]].x, - uvs[uvIndexes[skip + (node.ccw ? 2 : 1)]].y - ) - ]); - } else { - //scope.log('Missing either uvs or indexes'); - } - - skip++; - - object.faces.push(face); - - } - - } - - } - - object.computeFaceNormals(); - - //object.computeVertexNormals(); // does not show - - object.computeBoundingSphere(); - - break; - - case 'IndexedLineSet': - var vec; - var point; - var object = new THREE.Geometry(); - var vertices = []; - - // first create a buffer of vectors to use for the points. - // the challenge lies in the fact that ThreeJs draws lines in the order the vertices are added - // I do not yet see a way to tell ThreeJs to draw any amount of lines between all points. - // Could it be just a simple as using a LineMaterial for a shape? - if ( node.has('coord') ) { - - for ( var k = 0, l = node.coord.point.length; k < l; k++ ) { - - point = node.coord.point[k]; - - vec = new THREE.Vector3(point.x, point.y, point.z); - - vertices.push(vec); - - } - - } - - if ( node.has('coordIndex') ) { - - for ( var i = 0, j = node.coordIndex.length; i < j; i++ ) { - - indexes = node.coordIndex[i]; - - // loop over all the points and add their vertex to the geometry. - // hopefully, using the same vertex twice will not lead to an error, - // but just draw a line as intended. - for ( var p = 0; p < indexes.length; p++ ) { - - var a = indexes[p]; - - var pointA = vertices[a]; - - object.vertices.push(new THREE.Vector3(pointA.x, pointA.y, pointA.z)); - } - - } - - object.computeBoundingSphere(); - - } - // @todo: is there a color property to support? - break; - case 'PointSet': - - var vec; - var point; - var object = new THREE.Geometry(); - - if ( node.has('coord') ) { - - for ( var k = 0, l = node.coord.point.length; k < l; k++ ) { - - point = node.coord.point[k]; - - vec = new THREE.Vector3(point.x, point.y, point.z); - - object.vertices.push(vec); - - } - - } - - object.computeBoundingSphere(); - - // if ( node.has('color') ) { - // for ( var k = 0, l = node.coord.point.length; k < l; k++ ) { - // - // point = node.coord.point[k]; - // - // vec = new THREE.Vector3(point.x, point.y, point.z); - // - // geometry.vertices.push(vec); - // - // } - // } - - break; - case 'TouchSensor': - // just explicitly keep the object (by not setting it to false), do nothing else - if ( scope.debug ) { - // in debug mode, add a ten x ten cm cube to indicate the presence of a touchsensor - // @todo: register this with a legenda - object = new THREE.Mesh(); - object.geometry = new THREE.CubeGeometry(0.1, 0.1, 0.1); - object.material = new THREE.MeshNormalMaterial(); - object.material.color = new THREE.Color(0.5, 0.5, 0.5); - } - break; - default: - // unsupported nodes will not be added to the scene as an object - object = false; - break; - } - - if ( false !== object ) { - if ( undefined !== object.userData ) { - // keep the original VRML node for reference - object.userData.originalVrmlNode = node; - } - - if ( '' === object.name ) { - if ( node.has('name') ) { - object.name = node.name; - } else if ( node.has('node') ) { - object.name = node.node; - } - } - object.castShadow = !isPoint; - object.receiveShadow = !isPoint; - } - - if ( false !== surroundingGroup ) { - surroundingGroup.name = 'surrounding_' + object.name; - return surroundingGroup; - } - return object; - }; - - for ( var n = 0; n < nodeTree.length; n++ ) { - var childNode = parseNode(nodeTree[n]); - if ( false !== childNode ) { - scene.add(childNode); - } - } - - scene.userData.routes = nodeTree.routes; - console.log(scene); - - // @todo: parse nodeTree.nodeDefinitions - - }, - -}; diff --git a/examples/js/loaders/vrml/ThreeJs/Animation.js b/examples/js/loaders/vrml/ThreeJs/Animation.js deleted file mode 100644 index 2653ae8bb0..0000000000 --- a/examples/js/loaders/vrml/ThreeJs/Animation.js +++ /dev/null @@ -1,335 +0,0 @@ -/** - * @author Bart McLeod, mcleod@spaceweb.nl - * @since May 25, 2016 - * - * @todo: Understand http://threejs.org/docs/#Reference/Extras.Animation/AnimationHandler, this code might duplicate for example removing an animation from the update loop - * - * Adds animation and interaction support to the VrmlParser.Renderer.ThreeJs - */ - -/** - * Offers support for interaction and animation. - * - * Currently support clicking an object and seeing a log message for that. - * - * Also, in debug mode, a blue line will be drawn from the perspective camera to the clicked point. - * You can see this line when zooming out after clicking and object. - * - * @param debug - * @constructor - */ -VrmlParser.Renderer.ThreeJs['Animation'] = function (debug) { - // use global camera, scene and renderer ( a weakness, I think ) - this.debug = debug ? true : false; - this.animations = {}; -}; - -VrmlParser.Renderer.ThreeJs.Animation.prototype = { - /** - * Updates or registered animations with a delta from the global clock. - * - * @param delta - */ - update: function (delta) { - for ( var a in this.animations ) { - if ( !this.animations.hasOwnProperty(a) ) { - continue; - } - var callback = this.animations[a]; - callback(delta); - } - }, - - /** - * Register a callback for the animations, it will be called at each tick with a delta - * from the global clock. - * - * @param name - * @param callback - */ - addAnimation: function (name, callback) { - this.animations[name] = callback; - }, - - /** - * Unregister a callback for the animations. - * @param name - */ - removeAnimation: function (name) { - delete this.animations[name]; - }, - - /** - * Gets all routes that were registered for a sensor in the original VRML world. - * - * Returned routes have a source and target object. Each have a name and event property. - * - * @param string name Name of the source node of the event. - * @returns {*} - */ - getRoutesForEvent: function (name) { - var routesRegistry = scene.userData.routes; - var routes = routesRegistry[name]; - //this.log('The routes are:'); - - for ( var r = 0; r < routes.length; r++ ) { - //this.log(routes[r]); - } - return routes; - }, - - /** - * Recursively finds all targetroutes for a given route. - * - * @param triggerRoute - * @returns {boolean} - */ - findTargetRoutes: function (triggerRoute) { - var targetRoutes = []; - - if ( 'undefined' === typeof triggerRoute ) { - return targetRoutes; - } - - var routesRegistry = scene.userData.routes; - - if ( 'undefined' === typeof routesRegistry[triggerRoute.target.name] ) { - // this is the leaf route - return triggerRoute; - } - - // 1. Find first level of targetRoutes (they can be chained) - var routes = routesRegistry[triggerRoute.target.name]; - - // find all the target routes of intermediate routes - for ( var i = 0; i < routes.length; i++ ) { - - var route = routes[i]; - - // verify if the route has yet another target (it is an intermediate route) - - // 2. Find targetroutes of intermediate route, create a nested array - var nestedTargetRoutes = this.findTargetRoutes(route); - targetRoutes.push(nestedTargetRoutes); - } - - // 3. Return targetroute - return targetRoutes; - }, - - /** - * Utility to easily switch logging on and off with the debug flag. - * @param obj - */ - log: function (obj) { - if ( this.debug ) { - console.log(obj); - } - }, - - /** - * Goes up the object tree recursively to find an object with an originalVrmlNode that is of a sensorType, - * for example a TouchSensor. - * - * @param Object3D the clicked shape. - * @param string sensorType - * @returns {boolean}|{string} name of the sensor or false. - */ - findSensor: function (object, sensorType) { - var scope = this; - - /** - * Will find a sensor in the children of obj, if any. - * - * It will do so recursively going down the object tree. - * It will not search up the tree to avoid infinite recursion. - * - * @param obj - * @param sensorType - */ - function findSensorinChildrenOf(obj, sensorType) { - if ( undefined === obj.children ) { - return false; - } - - for ( var b = 0; b < obj.children.length; b++ ) { - var checkNode = obj.children[b]; - - if ( undefined === checkNode ) { - continue; - } - - var eventName; - - // check this node - if ( 'undefined' !== typeof checkNode.userData.originalVrmlNode - && sensorType === checkNode.userData.originalVrmlNode.node ) { - // find the first route, we only use TimeSensor to get from one to the next - eventName = checkNode.name; - scope.log(sensorType + ': ' + eventName); - return eventName; - } - - // var foundItInChildren - // - // // recurse - // if ( foundItInChildren = findSensorinChildrenOf(checkNode, sensorType) ) { - // return foundItInChildren; - // } - - } - - return false; - } - - if ( null === object ) { - this.log('Cannot find a sensor of type ' + sensorType + ' in null'); - return false; - } - - var foundItInChildren; - - if ( foundItInChildren = findSensorinChildrenOf(object, sensorType) ) { - return foundItInChildren; - } - - this.log('No ' + sensorType + ' found amongst the children of the following node:'); - this.log(object); - - if ( 'undefined' === typeof object.parent || null === object.parent ) { - this.log('We cannot go up the tree any further'); - // we're out of parents, there's not a single sensorType to be found here. - return false; - } - - this.log('Searching up the tree'); - // not found in the parent object, look in its parent in turn (go up the object tree recursively) - return this.findSensor(object.parent, sensorType); - }, - - // @todo: support more interactions than just clicking - - /** - * Support clicking the scene. - * - * If an object is clicked, it will show up in here. If a handler was registered for it, - * we can execute the handler. - * - * Handlers will be registered by parsing VRML ROUTES for TouchSensors. - * - * Example: - * ROUTE klikopdeur.touchTime TO TimeSource.startTime - * ROUTE TimeSource.fraction_changed TO Deuropen.set_fraction - * ROUTE Deuropen.value_changed TO deur.rotation - * - * @todo: translate event names to English, so that they make sense to people who are not able to read Dutch - * The example is a three-step animation script: - * 1. The touchTime of the touch sensor is routed to the time source. We can translate this step, since we have - * a clock and a click event - */ - addClickSupport: function (camera, renderer) { - var localCamera = camera; - var localRenderer = renderer; - // clicking: enable clicking on the screen to interact with objects in the 3D world - projector = new THREE.Projector(); - var line; - var scope = this; - - renderer.domElement.addEventListener('mousedown', function (event) { - // use global camera, scene and renderer - var x = event.offsetX == undefined ? event.layerX : event.offsetX; - var y = event.offsetY == undefined ? event.layerY : event.offsetY; - - var vector = new THREE.Vector3(); - vector.set(( x / localRenderer.domElement.width ) * 2 - 1, -( y / localRenderer.domElement.height ) * 2 + 1, 0.5); - - vector.unproject(localCamera); - - var raycaster = new THREE.Raycaster(localCamera.position, vector.sub(localCamera.position).normalize()); - - var objects = scene.children; - var intersects = raycaster.intersectObjects(objects, true); - - if ( intersects.length ) { - var firstIntersect = intersects[0].object; - - var touch = scope.findSensor(firstIntersect, 'TouchSensor'); - - if ( false === touch ) { - // no touch sensor found - return; - } - - // work on a clone [slice(0)] of the routes, otherwise, using pop() will make the array useless for next time - var routes = scope.getRoutesForEvent(touch).slice(0); - - // naive, only use first - var targetRoutes = scope.findTargetRoutes(routes.pop()); - - // again, naive (good usecase for map reduce? - var targetRoute = targetRoutes; - - while ( 'function' === typeof targetRoute.pop ) { - targetRoute = targetRoute.pop(); - - if ( 'undefined' === typeof targetRoute ) { - scope.log('no target route found for ' + touch); - return; - } - } - - // we found the leaf targetRoute - scope.log(targetRoute); - - var originalNode = scene.getObjectByName(targetRoute.source.name).userData.originalVrmlNode; - - // any supported interpolator will work, for now, only OrientationInterpolator - if ( undefined === VrmlParser.Renderer.ThreeJs.Animation[originalNode.node] ) { - scope.log(originalNode.node + ' is not yet supported'); - return; - } - - var interpolator = new VrmlParser.Renderer.ThreeJs.Animation[originalNode.node](originalNode, scope.debug); - - var name = 'surrounding_' + targetRoute.target.name; - var target = scene.getObjectByName(name); - - // cleanup method for when the callback wants to be removed because it's done. - var finish = function () { - scope.removeAnimation(touch); - }; - - var callback = interpolator.getCallback(target, finish); - scope.addAnimation(touch, callback); - } - - // drawing a line for diagnostic purposes. - // keep this disabled, unless you really, really need it. - // The problem is: the line can prevent finding your sensor if the line is clicked instead of your object. - // if ( true === scope.debug ) { - // // draw a line where the object was clicked - // if ( null !== line ) { - // scene.remove(line); - // } - // - // var lineMaterial = new THREE.LineBasicMaterial({ - // color: 0x0000ff - // }); - // var geometry = new THREE.Geometry(); - // - // geometry.vertices.push(new THREE.Vector3(raycaster.ray.origin.x, raycaster.ray.origin.y, raycaster.ray.origin.z)); - // geometry.vertices.push(new THREE.Vector3(raycaster.ray.origin.x + (raycaster.ray.direction.x * 100000), raycaster.ray.origin.y + (raycaster.ray.direction.y * 100000), raycaster.ray.origin.z + (raycaster.ray.direction.z * 100000))); - // line = new THREE.Line(geometry, lineMaterial); - // scene.add(line); - // // / draw a line - // } - - } - , - false - ); - // / clicking - - } -}; - diff --git a/examples/js/loaders/vrml/ThreeJs/Animation/OrientationInterpolator.js b/examples/js/loaders/vrml/ThreeJs/Animation/OrientationInterpolator.js deleted file mode 100644 index e35a6aff84..0000000000 --- a/examples/js/loaders/vrml/ThreeJs/Animation/OrientationInterpolator.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @author Bart McLeod, mcleod@spaceweb.nl - * @since May 25, 2016 - * - * Adds animation and interaction support to the VrmlParser.Renderer.ThreeJs - * @todo: take time into account - */ - -/** - * The OrientationInterpolator wraps the essential properties of its original VRML node counterpart - * and adds functionality to support animation in Three.js. - * - * @param originalNode - * @constructor - */ -VrmlParser.Renderer.ThreeJs.Animation['OrientationInterpolator'] = function (originalNode, debug) { - this.key = originalNode.key; - this.keyValue = originalNode.keyValue; - this.debug = debug ? true : false; - // assumption that the object is already at keyValue[0], so start rotating toward keyValue[1] - this.index = 1; - this.finish = null; - this.target = null; - this.tweenObj = null; -} - -VrmlParser.Renderer.ThreeJs.Animation.OrientationInterpolator.prototype = { - - /** - * Utility to easily switch logging on and off with the debug flag. - * @param obj - */ - log: function (obj) { - if ( this.debug ) { - console.log(obj); - } - }, - - /** - * Runs when one tween completes and starts the next - */ - complete: function () { - // take next key or finish - this.index++; - - if ( this.index >= this.keyValue.length ) { - this.log('finish at index ' + this.index); - this.finish(); - return; - } - - this.tween(); - }, - - tween: function () { - var scope = this; - //this.log('tweening for ' + this.index); - var r = this.keyValue[this.index]; - var endRadians = r.radians; - this.log('Animating from ' + this.target.rotation.y + ' to ' + endRadians); - var endQuaternion = new THREE.Quaternion(); - var vector3 = new THREE.Vector3(r.x, r.y, r.z); - endQuaternion.setFromAxisAngle(vector3, endRadians); - - this.tweenObj = new TWEEN - .Tween(this.target.quaternion) - .to(endQuaternion) - .start(+new Date()) - .onComplete(function () { - scope.complete(); - }); - ; - }, - - /** - * Gets the animation callback method, which can play the animation associated with this OrientationInterpolator. - * @param Object3D target - * @param callable finish A method that will be called when the callback is ready to be removed - */ - getCallback: function (target, finish) { - var scope = this; - - // what to animate: - this.target = target; - - // what to do after completion - this.finish = finish; - - // trigger the animation - this.tween(); - - /** - * The animation callback - * - * @param float delta time difference - * @param callable finish will be called by the callback when it is ready to be removed - */ - var callback = function (delta) { - scope.tweenObj.update(+new Date()); - }; - - return callback; - } - -}; diff --git a/examples/js/loaders/vrml/ThreeJs/Animation/PositionInterpolator.js b/examples/js/loaders/vrml/ThreeJs/Animation/PositionInterpolator.js deleted file mode 100644 index 792521f503..0000000000 --- a/examples/js/loaders/vrml/ThreeJs/Animation/PositionInterpolator.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @author Bart McLeod, mcleod@spaceweb.nl - * @since May 25, 2016 - * - * Adds animation and interaction support to the VrmlParser.Renderer.ThreeJs - * @todo: take time into account - */ -// we use below notation to create exports for the Google closure compiler - -/** - * The OrientationInterpolator wraps the essential properties of its original VRML node counterpart - * and adds functionality to support animation in Three.js. - * - * @param originalNode - * @constructor - */ -VrmlParser.Renderer.ThreeJs.Animation['PositionInterpolator'] = function (originalNode, debug) { - this.key = originalNode.key; - this.keyValue = originalNode.keyValue; - this.debug = debug ? true : false; -} - -VrmlParser.Renderer.ThreeJs.Animation.PositionInterpolator.prototype = { - - /** - * Utility to easily switch logging on and off with the debug flag. - * @param obj - */ - log: function (obj) { - if ( this.debug ) { - console.log(obj); - } - }, - - tween: function (target, endPosition) { - return new TWEEN - .Tween(target.position) - .to(endPosition) - .start(+new Date()) - ; - }, - - /** - * Gets the animation callback method, which can play the animation associated with this OrientationInterpolator. - * @param Object3D target - * @param callable finish A method that will be called when the callback is ready to be removed - */ - getCallback: function (target, finish) { - var scope = this; - - // assumption that the first position is the position the target is already at, so we start with the next - var index = 1; - - var p = this.getPosition(index); - - this.log(p); - this.log(target); - - var tween = this.tween(target, p); - - tween.onComplete(function () { - // take next key or finish - index++; - - if ( index >= scope.keyValue.length ) { - console.log('finish'); - // now make the end position of the target exactly the same as p, to correct any rounding errors from tweening - target.position = p; - finish(); - return; - } - - p = scope.getPosition(index); - scope.log(p); - tween = scope.tween(target, p); - tween.onComplete = this; - }); - - /** - * The animation callback - * - * @param float delta time difference - * @param callable finish will be called by the callback when it is ready to be removed - */ - var callback = function (delta) { - tween.update(+new Date()); - }; - - return callback; - }, - - getPosition: function (index) { - var v = this.keyValue[index]; - return new THREE.Vector3(v.x, v.y, v.z); - } -}; diff --git a/examples/js/loaders/vrml/ThreeJs/VrmlNode.js b/examples/js/loaders/vrml/ThreeJs/VrmlNode.js deleted file mode 100644 index c90c7052d9..0000000000 --- a/examples/js/loaders/vrml/ThreeJs/VrmlNode.js +++ /dev/null @@ -1 +0,0 @@ -VrmlParser.Renderer.ThreeJs['VrmlNode'] = VrmlParser.Renderer.ThreeJs.VrmlNode || {}; diff --git a/examples/js/loaders/vrml/ThreeJs/VrmlNode/NavigationInfo.js b/examples/js/loaders/vrml/ThreeJs/VrmlNode/NavigationInfo.js deleted file mode 100644 index b7c031c7d7..0000000000 --- a/examples/js/loaders/vrml/ThreeJs/VrmlNode/NavigationInfo.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @author Bart McLeod, mcleod@spaceweb.nl - * @since September 20, 2016 - * - * Conversion of a VRML 97 NavigationInfo node to a ThreeJs camera - */ - -VrmlParser.Renderer.ThreeJs.VrmlNode[ 'NavigationInfo' ] = function (originalNode, debug) { - this.debug = debug; - this.node = originalNode; - this.node.has = function (property) { - return ('undefined' !== typeof this[ property ] && null !== this[ property ]); - }; - this.controls = null; -}; - -VrmlParser.Renderer.ThreeJs.VrmlNode.NavigationInfo.prototype = { - /** - * Utility to easily switch logging on and off with the debug flag. - * @param obj - */ - log: function (obj) { - if ( this.debug ) { - console.log(obj); - } - }, - - /** - * Uses the NavigationInfo from the original VRML to determine the best - * match for controls in ThreeJs. - * - * @todo: Figure out of support for avatarSize is possible - * @todo: Support for headlight - * @todo: Figure out if visibilityLimit can be implemented, could this be the 'far' property of the camera? - * @todo: Create controls that mimic the original design of VRML better. - * @param scene - */ - parse: function (scene) { - this.log('From NavigationInfo'); - var speed = undefined !== this.node.speed ? this.node.speed : 1; - - if ( undefined !== this.node.type ) { - switch ( this.node.type.toLowerCase() ) { - case 'fly': // fly - this.log('fly!'); - // use global controls and camera, no better solution at hand - controls = new THREE.FlyControls(camera); - controls.movementSpeed = speed; - break; - } - } else { - this.log('fly!'); - // use global controls and camera, no better solution at hand - controls = new THREE.FlyControls(camera); - controls.movementSpeed = speed; - } - - /** Example of originalNode - * avatarSize [ 0.1, 1.6, 0.2,] - * headlight FALSE - * speed 4 - * type "FLY" - * visibilityLimit 0.0 - */ - - } -} diff --git a/examples/js/loaders/vrml/ThreeJs/VrmlNode/Viewpoint.js b/examples/js/loaders/vrml/ThreeJs/VrmlNode/Viewpoint.js deleted file mode 100644 index de336a5bff..0000000000 --- a/examples/js/loaders/vrml/ThreeJs/VrmlNode/Viewpoint.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @author Bart McLeod, mcleod@spaceweb.nl - * @since September 1, 2016 - * - * Conversion of a VRML 97 Viewpoint node to a ThreeJs camera - */ - -VrmlParser.Renderer.ThreeJs.VrmlNode['Viewpoint'] = function (originalNode, debug) { - this.debug = debug; - this.node = originalNode; - this.node.has = function (property) { - return ('undefined' !== typeof this[property] && null !== this[property]); - }; -}; - -VrmlParser.Renderer.ThreeJs.VrmlNode.Viewpoint.prototype = { - /** - * Utility to easily switch logging on and off with the debug flag. - * @param obj - */ - log: function (obj) { - if ( this.debug ) { - console.log(obj); - } - }, - - parse: function (scene) { - var fov, aspect, near, far; - fov = Math.round(180 / Math.PI * this.node.fieldOfView); - aspect = window.innerWidth / window.innerHeight; - near = 0.01; - far = 1e5; - - // @todo: support for jump (bool) - - var camera = new THREE.PerspectiveCamera(fov, aspect, near, far); - - var surroundingGroup = new THREE.Group(); - surroundingGroup.add(camera); - - if ( this.node.has('name') ) { - camera.name = this.node.name; - } else { - camera.name = this.node.description; - } - - surroundingGroup.getCamera = function () { - return this.children[0]; - } - - var p = this.node.position; - surroundingGroup.position.set(p.x, p.y, p.z); - - var o = this.node.orientation; - var vector3 = new THREE.Vector3(o.x, o.y, o.z); - surroundingGroup.quaternion.setFromAxisAngle(vector3, o.radians); - - return surroundingGroup; - } -} -- GitLab