1 /** 2 * @fileOverview Plugins for tQuery.Geometry: tool box to play with geometry 3 */ 4 5 (function(){ // TODO why is there a closure here ? 6 7 ////////////////////////////////////////////////////////////////////////////////// 8 // Size functions // 9 ////////////////////////////////////////////////////////////////////////////////// 10 11 tQuery.Geometry.registerInstance('computeAll', function(){ 12 this.each(function(tGeometry){ 13 tGeometry.computeBoundingBox(); 14 //tGeometry.computeCentroids(); 15 tGeometry.computeFaceNormals(); 16 //tGeometry.computeVertexNormals(); 17 //tGeometry.computeTangents(); 18 }); 19 20 // return this, to get chained API 21 return this; 22 }); 23 24 /** 25 * zoom a geometry 26 * 27 * @name zoom 28 * @methodOf tQuery.Geometry 29 */ 30 tQuery.Geometry.registerInstance('scaleBy', function(vector3){ 31 // handle parameters 32 if( typeof vector3 === "number" && arguments.length === 1 ){ 33 vector3 = new THREE.Vector3(vector3, vector3, vector3); 34 }else if( typeof vector3 === "number" && arguments.length === 3 ){ 35 vector3 = new THREE.Vector3(arguments[0], arguments[1], arguments[2]); 36 } 37 console.assert(vector3 instanceof THREE.Vector3, "Geometry.vector3 parameter error"); 38 39 // change all geometry.vertices 40 this.each(function(geometry){ 41 for(var i = 0; i < geometry.vertices.length; i++) { 42 var vertex = geometry.vertices[i]; 43 vertex.multiplySelf(vector3); 44 } 45 // mark the vertices as dirty 46 geometry.verticesNeedUpdate = true; 47 geometry.computeBoundingBox(); 48 }) 49 50 // return this, to get chained API 51 return this; 52 }); 53 54 tQuery.Geometry.registerInstance('size', function(){ 55 // only on zero-or-one element 56 console.assert(this.length <= 1) 57 // if no element, return undefined 58 if( this.length === 0 ) return undefined 59 60 // else measure the size of the element 61 var geometry = this.get(0); 62 // compute middle 63 var size= new THREE.Vector3() 64 size.x = geometry.boundingBox.max.x - geometry.boundingBox.min.x; 65 size.y = geometry.boundingBox.max.y - geometry.boundingBox.min.y; 66 size.z = geometry.boundingBox.max.z - geometry.boundingBox.min.z; 67 68 // return the just computed middle 69 return size; 70 }); 71 72 /** 73 */ 74 tQuery.Geometry.registerInstance('normalize', function(){ 75 // change all geometry.vertices 76 this.each(function(geometry){ 77 var node = tQuery(geometry); 78 var size = node.size(); 79 if( size.x >= size.y && size.x >= size.z ){ 80 node.zoom(1/size.x); 81 }else if( size.y >= size.x && size.y >= size.z ){ 82 node.zoom(1/size.y); 83 }else{ 84 node.zoom(1/size.z); 85 } 86 }); 87 // return this, to get chained API 88 return this; 89 }); 90 91 92 ////////////////////////////////////////////////////////////////////////////////// 93 // // 94 ////////////////////////////////////////////////////////////////////////////////// 95 96 97 tQuery.Geometry.registerInstance('middlePoint', function(){ 98 // only on zero-or-one element 99 console.assert(this.length <= 1) 100 // if no element, return undegined 101 if( this.length === 0 ) return undefined 102 // else measure the size of the element 103 var geometry = this.get(0); 104 // compute middle 105 var middle = new THREE.Vector3() 106 middle.x = ( geometry.boundingBox.max.x + geometry.boundingBox.min.x ) / 2; 107 middle.y = ( geometry.boundingBox.max.y + geometry.boundingBox.min.y ) / 2; 108 middle.z = ( geometry.boundingBox.max.z + geometry.boundingBox.min.z ) / 2; 109 110 // return the just computed middle 111 return middle; 112 }); 113 114 ////////////////////////////////////////////////////////////////////////////////// 115 // move functions // 116 ////////////////////////////////////////////////////////////////////////////////// 117 118 tQuery.Geometry.registerInstance('translate', function(delta){ 119 // handle parameters 120 if( typeof delta === "number" && arguments.length === 3 ){ 121 delta = new THREE.Vector3(arguments[0], arguments[1], arguments[2]); 122 } 123 console.assert(delta instanceof THREE.Vector3, "Geometry.translate parameter error"); 124 125 // change all geometry.vertices 126 this.each(function(geometry){ 127 // change all geometry.vertices 128 for(var i = 0; i < geometry.vertices.length; i++) { 129 var vertex = geometry.vertices[i]; 130 vertex.addSelf(delta); 131 } 132 // mark the vertices as dirty 133 geometry.verticesNeedUpdate = true; 134 geometry.computeBoundingBox(); 135 }) 136 137 // return this, to get chained API 138 return this; 139 }); 140 141 tQuery.Geometry.registerInstance('rotate', function(angles, order){ 142 // handle parameters 143 if( typeof angles === "number" && arguments.length === 3 ){ 144 angles = new THREE.Vector3(arguments[0], arguments[1], arguments[2]); 145 } 146 console.assert(angles instanceof THREE.Vector3, "Geometry.rotate parameter error"); 147 148 // set default rotation order if needed 149 order = order || 'XYZ'; 150 // compute transformation matrix 151 var matrix = new THREE.Matrix4(); 152 matrix.setRotationFromEuler(angles, order); 153 154 // change all geometry.vertices 155 this.each(function(geometry){ 156 // apply the matrix 157 geometry.applyMatrix( matrix ); 158 159 // mark the vertices as dirty 160 geometry.verticesNeedUpdate = true; 161 geometry.computeBoundingBox(); 162 }); 163 164 // return this, to get chained API 165 return this; 166 }); 167 168 /** 169 */ 170 tQuery.Geometry.registerInstance('center', function(noX, noY, noZ){ 171 // change all geometry.vertices 172 this.each(function(tGeometry){ 173 var geometry = tQuery(tGeometry); 174 // compute delta 175 var delta = geometry.middlePoint().negate(); 176 if( noX ) delta.x = 0; 177 if( noY ) delta.y = 0; 178 if( noZ ) delta.z = 0; 179 180 return geometry.translate(delta) 181 }); 182 // return this, to get chained API 183 return this; 184 }); 185 186 /** 187 * Smooth the geometry using catmull-clark 188 * 189 * @param {Number} subdivision the number of subdivision to do 190 */ 191 tQuery.Geometry.registerInstance('smooth', function(subdivision){ 192 // init the modifier 193 var modifier = new THREE.SubdivisionModifier( subdivision ); 194 // apply it to each geometry 195 this.each(function(geometry){ 196 // apply it 197 modifier.modify( geometry ) 198 199 // mark the vertices as dirty 200 geometry.verticesNeedUpdate = true; 201 geometry.computeBoundingBox(); 202 }); 203 // return this, to get chained API 204 return this; 205 }); 206 207 // some shortcuts 208 tQuery.Geometry.registerInstance('translateX' , function(delta){ return this.translate(delta, 0, 0); }); 209 tQuery.Geometry.registerInstance('translateY' , function(delta){ return this.translate(0, delta, 0); }); 210 tQuery.Geometry.registerInstance('translateZ' , function(delta){ return this.translate(0, 0, delta); }); 211 tQuery.Geometry.registerInstance('rotateX' , function(angle){ return this.rotate(angle, 0, 0); }); 212 tQuery.Geometry.registerInstance('rotateY' , function(angle){ return this.rotate(0, angle, 0); }); 213 tQuery.Geometry.registerInstance('rotateZ' , function(angle){ return this.rotate(0, 0, angle); }); 214 tQuery.Geometry.registerInstance('scaleXBy' , function(ratio){ return this.scaleBy(ratio, 1, 1); }); 215 tQuery.Geometry.registerInstance('scaleYBy' , function(ratio){ return this.scaleBy(1, ratio, 1); }); 216 tQuery.Geometry.registerInstance('scaleZBy' , function(ratio){ return this.scaleBy(1, 1, ratio); }); 217 218 // backward compatibility 219 tQuery.Geometry.registerInstance('zoom' , function(value){return this.scaleBy(value); }); 220 tQuery.Geometry.registerInstance('zoomX' , function(ratio){ return this.zoom(ratio, 1, 1); }); 221 tQuery.Geometry.registerInstance('zoomY' , function(ratio){ return this.zoom(1, ratio, 1); }); 222 tQuery.Geometry.registerInstance('zoomZ' , function(ratio){ return this.zoom(1, 1, ratio); }); 223 224 225 })(); // closure function end 226