├── PixelVoronoi_KdTree_v05 ├── SHADERS │ ├── KdTree_frag.glsl │ ├── DwScreenQuad_vert.glsl │ ├── KdTree_vert.glsl │ ├── DwScreenQuad_frag.glsl │ ├── PixelVoronoiKdTree_vert.glsl │ └── PixelVoronoiKdTree_frag.glsl ├── libs │ ├── Dw │ │ ├── utilitys │ │ │ ├── DwString.js │ │ │ ├── DwState.js │ │ │ └── Byter.js │ │ ├── context │ │ │ ├── DwFrameInfo.js │ │ │ ├── DwKeyInfo.js │ │ │ ├── DwMouseInfo.js │ │ │ └── DwContext.js │ │ ├── camera │ │ │ ├── DwDampedAction.js │ │ │ ├── DwCameraState.js │ │ │ ├── DwInterpolationManager.js │ │ │ └── DwCamera.js │ │ ├── geometry_templates │ │ │ ├── DwScreenQuad.js │ │ │ ├── DwQuadShader.js │ │ │ ├── DwXYZaxis.js │ │ │ ├── DwQuad.js │ │ │ ├── DwXYZaxisShader.js │ │ │ ├── DwScreenQuadShader.js │ │ │ ├── DwRectangle.js │ │ │ └── DwRectangleShader.js │ │ ├── math │ │ │ ├── DwPlane3D.js │ │ │ ├── DwRotationOrder.js │ │ │ ├── DwClippingPlane3D.js │ │ │ ├── DwVec2.js │ │ │ ├── DwVec3.js │ │ │ ├── DwVec4.js │ │ │ ├── DwMat3.js │ │ │ └── DwQuat.js │ │ ├── shader │ │ │ ├── DEPRECATED │ │ │ │ └── DwShader_ORIG.js │ │ │ └── DwShader.js │ │ ├── DOF │ │ │ └── DOF_shader.js │ │ ├── FBO │ │ │ └── DwFBO.js │ │ ├── image │ │ │ ├── DwImage.js │ │ │ └── DwImage_TGA.js │ │ └── DwVBO.js │ └── webgl_utils │ │ ├── webgl-utils.js │ │ └── old │ │ └── webgl-utils.js ├── Point.js ├── pixelvoronoi_style.css ├── QuickSelect.js ├── QuickSort.js ├── FBO.js ├── KdTreeRenderer.js ├── ScreenQuad.js ├── PixelVoronoi_KdTree.js ├── mersenne-twister.js └── KdTree.js └── README /PixelVoronoi_KdTree_v05/SHADERS/KdTree_frag.glsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | precision mediump float; 4 | 5 | uniform vec3 UN_VEC3_RGB; 6 | varying float VRY_AlPHA; 7 | 8 | void main(void){ 9 | gl_FragColor = vec4(UN_VEC3_RGB, VRY_AlPHA); 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/SHADERS/DwScreenQuad_vert.glsl: -------------------------------------------------------------------------------- 1 | 2 | precision mediump float; 3 | 4 | attribute vec2 IN_VEC2_POSITION; 5 | attribute vec2 IN_VEC2_ST; 6 | 7 | varying vec2 VRY_VEC2_ST; 8 | 9 | void main(void) 10 | { 11 | VRY_VEC2_ST = IN_VEC2_ST; 12 | gl_Position = vec4(IN_VEC2_POSITION,0,1); // no need for transformation when pos is in ndc. 13 | } 14 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/SHADERS/KdTree_vert.glsl: -------------------------------------------------------------------------------- 1 | 2 | precision mediump float; 3 | 4 | attribute vec2 IN_VEC2_POSITION; 5 | attribute float IN_FLOAT_ALPHA; 6 | 7 | uniform mat4 UN_MAT4_PROJECTION; 8 | 9 | varying float VRY_AlPHA; 10 | 11 | 12 | void main(void){ 13 | VRY_AlPHA = IN_FLOAT_ALPHA; 14 | gl_Position = UN_MAT4_PROJECTION*vec4(IN_VEC2_POSITION, 0, 1); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/utilitys/DwString.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 19.02.12 5 | */ 6 | 7 | 8 | var DwString = DwString || {}; 9 | 10 | DwString.startsWith = function(str, start){ 11 | return str.substr(0, start.length) == start; 12 | }; 13 | 14 | DwString.endsWith = function(str, end) { 15 | return str.substr(this.length-end.length) == end; 16 | }; 17 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/SHADERS/DwScreenQuad_frag.glsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | precision mediump float; 4 | 5 | uniform sampler2D UN_SAMP_TEXTURE; 6 | uniform int UN_INT_RGB_INVERT; 7 | uniform vec3 UN_VEC3_RGB_SCALE; 8 | varying vec2 VRY_VEC2_ST; 9 | 10 | 11 | void main(void){ 12 | 13 | float dis = texture2D (UN_SAMP_TEXTURE, VRY_VEC2_ST).r; 14 | vec3 rgb = UN_VEC3_RGB_SCALE * dis; 15 | 16 | if( UN_INT_RGB_INVERT == 1 ){ 17 | rgb = 1.0-rgb; 18 | } 19 | 20 | gl_FragColor = vec4(rgb, 1.0); 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/utilitys/DwState.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 21.02.12 5 | */ 6 | 7 | 8 | 9 | var DwState = DwState || {}; 10 | 11 | DwState.mat4_stack = []; 12 | DwState.mat3_stack = []; 13 | 14 | 15 | DwState.pushMat4 = function(src_mat4){ 16 | DwState.mat4_stack.push(DwMat4.copy_new(src_mat4)); 17 | } 18 | 19 | DwState.popMat4 = function(dst_mat4){ 20 | DwMat4.copy_ref( DwState.mat4_stack.pop(), dst_mat4); 21 | } 22 | 23 | 24 | 25 | DwState.pushMat3 = function(src_mat3){ 26 | DwState.mat3_stack.push(DwMat3.copy_new(src_mat3)); 27 | } 28 | 29 | DwState.popMat3 = function(dst_mat3){ 30 | DwMat3.copy_ref( DwState.mat3_stack.pop(), dst_mat3); 31 | } 32 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/context/DwFrameInfo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 06.02.12 5 | */ 6 | 7 | function DwFrameInfo(dw_context){ 8 | this.context = dw_context; 9 | 10 | this.framerate = null; 11 | this.framecount = null; 12 | this.time_last = 1; 13 | this.time_now = 1; 14 | this.date = new Date(); 15 | } 16 | 17 | DwFrameInfo.prototype.update = function (){ 18 | this.date = new Date(); 19 | this.framecount++; 20 | this.time_last = this.time_now; 21 | this.time_now = Date.now(); //new Date().getTime(); 22 | var time_dif = (this.time_now - this.time_last); 23 | if( time_dif == 0){ 24 | time_dif = 1; 25 | } 26 | this.framerate = (this.framerate * .9) + 100.0 / time_dif; 27 | } 28 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/SHADERS/PixelVoronoiKdTree_vert.glsl: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // author: thomas diewald 3 | // date: 17.03.2013 4 | // 5 | // WebGL vertex shader: "PixelVoronoiKdTree_vert.glsl" 6 | // for creating a pixel-based voronoi diagram. 7 | // distance to nearest neighbor affects pixel-shading. 8 | // nearest neighbor search is done by traversing a kd-tree. 9 | //------------------------------------------------------------------------------ 10 | 11 | precision mediump float; 12 | 13 | attribute vec2 IN_VEC2_POSITION; 14 | attribute vec2 IN_VEC2_ST; 15 | 16 | varying vec2 VRY_VEC2_ST; 17 | 18 | void main(void) 19 | { 20 | VRY_VEC2_ST = IN_VEC2_ST; 21 | gl_Position = vec4(IN_VEC2_POSITION,0,1); // no need for transformation when pos is in ndc. 22 | } 23 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/camera/DwDampedAction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 13.02.12 5 | */ 6 | 7 | 8 | function DwDampedAction (cam, behave){ 9 | this.cam = cam; 10 | this.velocity = 0; 11 | this.damping = 0.85; 12 | // this.damping = 0; 13 | this.behave = behave; 14 | } 15 | 16 | DwDampedAction.prototype.impulse = function(impulse) { 17 | this.velocity += impulse; 18 | } 19 | 20 | DwDampedAction.prototype.update = function() { 21 | if (this.velocity == 0) { 22 | return; 23 | } 24 | this.behave(this.cam, this.velocity); 25 | // this.cam.feed(); 26 | this.velocity *= this.damping; 27 | if (Math.abs(this.velocity) < .001) { 28 | this.velocity = 0; 29 | } 30 | } 31 | 32 | 33 | DwDampedAction.prototype.stop = function(){ 34 | this.velocity = 0; 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/Point.js: -------------------------------------------------------------------------------- 1 | /** 2 | * author: thomas diewald 3 | * date: 15.03.13 4 | * 5 | * simple point class. (position, direction) 6 | */ 7 | 8 | 9 | function Point(CTX, idx, x, y, dx, dy){ 10 | this.CTX = CTX; 11 | this.idx = idx; 12 | this.x = x ; 13 | this.y = y ; 14 | this.dx = dx ; 15 | this.dy = dy ; 16 | } 17 | 18 | Point.prototype.update = function(){ 19 | var mouse = this.CTX.mouse_info; 20 | 21 | var mx = mouse.mouseX; 22 | var my = mouse.mouseY; 23 | var px = this.x; 24 | var py = this.y; 25 | var dx = this.dx; 26 | var dy = this.dy; 27 | 28 | var dxm = mx-px; 29 | var dym = my-py; 30 | 31 | var d_sq = (dxm*dxm)+(dym*dym); 32 | // var d = (Math.sqrt(d_sq)); 33 | // var damp = 50.0/(Math.sqrt(d*d*d)); 34 | var damp = -250.0/(d_sq); 35 | px += dxm * damp; 36 | py += dym * damp; 37 | 38 | px += dx*0.5; 39 | py += dy*0.3; 40 | 41 | var viewp = this.CTX.VIEWPORT; 42 | if( px < 0 || px > viewp.width || 43 | py < 0 || py > viewp.height ) 44 | { 45 | px = viewp.width *0.5 + dx*50; 46 | py = viewp.height*0.5 + dy*50; 47 | } 48 | 49 | this.x = px; 50 | this.y = py; 51 | } 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/camera/DwCameraState.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 13.02.12 5 | */ 6 | 7 | 8 | 9 | function DwCameraState(rotation_quat4, center_vec3, distance_float) { 10 | this.rotation = rotation_quat4; 11 | this.center = center_vec3; 12 | this.distance = distance_float; 13 | } 14 | 15 | DwCameraState.prototype.getCopy = function(){ 16 | return new DwCameraState(DwQuat.copy_new(this.rotation), DwVec3.copy_new(this.center), this.distance); 17 | } 18 | DwCameraState.prototype.compareRotation = function(state){ 19 | return ( state.rotation[0] === this.rotation[0] 20 | && state.rotation[1] === this.rotation[1] 21 | && state.rotation[2] === this.rotation[2] 22 | && state.rotation[3] === this.rotation[3]); 23 | } 24 | DwCameraState.prototype.compareCenter = function(state){ 25 | return ( state.center[0] === this.center[0] 26 | && state.center[1] === this.center[1] 27 | && state.center[2] === this.center[2]); 28 | } 29 | DwCameraState.prototype.compareDistance = function(state){ 30 | return state.distance == this.distance; 31 | } 32 | DwCameraState.prototype.print = function(){ 33 | console.log("------ CAMERA STATE ------"); 34 | console.log("rotation = "+ this.rotation); 35 | console.log("center = "+ this.center); 36 | console.log("distance = "+ this.distance); 37 | } 38 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/pixelvoronoi_style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background: #555; 3 | font-family: "Trebuchet MS","Helvetica","Arial","Verdana","sans-serif"; 4 | } 5 | 6 | #div_webgl_canvas { 7 | 8 | padding: 0.0em; 9 | position:absolute ; 10 | left: 50px; 11 | top: 50; 12 | width: 400px; 13 | height: 300px; 14 | z-index: 2; 15 | opacity: 1; 16 | 17 | } 18 | 19 | 20 | #gui{ 21 | padding: 0.0em; 22 | padding: 15px; 23 | position:absolute ; 24 | left: 50px; 25 | top: 0px; 26 | width: 250px; 27 | height: 560px; 28 | z-index: 2; 29 | color: #FFF; 30 | background: #000; 31 | opacity: .7; 32 | 33 | /*visibility: hidden;*/ 34 | } 35 | 36 | a:link { font-weight:bold; color:#FFF; text-decoration:underline; } 37 | a:visited { font-weight:bold; color:#FFF; text-decoration:underline; } 38 | a:focus { font-weight:bold; color:#333; text-decoration:underline; } 39 | a:hover { font-weight:bold; color:#333; text-decoration:underline; } 40 | a:active { font-weight:bold; color:#333; text-decoration:underline; } 41 | 42 | .slider{ 43 | /*width:250px;*/ 44 | width:100%; 45 | float:left; 46 | clear:both; 47 | opacity: 1; 48 | } 49 | 50 | 51 | #gui_controls{ 52 | position:static; 53 | padding: 0.0em; 54 | margin: 100 10 10 10; 55 | /*left: 0px;*/ 56 | /*top: 0px;*/ 57 | color: #FFF; 58 | z-index: 3; 59 | font-size:11px; 60 | font-family: "Trebuchet MS","Helvetica","Arial","Verdana","sans-serif"; 61 | opacity: 1; 62 | /*color: #FFF;*/ 63 | /*background: #111;*/ 64 | /*opacity: .7;*/ 65 | } 66 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/camera/DwInterpolationManager.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 13.02.12 5 | */ 6 | 7 | function DwInterpolationManager(cam, func_interpolate, func_finish) { 8 | this.cam = cam; 9 | this.func_interpolate = func_interpolate; 10 | this.func_finish = func_finish; 11 | 12 | this.animation_time = null; 13 | this.run_interpolation = false; 14 | 15 | this.value_start = null; 16 | this.value_end = null; 17 | 18 | this.time_start = 0; 19 | this.time_now = 0; 20 | } 21 | 22 | DwInterpolationManager.prototype.start = function(value_start, value_end, animation_time ) { 23 | this.run_interpolation = true; 24 | 25 | this.value_start = value_start; 26 | this.value_end = value_end; 27 | 28 | this.animation_time = animation_time; 29 | this.time_start = Date.now(); 30 | } 31 | 32 | 33 | DwInterpolationManager.prototype.update = function() { 34 | // console.log("rotation_update: "+ this.run_interpolation); 35 | if( this.run_interpolation !== true) 36 | return; 37 | 38 | // this.time_now = Date.now(); //new Date().getTime(); 39 | var fac = (Date.now()- this.time_start) / this.animation_time; 40 | if( fac > 1 ){ // animation time is over 41 | this.stop(this.value_end); 42 | } else { 43 | this.func_interpolate(this.cam, this.value_start, this.value_end, fac); 44 | } 45 | } 46 | 47 | DwInterpolationManager.prototype.stop = function(value_end) { 48 | 49 | this.run_interpolation = false; 50 | 51 | value_end = value_end || 0; 52 | if( value_end !== 0){ 53 | this.func_finish(this.cam, value_end); 54 | } 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/geometry_templates/DwScreenQuad.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 22.02.12 5 | */ 6 | 7 | 8 | function DwScreenQuad(gl, width, height){ 9 | this.gl = gl; 10 | 11 | this.HANDLE_vbo = gl.createBuffer(); 12 | 13 | this.resize( width, height); 14 | } 15 | 16 | DwScreenQuad.prototype.resize = function(width, height){ 17 | var w = width; 18 | var h = height; 19 | var gl = this.gl; 20 | this.vertex_data = 21 | [ 22 | 0, 0, 0, 0, 0, 23 | 0, h, 0, 0, 1, 24 | w, 0, 0, 1, 0, 25 | w, h, 0, 1, 1 26 | ]; 27 | 28 | this.data_Float32 = new Float32Array(this.vertex_data); 29 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 30 | gl.bufferData(gl.ARRAY_BUFFER, this.data_Float32, gl.STATIC_DRAW); 31 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 32 | this.Mat4_Projection = DwMat4.ortho_new(0, w, 0, h, -100, 100); 33 | } 34 | 35 | DwScreenQuad.prototype.delete = function(){ 36 | this.gl.deleteBuffer(this.HANDLE_vbo); 37 | this.HANDLE_vbo = null; 38 | this.vertex_data = null; 39 | this.vertex_data = []; 40 | } 41 | 42 | 43 | 44 | DwScreenQuad.prototype.draw = function(shader){ 45 | var gl = this.gl; 46 | 47 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 48 | 49 | gl.vertexAttribPointer(shader.IN_VEC3_POSITION, 3, gl.FLOAT, false, 20, 0 ); 50 | gl.vertexAttribPointer(shader.IN_VEC2_ST, 2, gl.FLOAT, false, 20, 12 ); 51 | 52 | gl.enableVertexAttribArray(shader.IN_VEC3_POSITION ); 53 | gl.enableVertexAttribArray(shader.IN_VEC2_ST ); 54 | 55 | this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4 ); 56 | this.gl.flush(); 57 | } 58 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/math/DwPlane3D.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 10.02.12 5 | */ 6 | 7 | 8 | var DwPlane3D = DwPlane3D || {}; 9 | 10 | //TODO: a lot 11 | 12 | 13 | 14 | 15 | DwPlane3D.nullplane = function(){ 16 | return [0, 0, 0, 0]; 17 | } 18 | 19 | DwPlane3D.yz = function(){ 20 | return [1, 0, 0, 0]; 21 | } 22 | DwPlane3D.xz = function(){ 23 | return [0, 1, 0, 0]; 24 | } 25 | DwPlane3D.xy = function(){ 26 | return [0, 0, 1, 0]; 27 | } 28 | 29 | DwPlane3D.setNormals_ref = function(n_v3, dst_p){ 30 | dst_p[0] = n_v3[0]; 31 | dst_p[1] = n_v3[1]; 32 | dst_p[2] = n_v3[2]; 33 | } 34 | DwPlane3D.setNormals_new = function(n_v3){ 35 | return [n_v3[0], n_v3[1], n_v3[2], 0]; 36 | } 37 | 38 | 39 | DwPlane3D.setOffset_ref = function(o_f, dst_p){ 40 | dst_p[3] = o_f; 41 | } 42 | 43 | 44 | DwPlane3D.normalize_ref = function(p, dst_p){ 45 | var nx = p[0], ny = p[1], nz = p[2], o = p[3]; 46 | var dot = nx*nx + ny*ny + nz*nz; 47 | var len_inv = 1/Math.sqrt(dot); 48 | 49 | dst_p[0] = nx*len_inv; 50 | dst_p[1] = ny*len_inv; 51 | dst_p[2] = nz*len_inv; 52 | dst_p[3] = o*len_inv; 53 | } 54 | DwPlane3D.normalize_ref_slf = function(p){ 55 | var nx = p[0], ny = p[1], nz = p[2], o = p[3]; 56 | var dot = nx*nx + ny*ny + nz*nz; 57 | var len_inv = 1/Math.sqrt(dot); 58 | 59 | p[0] *= len_inv; 60 | p[1] *= len_inv; 61 | p[2] *= len_inv; 62 | p[3] *= len_inv; 63 | } 64 | DwPlane3D.normalize_new = function(p){ 65 | var nx = p[0], ny = p[1], nz = p[2], o = p[3]; 66 | var dot = nx*nx + ny*ny + nz*nz; 67 | var len_inv = 1/Math.sqrt(dot); 68 | return[nx*len_inv, ny*len_inv, nz*len_inv, o*len_inv]; 69 | } 70 | 71 | 72 | DwPlane3D.toStr = function (p) { 73 | return "[plane n_xyz,o:"+p[0]+", "+p[1]+", "+p[2]+", "+p[3]+"]"; 74 | }; 75 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/geometry_templates/DwQuadShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 08.02.12 5 | */ 6 | 7 | 8 | function DwQuadShader(gl){ 9 | this.gl = gl; 10 | this.shader = new DwShader(gl, "", "quad_vert.glsl", "quad_frag.glsl"); 11 | 12 | this.gl.useProgram(this.shader.HANDLE_program); 13 | 14 | this.IN_VEC3_POSITION = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_POSITION"); 15 | this.IN_VEC2_TEXCOORDS = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC2_TEXCOORDS"); 16 | this.IN_VEC3_COLOR = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_COLOR"); 17 | 18 | this.UN_MAT4_PROJECTION = gl.getUniformLocation(this.shader.HANDLE_program, "UN_MAT4_PROJECTION"); 19 | this.UN_MAT4_MODELVIEW = gl.getUniformLocation(this.shader.HANDLE_program, "UN_MAT4_MODELVIEW"); 20 | this.gl.useProgram(null); 21 | 22 | console.log("attribute location: IN_VEC3_POSITION = "+this.IN_VEC3_POSITION); 23 | console.log("attribute location: IN_VEC2_TEXCOORDS = "+this.IN_VEC2_TEXCOORDS); 24 | console.log("attribute location: IN_VEC3_COLOR = "+this.IN_VEC3_COLOR); 25 | console.log("uniform location: UN_MAT4_PROJECTION = "+this.UN_MAT4_PROJECTION); 26 | console.log("uniform location: UN_MAT4_MODELVIEW = "+this.UN_MAT4_MODELVIEW); 27 | 28 | } 29 | DwQuadShader.prototype.delete = function(){ 30 | this.shader.delete(); 31 | this.shader = null; 32 | } 33 | 34 | DwQuadShader.prototype.setMat4_Projection = function(MAT4){ 35 | this.gl.uniformMatrix4fv( this.UN_MAT4_PROJECTION, false, MAT4); 36 | } 37 | 38 | DwQuadShader.prototype.setMat4_ModelView = function(MAT4){ 39 | this.gl.uniformMatrix4fv( this.UN_MAT4_MODELVIEW, false, MAT4); 40 | } 41 | 42 | 43 | DwQuadShader.prototype.bind = function(){ 44 | this.gl.useProgram(this.shader.HANDLE_program); 45 | } 46 | 47 | DwQuadShader.prototype.unbind = function(){ 48 | this.gl.useProgram(null); 49 | } 50 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/geometry_templates/DwXYZaxis.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 07.02.12 5 | */ 6 | 7 | 8 | 9 | function DwXYZaxis(gl, size){ 10 | this.gl = gl; 11 | var s = size; 12 | 13 | this.vertex_data = 14 | [ 15 | // vertex 0 16 | 0.0, 0.0, 0.0, // x-axis - start 17 | 1.0, 0.0, 0.0, // x-axis - start - color 18 | 19 | // vertex 1 20 | s, 0.0, 0.0, // x-axis - end 21 | 1.0, 0.0, 0.0, // x-axis - end - color 22 | 23 | // vertex 2 24 | 0.0, 0.0, 0.0, // y-axis - start 25 | 0.0, 1.0, 0.0, // y-axis - start - color 26 | 27 | // vertex 3 28 | 0.0, s, 0.0, // y-axis - end 29 | 0.0, 1.0, 0.0, // y-axis - end - color 30 | 31 | // vertex 4 32 | 0.0, 0.0, 0.0, // z-axis - start 33 | 0.0, 0.0, 1.0, // z-axis - start - color 34 | 35 | // vertex 5 36 | 0.0, 0.0, s, // z-axis - end 37 | 0.0, 0.0, 1.0 // z-axis - end - color 38 | ]; 39 | 40 | this.data_Float32 = new Float32Array(this.vertex_data); 41 | 42 | this.HANDLE_vbo = gl.createBuffer(); 43 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 44 | gl.bufferData(gl.ARRAY_BUFFER, this.data_Float32, gl.STATIC_DRAW); 45 | } 46 | DwXYZaxis.prototype.delete = function(){ 47 | this.gl.deleteBuffer(this.HANDLE_vbo); 48 | this.HANDLE_vbo = null; 49 | this.data_Float32 = null; 50 | this.vertex_data = []; 51 | } 52 | 53 | 54 | DwXYZaxis.prototype.draw = function(shader){ 55 | var gl = this.gl; 56 | 57 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 58 | 59 | gl.vertexAttribPointer(shader.IN_VEC3_POSITION, 3, gl.FLOAT, false, 24, 0 ); 60 | gl.vertexAttribPointer(shader.IN_VEC3_COLOR, 3, gl.FLOAT, false, 24, 12 ); 61 | 62 | gl.enableVertexAttribArray(shader.IN_VEC3_POSITION ); 63 | gl.enableVertexAttribArray(shader.IN_VEC3_COLOR ); 64 | 65 | gl.drawArrays(gl.LINES, 0, 6 ); 66 | gl.flush(); 67 | } 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/geometry_templates/DwQuad.js: -------------------------------------------------------------------------------- 1 | ///** 2 | // * project: ... 3 | // * author: thomas diewald 4 | // * date: 08.02.12 5 | // */ 6 | // 7 | // 8 | //function DwQuad(gl, width, height){ 9 | // var w = width; 10 | // var h = height; 11 | // this.vertex_data = 12 | // [ 13 | // 0.0, 0.0, 0.0, // vertex 0 14 | // 1.0, 0.0, 0.0, // color red 15 | // 0.0, 0.0, // texcoords 16 | // 17 | // w, 0.0, 0.0, // vertex 1 18 | // 0.0, 1.0, 0.0, // color green 19 | // 1.0, 0.0, // texcoords 20 | // 21 | // w, h, 0.0, // vertex 2 22 | // 0.0, 0.0, 1.0, // color blue 23 | // 1.0, 1.0, // texcoords 24 | // 25 | // 0.0, h, 0.0, // vertex 3 26 | // 1.0, 1.0, 1.0, // color white 27 | // 0.0, 1.0 // texcoords 28 | // ]; 29 | // 30 | // this.data_Float32 = new Float32Array(this.vertex_data); 31 | // 32 | // this.HANDLE_vbo = gl.createBuffer(); 33 | // gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 34 | // gl.bufferData(gl.ARRAY_BUFFER, this.data_Float32, gl.STATIC_DRAW); 35 | //} 36 | // 37 | //DwQuad.prototype.delete = function(){ 38 | // this.gl.deleteBuffer(this.HANDLE_vbo); 39 | // this.HANDLE_vbo = null; 40 | //} 41 | // 42 | // 43 | // 44 | // 45 | ////DwQuad.prototype.draw = function(shader){ 46 | //// var gl = this.gl; 47 | //// 48 | //// gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 49 | //// 50 | //// gl.vertexAttribPointer(shader.IN_VEC3_POSITION, 3, gl.FLOAT, false, 24, 0 ); 51 | //// gl.vertexAttribPointer(shader.IN_VEC3_COLOR, 3, gl.FLOAT, false, 24, 12 ); 52 | //// gl.vertexAttribPointer(shader.IN_VEC3_COLOR, 3, gl.FLOAT, false, 24, 12 ); 53 | //// 54 | //// gl.enableVertexAttribArray(shader.IN_VEC3_POSITION ); 55 | //// gl.enableVertexAttribArray(shader.IN_VEC3_COLOR ); 56 | //// 57 | //// this.gl.drawArrays(this.gl.LINES, 0, 6 ); 58 | //// this.gl.flush(); 59 | ////} 60 | //// 61 | // 62 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/QuickSelect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 15.04.13 5 | */ 6 | 7 | function QuickSelect(){ 8 | 9 | } 10 | 11 | 12 | 13 | QuickSelect.prototype.sort = function(points, dim, left, right, m) { 14 | if (points == null || points.length == 0) return; 15 | this.pts = points; 16 | this.dim = dim; 17 | this.quickfindFirstK(left, right, m); 18 | } 19 | 20 | 21 | QuickSelect.prototype.partitionX = function(left, right, pivot_idx) { 22 | var pivot = this.pts[pivot_idx].x; 23 | this.swap( right, pivot_idx); // Move pivot to end 24 | 25 | for (var i = pivot_idx = left; i < right; i++) { 26 | // console.log(this.pts[i].x); 27 | if (this.pts[i].x < pivot) { 28 | this.swap( pivot_idx++, i); 29 | } 30 | } 31 | this.swap( right, pivot_idx); // Move pivot to its final place 32 | return pivot_idx; 33 | } 34 | QuickSelect.prototype.partitionY = function(left, right, pivot_idx) { 35 | var pivot = this.pts[pivot_idx].y; 36 | this.swap( right, pivot_idx); // Move pivot to end 37 | for (var i = pivot_idx = left; i < right; i++) { 38 | if (this.pts[i].y < pivot) { 39 | this.swap( pivot_idx++, i); 40 | } 41 | } 42 | this.swap( right, pivot_idx); // Move pivot to its final place 43 | return pivot_idx; 44 | } 45 | 46 | QuickSelect.prototype.quickfindFirstK = function( left, right, k) { 47 | if (right > left) { 48 | var pivot_idx = (left + right) >> 1; 49 | 50 | switch(this.dim){ 51 | case 0: pivot_idx = this.partitionX( left, right, pivot_idx); break; 52 | case 1: pivot_idx = this.partitionY( left, right, pivot_idx); break; 53 | } 54 | 55 | if (pivot_idx > k) this.quickfindFirstK( left, pivot_idx-1, k); 56 | if (pivot_idx < k) this.quickfindFirstK( pivot_idx+1, right, k); 57 | } 58 | } 59 | 60 | 61 | QuickSelect.prototype.swap = function(i, j) { 62 | var pts_t = this.pts[i]; 63 | this.pts[i] = this.pts[j]; 64 | this.pts[j] = pts_t; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/geometry_templates/DwXYZaxisShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 08.02.12 5 | */ 6 | 7 | 8 | function DwXYZaxisShader(gl){ 9 | this.gl = gl; 10 | var _this = this; 11 | 12 | _this.shader = new DwShader(gl, "", "SHADERS/XYZaxis_vert.glsl", "SHADERS/XYZaxis_frag.glsl"); 13 | _this.shader.onload = function(){ 14 | _this.saveShaderLocations(); 15 | } 16 | _this.shader.load(null); 17 | } 18 | 19 | DwXYZaxisShader.prototype.saveShaderLocations = function(){ 20 | var gl = this.gl; 21 | gl.useProgram(this.shader.HANDLE_program); 22 | { 23 | this.IN_VEC3_POSITION = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_POSITION"); 24 | this.IN_VEC3_COLOR = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_COLOR"); 25 | this.UN_MAT4_PROJECTION = gl.getUniformLocation(this.shader.HANDLE_program, "UN_MAT4_PROJECTION"); 26 | this.UN_MAT4_MODELVIEW = gl.getUniformLocation(this.shader.HANDLE_program, "UN_MAT4_MODELVIEW"); 27 | } 28 | gl.useProgram(null); 29 | // console.log("attribute location: IN_VEC3_POSITION = "+this.IN_VEC3_POSITION); 30 | // console.log("attribute location: IN_VEC3_COLOR = "+this.IN_VEC3_COLOR); 31 | // console.log("uniform location: UN_MAT4_PROJECTION = "+this.UN_MAT4_PROJECTION); 32 | // console.log("uniform location: UN_MAT4_MODELVIEW = "+this.UN_MAT4_MODELVIEW); 33 | } 34 | DwXYZaxisShader.prototype.delete = function(){ 35 | this.shader.delete(); 36 | this.shader = null; 37 | } 38 | 39 | DwXYZaxisShader.prototype.setMat4_Projection = function(MAT4){ 40 | this.gl.uniformMatrix4fv( this.UN_MAT4_PROJECTION, false, MAT4); 41 | } 42 | 43 | DwXYZaxisShader.prototype.setMat4_ModelView = function(MAT4){ 44 | this.gl.uniformMatrix4fv( this.UN_MAT4_MODELVIEW, false, MAT4); 45 | } 46 | 47 | DwXYZaxisShader.prototype.bind = function(){ 48 | this.gl.useProgram(this.shader.HANDLE_program); 49 | } 50 | 51 | DwXYZaxisShader.prototype.unbind = function(){ 52 | this.gl.useProgram(null); 53 | } 54 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/context/DwKeyInfo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 07.02.12 5 | */ 6 | 7 | 8 | 9 | 10 | 11 | 12 | function DwKeyInfo(dw_context) 13 | { 14 | this.context = dw_context; 15 | this.canvas = this.context.canvas; 16 | 17 | // states 18 | this.keypressed = false; 19 | this.keyreleased = false; 20 | 21 | this.keycode = ' '; 22 | this.key = ' '; 23 | this.keychar = ' '; 24 | this.ctrl = false; 25 | this.alt = false; 26 | this.shift = false; 27 | 28 | this.activate(); 29 | 30 | } 31 | 32 | 33 | DwKeyInfo.prototype.activate = function (){ 34 | DwKeyInfo.attachToDocument(this.canvas, this); 35 | } 36 | 37 | 38 | DwKeyInfo.prototype.keyPressed = function (event) { 39 | this.keypressed = true; 40 | this.keyreleased = false; 41 | this.getEventVal(event); 42 | } 43 | 44 | 45 | DwKeyInfo.prototype.keyReleased = function (event) { 46 | this.keypressed = false; 47 | this.keyreleased = true; 48 | this.getEventVal(event); 49 | // console.log("____KEY="+this.keychar+", "+event.keyCode+", "+event.which); 50 | } 51 | 52 | 53 | DwKeyInfo.prototype.getEventVal = function (event){ 54 | this.keycode = event.keyCode; 55 | this.key = event.which; 56 | this.keychar = String.fromCharCode(this.key); 57 | this.ctrl = event.ctrlKey; 58 | this.alt = event.altKey; 59 | this.shift = event.shiftKey; 60 | } 61 | 62 | DwKeyInfo.prototype.updateBegin = function (){ 63 | 64 | } 65 | DwKeyInfo.prototype.updateEnd = function (){ 66 | this.keyreleased = false; 67 | } 68 | 69 | 70 | /** 71 | * attachToDocument(); 72 | * static method 73 | * @param mouse_info an instance of the class MouseInfo 74 | */ 75 | DwKeyInfo.attachToDocument = function(canvas, key_info){ 76 | 77 | // document.onkeypress = function(event){ 78 | // key_info.keyPressed(event); 79 | // }; 80 | document.onkeydown= function(event){ 81 | key_info.keyPressed(event); 82 | }; 83 | 84 | document.onkeyup = function(event){ 85 | key_info.keyReleased(event); 86 | }; 87 | }; 88 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/geometry_templates/DwScreenQuadShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 22.02.12 5 | */ 6 | 7 | 8 | 9 | function DwScreenQuadShader(gl){ 10 | this.gl = gl; 11 | var _this = this; 12 | 13 | _this.shader = new DwShader(gl, "", "SHADERS/DwScreenQuad_vert.glsl", "SHADERS/DwScreenQuad_frag.glsl"); 14 | // console.log("DwScreenQuadShader "); 15 | _this.shader.onload = function(){ 16 | // console.log("DwScreenQuadShader loading shader"); 17 | _this.saveShaderLocations(); 18 | } 19 | _this.shader.load(null); 20 | } 21 | 22 | 23 | DwScreenQuadShader.prototype.saveShaderLocations = function(){ 24 | var gl = this.gl; 25 | gl.useProgram(this.shader.HANDLE_program); 26 | { 27 | this.IN_VEC3_POSITION = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_POSITION"); 28 | this.IN_VEC2_ST = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC2_ST"); 29 | 30 | this.UN_MAT4_PROJECTION = gl.getUniformLocation(this.shader.HANDLE_program, "UN_MAT4_PROJECTION"); 31 | this.UN_SAMP_TEXTURE = gl.getUniformLocation(this.shader.HANDLE_program, "UN_SAMP_TEXTURE"); 32 | } 33 | gl.useProgram(null); 34 | console.log("attribute location: IN_VEC3_POSITION = "+this.IN_VEC3_POSITION); 35 | console.log("attribute location: IN_VEC2_ST = "+this.IN_VEC2_ST); 36 | console.log("uniform location: UN_MAT4_PROJECTION = "+this.UN_MAT4_PROJECTION); 37 | console.log("uniform location: UN_SAMP_TEXTURE = "+this.UN_SAMP_TEXTURE); 38 | } 39 | 40 | DwScreenQuadShader.prototype.delete = function(){ 41 | this.shader.delete(); 42 | this.shader = null; 43 | } 44 | 45 | DwScreenQuadShader.prototype.setMat4_Projection = function(MAT4){ 46 | this.gl.uniformMatrix4fv( this.UN_MAT4_PROJECTION, false, MAT4); 47 | } 48 | 49 | DwScreenQuadShader.prototype.setMat4_ModelView = function(MAT4){ 50 | this.gl.uniformMatrix4fv( this.UN_MAT4_MODELVIEW, false, MAT4); 51 | } 52 | DwScreenQuadShader.prototype.activeTexture = function(tex_loc){ 53 | this.gl.uniform1i(this.UN_SAMP_TEXTURE, tex_loc); 54 | } 55 | 56 | DwScreenQuadShader.prototype.bind = function(){ 57 | this.gl.useProgram(this.shader.HANDLE_program); 58 | } 59 | 60 | DwScreenQuadShader.prototype.unbind = function(){ 61 | this.gl.useProgram(null); 62 | } 63 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/shader/DEPRECATED/DwShader_ORIG.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas 4 | * date: 05.02.12 5 | */ 6 | 7 | 8 | 9 | 10 | function DwShader(gl, path, shader_name_vert, shader_name_frag){ 11 | 12 | this.gl = gl; 13 | this.HANDLE_program = null; 14 | this.HANDLE_vert = null; 15 | this.HANDLE_frag = null; 16 | 17 | this.path = path; 18 | this.shader_name_vert = shader_name_vert; 19 | this.shader_name_frag = shader_name_frag; 20 | this.create(); 21 | 22 | } 23 | 24 | 25 | /** 26 | * static loadShaderFileContent() 27 | * @param filename 28 | */ 29 | DwShader.loadShaderFileContent = function (filename){ 30 | var XHR = new XMLHttpRequest(); 31 | XHR.open('GET', filename, !true); 32 | XHR.responseType = "text"; 33 | XHR.send(null); 34 | if (XHR.readyState === 4) { 35 | if (XHR.status === 0) { // TODO: 200 36 | return XHR.responseText; 37 | } 38 | // alert("xhr.status = "+xhr.status); 39 | return null; 40 | } 41 | // alert("xhr.status != 4"); 42 | return null; 43 | } 44 | 45 | 46 | /** 47 | * static getShader() 48 | * 49 | * @param gl 50 | * @param shader_file 51 | * @param shader_type 52 | */ 53 | DwShader.getShader = function (gl, shader_file, shader_type) { 54 | var shader_content = DwShader.loadShaderFileContent(shader_file); 55 | if( shader_content == null ) 56 | return null; 57 | 58 | var handle = gl.createShader(shader_type); 59 | 60 | gl.shaderSource(handle, shader_content); 61 | gl.compileShader(handle); 62 | 63 | if (!gl.getShaderParameter(handle, gl.COMPILE_STATUS)) { 64 | alert(gl.getShaderInfoLog(handle)); 65 | return null; 66 | } 67 | 68 | return handle; 69 | } 70 | 71 | 72 | DwShader.prototype.create = function (){ 73 | var gl = this.gl; 74 | this.HANDLE_vert = DwShader.getShader(gl, this.path+this.shader_name_vert, gl.VERTEX_SHADER); 75 | this.HANDLE_frag = DwShader.getShader(gl, this.path+this.shader_name_frag, gl.FRAGMENT_SHADER); 76 | 77 | this.HANDLE_program = gl.createProgram(); 78 | gl.attachShader(this.HANDLE_program, this.HANDLE_vert); 79 | gl.attachShader(this.HANDLE_program, this.HANDLE_frag); 80 | gl.linkProgram(this.HANDLE_program); 81 | 82 | if (!gl.getProgramParameter(this.HANDLE_program, gl.LINK_STATUS)) { 83 | alert("Could not initialise shaders"); 84 | } 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- 3 | -------------------------------------------------------------------------------- 4 | 5 | AUTHOR: Thomas Diewald 6 | 7 | Date: 24.03.2013 8 | 9 | website: www.thomasdiewald.com 10 | 11 | -------------------------------------------------------------------------------- 12 | -------------------------------------------------------------------------------- 13 | 14 | 15 | 16 | ################################################################################ 17 | -------------------------------------------------------------------------------- 18 | WebGL/JavaScript - KdTree Nearest neighbor Search - GL ES 19 | -------------------------------------------------------------------------------- 20 | ################################################################################ 21 | 22 | 23 | blog-post: http://thomasdiewald.com/blog/?p=1825 24 | online-demo: http://thomasdiewald.com/javascript/webgl/PixelVoronoi_KdTree_v05/ 25 | 26 | 27 | Kd-Tree Nearest Neighbor Search. 28 | For each pixel, the distance to the nearest neighbor is stored in a 29 | "distance-map", which results in a voronoi-diagram. 30 | The NNS is done in the fragment shader. The kdTree is build in javascript. 31 | 32 | 33 | 34 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 35 | * 36 | * 37 | * (c) thomas diewald 38 | * 39 | * 40 | * This source is free software; you can redistribute it and/or modify 41 | * it under the terms of the GNU General Public License as published by 42 | * the Free Software Foundation; either version 2 of the License, or 43 | * (at your option) any later version. 44 | * 45 | * This code is distributed in the hope that it will be useful, but 46 | * WITHOUT ANY WARRANTY; without even the implied warranty of 47 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 48 | * General Public License for more details. 49 | * 50 | * A copy of the GNU General Public License is available on the World 51 | * Wide Web at . You can also 52 | * obtain it by writing to the Free Software Foundation, 53 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 54 | * 55 | * 56 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/math/DwRotationOrder.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 14.02.12 5 | */ 6 | 7 | //TODO: check if values by reference is problematic 8 | var DwAxis = { 9 | X: [1, 0, 0], 10 | Y: [0, 1, 0], 11 | Z: [0, 0, 1] 12 | } 13 | 14 | var DwRotationOrder = {}; 15 | 16 | DwRotationOrder.XYZ = [DwAxis.X, DwAxis.Y, DwAxis.Z]; 17 | DwRotationOrder.XZY = [DwAxis.X, DwAxis.Z, DwAxis.Y]; 18 | DwRotationOrder.YXZ = [DwAxis.Y, DwAxis.X, DwAxis.Z]; 19 | DwRotationOrder.YZX = [DwAxis.Y, DwAxis.Z, DwAxis.X]; 20 | DwRotationOrder.ZXY = [DwAxis.Z, DwAxis.X, DwAxis.Y]; 21 | DwRotationOrder.ZYX = [DwAxis.Z, DwAxis.Y, DwAxis.X]; 22 | DwRotationOrder.XYX = [DwAxis.X, DwAxis.Y, DwAxis.X]; 23 | DwRotationOrder.XZX = [DwAxis.X, DwAxis.Z, DwAxis.Z]; 24 | DwRotationOrder.YXY = [DwAxis.Y, DwAxis.X, DwAxis.Y]; 25 | DwRotationOrder.YZY = [DwAxis.Y, DwAxis.Z, DwAxis.Y]; 26 | DwRotationOrder.ZXZ = [DwAxis.Z, DwAxis.X, DwAxis.Z]; 27 | DwRotationOrder.ZYZ = [DwAxis.Z, DwAxis.Y, DwAxis.Z]; 28 | 29 | 30 | 31 | //public static final RotationOrder XYZ = new RotationOrder("XYZ", Vector3D.plusI,Vector3D.plusJ, Vector3D.plusK); 32 | //public static final RotationOrder XZY = new RotationOrder("XZY", Vector3D.plusI,Vector3D.plusK, Vector3D.plusJ); 33 | //public static final RotationOrder YXZ = new RotationOrder("YXZ", Vector3D.plusJ,Vector3D.plusI, Vector3D.plusK); 34 | // 35 | //public static final RotationOrder YZX = new RotationOrder("YZX", Vector3D.plusJ,Vector3D.plusK, Vector3D.plusI); 36 | //public static final RotationOrder ZXY = new RotationOrder("ZXY", Vector3D.plusK,Vector3D.plusI, Vector3D.plusJ); 37 | //public static final RotationOrder ZYX = new RotationOrder("ZYX", Vector3D.plusK,Vector3D.plusJ, Vector3D.plusI); 38 | // 39 | //public static final RotationOrder XYX = new RotationOrder("XYX", Vector3D.plusI,Vector3D.plusJ, Vector3D.plusI); 40 | //public static final RotationOrder XZX = new RotationOrder("XZX", Vector3D.plusI,Vector3D.plusK, Vector3D.plusI); 41 | //public static final RotationOrder YXY = new RotationOrder("YXY", Vector3D.plusJ,Vector3D.plusI, Vector3D.plusJ); 42 | // 43 | //public static final RotationOrder YZY = new RotationOrder("YZY", Vector3D.plusJ,Vector3D.plusK, Vector3D.plusJ); 44 | //public static final RotationOrder ZXZ = new RotationOrder("ZXZ", Vector3D.plusK,Vector3D.plusI, Vector3D.plusK); 45 | //public static final RotationOrder ZYZ = new RotationOrder("ZYZ", Vector3D.plusK,Vector3D.plusJ, Vector3D.plusK); 46 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/math/DwClippingPlane3D.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 10.02.12 5 | */ 6 | 7 | /** 8 | * general: 9 | * m4 = (mat4x4) projection matrix 10 | * p = ([x, y, z, o]) plane3D 11 | */ 12 | 13 | var DwClippingPlane3D = DwClippingPlane3D || {}; 14 | 15 | 16 | DwClippingPlane3D.near_ref = function(m4, p){ 17 | p[0] = m4[ 3] + m4[ 2]; 18 | p[1] = m4[ 7] + m4[ 6]; 19 | p[2] = m4[11] + m4[10]; 20 | p[3] = m4[15] + m4[14]; 21 | } 22 | DwClippingPlane3D.near_new = function(m4){ 23 | return [m4[ 3] + m4[ 2], 24 | m4[ 7] + m4[ 6], 25 | m4[11] + m4[10], 26 | m4[15] + m4[14]]; 27 | } 28 | 29 | 30 | DwClippingPlane3D.far_ref = function(m4, p){ 31 | p[0] = m4[ 3] - m4[ 2]; 32 | p[1] = m4[ 7] - m4[ 6]; 33 | p[2] = m4[11] - m4[10]; 34 | p[3] = m4[15] - m4[14]; 35 | } 36 | DwClippingPlane3D.far_new = function(m4){ 37 | return [m4[ 3] - m4[ 2], 38 | m4[ 7] - m4[ 6], 39 | m4[11] - m4[10], 40 | m4[15] - m4[14]]; 41 | } 42 | 43 | 44 | DwClippingPlane3D.left_ref = function(m4, p){ 45 | p[0] = m4[ 3] + m4[ 0]; 46 | p[1] = m4[ 7] + m4[ 4]; 47 | p[2] = m4[11] + m4[ 8]; 48 | p[3] = m4[15] + m4[12]; 49 | } 50 | DwClippingPlane3D.left_new = function(m4){ 51 | return [m4[ 3] + m4[ 0], 52 | m4[ 7] + m4[ 4], 53 | m4[11] + m4[ 8], 54 | m4[15] + m4[12]]; 55 | } 56 | 57 | 58 | DwClippingPlane3D.right_ref = function(m4, p){ 59 | p[0] = m4[ 3] - m4[ 0]; 60 | p[1] = m4[ 7] - m4[ 4]; 61 | p[2] = m4[11] - m4[ 8]; 62 | p[3] = m4[15] - m4[12]; 63 | } 64 | DwClippingPlane3D.right_new = function(m4){ 65 | return 66 | [m4[ 3] - m4[ 0], 67 | m4[ 7] - m4[ 4], 68 | m4[11] - m4[ 8], 69 | m4[15] - m4[12]]; 70 | } 71 | 72 | 73 | DwClippingPlane3D.bottom_ref = function(m4, p){ 74 | p[0] = m4[ 3] + m4[ 1]; 75 | p[1] = m4[ 7] + m4[ 5]; 76 | p[2] = m4[11] + m4[ 9]; 77 | p[3] = m4[15] + m4[13]; 78 | } 79 | DwClippingPlane3D.bottom_new = function(m4){ 80 | return [m4[ 3] + m4[ 1], 81 | m4[ 7] + m4[ 5], 82 | m4[11] + m4[ 9], 83 | m4[15] + m4[13]]; 84 | } 85 | 86 | 87 | DwClippingPlane3D.top_ref = function(m4, p){ 88 | p[0] = m4[ 3] - m4[ 1]; 89 | p[1] = m4[ 7] - m4[ 5]; 90 | p[2] = m4[11] - m4[ 9]; 91 | p[3] = m4[15] - m4[13]; 92 | } 93 | DwClippingPlane3D.top_new = function(m4){ 94 | return [m4[ 3] - m4[ 1], 95 | m4[ 7] - m4[ 5], 96 | m4[11] - m4[ 9], 97 | m4[15] - m4[13]]; 98 | } 99 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/QuickSort.js: -------------------------------------------------------------------------------- 1 | /** 2 | * author: thomas diewald 3 | * date: 15.03.13 4 | * 5 | * Quicksort in Java, Version 0.6 6 | * Copyright 2009-2010 Lars Vogel 7 | * 8 | * http://www.vogella.com/articles/JavaAlgorithmsQuicksort/article.html 9 | * 10 | * adaptded for js by thomas diewald. 11 | */ 12 | 13 | function Quicksort() { 14 | 15 | } 16 | 17 | Quicksort.prototype.sort = function(points, dim) { 18 | if (points == null || points.length == 0) return; 19 | 20 | var lo = 0; 21 | var hi = points.length - 1; 22 | // this.quicksort(points, lo, hi); 23 | if( dim == 0) this.quicksortX(points, lo, hi); 24 | if( dim == 1) this.quicksortY(points, lo, hi); 25 | 26 | } 27 | 28 | 29 | 30 | Quicksort.prototype.quicksort = function(pts, low, high) { 31 | 32 | var i = low, j = high; 33 | var pivot = pts[low + ((high-low)>>1)]; 34 | 35 | while (i <= j) { 36 | switch(this.dim){ 37 | case 0: while(pts[i].xpivot.x)j--; break; 38 | case 1: while(pts[i].ypivot.y)j--; break; 39 | } 40 | if (i <= j) this.swap(pts, i++, j--); 41 | } 42 | 43 | if (low < j) this.quicksort(pts, low, j); 44 | if (i < high) this.quicksort(pts, i, high); 45 | } 46 | 47 | 48 | Quicksort.prototype.quicksortX = function(pts, lo, hi) { 49 | var i = lo, j = hi; 50 | var x = pts[lo + ((hi-lo)>>1)].x; 51 | // var x = pts.coord(lo + ((hi-lo)>>1)); 52 | while (i <= j) { 53 | while(pts[i].xx)j--; 55 | // while(pts.coord(i)x)j--; 57 | if (i <= j) this.swap(pts, i++, j--); 58 | } 59 | 60 | if (lo < j) this.quicksortX(pts, lo, j); 61 | if (i < hi) this.quicksortX(pts, i, hi); 62 | } 63 | 64 | Quicksort.prototype.quicksortY = function(pts, lo, hi) { 65 | var i = lo, j = hi; 66 | var y = pts[lo + ((hi-lo)>>1)].y; 67 | while (i <= j) { 68 | while(pts[i].yy)j--; 70 | if (i <= j) this.swap(pts, i++, j--); 71 | } 72 | 73 | if (lo < j) this.quicksortY(pts, lo, j); 74 | if (i < hi) this.quicksortY(pts, i, hi); 75 | } 76 | 77 | 78 | Quicksort.prototype.swap = function(pts, i, j) { 79 | var pts_t = pts[i]; 80 | pts[i] = pts[j]; 81 | pts[j] = pts_t; 82 | } 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/geometry_templates/DwRectangle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 08.02.12 5 | */ 6 | 7 | 8 | function DwRectangle(gl, x, y, width, height){ 9 | this.gl = gl; 10 | 11 | var w = width; 12 | var h = height; 13 | 14 | var x_s = x; 15 | var y_s = y; 16 | var x_e = x+width; 17 | var y_e = y+height; 18 | 19 | var wh = w*0.5; 20 | var hh = h*0.5; 21 | 22 | this.vertex_data = 23 | [ 24 | x_s, y_s, 0.0, // vertex 0 25 | 0.0, 0.0, 1.0, // normal 26 | 1.0, 0.0, 0.0, // color red 27 | 0.0, 0.0, // texcoords 28 | 29 | x_s, y_e, 0.0, // vertex 3 30 | 0.0, 0.0, 1.0, // normal 31 | 1.0, 1.0, 1.0, // color white 32 | 0.0, 1.0, // texcoords 33 | 34 | x_e, y_s, 0.0, // vertex 1 35 | 0.0, 0.0, 1.0, // normal 36 | 0.0, 1.0, 0.0, // color green 37 | 1.0, 0.0, // texcoords 38 | // x_s, y_e, 0.0, // vertex 3 39 | // 0.0, 0.0, 1.0, // normal 40 | // 1.0, 1.0, 1.0, // color white 41 | // 0.0, 1.0, // texcoords 42 | 43 | x_e, y_e, 0.0, // vertex 2 44 | 0.0, 0.0, 1.0, // normal 45 | 0.0, 0.0, 1.0, // color blue 46 | 1.0, 1.0 // texcoords 47 | ]; 48 | 49 | 50 | this.data_Float32 = new Float32Array(this.vertex_data); 51 | 52 | this.HANDLE_vbo = gl.createBuffer(); 53 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 54 | gl.bufferData(gl.ARRAY_BUFFER, this.data_Float32, gl.STATIC_DRAW); 55 | } 56 | 57 | DwRectangle.prototype.delete = function(){ 58 | this.gl.deleteBuffer(this.HANDLE_vbo); 59 | this.HANDLE_vbo = null; 60 | this.data_Float32 = null; 61 | this.vertex_data = []; 62 | } 63 | 64 | 65 | 66 | DwRectangle.prototype.draw = function(shader){ 67 | var gl = this.gl; 68 | 69 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 70 | 71 | gl.vertexAttribPointer(shader.IN_VEC3_POSITION, 3, gl.FLOAT, false, 44, 0 ); 72 | gl.vertexAttribPointer(shader.IN_VEC3_NORMAL, 3, gl.FLOAT, false, 44, 12 ); 73 | // gl.vertexAttribPointer(shader.IN_VEC3_COLOR, 3, gl.FLOAT, false, 44, 24 ); 74 | gl.vertexAttribPointer(shader.IN_VEC2_ST, 2, gl.FLOAT, false, 44, 36 ); 75 | 76 | gl.enableVertexAttribArray(shader.IN_VEC3_POSITION ); 77 | gl.enableVertexAttribArray(shader.IN_VEC3_NORMAL ); 78 | // gl.enableVertexAttribArray(shader.IN_VEC3_COLOR ); 79 | gl.enableVertexAttribArray(shader.IN_VEC2_ST ); 80 | 81 | gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4 ); 82 | // gl.drawArrays(this.gl.TRIANGLE_FAN, 0, 6 ); 83 | gl.flush(); 84 | } 85 | 86 | 87 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/geometry_templates/DwRectangleShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 08.02.12 5 | */ 6 | 7 | 8 | function DwRectangleShader(gl){ 9 | this.gl = gl; 10 | var _this = this; 11 | 12 | _this.shader = new DwShader(gl, "", "SHADERS/DwRectangle_vert.glsl", "SHADERS/DwRectangle_frag.glsl"); 13 | _this.shader.onload = function(){ 14 | _this.saveShaderLocations(); 15 | } 16 | _this.shader.load(null); 17 | } 18 | 19 | 20 | DwRectangleShader.prototype.saveShaderLocations = function(){ 21 | var gl = this.gl; 22 | gl.useProgram(this.shader.HANDLE_program); 23 | { 24 | this.IN_VEC3_POSITION = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_POSITION"); 25 | this.IN_VEC3_NORMAL = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_NORMAL"); 26 | this.IN_VEC3_COLOR = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_COLOR"); 27 | this.IN_VEC2_ST = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC2_ST"); 28 | 29 | this.UN_MAT4_PROJECTION = gl.getUniformLocation(this.shader.HANDLE_program, "UN_MAT4_PROJECTION"); 30 | this.UN_MAT4_MODELVIEW = gl.getUniformLocation(this.shader.HANDLE_program, "UN_MAT4_MODELVIEW"); 31 | 32 | this.UN_SAMP_TEXTURE = gl.getUniformLocation(this.shader.HANDLE_program, "UN_SAMP_TEXTURE"); 33 | } 34 | gl.useProgram(null); 35 | // console.log("attribute location: IN_VEC3_POSITION = "+this.IN_VEC3_POSITION); 36 | // console.log("attribute location: IN_VEC3_NORMAL = "+this.IN_VEC3_NORMAL); 37 | // console.log("attribute location: IN_VEC3_COLOR = "+this.IN_VEC3_COLOR); 38 | // console.log("attribute location: IN_VEC2_ST = "+this.IN_VEC2_ST); 39 | // console.log("uniform location: UN_MAT4_PROJECTION = "+this.UN_MAT4_PROJECTION); 40 | // console.log("uniform location: UN_MAT4_MODELVIEW = "+this.UN_MAT4_MODELVIEW); 41 | // console.log("uniform location: UN_SAMP_TEXTURE = "+this.UN_SAMP_TEXTURE); 42 | } 43 | DwRectangleShader.prototype.delete = function(){ 44 | this.shader.delete(); 45 | this.shader = null; 46 | } 47 | 48 | 49 | DwRectangleShader.prototype.setMat4_Projection = function(MAT4){ 50 | this.gl.uniformMatrix4fv( this.UN_MAT4_PROJECTION, false, MAT4); 51 | } 52 | 53 | DwRectangleShader.prototype.setMat4_ModelView = function(MAT4){ 54 | this.gl.uniformMatrix4fv( this.UN_MAT4_MODELVIEW, false, MAT4); 55 | } 56 | DwRectangleShader.prototype.activeTexture = function(tex_loc){ 57 | this.gl.uniform1i(this.UN_SAMP_TEXTURE, tex_loc); 58 | } 59 | 60 | DwRectangleShader.prototype.bind = function(){ 61 | this.gl.useProgram(this.shader.HANDLE_program); 62 | } 63 | 64 | DwRectangleShader.prototype.unbind = function(){ 65 | this.gl.useProgram(null); 66 | } 67 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/FBO.js: -------------------------------------------------------------------------------- 1 | /** 2 | * author: thomas diewald 3 | * date: 19.03.13 4 | * 5 | * FBO as a rendertarget for the distance map. 6 | */ 7 | 8 | 9 | function FBO(CTX){ 10 | 11 | this.CTX = CTX; 12 | var gl = this.CTX.gl; 13 | 14 | this.HANDLE_FBO = gl.createFramebuffer(); 15 | this.HANDLE_texture = null; 16 | 17 | // console.log("HANDLE_FBO = "+ this.HANDLE_FBO); 18 | // console.log("HANDLE_texture = "+ this.HANDLE_texture); 19 | } 20 | 21 | FBO.prototype.delete = function(){ 22 | this.CTX.gl.deleteFramebuffer(this.HANDLE_FBO); this.HANDLE_FBO = null; 23 | this.CTX.gl.deleteTexture(this.HANDLE_texture); this.HANDLE_texture = null; 24 | } 25 | 26 | FBO.prototype.resize = function(w, h, scale){ 27 | 28 | // TODO im not sure if theres some memory-leak when textures get resized 29 | 30 | if(this.w == w && this.h == h && this.scale == scale){ 31 | return; 32 | } 33 | 34 | var gl = this.CTX.gl; 35 | 36 | this.scale = scale; 37 | this.w = w/scale; 38 | this.h = h/scale; 39 | 40 | this.CTX.gl.deleteTexture(this.HANDLE_texture); this.HANDLE_texture = null; 41 | // this.delete(); 42 | 43 | // this.HANDLE_FBO = gl.createFramebuffer(); 44 | gl.deleteTexture(this.HANDLE_texture); 45 | this.HANDLE_texture = gl.createTexture(); 46 | 47 | // console.log("FBO.prototype.resize "+w+", "+h); 48 | 49 | // TEXTURE: distance map (for framebuffer) 50 | gl.bindTexture ( gl.TEXTURE_2D, this.HANDLE_texture); 51 | { 52 | gl.pixelStorei ( gl.UNPACK_ALIGNMENT, 1); 53 | // gl.pixelStorei ( gl.UNPACK_FLIP_Y_WEBGL, true); 54 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 55 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 56 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ) ; 57 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE ) ; 58 | // gl.texImage2D ( gl.TEXTURE_2D, 0, gl.RGBA, this.w, this.h, 0, gl.RGBA, gl.FLOAT, null ); 59 | gl.texImage2D ( gl.TEXTURE_2D, 0, gl.RGB, this.w, this.h, 0, gl.RGB, gl.FLOAT, null ); 60 | // gl.texImage2D ( gl.TEXTURE_2D, 0, gl.ALPHA, this.w, this.h, 0, gl.ALPHA, gl.FLOAT, null ); 61 | } 62 | gl.bindTexture ( gl.TEXTURE_2D, null); 63 | 64 | gl.bindFramebuffer(gl.FRAMEBUFFER, this.HANDLE_FBO); 65 | { 66 | gl.framebufferTexture2D (gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.HANDLE_texture, 0); 67 | DwContext.WEBGL_FBO_CHECK(gl, this.HANDLE_FBO); 68 | } 69 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); 70 | } 71 | 72 | 73 | FBO.prototype.bind = function(){ 74 | this.CTX.gl.viewport(0, 0,this.w, this.h); 75 | this.CTX.gl.bindFramebuffer(this.CTX.gl.FRAMEBUFFER, this.HANDLE_FBO); 76 | } 77 | FBO.prototype.unbind = function(){ 78 | this.CTX.gl.bindFramebuffer(this.CTX.gl.FRAMEBUFFER, null); 79 | } 80 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/KdTreeRenderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * author: thomas diewald 3 | * date: 23.03.13 4 | * 5 | * create a visual representation of a kd-tree. 6 | */ 7 | 8 | 9 | 10 | function KdTreeRenderer(CTX, kd_tree){ 11 | this.CTX = CTX; 12 | this.kd_tree = kd_tree; 13 | 14 | var gl = this.CTX.gl; 15 | 16 | this.HANDLE_vbo = gl.createBuffer(); 17 | 18 | this.shader; 19 | 20 | this.loadShader(); 21 | } 22 | 23 | KdTreeRenderer.prototype.delete = function(){ 24 | var gl = this.CTX.gl; 25 | gl.deleteBuffer(this.HANDLE_vbo); 26 | this.HANDLE_vbo = null; 27 | 28 | this.shader.delete(); 29 | this.shader = null; 30 | } 31 | 32 | 33 | 34 | KdTreeRenderer.prototype.loadShader = function(){ 35 | var gl = this.CTX.gl; 36 | var _this = this; 37 | 38 | var vert_shader = "SHADERS/KdTree_vert.glsl"; 39 | var frag_shader = "SHADERS/KdTree_frag.glsl"; 40 | 41 | _this.shader = new DwShader(gl, "", vert_shader, frag_shader); 42 | _this.shader.onload = function(){ 43 | // console.log("... LOADING SHADER"); 44 | _this.saveShaderLocations(); 45 | } 46 | _this.shader.load(null); 47 | } 48 | 49 | KdTreeRenderer.prototype.saveShaderLocations = function(){ 50 | var gl = this.CTX.gl; 51 | 52 | var HANDLE_shader = this.shader.HANDLE_program; 53 | // console.log("... SAVE SHADER LOCATIONS "+HANDLE_shader); 54 | gl.useProgram(this.HANDLE_shader); 55 | { 56 | this.IN_VEC2_POSITION = gl.getAttribLocation (HANDLE_shader, "IN_VEC2_POSITION" ); 57 | this.IN_FLOAT_ALPHA = gl.getAttribLocation (HANDLE_shader, "IN_FLOAT_ALPHA" ); 58 | this.UN_VEC3_RGB = gl.getUniformLocation(HANDLE_shader, "UN_VEC3_RGB" ); 59 | this.UN_MAT4_PROJECTION = gl.getUniformLocation(HANDLE_shader, "UN_MAT4_PROJECTION" ); 60 | } 61 | gl.useProgram(null); 62 | 63 | // console.log("IN_VEC2_POSITION = "+this.IN_VEC2_POSITION ); 64 | // console.log("IN_FLOAT_ALPHA = "+this.IN_FLOAT_ALPHA ); 65 | // console.log("UN_VEC3_RGB = "+this.UN_VEC3_RGB ); 66 | // console.log("UN_MAT4_PROJECTION = "+this.UN_MAT4_PROJECTION ); 67 | } 68 | 69 | KdTreeRenderer.prototype.resize = function(){ 70 | var w = this.CTX.VIEWPORT.width; 71 | var h = this.CTX.VIEWPORT.height; 72 | this.Mat4_Projection = DwMat4.ortho_new(0, w, h, 0, -1, 1); 73 | } 74 | 75 | 76 | 77 | 78 | KdTreeRenderer.prototype.render = function(invert){ 79 | 80 | if( this.IN_VEC2_POSITION==undefined){ 81 | return; 82 | } 83 | 84 | var gl = this.CTX.gl; 85 | var shader = this.shader; 86 | var coords = this.kd_tree.kd_tree_planes; 87 | var num_coords = this.kd_tree.BUF_IDX; 88 | 89 | var rgb = [1,1,1]; 90 | if( invert ) rgb = [.2,.2,.2]; 91 | 92 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); 93 | 94 | gl.lineWidth(.5); 95 | gl.useProgram(shader.HANDLE_program); 96 | { 97 | 98 | gl.uniformMatrix4fv(this.UN_MAT4_PROJECTION, false, this.Mat4_Projection); 99 | gl.uniform3fv(this.UN_VEC3_RGB, new Float32Array(rgb) ); 100 | 101 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 102 | gl.bufferData(gl.ARRAY_BUFFER, coords, gl.STATIC_DRAW); 103 | gl.vertexAttribPointer(this.IN_VEC2_POSITION, 2, gl.FLOAT, false, 12, 0 ); 104 | gl.vertexAttribPointer(this.IN_FLOAT_ALPHA, 1, gl.FLOAT, false, 12, 8 ); 105 | 106 | gl.enableVertexAttribArray(this.IN_VEC2_POSITION ); 107 | gl.enableVertexAttribArray(this.IN_FLOAT_ALPHA ); 108 | 109 | gl.drawArrays(gl.LINES, 0, 2*num_coords/6 ); 110 | gl.flush(); 111 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 112 | } 113 | gl.useProgram(null); 114 | } 115 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/DOF/DOF_shader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 23.02.12 5 | */ 6 | 7 | 8 | function DOF_shader(gl){ 9 | this.gl = gl; 10 | var _this = this; 11 | 12 | _this.shader = new DwShader(gl, "", "SHADERS/SH_DOF_vert.glsl", "SHADERS/SH_DOF_frag.glsl"); 13 | _this.shader.onload = function(){ 14 | _this.saveShaderLocations(); 15 | } 16 | _this.shader.load(null); 17 | } 18 | 19 | 20 | DOF_shader.prototype.saveShaderLocations = function(){ 21 | var gl = this.gl; 22 | gl.useProgram(this.shader.HANDLE_program); 23 | { 24 | this.IN_VEC3_POSITION = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC3_POSITION" ); 25 | this.IN_VEC2_ST = gl.getAttribLocation (this.shader.HANDLE_program, "IN_VEC2_ST" ); 26 | this.UN_MAT4_PROJECTION = gl.getUniformLocation(this.shader.HANDLE_program, "UN_MAT4_PROJECTION" ); 27 | 28 | this.UN_SAMP2D_RENDERING = gl.getUniformLocation(this.shader.HANDLE_program, "UN_SAMP2D_RENDERING" ); 29 | this.UN_SAMP2D_NORMAL_Z = gl.getUniformLocation(this.shader.HANDLE_program, "UN_SAMP2D_NORMAL_Z" ); 30 | 31 | this.UN_FLOAT_CAM_FAR = gl.getUniformLocation(this.shader.HANDLE_program, "UN_FLOAT_CAM_FAR" ); 32 | this.UN_FLOAT_CAM_NEAR = gl.getUniformLocation(this.shader.HANDLE_program, "UN_FLOAT_CAM_NEAR" ); 33 | this.UN_FLOAT_DOF_DISTANCE = gl.getUniformLocation(this.shader.HANDLE_program, "UN_FLOAT_DOF_DISTANCE" ); 34 | this.UN_FLOAT_DOF_STRENGTH = gl.getUniformLocation(this.shader.HANDLE_program, "UN_FLOAT_DOF_STRENGTH" ); 35 | this.UN_VEC2_VIEWPORT_SIZE = gl.getUniformLocation(this.shader.HANDLE_program, "UN_VEC2_VIEWPORT_SIZE" ); 36 | 37 | } 38 | gl.useProgram(null); 39 | // console.log("attribute location: IN_VEC3_POSITION = "+this.IN_VEC3_POSITION); 40 | // console.log("attribute location: IN_VEC2_ST = "+this.IN_VEC2_ST); 41 | // console.log("uniform location: UN_MAT4_PROJECTION = "+this.UN_MAT4_PROJECTION); 42 | // 43 | // console.log("uniform location: UN_SAMP2D_RENDERING = "+this.UN_SAMP2D_RENDERING); 44 | // console.log("uniform location: UN_SAMP2D_NORMAL_Z = "+this.UN_SAMP2D_NORMAL_Z); 45 | // 46 | // console.log("uniform location: UN_FLOAT_CAM_FAR = "+this.UN_FLOAT_CAM_FAR ); 47 | // console.log("uniform location: UN_FLOAT_CAM_NEAR = "+this.UN_FLOAT_CAM_NEAR ); 48 | // console.log("uniform location: UN_FLOAT_DOF_DISTANCE = "+this.UN_FLOAT_DOF_DISTANCE); 49 | // console.log("uniform location: UN_FLOAT_DOF_STRENGTH = "+this.UN_FLOAT_DOF_STRENGTH); 50 | // console.log("uniform location: UN_VEC2_VIEWPORT_SIZE = "+this.UN_VEC2_VIEWPORT_SIZE); 51 | } 52 | 53 | DOF_shader.prototype.delete = function(){ 54 | this.shader.delete(); 55 | this.shader = null; 56 | } 57 | 58 | DOF_shader.prototype.setMat4_Projection = function(MAT4){ 59 | this.gl.uniformMatrix4fv( this.UN_MAT4_PROJECTION, false, MAT4); 60 | } 61 | 62 | DOF_shader.prototype.activeTexture = function(handle, tex_loc){ 63 | this.gl.uniform1i(handle, tex_loc); 64 | } 65 | DOF_shader.prototype.setCamNearFar = function(NEAR, FAR){ 66 | this.gl.uniform1f( this.UN_FLOAT_CAM_NEAR, NEAR); 67 | this.gl.uniform1f( this.UN_FLOAT_CAM_FAR, FAR); 68 | } 69 | DOF_shader.prototype.setDOF = function(DOF_DIS, STRENGTH){ 70 | this.gl.uniform1f( this.UN_FLOAT_DOF_DISTANCE, DOF_DIS); 71 | this.gl.uniform1f( this.UN_FLOAT_DOF_STRENGTH, STRENGTH); 72 | } 73 | DOF_shader.prototype.setViewportSize = function(WIDTH, HEIGHT){ 74 | this.gl.uniform2fv( this.UN_VEC2_VIEWPORT_SIZE, [WIDTH,HEIGHT ]); 75 | } 76 | DOF_shader.prototype.bind = function(){ 77 | this.gl.useProgram(this.shader.HANDLE_program); 78 | } 79 | 80 | DOF_shader.prototype.unbind = function(){ 81 | this.gl.useProgram(null); 82 | } 83 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/FBO/DwFBO.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 23.02.12 5 | */ 6 | 7 | 8 | // http://www.khronos.org/webgl/wiki_1_15/index.php/WebGL_and_OpenGL_Differences 9 | function DwFBO(gl, width, height, datatype){ 10 | this.gl = gl; 11 | this.width = width; 12 | this.height = height; 13 | this.datatype = datatype || gl.UNSIGNED_BYTE; 14 | 15 | 16 | // TEXTURE 17 | this.HANDLE_tex = gl.createTexture(); 18 | gl.bindTexture ( gl.TEXTURE_2D, this.HANDLE_tex); 19 | { 20 | // gl.pixelStorei ( gl.UNPACK_FLIP_Y_WEBGL, true); 21 | // gl.pixelStorei ( gl.UNPACK_ALIGNMENT, 1); 22 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 23 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 24 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ) ; 25 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE ) ; 26 | gl.texImage2D ( gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, this.datatype, null); 27 | // gl.generateMipmap( gl.TEXTURE_2D); 28 | 29 | } 30 | gl.bindTexture ( gl.TEXTURE_2D, null); 31 | 32 | 33 | // RENDERBUFFER / DEPTH 34 | this.HANDLE_rb_depth = gl.createRenderbuffer(); 35 | gl.bindRenderbuffer (gl.RENDERBUFFER, this.HANDLE_rb_depth); 36 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); 37 | gl.bindRenderbuffer (gl.RENDERBUFFER, null); 38 | 39 | // RENDERBUFFER / STENCIL 40 | this.HANDLE_rb_stencil = gl.createRenderbuffer(); 41 | gl.bindRenderbuffer (gl.RENDERBUFFER, this.HANDLE_rb_stencil); 42 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); 43 | gl.bindRenderbuffer (gl.RENDERBUFFER, null); 44 | 45 | 46 | // FBO 47 | this.HANDLE_FBO = gl.createFramebuffer(); 48 | gl.bindFramebuffer(gl.FRAMEBUFFER, this.HANDLE_FBO); 49 | { 50 | gl.framebufferTexture2D (gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.HANDLE_tex, 0); 51 | // gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.HANDLE_rb_depth); 52 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.HANDLE_rb_stencil); 53 | 54 | DwContext.WEBGL_FBO_CHECK(gl, this.HANDLE_FBO); 55 | 56 | } 57 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); 58 | } 59 | 60 | DwFBO.prototype.resize = function(width, height){ 61 | this.width = width; 62 | this.height = height; 63 | var gl = this.gl; 64 | // TEXTURE 2D 65 | gl.bindFramebuffer(gl.FRAMEBUFFER, this.HANDLE_FBO); 66 | 67 | gl.bindTexture ( gl.TEXTURE_2D, this.HANDLE_tex); 68 | gl.texImage2D ( gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, this.datatype, null); 69 | gl.bindTexture ( gl.TEXTURE_2D, null); 70 | 71 | // RENDERBUFFER / DEPTH 72 | gl.bindRenderbuffer (gl.RENDERBUFFER, this.HANDLE_rb_depth); 73 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height); 74 | gl.bindRenderbuffer (gl.RENDERBUFFER, null); 75 | 76 | // RENDERBUFFER / STENCIL 77 | gl.bindRenderbuffer (gl.RENDERBUFFER, this.HANDLE_rb_stencil); 78 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, this.width, this.height); 79 | gl.bindRenderbuffer (gl.RENDERBUFFER, null); 80 | 81 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); 82 | } 83 | 84 | DwFBO.prototype.delete = function(width, height){ 85 | var gl = this.gl; 86 | gl.deleteTexture(this.HANDLE_tex); 87 | gl.deleteRenderbuffer(this.HANDLE_rb_stencil); 88 | gl.deleteFramebuffer(this.HANDLE_FBO); 89 | this.HANDLE_FBO = null; 90 | this.HANDLE_rb_stencil = null; 91 | this.HANDLE_tex = null; 92 | this.gl = null; 93 | this.width = 0; 94 | this.height = 0; 95 | this.datatype = 0; 96 | } 97 | 98 | 99 | 100 | DwFBO.prototype.getTexture = function(){ 101 | return this.HANDLE_tex; 102 | } 103 | DwFBO.prototype.getWidth = function(){ 104 | return this.width; 105 | } 106 | DwFBO.prototype.getHeight = function(){ 107 | return this.height; 108 | } 109 | DwFBO.prototype.bind = function(){ 110 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.HANDLE_FBO); 111 | } 112 | DwFBO.prototype.unbind = function(){ 113 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null); 114 | } 115 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/image/DwImage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 20.02.12 5 | */ 6 | 7 | 8 | 9 | function DwImage(gl, path, filename){ 10 | this.gl = gl; 11 | this.path = path; 12 | this.filename = filename; 13 | 14 | this.image = null; 15 | this.LOADED = false; 16 | 17 | this.HANDLE_TEX = null; 18 | var _this = this; 19 | 20 | this.filesuffix = filename.substring(filename.lastIndexOf(".")); 21 | 22 | // handle TGAs separately 23 | if( this.filesuffix === ".tga"){ 24 | // console.log("image type: TGA"); 25 | var tga = new DwImage_TGA(path, filename); 26 | tga.onload = function(){ 27 | 28 | // http://www.khronos.org/registry/webgl/specs/latest/#TEXIMAGE2D 29 | if( tga.pixel_depth == 32 ){ 30 | _this.createTextureFromTGA (_this, _this.gl.RGBA, tga.width, tga.height, _this.gl.RGBA, tga.pixels); 31 | _this.image = tga; 32 | 33 | } else if( tga.pixel_depth == 24 ){ 34 | _this.createTextureFromTGA (_this, _this.gl.RGB, tga.width, tga.height, _this.gl.RGB, tga.pixels); 35 | _this.image = tga; 36 | } 37 | }; 38 | tga.load(null); 39 | // http://www.khronos.org/registry/webgl/specs/latest/#TEXIMAGE2D 40 | // if( tga.pixel_depth == 32 ){ 41 | // this.createTextureFromTGA (this, this.gl.RGBA, tga.width, tga.height, this.gl.RGBA, tga.pixels); 42 | // this.image = tga; 43 | // 44 | // } else if( tga.pixel_depth == 24 ){ 45 | // this.createTextureFromTGA (this, this.gl.RGB, tga.width, tga.height, this.gl.RGB, tga.pixels); 46 | // this.image = tga; 47 | // } 48 | } 49 | else 50 | if ( 51 | this.filesuffix === ".jpg" 52 | || this.filesuffix === ".jpeg" 53 | || this.filesuffix === ".png" 54 | || this.filesuffix === ".bmp" 55 | || this.filesuffix === ".gif") 56 | { 57 | try{ 58 | var tmp_image = new Image(); 59 | tmp_image.src = path+filename; 60 | tmp_image.onload = function() { 61 | _this.createTexture(_this, tmp_image); 62 | _this.image = tmp_image; 63 | }; 64 | tmp_image.onerror = function() { 65 | console.log("ERROR while loading Image: "+path+filename); 66 | }; 67 | } catch (exception){ 68 | console.log(exception); 69 | } 70 | } 71 | else 72 | { 73 | console.log("(DwImage) filename, filetype not suported: "+this.filesuffix); 74 | } 75 | } 76 | 77 | DwImage.prototype.delete = function(_this, image){ 78 | this.gl.deleteTexture(this.HANDLE_TEX ); 79 | this.HANDLE_TEX = null; 80 | } 81 | 82 | 83 | 84 | DwImage.prototype.createTextureFromTGA = function(_this, gl_internalformat, width, height,gl_format, pixels){ 85 | // console.log("loading tga: "+_this.path +", "+_this.filename); 86 | var gl = _this.gl; 87 | _this.HANDLE_TEX = gl.createTexture(); 88 | gl.bindTexture ( gl.TEXTURE_2D, _this.HANDLE_TEX); 89 | gl.pixelStorei ( gl.UNPACK_FLIP_Y_WEBGL, true); 90 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 91 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); 92 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT ) ; 93 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT ) ; 94 | gl.texImage2D ( gl.TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl.UNSIGNED_BYTE, pixels); 95 | // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 96 | 97 | gl.generateMipmap( gl.TEXTURE_2D); 98 | gl.bindTexture ( gl.TEXTURE_2D, null); 99 | _this.LOADED = true; 100 | } 101 | DwImage.prototype.createTexture = function(_this, image){ 102 | 103 | var gl = _this.gl; 104 | _this.HANDLE_TEX = gl.createTexture(); 105 | gl.bindTexture ( gl.TEXTURE_2D, _this.HANDLE_TEX); 106 | // gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); //TODO: check 107 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 108 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); 109 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT ) ; 110 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT ) ; 111 | gl.texImage2D ( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 112 | gl.generateMipmap( gl.TEXTURE_2D); 113 | gl.bindTexture ( gl.TEXTURE_2D, null); 114 | _this.LOADED = true; 115 | } 116 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/ScreenQuad.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 19.03.13 5 | */ 6 | 7 | 8 | function ScreenQuad(CTX){ 9 | 10 | this.CTX = CTX; 11 | var gl = this.CTX.gl; 12 | 13 | this.shader; 14 | 15 | var screenquad = new Float32Array( [ -1, -1, 0, 0, // x,y, s,t, no matrix needed 16 | -1, +1, 0, 1, 17 | +1, -1, 1, 0, 18 | +1, +1, 1, 1 ]); 19 | 20 | this.HANDLE_vbo = gl.createBuffer(); 21 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 22 | gl.bufferData(gl.ARRAY_BUFFER, screenquad, gl.STATIC_DRAW); 23 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 24 | } 25 | 26 | 27 | ScreenQuad.prototype.delete = function(){ 28 | this.shader.delete(); 29 | this.shader = null; 30 | this.CTX.gl.deleteBuffer( this.HANDLE_vbo); 31 | this.HANDLE_vbo = null; 32 | } 33 | 34 | 35 | ScreenQuad.prototype.loadShader = function(){ 36 | var gl = this.CTX.gl; 37 | var _this = this; 38 | 39 | _this.shader = new DwShader(gl, "", "SHADERS/DwScreenQuad_vert.glsl", "SHADERS/DwScreenQuad_frag.glsl"); 40 | _this.shader.onload = function(){ 41 | // console.log("(ScreenQuad)... LOADING SHADER Draw"); 42 | _this.saveShaderLocations(); 43 | } 44 | _this.shader.load(null); 45 | } 46 | 47 | ScreenQuad.prototype.saveShaderLocations = function(){ 48 | var gl = this.CTX.gl; 49 | 50 | var HANDLE_shader = this.shader.HANDLE_program; 51 | // console.log("(ScreenQuad)... SAVE SHADER LOCATIONS "+HANDLE_shader); 52 | gl.useProgram(HANDLE_shader); 53 | { 54 | this.IN_VEC2_POSITION = gl.getAttribLocation (HANDLE_shader, "IN_VEC2_POSITION" ); 55 | this.IN_VEC2_ST = gl.getAttribLocation (HANDLE_shader, "IN_VEC2_ST" ); 56 | this.UN_SAMP_TEXTURE = gl.getUniformLocation(HANDLE_shader, "UN_SAMP_TEXTURE" ); 57 | this.UN_INT_RGB_INVERT = gl.getUniformLocation(HANDLE_shader, "UN_INT_RGB_INVERT" ); 58 | this.UN_VEC3_RGB_SCALE = gl.getUniformLocation(HANDLE_shader, "UN_VEC3_RGB_SCALE" ); 59 | } 60 | gl.useProgram(null); 61 | 62 | // console.log("IN_VEC2_POSITION = "+this.IN_VEC2_POSITION ); 63 | // console.log("IN_VEC2_ST = "+this.IN_VEC2_ST ); 64 | // console.log("UN_SAMP_TEXTURE = "+this.UN_SAMP_TEXTURE ); 65 | // console.log("UN_INT_RGB_INVERT = "+this.UN_INT_RGB_INVERT ); 66 | // console.log("UN_VEC3_RGB_SCALE = "+this.UN_VEC3_RGB_SCALE ); 67 | } 68 | 69 | function map(val, a, b, A, B){ 70 | return ((val-a)/(b-a))*(B-A)+A; 71 | } 72 | 73 | ScreenQuad.prototype.setUniforms = function(invert, num_points){ 74 | var viewport = this.CTX.VIEWPORT; 75 | var mouse = this.CTX.mouse_info; 76 | var key = this.CTX.key_info; 77 | 78 | var w = viewport.width; 79 | var h = viewport.height; 80 | 81 | var mx_norm = mouse.mouseX/w; 82 | var my_norm = mouse.mouseY/h; 83 | 84 | // var fs = Math.log( Math.sqrt( (num_points ))) ; 85 | // fs = fs*fs*fs*0.00005; 86 | 87 | var px = w*w/num_points; 88 | var py = h*h/num_points; 89 | 90 | var fs = 1/(Math.sqrt(px + py)*Math.log( num_points )*1.5); 91 | 92 | var rgb_scale = []; 93 | rgb_scale[0] = (4*fs); 94 | rgb_scale[1] = (5*fs) * mx_norm; 95 | rgb_scale[2] = (9*fs) * my_norm; 96 | 97 | // clamp values [0,1] 98 | rgb_scale[0] = Math.min(Math.max( rgb_scale[0], 0), 1); 99 | rgb_scale[1] = Math.min(Math.max( rgb_scale[1], 0), 1); 100 | rgb_scale[2] = Math.min(Math.max( rgb_scale[2], 0), 1); 101 | 102 | if( invert ){ 103 | rgb_scale[0] *= 3; 104 | rgb_scale[1] *= 4; 105 | rgb_scale[2] *= 5; 106 | } 107 | 108 | var gl = this.CTX.gl; 109 | var HANDLE_shader = this.shader.HANDLE_program; 110 | gl.useProgram(HANDLE_shader); 111 | { 112 | gl.uniform1i (this.UN_INT_RGB_INVERT, invert?1:0); 113 | gl.uniform3fv(this.UN_VEC3_RGB_SCALE, new Float32Array(rgb_scale)); 114 | } 115 | gl.useProgram(null); 116 | } 117 | 118 | ScreenQuad.prototype.render = function(HANDLE_texture, invert, num_points){ 119 | if( this.IN_VEC2_POSITION==undefined){ 120 | return; 121 | } 122 | 123 | this.setUniforms(invert, num_points); 124 | 125 | var gl = this.CTX.gl; 126 | var HANDLE_shader = this.shader.HANDLE_program; 127 | gl.useProgram(HANDLE_shader); 128 | { 129 | gl.activeTexture(gl.TEXTURE0); 130 | gl.bindTexture (gl.TEXTURE_2D, HANDLE_texture ); 131 | gl.uniform1i (this.UN_SAMP_TEXTURE, 0); 132 | 133 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo); 134 | gl.vertexAttribPointer(this.IN_VEC2_POSITION, 2, gl.FLOAT, false, 16, 0 ); 135 | gl.vertexAttribPointer(this.IN_VEC2_ST, 2, gl.FLOAT, false, 16, 8 ); 136 | 137 | gl.enableVertexAttribArray(this.IN_VEC2_POSITION ); 138 | gl.enableVertexAttribArray(this.IN_VEC2_ST ); 139 | 140 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4 ); 141 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 142 | 143 | gl.activeTexture(gl.TEXTURE0); 144 | gl.bindTexture (gl.TEXTURE_2D, null ); 145 | 146 | gl.flush(); 147 | } 148 | gl.useProgram(null); 149 | } 150 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/context/DwMouseInfo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 06.02.12 5 | */ 6 | 7 | 8 | function DwMouseInfo(dw_context){ 9 | this.context = dw_context; 10 | 11 | this.canvas = this.context.canvas; 12 | this.VIEWPORT = this.context.VIEWPORT; 13 | 14 | // states 15 | this.mousepressed = false; 16 | this.mousereleased = false; 17 | this.mousemooved = false; 18 | this.doubleclicked = false; 19 | 20 | // mouse button 21 | this.button = -1; 22 | this.lmb = 0; 23 | this.mmb = 1; 24 | this.rmb = 2; 25 | 26 | // current mouse position, on whole document 27 | this.documentmouseX = 0; 28 | this.documentmouseY = 0; 29 | 30 | // current mouse position - relative to canvase 31 | this.mouseX = 0; 32 | this.mouseY = 0; 33 | 34 | // previous mouse position - relative to canvase 35 | this.pmouseX = 0; 36 | this.pmouseY = 0; 37 | 38 | this.last_time_clicked = 0; 39 | 40 | this.activate(); 41 | } 42 | 43 | 44 | DwMouseInfo.prototype.activate = function(){ 45 | DwMouseInfo.attachToDocument(this.canvas, this); 46 | } 47 | 48 | 49 | DwMouseInfo.prototype.handleMousePressed = function (event) { 50 | this.mousepressed = true; 51 | this.mousereleased = false; 52 | this.button = event.button; 53 | } 54 | 55 | 56 | DwMouseInfo.prototype.handleMouseReleased = function (event) { 57 | var time = Date.now(); 58 | var time_diff = time - this.last_time_clicked; 59 | this.last_time_clicked = time; 60 | 61 | if( time_diff < 300 ) 62 | this.doubleclicked = true; 63 | 64 | this.mousepressed = false; 65 | this.mousereleased = true; 66 | } 67 | 68 | 69 | DwMouseInfo.prototype.handleMouseMoved = function (event) { 70 | this.documentmouseX = event.clientX + document.body.scrollLeft; 71 | this.documentmouseY = event.clientY + document.body.scrollTop; 72 | 73 | this.mouseX = this.documentmouseX - this.VIEWPORT.off_x; 74 | this.mouseY = this.documentmouseY - this.VIEWPORT.off_y; 75 | 76 | this.mousemooved = true; 77 | } 78 | 79 | DwMouseInfo.prototype.updateBegin = function (){ 80 | 81 | } 82 | DwMouseInfo.prototype.updateEnd = function (){ 83 | this.pmouseX = this.mouseX 84 | this.pmouseY = this.mouseY; 85 | 86 | this.mousereleased = false; 87 | this.doubleclicked = false; 88 | this.mousemooved = false; 89 | } 90 | 91 | 92 | DwMouseInfo.prototype.insideCanvas = function (){ 93 | var x_min = this.VIEWPORT.off_x; 94 | var y_min = this.VIEWPORT.off_y; 95 | var x_max = x_min + this.VIEWPORT.width; 96 | var y_max = y_min + this.VIEWPORT.height; 97 | // console.log(x_min+", "+y_min+", "+x_max+", "+y_max); 98 | var mx = this.documentmouseX; 99 | var my = this.documentmouseY; 100 | return ( 101 | mx >= x_min && 102 | mx <= x_max && 103 | my >= y_min && 104 | my <= y_max 105 | ); 106 | } 107 | 108 | 109 | 110 | 111 | /** 112 | * attachToDocument(); 113 | * static method 114 | * @param mouse_info an instance of the class MouseInfo 115 | */ 116 | DwMouseInfo.attachToDocument = function(canvas, mouse_info){ 117 | 118 | document.onmousemove = function(event){ 119 | mouse_info.handleMouseMoved(event); 120 | }; 121 | 122 | document.onmouseup = function(event){ 123 | mouse_info.handleMouseReleased(event); 124 | }; 125 | 126 | document.onmousedown = function(event){ 127 | mouse_info.handleMousePressed(event); 128 | }; 129 | 130 | // canvas.onmousedown = function(event){ 131 | // mouse_info.handleMousePressed(event); 132 | // }; 133 | }; 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | /* 161 | var mousepressed = false; 162 | var mousereleased = false; 163 | 164 | var canvasmouseX = 0; 165 | var canvasmouseY = 0; 166 | 167 | var mouseX = 0; 168 | var mouseY = 0; 169 | 170 | var pmouseX = 0; 171 | var pmouseY = 0; 172 | 173 | 174 | 175 | 176 | function handleMousePressed(event) { 177 | mousepressed = true; 178 | mousereleased = false; 179 | pmouseX = event.clientX; 180 | pmouseY = event.clientY; 181 | } 182 | 183 | 184 | function handleMouseReleased(event) { 185 | mousepressed = false; 186 | mousereleased = true; 187 | } 188 | 189 | var current_canvas = null; 190 | 191 | 192 | function initMouse(canvas){ 193 | current_canvas = canvas; 194 | current_canvas.onmousedown = handleMousePressed; 195 | document.onmouseup = handleMouseReleased; 196 | document.onmousemove = handleMouseMoved; 197 | 198 | } 199 | 200 | function handleMouseMoved(event) { 201 | canvasmouseX = event.clientX + document.body.scrollLeft; 202 | canvasmouseY = event.clientY + document.body.scrollTop; 203 | 204 | mouseX = canvasmouseX - current_canvas.offsetLeft; 205 | mouseY = canvasmouseY - current_canvas.offsetTop; 206 | 207 | 208 | var dx = mouseY - pmouseX 209 | var dy = mouseY - pmouseY; 210 | 211 | pmouseX = mouseX 212 | pmouseY = mouseX; 213 | } 214 | 215 | function insideCanvas(){ 216 | var x_min = current_canvas.offsetLeft; 217 | var y_min = current_canvas.offsetTop; 218 | var x_max = x_min + current_canvas.width; 219 | var y_max = y_min + current_canvas.height; 220 | return ( 221 | mouseX >= x_min && 222 | mouseX <= x_max && 223 | mouseY >= y_min && 224 | mouseY <= y_max 225 | ); 226 | } 227 | */ 228 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/context/DwContext.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 11.02.12 5 | */ 6 | 7 | 8 | 9 | function DwContext(b_init, canvas_name){ 10 | this.canvas_name = canvas_name; 11 | this.gl; 12 | this.gl_debug; 13 | 14 | this.VIEWPORT = { 15 | width : 0, 16 | height: 0, 17 | off_x : 0, 18 | off_y : 0 19 | }; 20 | 21 | this.fullscreen = true; 22 | 23 | this.div_canvas; 24 | this.canvas; 25 | this.ANIMATOR = true; 26 | 27 | this.frame_info; 28 | this.mouse_info; 29 | this.key_info; 30 | 31 | var _this = this; 32 | this.onresize = function(){}; 33 | 34 | window.onresize = function(){ 35 | _this.updateVIEWPORTdimensions(); 36 | _this.onresize(); 37 | }; 38 | this.onclose = function(){}; 39 | 40 | window.onunload = function(){ 41 | _this.onclose(); 42 | } 43 | 44 | 45 | if( b_init ){ 46 | this.init(); 47 | } 48 | } 49 | 50 | 51 | DwContext.prototype.updateBegin = function(){ 52 | this.mouse_info.updateBegin(); 53 | this.frame_info.update(); 54 | this.key_info .updateBegin(); 55 | } 56 | 57 | DwContext.prototype.updateEnd = function(){ 58 | this.mouse_info.updateEnd(); 59 | this.key_info .updateEnd(); 60 | } 61 | 62 | DwContext.prototype.updateVIEWPORTdimensions = function () { 63 | if( this.fullscreen ){ 64 | this.VIEWPORT.width = window.innerWidth; 65 | this.VIEWPORT.height = window.innerHeight; 66 | this.VIEWPORT.off_x = 0; 67 | this.VIEWPORT.off_y = 0; 68 | this.div_canvas.style.width = 0; 69 | this.div_canvas.style.height = 0; 70 | } 71 | if( !this.fullscreen ){ 72 | this.VIEWPORT.width = this.div_canvas.offsetWidth; 73 | this.VIEWPORT.height = this.div_canvas.offsetHeight; 74 | this.VIEWPORT.off_x = getOffsetX(this.div_canvas); 75 | this.VIEWPORT.off_y = getOffsetY(this.div_canvas); 76 | } 77 | this.canvas.width = this.VIEWPORT.width; 78 | this.canvas.height = this.VIEWPORT.height; 79 | this.div_canvas.style.left = this.VIEWPORT.off_x ; 80 | this.div_canvas.style.top = this.VIEWPORT.off_y; 81 | } 82 | 83 | 84 | DwContext.prototype.init = function () { 85 | this.canvas = document.getElementById(this.canvas_name); 86 | this.div_canvas = document.getElementById("div_webgl_canvas"); 87 | var _this = this; 88 | 89 | this.updateVIEWPORTdimensions(); 90 | 91 | try { 92 | // this.gl = this.canvas.getContext("experimental-webgl", antialias: !false); 93 | this.gl = this.canvas.getContext("webgl"); //TODO 94 | 95 | if( !this.gl ){ 96 | // http://www.khronos.org/registry/webgl/specs/latest/#5.2.1 97 | console.log("using : experimental-webgl"); 98 | this.gl = this.canvas.getContext("experimental-webgl" 99 | ,{ 100 | alpha: true, 101 | depth: true, 102 | // antialias: true, 103 | stencil:true, 104 | preserveDrawingBuffer: true 105 | } 106 | ); //, { antialias: false,stencil: true }); 107 | }else { 108 | console.log("using : webgl"); 109 | } 110 | // this.gl = this.canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true}); 111 | this.gl_debug = WebGLDebugUtils.makeDebugContext( this.gl ); 112 | WebGLDebugUtils.init(this.gl_debug); 113 | } catch (e) { 114 | console.log(e); 115 | } 116 | if (!this.gl) { 117 | alert("Could not initialise WebGL, sorry :-("); 118 | } 119 | this.frame_info = new DwFrameInfo(this); 120 | this.mouse_info = new DwMouseInfo(this); 121 | this.key_info = new DwKeyInfo(this); 122 | } 123 | 124 | 125 | DwContext.prototype.WEBGL_ERROR_CHECK = function (){ 126 | var error = this.gl_debug.getError(); 127 | var error_str = WebGLDebugUtils.glEnumToString(error); 128 | if (error != 0) 129 | alert("WebGL_ERROR: "+error_str); 130 | } 131 | 132 | DwContext.WEBGL_FBO_CHECK = function(gl, handle_fbo){ 133 | if (!gl.isFramebuffer(handle_fbo)) { 134 | throw("Invalid framebuffer"); 135 | } 136 | var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); 137 | switch (status) { 138 | case gl.FRAMEBUFFER_COMPLETE: 139 | break; 140 | case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 141 | throw("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); 142 | break; 143 | case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 144 | throw("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); 145 | break; 146 | case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 147 | throw("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); 148 | break; 149 | case gl.FRAMEBUFFER_UNSUPPORTED: 150 | throw("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED"); 151 | break; 152 | default: 153 | throw("Incomplete framebuffer: " + status); 154 | } 155 | } 156 | 157 | function getOffsetX(obj){ 158 | var curleft = 0; 159 | if (obj.offsetParent){ 160 | while (obj.offsetParent){ 161 | curleft += obj.offsetLeft; 162 | obj = obj.offsetParent; 163 | } 164 | } 165 | else if (obj.x) curleft += obj.x; 166 | return curleft; 167 | } 168 | 169 | function getOffsetY(obj){ 170 | var curtop = 0; 171 | if (obj.offsetParent){ 172 | while (obj.offsetParent){ 173 | curtop += obj.offsetTop; 174 | obj = obj.offsetParent; 175 | } 176 | } 177 | else if (obj.y) curtop += obj.y; 178 | return curtop; 179 | } 180 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/shader/DwShader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas 4 | * date: 05.02.12 5 | */ 6 | 7 | //http://www.opengl.org/wiki/OpenGL_Shading_Language#Building_shaders 8 | function DwShader(gl, path, shader_name_vert, shader_name_frag){ 9 | this.gl = gl; 10 | this.path = path; 11 | this.shader_name_vert = shader_name_vert; 12 | this.shader_name_frag = shader_name_frag; 13 | 14 | this.HANDLE_program = null; 15 | this.HANDLE_vert = null; 16 | this.HANDLE_frag = null; 17 | 18 | this.onload = function(){}; 19 | } 20 | 21 | DwShader.prototype.load = function(obj){ 22 | var _this = this; 23 | 24 | var shader_vert = new DwShaderElement(_this.gl,_this.path, _this.shader_name_vert, _this.gl.VERTEX_SHADER); 25 | var shader_frag = new DwShaderElement(_this.gl,_this.path, _this.shader_name_frag, _this.gl.FRAGMENT_SHADER); 26 | 27 | // fragment shader is loaded after vertex shader 28 | shader_frag.onload = function(){ 29 | _this.createShaderProgram(shader_vert, shader_frag); 30 | _this.onload(); // defined by caller!!! 31 | }; 32 | 33 | // vertex shader is loaded at first, ... on load the fragmentshader is getting loaded 34 | shader_vert.onload = function(){ 35 | shader_frag.load(obj); 36 | }; 37 | 38 | // now, init the loading process (asynchronous) 39 | shader_vert.load(obj); 40 | } 41 | DwShader.prototype.delete = function(){ 42 | this.gl.deleteShader (this.HANDLE_vert); 43 | this.gl.deleteShader (this.HANDLE_frag); 44 | this.gl.deleteProgram(this.HANDLE_program); 45 | this.HANDLE_vert = null; 46 | this.HANDLE_frag = null; 47 | this.HANDLE_program = null; 48 | } 49 | 50 | 51 | DwShader.prototype.createShaderProgram = function(vert, frag){ 52 | this.HANDLE_vert = vert.HANDLE; 53 | this.HANDLE_frag = frag.HANDLE; 54 | this.HANDLE_program = this.gl.createProgram(); 55 | this.gl.attachShader(this.HANDLE_program, vert.HANDLE); 56 | this.gl.attachShader(this.HANDLE_program, frag.HANDLE); 57 | this.gl.validateProgram(this.HANDLE_program); 58 | this.gl.linkProgram (this.HANDLE_program); 59 | 60 | if (!this.gl.getProgramParameter(this.HANDLE_program, this.gl.LINK_STATUS)) { 61 | alert("Could not initialise shaders"); 62 | console.log(this.gl.getProgramInfoLog(this.HANDLE_program)); 63 | } 64 | } 65 | 66 | 67 | 68 | 69 | 70 | function DwShaderElement(gl, path, filename, shader_type){ 71 | this.gl = gl; 72 | this.HANDLE = null; 73 | this.total_file_path = path + filename; 74 | this.shader_type = shader_type; 75 | var _this = this; 76 | this.onload = function(){}; 77 | this.onerror = function(){ 78 | console.log("ERROR while loading SHADER-file: "+_this.total_file_path); 79 | }; 80 | } 81 | 82 | //https://developer.mozilla.org/en/XMLHttpRequest 83 | DwShaderElement.prototype.load = function(obj, async){ 84 | var _this = this; 85 | var XHR = new XMLHttpRequest(); 86 | XHR.open("GET", this.total_file_path, (async === undefined) || async ); //true=asynchronous 87 | XHR.responseType = "text"; 88 | XHR.onload = function (event) { 89 | 90 | _this.HANDLE = _this.gl.createShader(_this.shader_type); 91 | _this.gl.shaderSource(_this.HANDLE, XHR.responseText); 92 | _this.gl.compileShader(_this.HANDLE); 93 | if (!_this.gl.getShaderParameter(_this.HANDLE, _this.gl.COMPILE_STATUS)) { 94 | // alert("ERROR ON COMPILING SHADER"); 95 | // _this.onerror(); 96 | alert("ERROR on compiling shader: "+_this.total_file_path+"\n"+_this.gl.getShaderInfoLog(_this.HANDLE)); 97 | }else { 98 | _this.onload(); 99 | } 100 | }; 101 | 102 | try{ 103 | XHR.send(obj); // usually null 104 | } catch (exception){ 105 | // console.log(exception); 106 | // console.log("ERROR while loading SHADER-file: "+this.total_file_path); 107 | _this.onerror(); 108 | } 109 | } 110 | DwShaderElement.prototype.delete = function(){ 111 | this.gl.deleteShader(this.HANDLE); 112 | this.HANDLE = null; 113 | } 114 | 115 | 116 | 117 | ///** 118 | // * static loadShaderFileContent() 119 | // * @param filename 120 | // */ 121 | //DwShader.loadShaderFileContent = function (filename){ 122 | // var XHR = new XMLHttpRequest(); 123 | // XHR.open('GET', filename, !true); 124 | // XHR.responseType = "text"; 125 | // XHR.send(null); 126 | // if (XHR.readyState === 4) { 127 | // if (XHR.status === 0) { // TODO: 200 128 | // return XHR.responseText; 129 | // } 130 | //// alert("xhr.status = "+xhr.status); 131 | // return null; 132 | // } 133 | //// alert("xhr.status != 4"); 134 | // return null; 135 | //} 136 | // 137 | // 138 | ///** 139 | // * static getShader() 140 | // * 141 | // * @param gl 142 | // * @param shader_file 143 | // * @param shader_type 144 | // */ 145 | //DwShader.getShader = function (gl, shader_file, shader_type) { 146 | // var shader_content = DwShader.loadShaderFileContent(shader_file); 147 | // if( shader_content == null ) 148 | // return null; 149 | // 150 | // var handle = gl.createShader(shader_type); 151 | // 152 | // gl.shaderSource(handle, shader_content); 153 | // gl.compileShader(handle); 154 | // 155 | // if (!gl.getShaderParameter(handle, gl.COMPILE_STATUS)) { 156 | // alert(gl.getShaderInfoLog(handle)); 157 | // return null; 158 | // } 159 | // 160 | // return handle; 161 | //} 162 | // 163 | //DwShader.prototype.create = function (){ 164 | // var gl = this.gl; 165 | // this.HANDLE_vert = DwShader.getShader(gl, this.path+this.shader_name_vert, gl.VERTEX_SHADER); 166 | // this.HANDLE_frag = DwShader.getShader(gl, this.path+this.shader_name_frag, gl.FRAGMENT_SHADER); 167 | // 168 | // this.HANDLE_program = gl.createProgram(); 169 | // gl.attachShader(this.HANDLE_program, this.HANDLE_vert); 170 | // gl.attachShader(this.HANDLE_program, this.HANDLE_frag); 171 | // gl.linkProgram(this.HANDLE_program); 172 | // 173 | // if (!gl.getProgramParameter(this.HANDLE_program, gl.LINK_STATUS)) { 174 | // alert("Could not initialise shaders"); 175 | // } 176 | //} 177 | // 178 | 179 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/math/DwVec2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 09.02.12 5 | */ 6 | 7 | 8 | 9 | var DwVec2 = DwVec2 || {}; 10 | 11 | 12 | 13 | DwVec2.nullvector = function () { 14 | return [0, 0]; 15 | } 16 | 17 | DwVec2.copy_ref = function (a, dst) { 18 | dst[0] = a[0]; 19 | dst[1] = a[1]; 20 | }; 21 | 22 | DwVec2.copy_new = function (a) { 23 | return [a[0], a[1]]; 24 | }; 25 | 26 | 27 | DwVec2.equals = function (a, b) { 28 | return (a[0] === b[0] && a[1] === b[1] ); 29 | }; 30 | 31 | 32 | DwVec2.add_ref = function (a, b, dst) { 33 | dst[0] = a[0]+b[0]; dst[1] = a[1]+b[1]; 34 | }; 35 | DwVec2.add_new = function (a, b) { 36 | return [(a[0]+b[0]), (a[1]+b[1])]; 37 | }; 38 | 39 | 40 | DwVec2.sub_ref = function (a, b, dst) { 41 | dst[0] = a[0]-b[0]; dst[1] = a[1]-b[1]; 42 | }; 43 | DwVec2.sub_new = function (a, b) { 44 | return [(a[0]-b[0]), (a[1]-b[1])]; 45 | }; 46 | 47 | 48 | DwVec2.line_midpoint_ref = function (a, b, dst) { 49 | dst[0] = (a[0] + b[0]) * 0.5; 50 | dst[1] = (a[1] + b[1]) * 0.5; 51 | }; 52 | DwVec2.line_midpoint_new = function (a, b) { 53 | return [(a[0]+b[0])*0.5, (a[1]+b[1])*0.5]; 54 | }; 55 | 56 | DwVec2.triangle_midpoint_ref = function (a, b, c, dst) { 57 | var f = 1/3; 58 | dst[0] = (a[0]+b[0]+c[0]) * f; 59 | dst[1] = (a[1]+b[1]+c[1]) * f; 60 | }; 61 | DwVec2.triangle_midpoint_new = function (a, b, c) { 62 | var f = 1/3; 63 | return [(a[0]+b[0]+c[0]) * f, (a[1]+b[1]+c[1]) * f]; 64 | }; 65 | 66 | 67 | DwVec2.sum_ref = function(a, b, c, dst){ 68 | dst[0] = a[0]+b[0]+c[0]; 69 | dst[1] = a[1]+b[1]+c[1]; 70 | } 71 | DwVec2.sum_new = function(a, b, c){ 72 | return [a[0]+b[0]+c[0], a[1]+b[1]+c[1]]; 73 | } 74 | 75 | 76 | DwVec2.sumlist_ref = function(arr, dst){ 77 | var len = arr.length; 78 | for(var i = 0; i < len; i++){ 79 | dst[0] += arr[i][0]; 80 | dst[1] += arr[i][1]; 81 | } 82 | } 83 | 84 | DwVec2.sumlist_new = function(arr){ 85 | var dst = []; 86 | var len = arr.length; 87 | for(var i = 0; i < len; i++){ 88 | dst[0] += arr[i][0]; 89 | dst[1] += arr[i][1]; 90 | } 91 | return dst; 92 | } 93 | 94 | 95 | 96 | 97 | 98 | 99 | DwVec2.multiply_ref = function (a, b, dst) { 100 | dst[0] = a[0] * b[0]; 101 | dst[1] = a[1] * b[1]; 102 | }; 103 | DwVec2.multiply_new = function (a, b) { 104 | return [a[0]*b[0], a[1]*b[1]]; 105 | }; 106 | 107 | 108 | 109 | DwVec2.negate_ref = function (a, dst) { 110 | dst[0] = -a[0]; 111 | dst[1] = -a[1]; 112 | }; 113 | DwVec2.negate_ref_slf = function (a) { 114 | a[0] = -a[0]; 115 | a[1] = -a[1]; 116 | }; 117 | DwVec2.negate_new = function (a) { 118 | return [-a[0], -a[1]]; 119 | }; 120 | 121 | 122 | 123 | DwVec2.scale_ref = function (a, val, dst) { 124 | dst[0] = a[0] * val; 125 | dst[1] = a[1] * val; 126 | }; 127 | DwVec2.scale_ref_slf = function (a, val) { 128 | a[0] *= val; 129 | a[1] *= val; 130 | }; 131 | DwVec2.scale_new = function (a, val) { 132 | return [a[0] * val, a[1] * val]; 133 | }; 134 | 135 | 136 | 137 | DwVec2.normalize_ref_slf = function (a) { 138 | var x = a[0], y = a[1]; 139 | var len = Math.sqrt(x*x + y*y); 140 | 141 | if (len != 1) { 142 | len = 1 / len; 143 | a[0] *= len; 144 | a[1] *= len; 145 | } 146 | }; 147 | DwVec2.normalize_ref = function (a, dst) { 148 | var x = a[0], y = a[1]; 149 | var len = Math.sqrt(x*x + y*y); 150 | 151 | if (!len) { 152 | dst[0] = 0; 153 | dst[1] = 0; 154 | } else if (len === 1) { 155 | dst[0] = x; 156 | dst[1] = y; 157 | } else { 158 | len = 1 / len; 159 | dst[0] = x * len; 160 | dst[1] = y * len; 161 | } 162 | }; 163 | DwVec2.normalize_new = function (a) { 164 | var x = a[0], y = a[1]; 165 | var len = Math.sqrt(x*x + y*y); 166 | 167 | if (!len) { 168 | return [0, 0, 0]; 169 | } else if (len === 1) { 170 | return [x, y]; 171 | } else { 172 | return [x*len, y*len]; 173 | } 174 | }; 175 | 176 | 177 | //DwVec2.cross_ref = function (a, b, dst) { 178 | // var ax = a[0], ay = a[1], az = a[2]; 179 | // var bx = b[0], by = b[1], bz = b[2]; 180 | // 181 | // dst[0] = ay * bz - az * by; 182 | // dst[1] = az * bx - ax * bz; 183 | // dst[2] = ax * by - ay * bx; 184 | //}; 185 | //DwVec2.cross_new = function (a, b) { 186 | // var ax = a[0], ay = a[1], az = a[2]; 187 | // var bx = b[0], by = b[1], bz = b[2]; 188 | // 189 | // return [ay*bz - az*by, az*bx - ax*bz, ax*by - ay*bx]; 190 | //}; 191 | 192 | 193 | 194 | DwVec2.dot = function (a, b) { 195 | return a[0]*b[0] + a[1]*b[1]; 196 | }; 197 | 198 | 199 | 200 | DwVec2.angleBetween = function(a, b){ 201 | return Math.acos( DwVec2.dot(a,b)/(DwVec2.mag(a)*DwVec2.mag(b)) ); 202 | } 203 | DwVec2.angleBetween_unit = function(a, b){ 204 | return Math.acos( DwVec2.dot(a,b) ); 205 | } 206 | 207 | 208 | 209 | DwVec2.mag = function (a) { 210 | var x = a[0], y = a[1]; 211 | return Math.sqrt(x*x + y*y); 212 | }; 213 | DwVec2.mag_sq = function (a) { 214 | var x = a[0], y = a[1]; 215 | return x*x + y*y; 216 | }; 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | DwVec2.dir_unit_ref = function (a, b, dst) { 225 | DwVec2.sub_ref(a, b, dst); 226 | DwVec2.normalize_ref_slf(dst); 227 | }; 228 | 229 | DwVec2.dir_unit_new = function (a, b) { 230 | var dst = []; 231 | DwVec2.sub_ref(a, b, dst); 232 | DwVec2.normalize_ref_slf(dst); 233 | return dst; 234 | }; 235 | 236 | 237 | 238 | DwVec2.lerp_ref = function (a, b, val, dst) { 239 | dst[0] = a[0] + val * (b[0] - a[0]); 240 | dst[1] = a[1] + val * (b[1] - a[1]); 241 | }; 242 | 243 | DwVec2.lerp_new = function (a, b, val) { 244 | return [a[0]+val*(b[0]-a[0]), a[1]+val*(b[1]-a[1])]; 245 | }; 246 | 247 | 248 | DwVec2.dist = function (a, b) { 249 | var dst = DwVec2.sub_new(a, b); 250 | return DwVec2.mag(dst); 251 | }; 252 | 253 | 254 | 255 | DwVec2.toStr = function (a, prec) { 256 | prec = prec || 5; 257 | return "["+a[0].toFixed(prec)+", "+a[1].toFixed(prec)+"]"; 258 | }; 259 | 260 | 261 | DwVec2.toIntStr = function (a) { 262 | return "["+a[0]+", "+a[1]+"]"; 263 | }; 264 | 265 | 266 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/DwVBO.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 07.02.12 5 | */ 6 | 7 | 8 | function DwVBO(gl){ 9 | this.gl = gl; 10 | 11 | this.HANDLE_indices = gl.createBuffer(); 12 | this.HANDLE_vertex_data = gl.createBuffer(); 13 | 14 | this.number_of_vertices = 0; 15 | this.vertices_offset = 0; 16 | 17 | this.vertex_data_set; 18 | 19 | this.use_indices = true; 20 | 21 | this.drawing_mode = gl.TRIANGLES;//drawing_type; // gl.TRIANGLES, gl.LINES, etc.... 22 | 23 | } 24 | 25 | 26 | 27 | 28 | 29 | /** 30 | * 31 | * draw() 32 | * 33 | */ 34 | DwVBO.prototype.draw = function(){ 35 | 36 | var gl = this.gl; 37 | var dataset_list = this.vertex_data_set; 38 | var dataset; 39 | 40 | // ____ ATTRIBUTES ____ (shader, enable) 41 | for(var i = 0; i < dataset_list.length, dataset = dataset_list[i]; i++){ 42 | gl.enableVertexAttribArray(dataset.index); 43 | } 44 | 45 | // ____ ATTRIBUTES ____ (vbo) 46 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vertex_data); 47 | for(var i = 0; i < dataset_list.length, dataset = dataset_list[i]; i++){ 48 | // if( dataset.index < 0) 49 | // continue; 50 | gl.vertexAttribPointer(dataset.index, dataset.size, dataset.type, dataset.normalized, dataset.stride, dataset.offset); 51 | } 52 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 53 | 54 | // ____ DRAW ____ 55 | if( !this.use_indices ){ 56 | gl.drawArrays(this.drawing_mode, this.vertices_offset, this.number_of_vertices); 57 | } else { 58 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.HANDLE_indices); 59 | gl.drawElements(this.drawing_mode, this.number_of_vertices, gl.UNSIGNED_SHORT, this.vertices_offset); 60 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 61 | } 62 | gl.flush(); 63 | 64 | // ____ ATTRIBUTES ____ (shader, disable) 65 | for(var i = 0; i < dataset_list.length, dataset = dataset_list[i]; i++){ 66 | gl.disableVertexAttribArray(dataset.index); 67 | } 68 | } 69 | 70 | 71 | // buffer_access = [ 72 | // gl.STREAM_DRAW, // 0 73 | // gl.STATIC_DRAW, // 3 74 | // gl.DYNAMIC_DRAW // 6 75 | // ]; 76 | 77 | 78 | 79 | 80 | /** 81 | * 82 | * updateVBO_indices() 83 | * 84 | */ 85 | DwVBO.prototype.updateVBO_indices = function(buffer, data_usage){ 86 | var gl = this.gl; 87 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.HANDLE_indices); 88 | gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, buffer, data_usage); 89 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 90 | } 91 | 92 | /** 93 | * 94 | * updateVBO_vertices() 95 | * 96 | */ 97 | DwVBO.prototype.updateVBO_vertices = function(buffer, data_usage){ 98 | var gl = this.gl; 99 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vertex_data); 100 | gl.bufferData(gl.ARRAY_BUFFER, buffer, data_usage); 101 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 102 | 103 | } 104 | 105 | 106 | /** 107 | * 108 | * initVertexDataLayout() 109 | * 110 | */ 111 | DwVBO.prototype.initVertexDataLayout = function(){ 112 | this.vertex_data_set = new Array(); 113 | } 114 | 115 | 116 | 117 | /** 118 | * 119 | * addVertexDataSet() 120 | * 121 | */ 122 | DwVBO.prototype.addVertexDataSet = function(data_set_idx, description, shader_location, number_of_values){ 123 | var dataset = { 124 | "description" : description, // description 125 | "index" : shader_location, // glVertexAttribPointer ... index 126 | "size" : number_of_values, // glVertexAttribPointer ... size, number of elements 127 | "type" : this.gl.FLOAT, // glVertexAttribPointer ... type 128 | "normalized" : false, // glVertexAttribPointer ... normalized 129 | "stride" : 0, // glVertexAttribPointer ... stride 130 | "offset" : 0, // glVertexAttribPointer ... offset 131 | "size_in_bytes": number_of_values * 4 // glVertexAttribPointer ... size in bytes 132 | }; 133 | this.vertex_data_set[data_set_idx] = dataset; 134 | } 135 | 136 | 137 | /** 138 | * 139 | * updateVertexDataSets() 140 | * 141 | */ 142 | DwVBO.prototype.updateVertexDataSets = function (){ 143 | //calculate overall stride (in bytes) 144 | var gl = this.gl; 145 | var stride = 0; 146 | var dataset = this.vertex_data_set; 147 | for(var i = 0; i < dataset.length; i++){ 148 | stride += dataset[i].size_in_bytes; 149 | } 150 | 151 | // set vertex-attribute-pointer for each VertexDataSet 152 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vertex_data); 153 | var offset = 0; 154 | for(var i = 0; i < dataset.length; i++){ 155 | var ds = dataset[i]; 156 | ds.offset = offset; 157 | ds.stride = stride; 158 | console.log("..." +ds.description +": gl.vertexAttribPointer("+ds.index+", "+ds.size+", "+ ds.type+", "+ ds.normalized+", "+ ds.stride+", "+ ds.offset+");"); 159 | // gl.vertexAttribPointer(ds.index, ds.size, ds.type, ds.normalized, ds.stride, ds.offset); 160 | offset += ds.size_in_bytes; 161 | } 162 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 163 | } 164 | 165 | 166 | 167 | /** 168 | * 169 | * printvertexDataSet() 170 | * 171 | */ 172 | DwVBO.prototype.printvertexDataSet = function(dataset){ 173 | console.log("dataset: "+dataset.description+", "+dataset.index+", "+dataset.size+", "+dataset.type+", "+dataset.normalized+", "+dataset.stride+", "+dataset.size_in_bytes); 174 | } 175 | /** 176 | * 177 | * useIndices() 178 | * 179 | */ 180 | DwVBO.prototype.useIndices = function(use_indices){ 181 | this.use_indices = use_indices; 182 | } 183 | /** 184 | * 185 | * setDrawingMode() 186 | * 187 | */ 188 | DwVBO.prototype.setDrawingMode = function(drawing_mode){ 189 | this.drawing_mode = drawing_mode; 190 | } 191 | 192 | 193 | 194 | DwVBO.prototype.setDrawingRange = function(offset, length){ 195 | this.number_of_vertices = length; 196 | this.vertices_offset = offset; 197 | } 198 | 199 | 200 | 201 | function ERROR_CHECK(gl, debug_note, print_note) { 202 | // var c = gl.getError(); 203 | // if (print_note) console.log("--------------------------< ERROR_CHECK >--------------------------( "+debug_note+" )"); 204 | // var has_error = c != gl.NO_ERROR; 205 | // if (has_error ) 206 | // console.logn(glu.gluErrorString(c)); 207 | // if (print_note) System.out.println("--------------------------< /ERROR_CHECK >--------------------------"); 208 | // return has_error; 209 | } 210 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/webgl_utils/webgl-utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | /** 34 | * @fileoverview This file contains functions every webgl program will need 35 | * a version of one way or another. 36 | * 37 | * Instead of setting up a context manually it is recommended to 38 | * use. This will check for success or failure. On failure it 39 | * will attempt to present an approriate message to the user. 40 | * 41 | * gl = WebGLUtils.setupWebGL(canvas); 42 | * 43 | * For animated WebGL apps use of setTimeout or setInterval are 44 | * discouraged. It is recommended you structure your rendering 45 | * loop like this. 46 | * 47 | * function render() { 48 | * window.requestAnimFrame(render, canvas); 49 | * 50 | * // do rendering 51 | * ... 52 | * } 53 | * render(); 54 | * 55 | * This will call your rendering function up to the refresh rate 56 | * of your display but will stop rendering if your app is not 57 | * visible. 58 | */ 59 | 60 | WebGLUtils = function() { 61 | 62 | /** 63 | * Creates the HTLM for a failure message 64 | * @param {string} canvasContainerId id of container of th 65 | * canvas. 66 | * @return {string} The html. 67 | */ 68 | var makeFailHTML = function(msg) { 69 | return '' + 70 | '' + 71 | '
' + 72 | '
' + 73 | '
' + msg + '
' + 74 | '
' + 75 | '
'; 76 | }; 77 | 78 | /** 79 | * Mesasge for getting a webgl browser 80 | * @type {string} 81 | */ 82 | var GET_A_WEBGL_BROWSER = '' + 83 | 'This page requires a browser that supports WebGL.
' + 84 | 'Click here to upgrade your browser.'; 85 | 86 | /** 87 | * Mesasge for need better hardware 88 | * @type {string} 89 | */ 90 | var OTHER_PROBLEM = '' + 91 | "It doesn't appear your computer can support WebGL.
" + 92 | 'Click here for more information.'; 93 | 94 | /** 95 | * Creates a webgl context. If creation fails it will 96 | * change the contents of the container of the 97 | * tag to an error message with the correct links for WebGL. 98 | * @param {Element} canvas. The canvas element to create a 99 | * context from. 100 | * @param {WebGLContextCreationAttirbutes} opt_attribs Any 101 | * creation attributes you want to pass in. 102 | * @return {WebGLRenderingContext} The created context. 103 | */ 104 | var setupWebGL = function(canvas, opt_attribs) { 105 | function showLink(str) { 106 | var container = canvas.parentNode; 107 | if (container) { 108 | container.innerHTML = makeFailHTML(str); 109 | } 110 | }; 111 | 112 | if (!window.WebGLRenderingContext) { 113 | showLink(GET_A_WEBGL_BROWSER); 114 | return null; 115 | } 116 | 117 | var context = create3DContext(canvas, opt_attribs); 118 | if (!context) { 119 | showLink(OTHER_PROBLEM); 120 | } 121 | return context; 122 | }; 123 | 124 | /** 125 | * Creates a webgl context. 126 | * @param {!Canvas} canvas The canvas tag to get context 127 | * from. If one is not passed in one will be created. 128 | * @return {!WebGLContext} The created context. 129 | */ 130 | var create3DContext = function(canvas, opt_attribs) { 131 | var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; 132 | var context = null; 133 | for (var ii = 0; ii < names.length; ++ii) { 134 | try { 135 | context = canvas.getContext(names[ii], opt_attribs); 136 | } catch(e) {} 137 | if (context) { 138 | break; 139 | } 140 | } 141 | return context; 142 | } 143 | 144 | return { 145 | create3DContext: create3DContext, 146 | setupWebGL: setupWebGL 147 | }; 148 | }(); 149 | 150 | /** 151 | * Provides requestAnimationFrame in a cross browser way. 152 | */ 153 | window.requestAnimFrame = (function() { 154 | return window.requestAnimationFrame || 155 | window.webkitRequestAnimationFrame || 156 | window.mozRequestAnimationFrame || 157 | window.oRequestAnimationFrame || 158 | window.msRequestAnimationFrame || 159 | function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) { 160 | return window.setTimeout(callback, 1000/60); 161 | }; 162 | })(); 163 | 164 | /** 165 | * Provides cancelAnimationFrame in a cross browser way. 166 | */ 167 | window.cancelAnimFrame = (function() { 168 | return window.cancelAnimationFrame || 169 | window.webkitCancelAnimationFrame || 170 | window.mozCancelAnimationFrame || 171 | window.oCancelAnimationFrame || 172 | window.msCancelAnimationFrame || 173 | window.clearTimeout; 174 | })(); 175 | 176 | 177 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/webgl_utils/old/webgl-utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | /** 34 | * @fileoverview This file contains functions every webgl program will need 35 | * a version of one way or another. 36 | * 37 | * Instead of setting up a context manually it is recommended to 38 | * use. This will check for success or failure. On failure it 39 | * will attempt to present an approriate message to the user. 40 | * 41 | * gl = WebGLUtils.setupWebGL(canvas); 42 | * 43 | * For animated WebGL apps use of setTimeout or setInterval are 44 | * discouraged. It is recommended you structure your rendering 45 | * loop like this. 46 | * 47 | * function render() { 48 | * window.requestAnimFrame(render, canvas); 49 | * 50 | * // do rendering 51 | * ... 52 | * } 53 | * render(); 54 | * 55 | * This will call your rendering function up to the refresh rate 56 | * of your display but will stop rendering if your app is not 57 | * visible. 58 | */ 59 | 60 | WebGLUtils = function() { 61 | 62 | /** 63 | * Creates the HTLM for a failure message 64 | * @param {string} canvasContainerId id of container of th 65 | * canvas. 66 | * @return {string} The html. 67 | */ 68 | var makeFailHTML = function(msg) { 69 | return '' + 70 | '' + 71 | '
' + 72 | '
' + 73 | '
' + msg + '
' + 74 | '
' + 75 | '
'; 76 | }; 77 | 78 | /** 79 | * Mesasge for getting a webgl browser 80 | * @type {string} 81 | */ 82 | var GET_A_WEBGL_BROWSER = '' + 83 | 'This page requires a browser that supports WebGL.
' + 84 | 'Click here to upgrade your browser.'; 85 | 86 | /** 87 | * Mesasge for need better hardware 88 | * @type {string} 89 | */ 90 | var OTHER_PROBLEM = '' + 91 | "It doesn't appear your computer can support WebGL.
" + 92 | 'Click here for more information.'; 93 | 94 | /** 95 | * Creates a webgl context. If creation fails it will 96 | * change the contents of the container of the 97 | * tag to an error message with the correct links for WebGL. 98 | * @param {Element} canvas. The canvas element to create a 99 | * context from. 100 | * @param {WebGLContextCreationAttirbutes} opt_attribs Any 101 | * creation attributes you want to pass in. 102 | * @return {WebGLRenderingContext} The created context. 103 | */ 104 | var setupWebGL = function(canvas, opt_attribs) { 105 | function showLink(str) { 106 | var container = canvas.parentNode; 107 | if (container) { 108 | container.innerHTML = makeFailHTML(str); 109 | } 110 | }; 111 | 112 | if (!window.WebGLRenderingContext) { 113 | showLink(GET_A_WEBGL_BROWSER); 114 | return null; 115 | } 116 | 117 | var context = create3DContext(canvas, opt_attribs); 118 | if (!context) { 119 | showLink(OTHER_PROBLEM); 120 | } 121 | return context; 122 | }; 123 | 124 | /** 125 | * Creates a webgl context. 126 | * @param {!Canvas} canvas The canvas tag to get context 127 | * from. If one is not passed in one will be created. 128 | * @return {!WebGLContext} The created context. 129 | */ 130 | var create3DContext = function(canvas, opt_attribs) { 131 | var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; 132 | var context = null; 133 | for (var ii = 0; ii < names.length; ++ii) { 134 | try { 135 | context = canvas.getContext(names[ii], opt_attribs); 136 | } catch(e) {} 137 | if (context) { 138 | break; 139 | } 140 | } 141 | return context; 142 | } 143 | 144 | return { 145 | create3DContext: create3DContext, 146 | setupWebGL: setupWebGL 147 | }; 148 | }(); 149 | 150 | /** 151 | * Provides requestAnimationFrame in a cross browser way. 152 | */ 153 | window.requestAnimFrame = (function() { 154 | return window.requestAnimationFrame || 155 | window.webkitRequestAnimationFrame || 156 | window.mozRequestAnimationFrame || 157 | window.oRequestAnimationFrame || 158 | window.msRequestAnimationFrame || 159 | function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) { 160 | return window.setTimeout(callback, 1000/60); 161 | }; 162 | })(); 163 | 164 | /** 165 | * Provides cancelRequestAnimationFrame in a cross browser way. 166 | */ 167 | window.cancelRequestAnimFrame = (function() { 168 | return window.cancelCancelRequestAnimationFrame || 169 | window.webkitCancelRequestAnimationFrame || 170 | window.mozCancelRequestAnimationFrame || 171 | window.oCancelRequestAnimationFrame || 172 | window.msCancelRequestAnimationFrame || 173 | window.clearTimeout; 174 | })(); 175 | 176 | 177 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/math/DwVec3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 09.02.12 5 | */ 6 | 7 | 8 | 9 | var DwVec3 = DwVec3 || {}; 10 | 11 | 12 | 13 | DwVec3.nullvector = function () { 14 | return [0, 0, 0]; 15 | } 16 | 17 | 18 | DwVec3.copy_ref = function (a, dst) { 19 | dst[0] = a[0]; 20 | dst[1] = a[1]; 21 | dst[2] = a[2]; 22 | }; 23 | 24 | DwVec3.copy_new = function (a) { 25 | return [a[0], a[1], a[2]]; 26 | }; 27 | 28 | 29 | DwVec3.equals = function (a, b) { 30 | return (a[0] === b[0] && a[1] === b[1] && a[2] === b[2]); 31 | }; 32 | 33 | 34 | DwVec3.add_ref = function (a, b, dst) { 35 | dst[0] = a[0]+b[0]; dst[1] = a[1]+b[1]; dst[2] = a[2]+b[2]; 36 | }; 37 | DwVec3.add_new = function (a, b) { 38 | return [(a[0]+b[0]), (a[1]+b[1]), (a[2]+b[2])]; 39 | }; 40 | 41 | 42 | DwVec3.sub_ref = function (a, b, dst) { 43 | dst[0] = a[0]-b[0]; dst[1] = a[1]-b[1]; dst[2] = a[2]-b[2]; 44 | }; 45 | DwVec3.sub_new = function (a, b) { 46 | return [(a[0]-b[0]), (a[1]-b[1]), (a[2]-b[2])]; 47 | }; 48 | 49 | 50 | DwVec3.line_midpoint_ref = function (a, b, dst) { 51 | dst[0] = (a[0] + b[0]) * 0.5; 52 | dst[1] = (a[1] + b[1]) * 0.5; 53 | dst[2] = (a[2] + b[2]) * 0.5; 54 | }; 55 | DwVec3.line_midpoint_new = function (a, b) { 56 | return [(a[0]+b[0])*0.5, (a[1]+b[1])*0.5, (a[2]+b[2])*0.5]; 57 | }; 58 | 59 | DwVec3.triangle_midpoint_ref = function (a, b, c, dst) { 60 | var f = 1/3; 61 | dst[0] = (a[0]+b[0]+c[0]) * f; 62 | dst[1] = (a[1]+b[1]+c[1]) * f; 63 | dst[2] = (a[2]+b[2]+c[2]) * f; 64 | }; 65 | DwVec3.triangle_midpoint_new = function (a, b, c) { 66 | var f = 1/3; 67 | return [(a[0]+b[0]+c[0]) * f, (a[1]+b[1]+c[1]) * f, (a[2]+b[2]+c[2]) * f]; 68 | }; 69 | 70 | 71 | DwVec3.sum_ref = function(a, b, c, dst){ 72 | dst[0] = a[0]+b[0]+c[0]; 73 | dst[1] = a[1]+b[1]+c[1]; 74 | dst[2] = a[2]+b[2]+c[2]; 75 | } 76 | DwVec3.sum_new = function(a, b, c){ 77 | return [a[0]+b[0]+c[0], a[1]+b[1]+c[1], a[2]+b[2]+c[2]]; 78 | } 79 | 80 | 81 | DwVec3.sumlist_ref = function(arr, dst){ 82 | var len = arr.length; 83 | for(var i = 0; i < len; i++){ 84 | dst[0] += arr[i][0]; 85 | dst[1] += arr[i][1]; 86 | dst[2] += arr[i][2]; 87 | } 88 | } 89 | 90 | DwVec3.sumlist_new = function(arr){ 91 | var dst = []; 92 | var len = arr.length; 93 | for(var i = 0; i < len; i++){ 94 | dst[0] += arr[i][0]; 95 | dst[1] += arr[i][1]; 96 | dst[2] += arr[i][2]; 97 | } 98 | return dst; 99 | } 100 | 101 | 102 | 103 | 104 | 105 | 106 | DwVec3.multiply_ref = function (a, b, dst) { 107 | dst[0] = a[0] * b[0]; 108 | dst[1] = a[1] * b[1]; 109 | dst[2] = a[2] * b[2]; 110 | }; 111 | DwVec3.multiply_new = function (a, b) { 112 | return [a[0]*b[0], a[1]*b[1], a[2]*b[2]]; 113 | }; 114 | 115 | 116 | 117 | DwVec3.negate_ref = function (a, dst) { 118 | dst[0] = -a[0]; 119 | dst[1] = -a[1]; 120 | dst[2] = -a[2]; 121 | }; 122 | DwVec3.negate_ref_slf = function (a) { 123 | a[0] = -a[0]; 124 | a[1] = -a[1]; 125 | a[2] = -a[2]; 126 | }; 127 | DwVec3.negate_new = function (a) { 128 | return [-a[0], -a[1], -a[2]]; 129 | }; 130 | 131 | 132 | 133 | DwVec3.scale_ref = function (a, val, dst) { 134 | dst[0] = a[0] * val; 135 | dst[1] = a[1] * val; 136 | dst[2] = a[2] * val; 137 | }; 138 | DwVec3.scale_ref_slf = function (a, val) { 139 | a[0] *= val; 140 | a[1] *= val; 141 | a[2] *= val; 142 | }; 143 | DwVec3.scale_new = function (a, val) { 144 | return [a[0] * val, a[1] * val, a[2] * val]; 145 | }; 146 | 147 | 148 | 149 | DwVec3.normalize_ref_slf = function (a) { 150 | var x = a[0], y = a[1], z = a[2]; 151 | var len = Math.sqrt(x*x + y*y + z*z); 152 | 153 | if (len != 1) { 154 | len = 1 / len; 155 | a[0] *= len; 156 | a[1] *= len; 157 | a[2] *= len; 158 | } 159 | }; 160 | DwVec3.normalize_ref = function (a, dst) { 161 | var x = a[0], y = a[1], z = a[2]; 162 | var len = Math.sqrt(x * x + y * y + z * z); 163 | 164 | if (!len) { 165 | dst[0] = 0; 166 | dst[1] = 0; 167 | dst[2] = 0; 168 | } else if (len === 1) { 169 | dst[0] = x; 170 | dst[1] = y; 171 | dst[2] = z; 172 | } else { 173 | len = 1 / len; 174 | dst[0] = x * len; 175 | dst[1] = y * len; 176 | dst[2] = z * len; 177 | } 178 | }; 179 | DwVec3.normalize_new = function (a) { 180 | var x = a[0], y = a[1], z = a[2]; 181 | var len = Math.sqrt(x * x + y * y + z * z); 182 | 183 | if (!len) { 184 | return [0, 0, 0]; 185 | } else if (len === 1) { 186 | return [x, y, z]; 187 | } else { 188 | len = 1 / len; 189 | return [x*len, y*len, z*len]; 190 | } 191 | }; 192 | 193 | 194 | DwVec3.cross_ref = function (a, b, dst) { 195 | var ax = a[0], ay = a[1], az = a[2]; 196 | var bx = b[0], by = b[1], bz = b[2]; 197 | 198 | dst[0] = ay * bz - az * by; 199 | dst[1] = az * bx - ax * bz; 200 | dst[2] = ax * by - ay * bx; 201 | }; 202 | DwVec3.cross_new = function (a, b) { 203 | var ax = a[0], ay = a[1], az = a[2]; 204 | var bx = b[0], by = b[1], bz = b[2]; 205 | 206 | return [ay*bz - az*by, az*bx - ax*bz, ax*by - ay*bx]; 207 | }; 208 | 209 | 210 | 211 | DwVec3.dot = function (a, b) { 212 | return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; 213 | }; 214 | 215 | 216 | 217 | DwVec3.angleBetween = function(a, b){ 218 | return Math.acos( DwVec3.dot(a,b)/(DwVec3.mag(a)*DwVec3.mag(b)) ); 219 | } 220 | DwVec3.angleBetween_unit = function(a, b){ 221 | return Math.acos( DwVec3.dot(a,b) ); 222 | } 223 | 224 | 225 | 226 | DwVec3.mag = function (a) { 227 | var x = a[0], y = a[1], z = a[2]; 228 | return Math.sqrt(x*x + y*y + z*z); 229 | }; 230 | DwVec3.mag_sq = function (a) { 231 | var x = a[0], y = a[1], z = a[2]; 232 | return x*x + y*y + z*z; 233 | }; 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | DwVec3.dir_unit_ref = function (a, b, dst) { 242 | DwVec3.sub_ref(a, b, dst); 243 | DwVec3.normalize_ref_slf(dst); 244 | }; 245 | 246 | DwVec3.dir_unit_new = function (a, b) { 247 | var dst = []; 248 | DwVec3.sub_ref(a, b, dst); 249 | DwVec3.normalize_ref_slf(dst); 250 | return dst; 251 | }; 252 | 253 | 254 | 255 | DwVec3.lerp_ref = function (a, b, val, dst) { 256 | dst[0] = a[0] + val * (b[0] - a[0]); 257 | dst[1] = a[1] + val * (b[1] - a[1]); 258 | dst[2] = a[2] + val * (b[2] - a[2]); 259 | }; 260 | 261 | DwVec3.lerp_new = function (a, b, val) { 262 | return [a[0]+val*(b[0]-a[0]), a[1]+val*(b[1]-a[1]), a[2]+val*(b[2]-a[2])]; 263 | }; 264 | 265 | 266 | DwVec3.dist = function (a, b) { 267 | var dst = DwVec3.sub_new(a, b); 268 | return DwVec3.mag(dst); 269 | }; 270 | 271 | 272 | 273 | DwVec3.toStr = function (a, prec) { 274 | prec = prec || 5; 275 | return "["+a[0].toFixed(prec)+", "+a[1].toFixed(prec)+", "+a[2].toFixed(prec)+"]"; 276 | }; 277 | 278 | 279 | DwVec3.toIntStr = function (a) { 280 | return "["+a[0]+", "+a[1]+", "+a[2]+"]"; 281 | }; 282 | 283 | 284 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/math/DwVec4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 25.02.12 5 | */ 6 | 7 | 8 | 9 | var DwVec4 = DwVec4 || {}; 10 | 11 | 12 | 13 | DwVec4.nullvector = function () { 14 | return [0, 0, 0, 0]; 15 | } 16 | 17 | 18 | DwVec4.copy_ref = function (a, dst) { 19 | dst[0] = a[0]; 20 | dst[1] = a[1]; 21 | dst[2] = a[2]; 22 | dst[3] = a[3]; 23 | }; 24 | 25 | DwVec4.copy_new = function (a) { 26 | return [a[0], a[1], a[2], a[3]]; 27 | }; 28 | 29 | 30 | DwVec4.equals = function (a, b) { 31 | return (a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]); 32 | }; 33 | 34 | 35 | 36 | 37 | 38 | 39 | //DwVec3.add_ref = function (a, b, dst) { 40 | // dst[0] = a[0]+b[0]; dst[1] = a[1]+b[1]; dst[2] = a[2]+b[2]; 41 | //}; 42 | //DwVec3.add_new = function (a, b) { 43 | // return [(a[0]+b[0]), (a[1]+b[1]), (a[2]+b[2])]; 44 | //}; 45 | // 46 | // 47 | //DwVec3.sub_ref = function (a, b, dst) { 48 | // dst[0] = a[0]-b[0]; dst[1] = a[1]-b[1]; dst[2] = a[2]-b[2]; 49 | //}; 50 | //DwVec3.sub_new = function (a, b) { 51 | // return [(a[0]-b[0]), (a[1]-b[1]), (a[2]-b[2])]; 52 | //}; 53 | // 54 | // 55 | //DwVec3.line_midpoint_ref = function (a, b, dst) { 56 | // dst[0] = (a[0] + b[0]) * 0.5; 57 | // dst[1] = (a[1] + b[1]) * 0.5; 58 | // dst[2] = (a[2] + b[2]) * 0.5; 59 | //}; 60 | //DwVec3.line_midpoint_new = function (a, b) { 61 | // return [(a[0]+b[0])*0.5, (a[1]+b[1])*0.5, (a[2]+b[2])*0.5]; 62 | //}; 63 | // 64 | //DwVec3.triangle_midpoint_ref = function (a, b, c, dst) { 65 | // var f = 1/3; 66 | // dst[0] = (a[0]+b[0]+c[0]) * f; 67 | // dst[1] = (a[1]+b[1]+c[1]) * f; 68 | // dst[2] = (a[2]+b[2]+c[2]) * f; 69 | //}; 70 | //DwVec3.triangle_midpoint_new = function (a, b, c) { 71 | // var f = 1/3; 72 | // return [(a[0]+b[0]+c[0]) * f, (a[1]+b[1]+c[1]) * f, (a[2]+b[2]+c[2]) * f]; 73 | //}; 74 | // 75 | // 76 | //DwVec3.sum_ref = function(a, b, c, dst){ 77 | // dst[0] = a[0]+b[0]+c[0]; 78 | // dst[1] = a[1]+b[1]+c[1]; 79 | // dst[2] = a[2]+b[2]+c[2]; 80 | //} 81 | //DwVec3.sum_new = function(a, b, c){ 82 | // return [a[0]+b[0]+c[0], a[1]+b[1]+c[1], a[2]+b[2]+c[2]]; 83 | //} 84 | // 85 | // 86 | //DwVec3.sumlist_ref = function(arr, dst){ 87 | // var len = arr.length; 88 | // for(var i = 0; i < len; i++){ 89 | // dst[0] += arr[i][0]; 90 | // dst[1] += arr[i][1]; 91 | // dst[2] += arr[i][2]; 92 | // } 93 | //} 94 | // 95 | //DwVec3.sumlist_new = function(arr){ 96 | // var dst = []; 97 | // var len = arr.length; 98 | // for(var i = 0; i < len; i++){ 99 | // dst[0] += arr[i][0]; 100 | // dst[1] += arr[i][1]; 101 | // dst[2] += arr[i][2]; 102 | // } 103 | // return dst; 104 | //} 105 | // 106 | // 107 | // 108 | // 109 | // 110 | // 111 | DwVec4.multiply_ref = function (a, b, dst) { 112 | dst[0] = a[0] * b[0]; 113 | dst[1] = a[1] * b[1]; 114 | dst[2] = a[2] * b[2]; 115 | dst[3] = a[3] * b[3]; 116 | }; 117 | DwVec4.multiply_new = function (a, b) { 118 | return [a[0]*b[0], a[1]*b[1], a[2]*b[2], a[3]*b[3]]; 119 | }; 120 | 121 | 122 | 123 | 124 | //DwVec3.negate_ref = function (a, dst) { 125 | // dst[0] = -a[0]; 126 | // dst[1] = -a[1]; 127 | // dst[2] = -a[2]; 128 | //}; 129 | //DwVec3.negate_ref_slf = function (a) { 130 | // a[0] = -a[0]; 131 | // a[1] = -a[1]; 132 | // a[2] = -a[2]; 133 | //}; 134 | //DwVec3.negate_new = function (a) { 135 | // return [-a[0], -a[1], -a[2]]; 136 | //}; 137 | // 138 | // 139 | // 140 | //DwVec3.scale_ref = function (a, val, dst) { 141 | // dst[0] = a[0] * val; 142 | // dst[1] = a[1] * val; 143 | // dst[2] = a[2] * val; 144 | //}; 145 | //DwVec3.scale_ref_slf = function (a, val) { 146 | // a[0] *= val; 147 | // a[1] *= val; 148 | // a[2] *= val; 149 | //}; 150 | //DwVec3.scale_new = function (a, val) { 151 | // return [a[0] * val, a[1] * val, a[2] * val]; 152 | //}; 153 | // 154 | // 155 | // 156 | //DwVec3.normalize_ref_slf = function (a) { 157 | // var x = a[0], y = a[1], z = a[2]; 158 | // var len = Math.sqrt(x*x + y*y + z*z); 159 | // 160 | // if (len != 1) { 161 | // len = 1 / len; 162 | // a[0] *= len; 163 | // a[1] *= len; 164 | // a[2] *= len; 165 | // } 166 | //}; 167 | //DwVec3.normalize_ref = function (a, dst) { 168 | // var x = a[0], y = a[1], z = a[2]; 169 | // var len = Math.sqrt(x * x + y * y + z * z); 170 | // 171 | // if (!len) { 172 | // dst[0] = 0; 173 | // dst[1] = 0; 174 | // dst[2] = 0; 175 | // } else if (len === 1) { 176 | // dst[0] = x; 177 | // dst[1] = y; 178 | // dst[2] = z; 179 | // } else { 180 | // len = 1 / len; 181 | // dst[0] = x * len; 182 | // dst[1] = y * len; 183 | // dst[2] = z * len; 184 | // } 185 | //}; 186 | //DwVec3.normalize_new = function (a) { 187 | // var x = a[0], y = a[1], z = a[2]; 188 | // var len = Math.sqrt(x * x + y * y + z * z); 189 | // 190 | // if (!len) { 191 | // return [0, 0, 0]; 192 | // } else if (len === 1) { 193 | // return [x, y, z]; 194 | // } else { 195 | // return [x*len, y*len, z*len]; 196 | // } 197 | //}; 198 | // 199 | // 200 | //DwVec3.cross_ref = function (a, b, dst) { 201 | // var ax = a[0], ay = a[1], az = a[2]; 202 | // var bx = b[0], by = b[1], bz = b[2]; 203 | // 204 | // dst[0] = ay * bz - az * by; 205 | // dst[1] = az * bx - ax * bz; 206 | // dst[2] = ax * by - ay * bx; 207 | //}; 208 | //DwVec3.cross_new = function (a, b) { 209 | // var ax = a[0], ay = a[1], az = a[2]; 210 | // var bx = b[0], by = b[1], bz = b[2]; 211 | // 212 | // return [ay*bz - az*by, az*bx - ax*bz, ax*by - ay*bx]; 213 | //}; 214 | // 215 | // 216 | // 217 | //DwVec3.dot = function (a, b) { 218 | // return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; 219 | //}; 220 | // 221 | // 222 | // 223 | //DwVec3.angleBetween = function(a, b){ 224 | // return Math.acos( DwVec3.dot(a,b)/(DwVec3.mag(a)*DwVec3.mag(b)) ); 225 | //} 226 | //DwVec3.angleBetween_unit = function(a, b){ 227 | // return Math.acos( DwVec3.dot(a,b) ); 228 | //} 229 | // 230 | // 231 | // 232 | //DwVec3.mag = function (a) { 233 | // var x = a[0], y = a[1], z = a[2]; 234 | // return Math.sqrt(x*x + y*y + z*z); 235 | //}; 236 | //DwVec3.mag_sq = function (a) { 237 | // var x = a[0], y = a[1], z = a[2]; 238 | // return x*x + y*y + z*z; 239 | //}; 240 | // 241 | // 242 | // 243 | // 244 | // 245 | // 246 | // 247 | //DwVec3.dir_unit_ref = function (a, b, dst) { 248 | // DwVec3.sub_ref(a, b, dst); 249 | // DwVec3.normalize_ref_slf(dst); 250 | //}; 251 | // 252 | //DwVec3.dir_unit_new = function (a, b) { 253 | // var dst = []; 254 | // DwVec3.sub_ref(a, b, dst); 255 | // DwVec3.normalize_ref_slf(dst); 256 | // return dst; 257 | //}; 258 | // 259 | // 260 | // 261 | //DwVec3.lerp_ref = function (a, b, val, dst) { 262 | // dst[0] = a[0] + val * (b[0] - a[0]); 263 | // dst[1] = a[1] + val * (b[1] - a[1]); 264 | // dst[2] = a[2] + val * (b[2] - a[2]); 265 | //}; 266 | // 267 | //DwVec3.lerp_new = function (a, b, val) { 268 | // return [a[0]+val*(b[0]-a[0]), a[1]+val*(b[1]-a[1]), a[2]+val*(b[2]-a[2])]; 269 | //}; 270 | // 271 | // 272 | //DwVec3.dist = function (a, b) { 273 | // var dst = DwVec3.sub_new(a, b); 274 | // return DwVec3.mag(dst); 275 | //}; 276 | // 277 | // 278 | // 279 | //DwVec3.toStr = function (a, prec) { 280 | // prec = prec || 5; 281 | // return "["+a[0].toFixed(prec)+", "+a[1].toFixed(prec)+", "+a[2].toFixed(prec)+"]"; 282 | //}; 283 | // 284 | // 285 | //DwVec3.toIntStr = function (a) { 286 | // return "["+a[0]+", "+a[1]+", "+a[2]+"]"; 287 | //}; 288 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/utilitys/Byter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 15.02.12 5 | */ 6 | 7 | 8 | function Byter(arraybuffer){ 9 | 10 | this.buffer_is_valid = (arraybuffer instanceof ArrayBuffer); 11 | 12 | if( !this.buffer_is_valid){ 13 | var err = "ERROR (Byter.js): praram \"data\" of wrong type ("+( typeof arraybuffer)+"), MUST be of type \"ArrayBuffer\"" 14 | console.log(err); 15 | alert(err); 16 | } 17 | 18 | this.bytearray = arraybuffer; // type of arrayBuffer 19 | 20 | this.BIG_ENDIAN = 1; 21 | this.LITTLE_ENDIAN = 2; 22 | 23 | this.idx = 0; 24 | this.total_size = this.bytearray.byteLength; 25 | 26 | this.byte_reading_counter = 0; 27 | this.byte_writing_counter = 0; 28 | 29 | this.byte_order = this.BIG_ENDIAN; 30 | 31 | } 32 | 33 | Byter.prototype.isValid = function(){ 34 | return this.buffer_is_valid; 35 | } 36 | 37 | Byter.prototype.getBytes = function(){ 38 | return this.bytearray; 39 | } 40 | 41 | 42 | Byter.prototype.getFloat32Value = function(offset){ 43 | return this.getFloat32Array(offset, 1)[0]; 44 | } 45 | 46 | Byter.prototype.getFloat32Array = function(offset, number_of_elements){ 47 | this.idx += offset; 48 | var values = new Float32Array (this.bytearray, this.idx, number_of_elements); 49 | 50 | var number_of_bytes = Float32Array.BYTES_PER_ELEMENT*number_of_elements; 51 | this.idx += number_of_bytes; 52 | this.byte_reading_counter+= number_of_bytes; 53 | return values; // returns Float32Array 54 | } 55 | 56 | 57 | Byter.prototype.getInt32Value = function(offset) { 58 | return this.getInt32Array(offset, 1)[0]; 59 | } 60 | Byter.prototype.getInt32Array = function(offset, number_of_elements) { 61 | this.idx += offset; 62 | var values = new Int32Array (this.bytearray, this.idx, number_of_elements); 63 | 64 | var number_of_bytes = Int32Array.BYTES_PER_ELEMENT*number_of_elements; 65 | this.idx += number_of_bytes; 66 | this.byte_reading_counter+= number_of_bytes; 67 | return values; // returns Int32Array 68 | } 69 | 70 | 71 | Byter.prototype.getInt16Value = function(offset) { 72 | return this.getInt16Array(offset, 1)[0]; 73 | } 74 | Byter.prototype.getInt16Array = function(offset, number_of_elements) { 75 | this.idx += offset; 76 | var values = new Int16Array (this.bytearray, this.idx, number_of_elements); 77 | 78 | var number_of_bytes = Int16Array.BYTES_PER_ELEMENT*number_of_elements; 79 | this.idx += number_of_bytes; 80 | this.byte_reading_counter+= number_of_bytes; 81 | return values; // returns Int16Array 82 | } 83 | 84 | Byter.prototype.getUint16Value = function(offset) { 85 | return this.getUint16Array(offset, 1)[0]; 86 | } 87 | Byter.prototype.getUint16Array = function(offset, number_of_elements) { 88 | this.idx += offset; 89 | 90 | var values = new Uint16Array(this.bytearray, this.idx, number_of_elements); 91 | 92 | var number_of_bytes = Uint16Array.BYTES_PER_ELEMENT*number_of_elements; 93 | this.idx += number_of_bytes; 94 | this.byte_reading_counter+= number_of_bytes; 95 | return values; // returns Uint16Array 96 | } 97 | 98 | 99 | 100 | 101 | Byter.prototype.getInt8Value = function(offset) { 102 | return this.getInt8Array(offset, 1)[0]; 103 | } 104 | Byter.prototype.getInt8Array = function(offset, number_of_elements) { 105 | this.idx += offset; 106 | var values = new Int8Array (this.bytearray, this.idx, number_of_elements); 107 | 108 | var number_of_bytes = Int8Array.BYTES_PER_ELEMENT*number_of_elements; 109 | this.idx += number_of_bytes; 110 | this.byte_reading_counter+= number_of_bytes; 111 | return values; // returns Int8Array 112 | } 113 | 114 | Byter.prototype.getUint8Value = function(offset) { 115 | return this.getUint8Array(offset, 1)[0]; 116 | } 117 | Byter.prototype.getUint8Array = function(offset, number_of_elements) { 118 | this.idx += offset; 119 | var values = new Uint8Array (this.bytearray, this.idx, number_of_elements); 120 | 121 | var number_of_bytes = Uint8Array.BYTES_PER_ELEMENT*number_of_elements; 122 | this.idx += number_of_bytes; 123 | this.byte_reading_counter+= number_of_bytes; 124 | return values; // returns Uint8Array 125 | } 126 | 127 | 128 | 129 | Byter.prototype.getString = function(offset, number_of_elements, lastchar) { 130 | var chars = this.getUint8Array(offset, number_of_elements); 131 | var str = this.conv_byteArray_to_string(chars); 132 | if( lastchar ){ 133 | var idx = str.indexOf("\0"); 134 | if( idx >= 0){ 135 | str = str.substring(0, idx); 136 | } 137 | } 138 | return str; 139 | } 140 | 141 | 142 | 143 | /* 144 | MAGIC 145 | http://stackoverflow.com/questions/1240408/reading-bytes-from-a-javascript-string 146 | http://stackoverflow.com/questions/3195865/javascript-html-converting-byte-array-to-string 147 | http://stackoverflow.com/questions/6965107/converting-between-strings-and-arraybuffers 148 | */ 149 | Byter.prototype.conv_byteArray_to_intArray = function(byte_array){ 150 | var len = byte_array.length; 151 | var int_array = new Array(byte_array.length); 152 | for (var i = 0; i < len; i++){ 153 | int_array[i] = byte_array[i]; 154 | } 155 | return int_array; // = int/ascii array 156 | } 157 | Byter.prototype.conv_intArray_to_string = function(int_array){ 158 | return String.fromCharCode.apply(String, int_array); 159 | } 160 | Byter.prototype.conv_byteArray_to_string = function(byte_array){ 161 | return String.fromCharCode.apply(String, this.conv_byteArray_to_intArray(byte_array)); 162 | } 163 | 164 | 165 | //Byter.prototype.getInteger3 = function(offset, number_of_elements) { 166 | // number_of_elements *= 3; 167 | // this.idx += offset; 168 | // var values = new Int32Array (this.data, idx, number_of_elements); 169 | // 170 | // var number_of_bytes = Int32Array.BYTES_PER_ELEMENT*number_of_elements; 171 | // this.idx += number_of_bytes; 172 | // this.byte_reading_counter+= number_of_bytes; 173 | // return values; // returns Int32Array [a0, a1, a2, b0, b1, b2, ...] 174 | //} 175 | 176 | 177 | 178 | Byter.prototype.forward = function(offset){ 179 | this.idx += offset; 180 | return this; 181 | } 182 | Byter.prototype.backward = function(offset){ 183 | this.idx -= offset; 184 | return this; 185 | } 186 | 187 | Byter.prototype.available = function(){ 188 | return this.total_size - this.idx; 189 | } 190 | Byter.prototype.totalSize = function(){ 191 | return this.total_size; 192 | } 193 | 194 | 195 | Byter.prototype.getPos = function(){ 196 | return this.idx; 197 | } 198 | Byter.prototype.setPos = function(newpos){ 199 | this.idx = newpos; 200 | } 201 | //conversion 202 | // public static final long convert_UInteger2Long(int v){ 203 | // return v & 0xffffffffL; 204 | // } 205 | // 206 | // public static final int convert_UShort2Integer(short v){ 207 | // return v & 0xffff; 208 | // } 209 | 210 | 211 | 212 | 213 | Byter.loadBinaryFile = function(filename, callback){ 214 | var oXHR = new XMLHttpRequest(); 215 | oXHR.open("GET", filename, true); 216 | oXHR.responseType = "arraybuffer"; 217 | // console.log("___oXHR = "+oXHR); 218 | 219 | oXHR.onload = function (oEvent) { 220 | var arrayBuffer = oXHR.response; // Note: not oXHR.responseText 221 | // console.log("___arrayBuffer = "+arrayBuffer); 222 | // console.log("___typeof arrayBuffer = "+(typeof arrayBuffer)); 223 | if (arrayBuffer) { 224 | // console.log("___arrayBuffer.length = "+arrayBuffer.byteLength); 225 | // loadMD3(filename, arrayBuffer); 226 | callback(filename, arrayBuffer); 227 | } 228 | }; 229 | oXHR.send(null); 230 | } 231 | 232 | 233 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/PixelVoronoi_KdTree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * author: thomas diewald 3 | * date: 16.03.13 4 | * 5 | * creating the distance map. 6 | */ 7 | 8 | 9 | 10 | function PixelVoronoi_KdTree(CTX, kdtree) { 11 | 12 | this.CTX = CTX; 13 | this.kdtree = kdtree; 14 | 15 | this.tex_size = []; 16 | this.num_nodes = 0; 17 | 18 | var gl = this.CTX.gl; 19 | 20 | this.shader_dis; 21 | this.HANDLE_shader_dis; 22 | 23 | this.loadShaderDis(); 24 | 25 | this.HANDLE_vbo_screen = gl.createBuffer(); 26 | // this.HANDLE_tex_kdtree = gl.createTexture(); 27 | 28 | // console.log("HANDLE_vbo_screen = "+ this.HANDLE_vbo_screen); 29 | // console.log("HANDLE_tex_kdtree = "+ this.HANDLE_tex_kdtree); 30 | 31 | // gl.bindTexture ( gl.TEXTURE_2D, this.HANDLE_tex_kdtree); 32 | // { 33 | // gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 34 | // gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 35 | // gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ) ; 36 | // gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE ) ; 37 | // } 38 | // gl.bindTexture ( gl.TEXTURE_2D, null); 39 | 40 | 41 | 42 | 43 | this.fbo = new FBO(CTX); 44 | this.screenquad = new ScreenQuad(CTX); 45 | this.screenquad.loadShader(); 46 | 47 | // weird thing: different values on the same system 48 | // firefox ... 16384 49 | // chrom ... 8192 50 | this.GL_MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE); 51 | // console.log("GL_MAX_TEXTURE_SIZE = "+ this.GL_MAX_TEXTURE_SIZE); 52 | 53 | } 54 | 55 | 56 | 57 | 58 | PixelVoronoi_KdTree.prototype.loadShaderDis = function(){ 59 | var gl = this.CTX.gl; 60 | var _this = this; 61 | 62 | var vert_shader = "SHADERS/PixelVoronoiKdTree_vert.glsl"; 63 | var frag_shader = "SHADERS/PixelVoronoiKdTree_frag.glsl"; 64 | 65 | _this.shader_dis = new DwShader(gl, "", vert_shader, frag_shader); 66 | _this.shader_dis.onload = function(){ 67 | // console.log("... LOADING SHADER"); 68 | _this.saveShaderDisLocations(); 69 | _this.createDistanceMap(); 70 | } 71 | _this.shader_dis.load(null); 72 | } 73 | 74 | 75 | 76 | 77 | 78 | PixelVoronoi_KdTree.prototype.saveShaderDisLocations = function(){ 79 | var gl = this.CTX.gl; 80 | 81 | this.HANDLE_shader_dis = this.shader_dis.HANDLE_program; 82 | // console.log("... SAVE SHADER LOCATIONS "+this.HANDLE_shader_dis); 83 | gl.useProgram(this.HANDLE_shader_dis); 84 | { 85 | this.IN_VEC2_POSITION = gl.getAttribLocation (this.HANDLE_shader_dis, "IN_VEC2_POSITION" ); 86 | this.IN_VEC2_ST = gl.getAttribLocation (this.HANDLE_shader_dis, "IN_VEC2_ST" ); 87 | this.UN_SAMP_KDTREE = gl.getUniformLocation(this.HANDLE_shader_dis, "UN_SAMP_KDTREE" ); 88 | this.UN_SAMP_KDTREE_SIZE = gl.getUniformLocation(this.HANDLE_shader_dis, "UN_SAMP_KDTREE_SIZE"); 89 | } 90 | gl.useProgram(null); 91 | 92 | 93 | // console.log("IN_VEC2_POSITION = "+this.IN_VEC2_POSITION ); 94 | // console.log("IN_VEC2_ST = "+this.IN_VEC2_ST ); 95 | // console.log("UN_SAMP_KDTREE = "+this.UN_SAMP_KDTREE ); 96 | // console.log("UN_SAMP_KDTREE_SIZE = "+this.UN_SAMP_KDTREE_SIZE ); 97 | } 98 | 99 | 100 | 101 | 102 | 103 | PixelVoronoi_KdTree.prototype.delete = function(){ 104 | var gl = this.CTX.gl; 105 | gl.deleteTexture(this.HANDLE_tex_kdtree); this.HANDLE_tex_kdtree = null; 106 | gl.deleteBuffer (this.HANDLE_vbo_screen); this.HANDLE_vbo_screen = null; 107 | this.shader_dis.delete(); this.HANDLE_shader_dis = null; 108 | 109 | this.fbo.delete(); 110 | this.screenquad.delete(); 111 | } 112 | 113 | 114 | 115 | 116 | PixelVoronoi_KdTree.prototype.resize = function(scale){ 117 | var gl = this.CTX.gl; 118 | var w = this.CTX.VIEWPORT.width; 119 | var h = this.CTX.VIEWPORT.height; 120 | // console.log("resizing voronoi "+w+", "+h); 121 | 122 | // SCREEN QUAD (height is mirrored!) 123 | var screenquad = new Float32Array( [ -1, -1, 0, h, // x,y, s,t ... no matrix needed 124 | -1, +1, 0, 0, 125 | +1, -1, w, h, 126 | +1, +1, w, 0 ]); 127 | 128 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo_screen); 129 | gl.bufferData(gl.ARRAY_BUFFER, screenquad, gl.STATIC_DRAW); 130 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 131 | 132 | this.fbo.resize(w, h, scale); 133 | } 134 | 135 | 136 | PixelVoronoi_KdTree.prototype.setKdTreeTexture = function(){ 137 | 138 | // TODO i'm not sure if resizing textures is causing a memory-leak! 139 | 140 | var gl = this.CTX.gl; 141 | 142 | this.num_nodes = this.kdtree.kd_tree.length; 143 | var tex_w = Math.min(Math.max(this.num_nodes,1), this.GL_MAX_TEXTURE_SIZE); 144 | var tex_h = Math.floor((this.num_nodes+tex_w-1)/tex_w); 145 | var tex_size_new = new Float32Array([tex_w, tex_h]); 146 | 147 | if( this.tex_size[0] != tex_size_new[0] || 148 | this.tex_size[1] != tex_size_new[1]) 149 | { 150 | gl.deleteTexture(this.HANDLE_tex_kdtree); 151 | this.HANDLE_tex_kdtree = gl.createTexture(); 152 | } 153 | 154 | 155 | var w = this.tex_size[0] = tex_size_new[0]; 156 | var h = this.tex_size[1] = tex_size_new[1]; 157 | var tex_data = this.kdtree.uint8Array; 158 | 159 | gl.bindTexture ( gl.TEXTURE_2D, this.HANDLE_tex_kdtree); 160 | { 161 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 162 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 163 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ) ; 164 | gl.texParameteri ( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE ) ; 165 | gl.texImage2D ( gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex_data ); 166 | } 167 | gl.bindTexture ( gl.TEXTURE_2D, null); 168 | 169 | } 170 | 171 | 172 | 173 | PixelVoronoi_KdTree.prototype.createDistanceMap = function(){ 174 | 175 | if( this.IN_VEC2_POSITION==undefined){ 176 | return; 177 | } 178 | 179 | var gl = this.CTX.gl; 180 | 181 | // this.num_nodes = this.kdtree.kd_tree.length; 182 | // var tex_w = Math.min(Math.max(this.num_nodes,1), this.GL_MAX_TEXTURE_SIZE); 183 | // var tex_h = Math.floor((this.num_nodes+tex_w-1)/tex_w); 184 | // this.tex_size = new Float32Array([tex_w, tex_h]); 185 | 186 | this.setKdTreeTexture(); 187 | 188 | this.fbo.bind(); 189 | 190 | gl.useProgram(this.HANDLE_shader_dis); 191 | { 192 | // set kdtree texture 193 | gl.activeTexture(gl.TEXTURE0); 194 | gl.bindTexture (gl.TEXTURE_2D, this.HANDLE_tex_kdtree ); 195 | gl.uniform1i (this.UN_SAMP_KDTREE, 0); 196 | // apply kd-tree to texture 197 | // gl.texImage2D ( gl.TEXTURE_2D, 0, gl.RGBA, tex_w, tex_h, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.kdtree.uint8Array ); 198 | 199 | gl.uniform2fv( this.UN_SAMP_KDTREE_SIZE, this.tex_size ); 200 | gl.uniform1i ( this.UN_SAMP_NUM_KDTREENODES, this.num_nodes); 201 | 202 | gl.bindBuffer(gl.ARRAY_BUFFER, this.HANDLE_vbo_screen); 203 | gl.vertexAttribPointer(this.IN_VEC2_POSITION, 2, gl.FLOAT, false, 16, 0 ); 204 | gl.vertexAttribPointer(this.IN_VEC2_ST, 2, gl.FLOAT, false, 16, 8 ); 205 | 206 | gl.enableVertexAttribArray(this.IN_VEC2_POSITION ); 207 | gl.enableVertexAttribArray(this.IN_VEC2_ST ); 208 | 209 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4 ); 210 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 211 | 212 | gl.activeTexture(gl.TEXTURE0); 213 | gl.bindTexture (gl.TEXTURE_2D, null ); 214 | 215 | gl.flush(); 216 | } 217 | gl.useProgram(null); 218 | 219 | this.fbo.unbind(); 220 | } 221 | 222 | 223 | PixelVoronoi_KdTree.prototype.render = function(invert){ 224 | this.screenquad.render(this.fbo.HANDLE_texture, invert, this.kdtree.points.length); 225 | } 226 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/SHADERS/PixelVoronoiKdTree_frag.glsl: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // author: thomas diewald 4 | // web: http://thomasdiewald.com 5 | // date: 22.03.2013 6 | // 7 | // WebGL vertex shader: "PixelVoronoiKdTree_frag.glsl" 8 | // for creating a pixel-based voronoi diagram. 9 | // distance to nearest neighbor affects pixel-shading. 10 | // nearest neighbor search is done by traversing a kd-tree. 11 | // the output of this shader is a "distance-map" saved to the alpha-channel. 12 | // 13 | // note: the OpenGL version is much faster and also much simpler! 14 | // webgl has a view annoying restrictions: 15 | // loops: no while loop, all and everything must be constant 16 | // arrays: only accessed by constants 17 | // vector components: access only per constant 18 | // no bitwise operators 19 | // precision highp int is limited from -2^16 to 2^16 20 | // chrome: it seems, that chrome needs more time than firefox to load (or verify??) a shader. 21 | // 22 | // ... and so on ... 23 | // 24 | // something to remember: using uniforms as buffers offers much more 25 | // flexibility and is a lot faster, than using textures. But since uniforms are 26 | // very limited in size, this only works for a small number of points. 27 | // 28 | // update: arithemtic expressions are used instead if bitwise-ops. 29 | // index-pointer-based iterative nearest-neighbor-search 30 | // 31 | //------------------------------------------------------------------------------ 32 | 33 | precision mediump float; 34 | precision highp int; 35 | 36 | // Bit-Shifting 37 | #define SHIFT_15 0x8000 38 | #define SHIFT_08 0x0100 39 | #define SHIFT_01 0x0002 40 | 41 | // RS_XX= Right Shift by XX, LS_XX = Left shift by XX 42 | #define RS_15(i) ( (i) / SHIFT_15 ) 43 | #define LS_15(i) ( (i) * SHIFT_15 ) 44 | #define RS_08(i) ( (i) / SHIFT_08 ) 45 | #define LS_08(i) ( (i) * SHIFT_08 ) 46 | #define RS_01(i) ( (i) / SHIFT_01 ) 47 | #define LS_01(i) ( (i) * SHIFT_01 ) 48 | 49 | // node index pointer 50 | #define P(i) ( RS_01(i) ) // parent node 51 | #define L(i) ( LS_01(i) ) // left child 52 | #define R(i) ( LS_01(i)+1 ) // right child 53 | 54 | #define POINT_PREC 0.1 // for scale point coords 55 | 56 | 57 | 58 | varying vec2 VRY_VEC2_ST; // fragment position, unnormalized 59 | 60 | uniform sampler2D UN_SAMP_KDTREE; 61 | uniform vec2 UN_SAMP_KDTREE_SIZE; 62 | 63 | vec2 VEC2_KDTREE_SIZE_INV = 1.0 / (UN_SAMP_KDTREE_SIZE); // precompute textcoord scaling 64 | int tex_kdtree_width = int(UN_SAMP_KDTREE_SIZE.x); // integer-size for texture look up (to get texture row) 65 | 66 | struct Node{ // Kd-Tree Node 67 | vec2 pnt; // node point 68 | int leaf, dim; // leaf, split-dimension 69 | }; 70 | 71 | struct NN{ // Nearest Neighbor. (really just "dis" is needed!) 72 | vec2 pnt; // pixel position, unnormalized! 73 | float dis; // init Float.MAX_VALUE; 74 | }; 75 | 76 | 77 | 78 | // Kd-Tree Node - texture look up 79 | void getNode(const int n_idx, inout Node node){ 80 | 81 | // re-create node: encoding of 32bit rgba: 82 | // 83 | // bit-pos 24 16 8 0 84 | // rgba RR GG BB AA 85 | // point_y/dim/point_x/leaf YY DY XX LX ( reversed in .rgba texture ) 86 | // rebuilt(swizzled) version LX XX DY YY ( .abgr ) 87 | 88 | // 1) tex-coords: s,t 89 | int t = n_idx/tex_kdtree_width; 90 | int s = n_idx - t*tex_kdtree_width; 91 | vec2 st = (vec2(s,t)+0.5) * VEC2_KDTREE_SIZE_INV; 92 | 93 | // 2) texture look-up of rgba normalized float values. 94 | // mult with 255 and convert to int, to get original bytes. 95 | // if dot(lx_xx_dy_yy,lx_xx_dy_yy) == 0, then node is "non existing". 96 | ivec4 lx_xx_dy_yy = ivec4(texture2D(UN_SAMP_KDTREE, st).abgr * 255.0); // .abgr !!! 97 | 98 | // 3) shift .rb 8 bytes to the left and merge with .ga 99 | ivec2 lxxx_dyyy = LS_08( lx_xx_dy_yy.rb ) + lx_xx_dy_yy.ga; 100 | 101 | // 4) extract leaf and dim, which both are saved in the last bit. so shift right by 15. 102 | ivec2 ld = RS_15( lxxx_dyyy ); // x=leaf, y=dim 103 | 104 | // 5) subtract leaf/dim bits to get x/y coordinates (still integer and scaled) 105 | ivec2 xy = lxxx_dyyy - LS_15( ld ); 106 | 107 | // 6) apply reconstructed values to the node 108 | node.leaf = ld.x; // 0=inter, 1=leaf, 109 | node.dim = ld.y; // dimension: 0 or 1 (for 2d-tree) 110 | node.pnt = vec2(xy)*POINT_PREC; // convert x/y to float and scale back. 111 | } 112 | 113 | 114 | void updateMinDis(inout NN nn, const Node node){ 115 | nn.dis = min( nn.dis, distance(node.pnt, nn.pnt) ); 116 | } 117 | 118 | float planeDistance(const NN nn, const Node node){ 119 | vec2 d = nn.pnt-node.pnt; 120 | return (node.dim == 0) ? d.x : d.y; // normal distance to plane, in split-dimension 121 | // return mix(d.x, d.y, float(node.dim)); // recommended ?!? 122 | } 123 | 124 | // 125 | // NEAREST NEIGHBOR SEARCH 126 | // 127 | // general algorithm: 128 | // 1) while traversing down, always choose half-space [HS] the point is in 129 | // 2) while traversing back, check if current min distance is greater 130 | // than normal distance to split plane. if so, check the other HS too. 131 | // 132 | // instead of using a stack, i use an index-pointer-based iterating process 133 | // by checking/modifying a bit-mask (... 2^depth) to avoid checking the same 134 | // HS again and again (endless recursion). This is BY FAR! the best solution 135 | // when using GLSL-ES 1.0, in GLSL a stackbased solution is probably better. 136 | void getNearestNeighbor(inout NN nn){ 137 | 138 | Node node; 139 | bool down = true; 140 | int n_idx = 1; // 1 = root 141 | int depth = 1; // current depth (power of 2 --> bit indicates depth) 142 | int dcode = 0; // depth-bits inidicate checked HalfSpaces 143 | 144 | for(int i = 0; i < 500; i++){ // constant loop (GL ES) 145 | 146 | getNode(n_idx, node); // get node from texture 147 | float pd = planeDistance(nn, node); // normal dist to split plane 148 | 149 | if(down){ // if traversing down 150 | if( down = (node.leaf == 0) ){ // if not leaf 151 | depth = LS_01(depth); // incr depth (go down) 152 | n_idx = (pd < 0.0) ? L(n_idx) : R(n_idx); // get child 153 | } else { // else (=leaf) 154 | updateMinDis(nn, node); // update min distance 155 | depth = RS_01(depth); // decr depth (go up now) 156 | n_idx = P(n_idx); // get parent 157 | } 158 | } else { // else (=undwinding) 159 | if(down = ((dcode < depth) && // if not checked yet 160 | (abs(pd) < nn.dis))) // AND overlapping 161 | { // --> check (other) HS 162 | dcode += depth; // set depth-bit 163 | depth = LS_01(depth); // incr depth (go down) 164 | n_idx = (pd < 0.0) ? R(n_idx) : L(n_idx); // get (other) child 165 | } else { // else (=undwinding) 166 | dcode -= (dcode < depth) ? 0 : depth; // clear depth-bit 167 | depth = RS_01(depth); // decr depth (go up) 168 | n_idx = P(n_idx); // get parent 169 | } 170 | } 171 | 172 | if(depth == 0) break; // THIS is the end of the nearest neighbor search. 173 | } 174 | } 175 | 176 | 177 | //------------------------------------------------------------------------------ 178 | // MAIN 179 | //------------------------------------------------------------------------------ 180 | void main(void){ 181 | NN nn = NN(VRY_VEC2_ST, 50000000.0); // init nearest neighbor values 182 | getNearestNeighbor(nn); // kd-tree nearest neighbor search 183 | 184 | gl_FragColor.r = nn.dis; 185 | } 186 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/mersenne-twister.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | I've wrapped Makoto Matsumoto and Takuji Nishimura's code in a namespace 4 | so it's better encapsulated. Now you can have multiple random number generators 5 | and they won't stomp all over eachother's state. 6 | 7 | If you want to use this as a substitute for Math.random(), use the random() 8 | method like so: 9 | 10 | var m = new MersenneTwister(); 11 | var randomNumber = m.random(); 12 | 13 | You can also call the other genrand_{foo}() methods on the instance. 14 | 15 | If you want to use a specific seed in order to get a repeatable random 16 | sequence, pass an integer into the constructor: 17 | 18 | var m = new MersenneTwister(123); 19 | 20 | and that will always produce the same random sequence. 21 | 22 | Sean McCullough (banksean@gmail.com) 23 | */ 24 | 25 | /* 26 | A C-program for MT19937, with initialization improved 2002/1/26. 27 | Coded by Takuji Nishimura and Makoto Matsumoto. 28 | 29 | Before using, initialize the state by using init_genrand(seed) 30 | or init_by_array(init_key, key_length). 31 | 32 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 33 | All rights reserved. 34 | 35 | Redistribution and use in source and binary forms, with or without 36 | modification, are permitted provided that the following conditions 37 | are met: 38 | 39 | 1. Redistributions of source code must retain the above copyright 40 | notice, this list of conditions and the following disclaimer. 41 | 42 | 2. Redistributions in binary form must reproduce the above copyright 43 | notice, this list of conditions and the following disclaimer in the 44 | documentation and/or other materials provided with the distribution. 45 | 46 | 3. The names of its contributors may not be used to endorse or promote 47 | products derived from this software without specific prior written 48 | permission. 49 | 50 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 51 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 52 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 53 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 54 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 55 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 56 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 57 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 58 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 59 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 60 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 | 62 | 63 | Any feedback is very welcome. 64 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html 65 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) 66 | */ 67 | 68 | var MersenneTwister = function(seed) { 69 | if (seed == undefined) { 70 | seed = new Date().getTime(); 71 | } 72 | /* Period parameters */ 73 | this.N = 624; 74 | this.M = 397; 75 | this.MATRIX_A = 0x9908b0df; /* constant vector a */ 76 | this.UPPER_MASK = 0x80000000; /* most significant w-r bits */ 77 | this.LOWER_MASK = 0x7fffffff; /* least significant r bits */ 78 | 79 | this.mt = new Array(this.N); /* the array for the state vector */ 80 | this.mti=this.N+1; /* mti==N+1 means mt[N] is not initialized */ 81 | 82 | this.init_genrand(seed); 83 | } 84 | 85 | /* initializes mt[N] with a seed */ 86 | MersenneTwister.prototype.init_genrand = function(s) { 87 | this.mt[0] = s >>> 0; 88 | for (this.mti=1; this.mti>> 30); 90 | this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) 91 | + this.mti; 92 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ 93 | /* In the previous versions, MSBs of the seed affect */ 94 | /* only MSBs of the array mt[]. */ 95 | /* 2002/01/09 modified by Makoto Matsumoto */ 96 | this.mt[this.mti] >>>= 0; 97 | /* for >32 bit machines */ 98 | } 99 | } 100 | 101 | /* initialize by an array with array-length */ 102 | /* init_key is the array for initializing keys */ 103 | /* key_length is its length */ 104 | /* slight change for C++, 2004/2/26 */ 105 | MersenneTwister.prototype.init_by_array = function(init_key, key_length) { 106 | var i, j, k; 107 | this.init_genrand(19650218); 108 | i=1; j=0; 109 | k = (this.N>key_length ? this.N : key_length); 110 | for (; k; k--) { 111 | var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30) 112 | this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) 113 | + init_key[j] + j; /* non linear */ 114 | this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ 115 | i++; j++; 116 | if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; } 117 | if (j>=key_length) j=0; 118 | } 119 | for (k=this.N-1; k; k--) { 120 | var s = this.mt[i-1] ^ (this.mt[i-1] >>> 30); 121 | this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) 122 | - i; /* non linear */ 123 | this.mt[i] >>>= 0; /* for WORDSIZE > 32 machines */ 124 | i++; 125 | if (i>=this.N) { this.mt[0] = this.mt[this.N-1]; i=1; } 126 | } 127 | 128 | this.mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */ 129 | } 130 | 131 | /* generates a random number on [0,0xffffffff]-interval */ 132 | MersenneTwister.prototype.genrand_int32 = function() { 133 | var y; 134 | var mag01 = new Array(0x0, this.MATRIX_A); 135 | /* mag01[x] = x * MATRIX_A for x=0,1 */ 136 | 137 | if (this.mti >= this.N) { /* generate N words at one time */ 138 | var kk; 139 | 140 | if (this.mti == this.N+1) /* if init_genrand() has not been called, */ 141 | this.init_genrand(5489); /* a default initial seed is used */ 142 | 143 | for (kk=0;kk>> 1) ^ mag01[y & 0x1]; 146 | } 147 | for (;kk>> 1) ^ mag01[y & 0x1]; 150 | } 151 | y = (this.mt[this.N-1]&this.UPPER_MASK)|(this.mt[0]&this.LOWER_MASK); 152 | this.mt[this.N-1] = this.mt[this.M-1] ^ (y >>> 1) ^ mag01[y & 0x1]; 153 | 154 | this.mti = 0; 155 | } 156 | 157 | y = this.mt[this.mti++]; 158 | 159 | /* Tempering */ 160 | y ^= (y >>> 11); 161 | y ^= (y << 7) & 0x9d2c5680; 162 | y ^= (y << 15) & 0xefc60000; 163 | y ^= (y >>> 18); 164 | 165 | return y >>> 0; 166 | } 167 | 168 | /* generates a random number on [0,0x7fffffff]-interval */ 169 | MersenneTwister.prototype.genrand_int31 = function() { 170 | return (this.genrand_int32()>>>1); 171 | } 172 | 173 | /* generates a random number on [0,1]-real-interval */ 174 | MersenneTwister.prototype.genrand_real1 = function() { 175 | return this.genrand_int32()*(1.0/4294967295.0); 176 | /* divided by 2^32-1 */ 177 | } 178 | 179 | /* generates a random number on [0,1)-real-interval */ 180 | MersenneTwister.prototype.random = function() { 181 | return this.genrand_int32()*(1.0/4294967296.0); 182 | /* divided by 2^32 */ 183 | } 184 | 185 | /* generates a random number on (0,1)-real-interval */ 186 | MersenneTwister.prototype.genrand_real3 = function() { 187 | return (this.genrand_int32() + 0.5)*(1.0/4294967296.0); 188 | /* divided by 2^32 */ 189 | } 190 | 191 | /* generates a random number on [0,1) with 53-bit resolution*/ 192 | MersenneTwister.prototype.genrand_res53 = function() { 193 | var a=this.genrand_int32()>>>5, b=this.genrand_int32()>>>6; 194 | return(a*67108864.0+b)*(1.0/9007199254740992.0); 195 | } 196 | 197 | /* These real versions are due to Isaku Wada, 2002/01/09 added */ 198 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/math/DwMat3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 09.02.12 5 | */ 6 | 7 | var DwMat3 = DwMat3 || {}; 8 | 9 | 10 | DwMat3.nullmatrix = function(){ 11 | return [0,0,0, 0,0,0, 0,0,0]; 12 | } 13 | 14 | 15 | DwMat3.copy_ref = function(m3, dst) { 16 | dst[0] = m3[0]; dst[3] = m3[3]; dst[6] = m3[6]; 17 | dst[1] = m3[1]; dst[4] = m3[4]; dst[7] = m3[7]; 18 | dst[2] = m3[2]; dst[5] = m3[5]; dst[8] = m3[8]; 19 | }; 20 | DwMat3.copy_new = function(m3) { 21 | return [m3[0], m3[1], m3[2], m3[3], m3[4], m3[5], m3[6], m3[7], m3[8] ]; 22 | }; 23 | 24 | 25 | 26 | DwMat3.identity_ref = function (dst) { 27 | dst[0] = 1; dst[3] = 0; dst[6] = 0; 28 | dst[1] = 0; dst[4] = 1; dst[7] = 0; 29 | dst[2] = 0; dst[5] = 0; dst[8] = 1; 30 | }; 31 | DwMat3.identity_new = function () { 32 | return [1,0,0, 0,1,0, 0,0,1]; 33 | }; 34 | 35 | 36 | 37 | DwMat3.transpose_ref = function (m3, dst) { 38 | dst[0] = m3[0]; dst[3] = m3[1]; dst[6] = m3[2]; 39 | dst[1] = m3[3]; dst[4] = m3[4]; dst[7] = m3[5]; 40 | dst[2] = m3[6]; dst[5] = m3[7]; dst[8] = m3[8]; 41 | }; 42 | 43 | DwMat3.transpose_ref_slf = function (dst) { 44 | var a01 = dst[1], a02 = dst[2], a12 = dst[5]; 45 | dst[1] = dst[3]; 46 | dst[2] = dst[6]; 47 | dst[3] = a01; 48 | dst[5] = dst[7]; 49 | dst[6] = a02; 50 | dst[7] = a12; 51 | }; 52 | 53 | DwMat3.transpose_new = function (m3) { 54 | return [ m3[0], m3[3], m3[6], m3[1], m3[4], m3[7], m3[2], m3[5], m3[8] ]; 55 | }; 56 | 57 | 58 | 59 | 60 | DwMat3.toMat4_ref = function (m3, dst_m4) { 61 | dst_m4[ 0] = m3[0]; dst_m4[ 4] = m3[3]; dst_m4[ 8] = m3[6]; dst_m4[12] = 0; 62 | dst_m4[ 1] = m3[1]; dst_m4[ 5] = m3[4]; dst_m4[ 9] = m3[7]; dst_m4[13] = 0; 63 | dst_m4[ 2] = m3[2]; dst_m4[ 6] = m3[5]; dst_m4[10] = m3[8]; dst_m4[14] = 0; 64 | dst_m4[ 3] = 0; dst_m4[ 7] = 0; dst_m4[11] = 0; dst_m4[15] = 1; 65 | }; 66 | DwMat3.toMat4_new = function (m3) { 67 | return [m3[0], m3[1], m3[2], 0, m3[3], m3[4], m3[5], 0, m3[6], m3[7], m3[8], 0, 0, 0, 0, 1]; 68 | }; 69 | 70 | 71 | DwMat3.getAxisX_ref = function (m3, v3_x) { 72 | v3_x[0] = m3[0]; 73 | v3_x[1] = m3[1]; 74 | v3_x[2] = m3[2]; 75 | }; 76 | DwMat3.getAxisX_new = function (m3) { 77 | return [m3[0], m3[1], m3[2]]; 78 | }; 79 | 80 | 81 | DwMat3.getAxisY_ref = function (m3, v3_y) { 82 | v3_y[0] = m3[3]; 83 | v3_y[1] = m3[4]; 84 | v3_y[2] = m3[5]; 85 | }; 86 | DwMat3.getAxisY_new = function (m3) { 87 | return [m3[3], m3[4], m3[5]]; 88 | }; 89 | 90 | 91 | DwMat3.getAxisZ_ref = function (m3, v3_z) { 92 | v3_z[0] = m3[6]; 93 | v3_z[1] = m3[7]; 94 | v3_z[2] = m3[8]; 95 | }; 96 | DwMat3.getAxisZ_new = function (m3) { 97 | return [m3[6], m3[7], m3[8]]; 98 | }; 99 | 100 | DwMat3.getAisXYZ_ref = function (m3, v3_x, v3_y, v3_z) { 101 | v3_x[0] = m3[0]; v3_y[0] = m3[4]; v3_z[0] = m3[ 8]; 102 | v3_x[1] = m3[1]; v3_y[1] = m3[5]; v3_z[1] = m3[ 9]; 103 | v3_x[2] = m3[2]; v3_y[2] = m3[6]; v3_z[2] = m3[10]; 104 | }; 105 | 106 | 107 | 108 | DwMat3.setAxisX = function (m3, v3_x) { 109 | m3[0] = v3_x[0]; 110 | m3[1] = v3_x[1]; 111 | m3[2] = v3_x[2]; 112 | }; 113 | DwMat3.setAxisY = function (m3, v3_y) { 114 | m3[3] = v3_y[0]; 115 | m3[4] = v3_y[1]; 116 | m3[5] = v3_y[2]; 117 | }; 118 | DwMat3.setAxisZ = function (m3, v3_z) { 119 | m3[6] = v3_z[0]; 120 | m3[7] = v3_z[1]; 121 | m3[8] = v3_z[2]; 122 | }; 123 | DwMat3.setAxisXYZ_ref = function (m3, v3_x, v3_y, v3_z) { 124 | m3[0] = v3_x[0]; m3[3] = v3_y[0]; m3[6] = v3_z[0]; 125 | m3[1] = v3_x[1]; m3[4] = v3_y[1]; m3[7] = v3_z[1]; 126 | m3[2] = v3_x[2]; m3[5] = v3_y[2]; m3[8] = v3_z[2]; 127 | }; 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | DwMat3.inverse_ref = function (m3, dst_m3) { 139 | var 140 | a00 = m3[0], a10 = m3[3], a20 = m3[6], 141 | a01 = m3[1], a11 = m3[4], a21 = m3[7], 142 | a02 = m3[2], a12 = m3[5], a22 = m3[8]; 143 | var 144 | b01 = a22 * a11 - a12 * a21, 145 | b11 = -a22 * a10 + a12 * a20, 146 | b21 = a21 * a10 - a11 * a20; 147 | 148 | var det = a00 * b01 + a01 * b11 + a02 * b21; 149 | 150 | if (!det) 151 | return null; 152 | var det_inv = 1 / det; 153 | 154 | dst_m3[0] = det_inv * ( b01); 155 | dst_m3[1] = det_inv * (-a22 * a01 + a02 * a21); 156 | dst_m3[2] = det_inv * ( a12 * a01 - a02 * a11); 157 | 158 | dst_m3[3] = det_inv * ( b11); 159 | dst_m3[4] = det_inv * ( a22 * a00 - a02 * a20); 160 | dst_m3[5] = det_inv * (-a12 * a00 + a02 * a10); 161 | 162 | dst_m3[6] = det_inv * ( b21) ; 163 | dst_m3[7] = det_inv * (-a21 * a00 + a01 * a20); 164 | dst_m3[8] = det_inv * ( a11 * a00 - a01 * a10); 165 | }; 166 | 167 | DwMat3.inverse_ref_slf = function (m3) { 168 | var 169 | a00 = m3[0], a10 = m3[3], a20 = m3[6], 170 | a01 = m3[1], a11 = m3[4], a21 = m3[7], 171 | a02 = m3[2], a12 = m3[5], a22 = m3[8]; 172 | var 173 | b01 = a22 * a11 - a12 * a21, 174 | b11 = -a22 * a10 + a12 * a20, 175 | b21 = a21 * a10 - a11 * a20; 176 | 177 | var det = a00 * b01 + a01 * b11 + a02 * b21; 178 | 179 | if (!det) 180 | return null; 181 | var det_inv = 1 / det; 182 | 183 | m3[0] = det_inv * ( b01); 184 | m3[1] = det_inv * (-a22 * a01 + a02 * a21); 185 | m3[2] = det_inv * ( a12 * a01 - a02 * a11); 186 | 187 | m3[3] = det_inv * ( b11); 188 | m3[4] = det_inv * ( a22 * a00 - a02 * a20); 189 | m3[5] = det_inv * (-a12 * a00 + a02 * a10); 190 | 191 | m3[6] = det_inv * ( b21) ; 192 | m3[7] = det_inv * (-a21 * a00 + a01 * a20); 193 | m3[8] = det_inv * ( a11 * a00 - a01 * a10); 194 | }; 195 | 196 | 197 | DwMat3.inverse_new = function (m3) { 198 | var dst_m3 = new Array(9); 199 | DwMat3.inverse_ref(m3, dst_m3); 200 | return dst_m3; 201 | }; 202 | 203 | 204 | DwMat3.inverseTranspose_ref = function (m3, dst_m3) { 205 | var 206 | a00 = m3[0], a10 = m3[3], a20 = m3[6], 207 | a01 = m3[1], a11 = m3[4], a21 = m3[7], 208 | a02 = m3[2], a12 = m3[5], a22 = m3[8]; 209 | var 210 | b01 = a22 * a11 - a12 * a21, 211 | b11 = -a22 * a10 + a12 * a20, 212 | b21 = a21 * a10 - a11 * a20; 213 | 214 | var det = a00 * b01 + a01 * b11 + a02 * b21; 215 | 216 | if (!det) 217 | return null; 218 | 219 | var det_inv = 1 / det; 220 | 221 | dst_m3[0] = det_inv * ( b01); 222 | dst_m3[3] = det_inv * (-a22 * a01 + a02 * a21); 223 | dst_m3[6] = det_inv * ( a12 * a01 - a02 * a11); 224 | 225 | dst_m3[1] = det_inv * ( b11); 226 | dst_m3[4] = det_inv * ( a22 * a00 - a02 * a20); 227 | dst_m3[7] = det_inv * (-a12 * a00 + a02 * a10); 228 | 229 | dst_m3[2] = det_inv * ( b21) ; 230 | dst_m3[5] = det_inv * (-a21 * a00 + a01 * a20); 231 | dst_m3[8] = det_inv * ( a11 * a00 - a01 * a10); 232 | }; 233 | DwMat3.inverseTranspose_ref_slf = function (m3) { 234 | var 235 | a00 = m3[0], a10 = m3[3], a20 = m3[6], 236 | a01 = m3[1], a11 = m3[4], a21 = m3[7], 237 | a02 = m3[2], a12 = m3[5], a22 = m3[8]; 238 | var 239 | b01 = a22 * a11 - a12 * a21, 240 | b11 = -a22 * a10 + a12 * a20, 241 | b21 = a21 * a10 - a11 * a20; 242 | 243 | var det = a00 * b01 + a01 * b11 + a02 * b21; 244 | 245 | if (!det) 246 | return null; 247 | 248 | var det_inv = 1 / det; 249 | 250 | m3[0] = det_inv * ( b01); 251 | m3[3] = det_inv * (-a22 * a01 + a02 * a21); 252 | m3[6] = det_inv * ( a12 * a01 - a02 * a11); 253 | 254 | m3[1] = det_inv * ( b11); 255 | m3[4] = det_inv * ( a22 * a00 - a02 * a20); 256 | m3[7] = det_inv * (-a12 * a00 + a02 * a10); 257 | 258 | m3[2] = det_inv * ( b21) ; 259 | m3[5] = det_inv * (-a21 * a00 + a01 * a20); 260 | m3[8] = det_inv * ( a11 * a00 - a01 * a10); 261 | }; 262 | 263 | DwMat3.inverseTranspose_new = function (m3) { 264 | var dst_m3 = new Array(9); 265 | DwMat3.inverseTranspose_ref(m3, dst_m3); 266 | return dst_m3; 267 | }; 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | DwMat3.toStr = function (m3, prec) { 276 | prec = prec || 5; 277 | return ( 278 | "[\n"+ 279 | +m3[0].toFixed(prec)+", "+m3[3].toFixed(prec)+", "+m3[6].toFixed(prec)+",\n"+ 280 | +m3[1].toFixed(prec)+", "+m3[4].toFixed(prec)+", "+m3[7].toFixed(prec)+",\n"+ 281 | +m3[2].toFixed(prec)+", "+m3[5].toFixed(prec)+", "+m3[8].toFixed(prec)+"\n];" 282 | ); 283 | }; 284 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/image/DwImage_TGA.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 19.02.12 5 | */ 6 | 7 | // http://netghost.narod.ru/gff/graphics/summary/tga.htm 8 | //http://netghost.narod.ru/gff/graphics/book/ch09_03.htm#RUEN-CHP-09 9 | 10 | function DwImage_TGA(path, filename ){ 11 | // this.gl = gl; 12 | this.path = path || ""; 13 | this.filename = filename; 14 | this.total_file_path = this.path + this.filename; 15 | if( !this.filename ) 16 | throw new ("(Image_TGA) invalid filename, can't load TGA: "+this.total_file_path); 17 | 18 | this.onload = function(){}; 19 | this.onerror = function(){ 20 | console.log("ERROR while loading TGA-Image: "+this.total_file_path); 21 | }; 22 | } 23 | 24 | DwImage_TGA.prototype.load = function(obj, async){ 25 | var _this = this; 26 | 27 | // make request 28 | var XHR = new XMLHttpRequest(); 29 | XHR.open("GET", this.total_file_path, (async === undefined) || async ); //true=asynchronous 30 | XHR.responseType = "arraybuffer"; 31 | XHR.onload = function (event) { 32 | _this.loadTGA(XHR.response); 33 | _this.onload(); 34 | }; 35 | try{ 36 | XHR.send(obj); // usually null 37 | } catch (exception){ 38 | // console.log(exception); 39 | _this.onerror(); 40 | } 41 | } 42 | 43 | 44 | 45 | DwImage_TGA.prototype.loadTGA = function(arraybuffer){ 46 | var time_start = new Date().getTime(); 47 | 48 | var buf = new Uint8Array(arraybuffer); 49 | var IDX = 0; 50 | this.ID = buf[IDX++]; // 0=no ID, otherwise length of id(0-255 51 | this.col_map_type = buf[IDX++]; // 0=not existing, 1=existing 52 | this.image_type = buf[IDX++]; // 0-11 53 | this.col_map_start = buf[IDX++] | (buf[IDX++] << 8); // 0=standard 54 | this.col_map_len = buf[IDX++] | (buf[IDX++] << 8); // number of colors 55 | this.col_map_depth = buf[IDX++]; // 15,16,24,32 56 | this.x_pos = buf[IDX++] | (buf[IDX++] << 8); // 0=standard 57 | this.y_pos = buf[IDX++] | (buf[IDX++] << 8); // 0=standard 58 | this.width = buf[IDX++] | (buf[IDX++] << 8); // 59 | this.height = buf[IDX++] | (buf[IDX++] << 8); // 60 | this.pixel_depth = buf[IDX++]; // 8, 15,16,24,32 61 | this.pixel_attr = buf[IDX++]; // 62 | 63 | this.pixel_count = this.width*this.height; 64 | 65 | // http://www.khronos.org/registry/webgl/specs/latest/#TEXIMAGE2D 66 | if( this.pixel_depth == 32 ){ 67 | // this.gl_target = this.gl.TEXTURE_2D; 68 | // this.gl_internalformat = this.gl.RGBA; 69 | // this.gl_format = this.gl.RGBA; 70 | // this.gl_type = this.gl.UNSIGNED_BYTE; 71 | this.pixels = new Uint8Array(this.pixel_count * 4); 72 | } 73 | if( this.pixel_depth == 24 ){ 74 | // this.gl_target = this.gl.TEXTURE_2D; 75 | // this.gl_internalformat = this.gl.RGB; 76 | // this.gl_format = this.gl.RGB; 77 | // this.gl_type = this.gl.UNSIGNED_BYTE; 78 | this.pixels = new Uint8Array(this.pixel_count * 3); 79 | } 80 | 81 | // this.log(); 82 | 83 | IDX += this.ID; //skip id-content 84 | if( this.col_map_type == 1 ){ 85 | throw ("TGA_Loader currently not supports color \"color map format\""); 86 | } 87 | 88 | // for(var i = 0; i < 1000; i++){ 89 | switch( this.image_type ){ 90 | case 0: break; //no data 91 | case 1: this.loadColorMap (buf, IDX); break; // color_map_indices, uncompressed 92 | case 2: this.loadTrueColor (buf, IDX); break; // true_color, uncompressed 93 | case 3: this.loadMonochrom (buf, IDX); break; // monochrom/grayscale, uncompressed 94 | case 9: this.loadColorMap_RLE (buf, IDX); break; // color_map_indices, RLE 95 | case 10: this.loadTrueColor_RLE(buf, IDX); break; // true_color,, RLE 96 | case 11: this.loadMonochrom_RLE(buf, IDX); break; // monochrom/grayscale, RLE 97 | } 98 | // } 99 | 100 | if( !true ){ //TODO 101 | throw ("(!CORRPUT FILE!)"); 102 | } else { 103 | var size = buf.length; 104 | this.loading_time = new Date().getTime() - time_start; 105 | // console.log(">>> loaded TGA-File ("+this.loading_time+" ms, "+size+" bytes): \""+this.filename+"\""); 106 | } 107 | } 108 | 109 | 110 | 111 | 112 | 113 | 114 | DwImage_TGA.prototype.loadTrueColor = function(buf, IDX){ 115 | var pixl_idx = 0; 116 | var buff_idx = IDX; 117 | var counter = this.pixel_count; 118 | if( this.pixel_depth == 32 ) { 119 | while(counter-- > 0){ 120 | this.pixels[pixl_idx++] = buf[buff_idx+2]; 121 | this.pixels[pixl_idx++] = buf[buff_idx+1]; 122 | this.pixels[pixl_idx++] = buf[buff_idx ]; 123 | this.pixels[pixl_idx++] = buf[buff_idx+3]; 124 | buff_idx+=4; 125 | } 126 | } else if( this.pixel_depth == 24 ){ 127 | while(counter-- > 0){ 128 | this.pixels[pixl_idx++] = buf[buff_idx+2]; 129 | this.pixels[pixl_idx++] = buf[buff_idx+1]; 130 | this.pixels[pixl_idx++] = buf[buff_idx ]; 131 | buff_idx+=3; 132 | } 133 | } 134 | } 135 | 136 | 137 | 138 | DwImage_TGA.prototype.loadTrueColor_RLE = function(buf, IDX){ 139 | var pixl_idx = 0; 140 | var buff_idx = IDX; 141 | var counter = this.pixel_count; 142 | 143 | if( this.pixel_depth == 32 ) { 144 | while (counter > 0) { 145 | var num = buf[buff_idx++]; 146 | var RLE = (num & 0x80) != 0; 147 | if (RLE) { // compressed 148 | // num -= 127; // (num & 0x7F) + 1 149 | while(num-- > 127 && --counter> 0){ 150 | this.pixels[pixl_idx++] = buf[buff_idx+2]; 151 | this.pixels[pixl_idx++] = buf[buff_idx+1]; 152 | this.pixels[pixl_idx++] = buf[buff_idx ]; 153 | this.pixels[pixl_idx++] = buf[buff_idx+3]; 154 | // --counter; 155 | } 156 | buff_idx+=4; 157 | } else { // uncompressed 158 | while(num-- >= 0 && --counter> 0){ 159 | this.pixels[pixl_idx++] = buf[buff_idx+2]; 160 | this.pixels[pixl_idx++] = buf[buff_idx+1]; 161 | this.pixels[pixl_idx++] = buf[buff_idx ]; 162 | this.pixels[pixl_idx++] = buf[buff_idx+3]; 163 | // --counter; 164 | buff_idx+=4; 165 | } 166 | } 167 | } 168 | } else if( this.pixel_depth == 24 ) { //24 bit 169 | while (counter > 0) { 170 | var num = buf[buff_idx++]; 171 | var RLE = (num & 0x80) != 0; 172 | if (RLE) { // compressed 173 | // num -= 127; // (num & 0x7F) + 1 174 | while(num-- > 127 && --counter> 0){ 175 | this.pixels[pixl_idx++] = buf[buff_idx+2]; 176 | this.pixels[pixl_idx++] = buf[buff_idx+1]; 177 | this.pixels[pixl_idx++] = buf[buff_idx ]; 178 | // --counter; 179 | } 180 | buff_idx+=3; 181 | } else { // uncompressed 182 | while(num-- >= 0 && --counter> 0){ 183 | this.pixels[pixl_idx++] = buf[buff_idx+2]; 184 | this.pixels[pixl_idx++] = buf[buff_idx+1]; 185 | this.pixels[pixl_idx++] = buf[buff_idx ]; 186 | // --counter; 187 | buff_idx+=3; 188 | } 189 | } 190 | } 191 | } 192 | } 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | DwImage_TGA.prototype.loadColorMap = function(buf, IDX){ 201 | throw ("TGA_Loader currently not supports color \"colorMap\""); // TODO 202 | } 203 | DwImage_TGA.prototype.loadColorMap_RLE = function(buf, IDX){ 204 | throw ("TGA_Loader currently not supports color \"colorMap, RLE\""); // TODO 205 | } 206 | 207 | 208 | 209 | DwImage_TGA.prototype.loadMonochrom = function(buf, IDX){ 210 | throw ("TGA_Loader currently not supports color \"monochrom\""); // TODO 211 | } 212 | DwImage_TGA.prototype.loadMonochrom_RLE = function(bufb, IDX){ 213 | throw ("TGA_Loader currently not supports color \"monochrom, RLE\""); // TODO 214 | } 215 | 216 | 217 | 218 | 219 | DwImage_TGA.prototype.log = function(){ 220 | console.log("ID = "+ this.ID ); 221 | console.log("col_map_type = "+ this.col_map_type ); 222 | console.log("image_type = "+ this.image_type ); 223 | console.log("col_map_start = "+ this.col_map_start ); 224 | console.log("col_map_len = "+ this.col_map_len ); 225 | console.log("col_map_depth = "+ this.col_map_depth ); 226 | console.log("x_pos = "+ this.x_pos ); 227 | console.log("y_pos = "+ this.y_pos ); 228 | console.log("width = "+ this.width ); 229 | console.log("height = "+ this.height ); 230 | console.log("pixel_depth = "+ this.pixel_depth ); 231 | console.log("pixel_attr = "+ this.pixel_attr ); 232 | } 233 | 234 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/KdTree.js: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | * author: thomas diewald 4 | * date: 15.03.13 5 | * 6 | * KD-Tree building, debugging, etc. 7 | * 8 | * 9 | */ 10 | 11 | 12 | //-------------------------------------------------------------------------- 13 | // KD-TREE NODE 14 | //-------------------------------------------------------------------------- 15 | // 16 | // Kd-Tree Node Encoding: 32 bit Integer 17 | // 18 | // 24 16 8 0 19 | // 32 bit node: LXXXXXXX XXXXXXXX DYYYYYYY YYYYYYYY 20 | // 21 | // L ... leaf (0, 1) 22 | // D ... dimension (0, 1) ... could also be computet in the shader (on the fly). 23 | // X ... Point.x ( scaled, and converted to int) 24 | // Y ... Point.y ( scaled, and converted to int) 25 | // 26 | // 27 | // nodes are saved in an integer array, having the root node at index 1. 28 | // childs are at the current-index * 2 (...+0=left, ...+1= right). 29 | // the parent node is found at current-index/2. 30 | // due to this tree-storage, some indices contain "no nodes". 31 | // 32 | //-------------------------------------------------------------------------- 33 | // KD-TREE NODE 34 | //-------------------------------------------------------------------------- 35 | 36 | 37 | // node encoding masks 38 | KdTree.BIT_LEAF = 0x80000000; // 31 39 | KdTree.BIT_DIM = 0x00008000; // 15 40 | KdTree.BIT_P_Y = 0x00007FFF; // 0-14 41 | KdTree.BIT_P_X = 0x7FFF0000; // 16-30 42 | 43 | // point-scaling (to keep some precision). !same scaling in shader! 44 | KdTree.PNT_SCALE = 10.0; 45 | 46 | // get node indices for: Parent, Left-child, Right-child 47 | KdTree.GET_P = function(node_idx){ return (node_idx>>1) ; } // parent node_idx 48 | KdTree.GET_L = function(node_idx){ return (node_idx<<1) ; } // left node_idx 49 | KdTree.GET_R = function(node_idx){ return (node_idx<<1)+1; } // right node_idx 50 | 51 | // get node data: leaf, dimension, point.x, point.y 52 | KdTree.IS_LEAF = function(node_val){ return ( node_val&KdTree.BIT_LEAF )>>31; } // last bit! 53 | KdTree.GET_DIM = function(node_val){ return ( node_val&KdTree.BIT_DIM )>>15; } 54 | KdTree.GET_PX = function(node_val){ return ((node_val&KdTree.BIT_P_X )>>16)/KdTree.PNT_SCALE; } 55 | KdTree.GET_PY = function(node_val){ return ((node_val&KdTree.BIT_P_Y )>> 0)/KdTree.PNT_SCALE; } 56 | 57 | 58 | 59 | 60 | function KdTree(){ 61 | 62 | 63 | //-------------------------------------------------------------------------- 64 | // KD-TREE 65 | //-------------------------------------------------------------------------- 66 | this.buffer = 0; // ArrayBuffer 67 | this.kd_tree = 0; // Int32Array: view for saving values 68 | this.uint8Array = 0; // Uint8Array: view for texture-data 69 | 70 | this.max_depth = 0; 71 | 72 | this.points = []; // copy of input points 73 | 74 | this.quick_sort = new Quicksort(); // turned out to be the fastest. 75 | this.quick_select = new QuickSelect(); // turned out to be the fastest. 76 | 77 | this.kd_tree_planes_buffer = 0; 78 | this.kd_tree_planes = 0; 79 | this.BUF_IDX = 0; 80 | } 81 | 82 | KdTree.prototype.delete = function(){ 83 | this.buffer = null; 84 | this.kd_tree = null; 85 | this.uint8Array = null; 86 | this.points = null; 87 | } 88 | 89 | //-------------------------------------------------------------------------- 90 | // BUILD 91 | //-------------------------------------------------------------------------- 92 | 93 | KdTree.prototype.build = function(points, DEBUG){ 94 | 95 | this.points = points.slice(0); // make sure original array doesn't get messed up 96 | 97 | this.initKdTree(points.length); 98 | 99 | // this.buildIterative(this.points); 100 | // this.printTree(); 101 | 102 | // console.log(""); 103 | // this.buildRecursive(1, this.points ); 104 | this.buildRecursiveFast(1, this.points, 0, this.points.length-1 ); 105 | // this.printTree(); 106 | if( DEBUG ){ 107 | this.printTree(); 108 | } 109 | return this; 110 | } 111 | 112 | KdTree.prototype.initKdTree = function(num_points){ 113 | var tmp_max_depth = Math.ceil( Math.log(num_points) / Math.log(2) ); // log2 114 | var tmp_num_nodes = (1 << (tmp_max_depth+1)); 115 | 116 | if( tmp_num_nodes != this.num_nodes || this.kd_tree == null){ 117 | this.max_depth = tmp_max_depth; 118 | this.num_nodes = tmp_num_nodes; 119 | this.buffer = new ArrayBuffer(this.num_nodes*4); 120 | this.kd_tree = new Int32Array(this.buffer); 121 | this.uint8Array = new Uint8Array(this.buffer); 122 | } 123 | 124 | var max = 2; 125 | var depth = 0; 126 | var dim = depth%2; 127 | for(var i = 0; i < this.num_nodes-1; i++){ 128 | if( i == max-1 ){ 129 | max<<=1; 130 | depth++; 131 | dim = (depth%2)<<15; 132 | } 133 | this.kd_tree[i+1] = dim; // setting dim bits ... always the sam 134 | } 135 | } 136 | 137 | 138 | 139 | KdTree.prototype.buildIterative = function(pnts){ 140 | 141 | 142 | var ptr_T = 0 // tree pointer for compressed tree-nodes (integer) 143 | var ptr_P = 1; // stack pointer for point-sets 144 | 145 | var stack_P = []; // FIFO 146 | stack_P[ptr_P++] = pnts; 147 | 148 | while( ptr_T++ < this.num_nodes ){ 149 | 150 | if( (pnts = stack_P[ptr_T]) == undefined ) continue; 151 | 152 | var e = pnts.length; 153 | var m = e>>1; 154 | 155 | if( e > 1 ){ // not a leaf 156 | this.quick_sort.sort(pnts, KdTree.GET_DIM(this.kd_tree[ptr_T]) ); 157 | 158 | stack_P[ptr_P++] = pnts.slice(0, m); 159 | stack_P[ptr_P++] = pnts.slice(m, e); 160 | } else { // leaf 161 | ptr_P+=2; 162 | this.kd_tree[ptr_T] |= KdTree.BIT_LEAF; // mark as leaf 163 | } 164 | 165 | this.kd_tree[ptr_T] |= Math.round( pnts[m].x * KdTree.PNT_SCALE )<<16; 166 | this.kd_tree[ptr_T] |= Math.round( pnts[m].y * KdTree.PNT_SCALE ); 167 | } 168 | 169 | } 170 | 171 | 172 | 173 | // slightly faster (~9%) than iterative version 174 | KdTree.prototype.buildRecursive = function(idx, pnts){ 175 | 176 | var e = pnts.length; 177 | var m = e>>1; 178 | 179 | if( e > 1 ){ 180 | this.quick_sort.sort(pnts, KdTree.GET_DIM(this.kd_tree[idx]) ); 181 | this.buildRecursive( (idx<<1), pnts.slice(0, m) ); 182 | this.buildRecursive( (idx<<1)+1, pnts.slice(m, e) ); 183 | } else { 184 | this.kd_tree[idx] |= KdTree.BIT_LEAF; // mark as leaf 185 | } 186 | 187 | this.kd_tree[idx] |= Math.round( pnts[m].x * KdTree.PNT_SCALE )<<16; 188 | this.kd_tree[idx] |= Math.round( pnts[m].y * KdTree.PNT_SCALE ); 189 | } 190 | 191 | // slightly faster (~9%) than iterative version 192 | KdTree.prototype.buildRecursiveFast = function(idx, pnts, left, right){ 193 | 194 | 195 | var m = (left+right)>>1; 196 | 197 | if( (right-left) >= 2 ){ 198 | // this.quick_sort.sort(pnts, KdTree.GET_DIM(this.kd_tree[idx]) ); 199 | this.quick_select.sort(pnts, KdTree.GET_DIM(this.kd_tree[idx]), left, right-1, m); 200 | this.kd_tree[idx] |= Math.round( pnts[m].x * KdTree.PNT_SCALE )<<16; 201 | this.kd_tree[idx] |= Math.round( pnts[m].y * KdTree.PNT_SCALE ); 202 | 203 | this.buildRecursiveFast( (idx<<1), pnts, left, m ); 204 | this.buildRecursiveFast( (idx<<1)+1, pnts, m, right); 205 | } else { 206 | this.kd_tree[idx] |= KdTree.BIT_LEAF; // mark as leaf 207 | this.kd_tree[idx] |= Math.round( pnts[m].x * KdTree.PNT_SCALE )<<16; 208 | this.kd_tree[idx] |= Math.round( pnts[m].y * KdTree.PNT_SCALE ); 209 | } 210 | 211 | 212 | } 213 | 214 | 215 | 216 | //-------------------------------------------------------------------------- 217 | // ANALYZE 218 | //-------------------------------------------------------------------------- 219 | 220 | KdTree.prototype.printTree = function(){ 221 | for(var i = 0; i < this.kd_tree.length; i++){ 222 | if( this.kd_tree[i] == 0 ){ 223 | console.log("tree[%d] null", i); 224 | } else { 225 | var leaf = KdTree.IS_LEAF (this.kd_tree[i]); 226 | var x = KdTree.GET_PX (this.kd_tree[i]); 227 | var y = KdTree.GET_PY (this.kd_tree[i]); 228 | var dim = KdTree.GET_DIM (this.kd_tree[i]); 229 | var P = KdTree.GET_P(i); 230 | var L = KdTree.GET_L(i); 231 | var R = KdTree.GET_R(i); 232 | 233 | console.log( 234 | "tree[%s] %s dim=%1s [P,L,R]=[%s,%s,%s] pnt=[%s,%s] code=%s", 235 | i, leaf?"-> LEAF":" ", dim, P,L,R, x.toFixed(2), y.toFixed(2), this.kd_tree[i]); 236 | } 237 | } 238 | } 239 | 240 | 241 | //-------------------------------------------------------------------------- 242 | // DISPLAY 243 | //-------------------------------------------------------------------------- 244 | 245 | KdTree.prototype.genVBO = function(b_points, b_planes, x_min, y_min, x_max, y_max){ 246 | 247 | var new_len = this.num_nodes*6; // 1 line per node, 4 coordinates per line 248 | if( this.kd_tree_planes==undefined || new_len != this.kd_tree_planes.length ){ 249 | this.kd_tree_planes = new Float32Array(new_len); 250 | } 251 | 252 | this.BUF_IDX = 0; 253 | 254 | if( b_planes ) this.genPlanesVBO(1, x_min, y_min, x_max, y_max, 1); 255 | } 256 | 257 | KdTree.prototype.genPlanesVBO = function(node_idx, x_min, y_min, x_max, y_max, depth){ 258 | 259 | var node = this.kd_tree[node_idx]; 260 | 261 | var pnt_x = KdTree.GET_PX(node); 262 | var pnt_y = KdTree.GET_PY(node); 263 | 264 | if( KdTree.GET_DIM(node) == 0 ){ 265 | if( !KdTree.IS_LEAF(node) ){ 266 | this.genPlanesVBO(KdTree.GET_L(node_idx), x_min, y_min, pnt_x, y_max, depth+1); 267 | this.genPlanesVBO(KdTree.GET_R(node_idx), pnt_x, y_min, x_max, y_max, depth+1); 268 | } 269 | this.drawLine (node_idx, pnt_x, y_min, pnt_x, y_max, depth); 270 | } else { 271 | if( !KdTree.IS_LEAF(node) ){ 272 | this.genPlanesVBO(KdTree.GET_L(node_idx), x_min, y_min, x_max, pnt_y, depth+1); 273 | this.genPlanesVBO(KdTree.GET_R(node_idx), x_min, pnt_y, x_max, y_max, depth+1); 274 | } 275 | this.drawLine(node_idx, x_min, pnt_y, x_max, pnt_y, depth); 276 | } 277 | } 278 | 279 | KdTree.prototype.drawLine = function(node_idx, x_min, y_min, x_max, y_max, depth){ 280 | // var dnorm = (KdTree.GET_DEPTH(kd_tree[node_idx]))/(float)(max_depth+1); 281 | // g.stroke(dnorm*150); 282 | // g.strokeWeight( Math.max((1-dnorm)*5, 1) ); 283 | // g.line(x_min, y_min, x_max, y_max); 284 | var alpha = 1-depth/(this.max_depth+2); 285 | var buffer = this.kd_tree_planes; 286 | var idx = this.BUF_IDX; 287 | 288 | buffer[idx++] = x_min; buffer[idx++] = y_min; buffer[idx++] = alpha; 289 | buffer[idx++] = x_max; buffer[idx++] = y_max; buffer[idx++] = alpha; 290 | this.BUF_IDX = idx 291 | } 292 | 293 | 294 | 295 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/math/DwQuat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: ... 3 | * author: thomas diewald 4 | * date: 10.02.12 5 | */ 6 | 7 | 8 | 9 | var DwQuat = DwQuat || {}; 10 | 11 | 12 | 13 | DwQuat.nullquat = function(){ 14 | return [0, 0, 0, 0]; // [ x, y, z, angle] 15 | } 16 | 17 | DwQuat.identity_new = function(){ 18 | return [0, 0, 0, 1]; // [ x, y, z, angle] 19 | } 20 | 21 | DwQuat.identity_ref = function(dst_q4){ 22 | dst_q4[0] = 0; 23 | dst_q4[1] = 0; 24 | dst_q4[2] = 0; 25 | dst_q4[3] = 1; 26 | } 27 | 28 | 29 | 30 | DwQuat.fromVec3 = function(axis_v3, angle) { 31 | var norm = DwVec3.mag(axis_v3); 32 | 33 | var halfAngle = -0.5 * angle; 34 | var coeff = Math.sin(halfAngle) / norm; 35 | 36 | var dst_q = new Array(4); 37 | dst_q[0] = coeff * axis_v3[0]; 38 | dst_q[1] = coeff * axis_v3[1]; 39 | dst_q[2] = coeff * axis_v3[2]; 40 | dst_q[3] = Math.cos(halfAngle); 41 | return dst_q; 42 | } 43 | 44 | 45 | 46 | 47 | DwQuat.copy_ref = function (q, dst_q) { 48 | dst_q[0] = q[0]; 49 | dst_q[1] = q[1]; 50 | dst_q[2] = q[2]; 51 | dst_q[3] = q[3]; 52 | }; 53 | DwQuat.copy_new = function (q) { 54 | return [q[0], q[1], q[2], q[3]]; 55 | }; 56 | 57 | 58 | 59 | DwQuat.calculateW_ref = function (q, dst_q) { 60 | var x = q[0], y = q[1], z = q[2]; 61 | dst_q[0] = x; 62 | dst_q[1] = y; 63 | dst_q[2] = z; 64 | dst_q[3] = -Math.sqrt(Math.abs(1.0 - x*x - y*y - z*z)); 65 | }; 66 | DwQuat.calculateW_ref_slf = function (q) { 67 | var x = q[0], y = q[1], z = q[2]; 68 | q[3] = -Math.sqrt(Math.abs(1.0 - x*x - y*y - z*z)); 69 | }; 70 | DwQuat.calculateW_new = function (q) { 71 | var dst_q = new Array(4); 72 | var x = q[0], y = q[1], z = q[2]; 73 | dst_q[0] = x; 74 | dst_q[1] = y; 75 | dst_q[2] = z; 76 | dst_q[3] = -Math.sqrt(Math.abs(1.0 - x*x - y*y - z*z)); 77 | return dst_q; 78 | }; 79 | 80 | 81 | 82 | 83 | DwQuat.dot = function(qA, qB){ 84 | return qA[0]*qB[0] + qA[1]*qB[1] + qA[2]*qB[2] + qA[3]*qB[3]; 85 | }; 86 | 87 | 88 | 89 | 90 | DwQuat.inverse_ref = function(q, dst_q) { 91 | var x = q[0], y = q[1], z = q[2], w = q[2]; 92 | 93 | var dot = x*x + y*y + z*z + w*w; 94 | if( dot === 0){ 95 | return; 96 | }else if (dot === 1.0){ 97 | dst_q[0] = -q[0]; dst_q[1] = -q[1]; dst_q[2] = -q[2]; dst_q[3] = q[3]; 98 | return; 99 | } 100 | var dot_inv = 1.0/dot; 101 | 102 | dst_q[0] = -x * dot_inv; 103 | dst_q[1] = -y * dot_inv; 104 | dst_q[2] = -z * dot_inv; 105 | dst_q[3] = w * dot_inv; 106 | }; 107 | DwQuat.inverse_ref_slf = function(q) { 108 | var x = q[0], y = q[1], z = q[2], w = q[2]; 109 | 110 | var dot = x*x + y*y + z*z + w*w; 111 | if( dot === 0){ 112 | return; 113 | }else if (dot === 1.0){ 114 | q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; 115 | return; 116 | } 117 | var dot_inv = 1.0/dot; 118 | 119 | q[0] *= -dot_inv; 120 | q[1] *= -dot_inv; 121 | q[2] *= -dot_inv; 122 | q[3] *= dot_inv; 123 | }; 124 | DwQuat.inverse_new = function(q) { 125 | var x = q[0], y = q[1], z = q[2], w = q[2]; 126 | 127 | var dot = x*x + y*y + z*z + w*w; 128 | if( dot === 0){ 129 | return DwQuat.copy_new(q); 130 | } else if (dot === 1.0){ 131 | return [-x, -y, -z, w]; 132 | } 133 | var dot_inv = 1.0/dot; 134 | 135 | return [-x*dot_inv, -y*dot_inv, -z*dot_inv, w*dot_inv]; 136 | }; 137 | 138 | 139 | 140 | DwQuat.conjugate_ref = function (q, dst_q){ 141 | dst_q[0] = -q[0]; dst_q[1] = -q[1]; dst_q[2] = -q[2]; dst_q[3] = q[3]; 142 | }; 143 | DwQuat.conjugate_ref_slf = function (q){ 144 | q[0] = -q[0]; q[1] = -q[1]; q[2] = -q[2]; 145 | }; 146 | DwQuat.conjugate_new = function (q) { 147 | return [-q[0], -q[1], -q[2], q[3]]; 148 | }; 149 | 150 | 151 | DwQuat.length = function (q) { 152 | var x = q[0], y = q[1], z = q[2], w = q[3]; 153 | return Math.sqrt(x*x + y*y + z*z + w*w); 154 | }; 155 | 156 | 157 | 158 | DwQuat.normalize_ref = function (q, dst_q) { 159 | var x = q[0], y = q[1], z = q[2], w = q[3]; 160 | var dot = x*x + y*y + z*z + w*w; 161 | if( dot === 0){ 162 | dst_q[0] = 0; dst_q[1] = 0; dst_q[2] = 0; dst_q[3] = 0; 163 | return; 164 | } 165 | var len_inv = 1/ Math.sqrt(dot); 166 | dst_q[0] = x*len_inv; 167 | dst_q[1] = y*len_inv; 168 | dst_q[2] = z*len_inv; 169 | dst_q[3] = w*len_inv; 170 | }; 171 | DwQuat.normalize_ref_slf = function (q) { 172 | var x = q[0], y = q[1], z = q[2], w = q[3]; 173 | var dot = x*x + y*y + z*z + w*w; 174 | if( dot === 0){ 175 | return; 176 | } 177 | var len_inv = 1/ Math.sqrt(dot); 178 | q[0] *= len_inv; 179 | q[1] *= len_inv; 180 | q[2] *= len_inv; 181 | q[3] *= len_inv; 182 | }; 183 | DwQuat.normalize_new = function (q) { 184 | var x = q[0], y = q[1], z = q[2], w = q[3]; 185 | var dot = x*x + y*y + z*z + w*w; 186 | if( dot === 0){ 187 | return [0, 0, 0, 0]; 188 | } 189 | var len_inv = 1/ Math.sqrt(dot); 190 | return [x*len_inv, y*len_inv, z*len_inv, w*len_inv]; 191 | }; 192 | 193 | 194 | 195 | DwQuat.mult_ref = function (q1, q2, dst_q) { 196 | var x1 = q1[0], y1 = q1[1], z1 = q1[2], w1 = q1[3]; 197 | var x2 = q2[0], y2 = q2[1], z2 = q2[2], w2 = q2[3]; 198 | 199 | dst_q[0] = x1*w2 + w1*x2 + y1*z2 - z1*y2; 200 | dst_q[1] = y1*w2 + w1*y2 + z1*x2 - x1*z2; 201 | dst_q[2] = z1*w2 + w1*z2 + x1*y2 - y1*x2; 202 | dst_q[3] = w1*w2 - x1*x2 - y1*y2 - z1*z2; 203 | }; 204 | DwQuat.mult_new = function (q1, q2) { 205 | var dst_q = new Array(4); 206 | var x1 = q1[0], y1 = q1[1], z1 = q1[2], w1 = q1[3]; 207 | var x2 = q2[0], y2 = q2[1], z2 = q2[2], w2 = q2[3]; 208 | 209 | dst_q[0] = x1*w2 + w1*x2 + y1*z2 - z1*y2; 210 | dst_q[1] = y1*w2 + w1*y2 + z1*x2 - x1*z2; 211 | dst_q[2] = z1*w2 + w1*z2 + x1*y2 - y1*x2; 212 | dst_q[3] = w1*w2 - x1*x2 - y1*y2 - z1*z2; 213 | return dst_q; 214 | }; 215 | 216 | 217 | 218 | 219 | DwQuat.multVec3_ref = function (q, v3, dst_v3) { 220 | var vx = v3[0], vy = v3[1], vz = v3[2]; 221 | var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; 222 | 223 | // q * v3 224 | var 225 | ix = qw*vx + qy*vz - qz*vy, 226 | iy = qw*vy + qz*vx - qx*vz, 227 | iz = qw*vz + qx*vy - qy*vx, 228 | iw = -qx*vx - qy*vy - qz*vz; 229 | 230 | // result * inverse quat 231 | dst_v3[0] = ix*qw + iw*-qx + iy*-qz - iz*-qy; 232 | dst_v3[1] = iy*qw + iw*-qy + iz*-qx - ix*-qz; 233 | dst_v3[2] = iz*qw + iw*-qz + ix*-qy - iy*-qx; 234 | }; 235 | DwQuat.multVec3_ref_slf = function (q, v3) { 236 | var vx = v3[0], vy = v3[1], vz = v3[2]; 237 | var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; 238 | 239 | // q * v3 240 | var 241 | ix = qw*vx + qy*vz - qz*vy, 242 | iy = qw*vy + qz*vx - qx*vz, 243 | iz = qw*vz + qx*vy - qy*vx, 244 | iw = -qx*vx - qy*vy - qz*vz; 245 | 246 | // result * inverse quat 247 | v3[0] = ix*qw + iw*-qx + iy*-qz - iz*-qy; 248 | v3[1] = iy*qw + iw*-qy + iz*-qx - ix*-qz; 249 | v3[2] = iz*qw + iw*-qz + ix*-qy - iy*-qx; 250 | }; 251 | DwQuat.multVec3_new = function (q, v3) { 252 | var dst_v3 = new Array(3); 253 | var vx = v3[0], vy = v3[1], vz = v3[2]; 254 | var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; 255 | 256 | // q * v3 257 | var 258 | ix = qw*vx + qy*vz - qz*vy, 259 | iy = qw*vy + qz*vx - qx*vz, 260 | iz = qw*vz + qx*vy - qy*vx, 261 | iw = -qx*vx - qy*vy - qz*vz; 262 | 263 | // result * inverse quat 264 | dst_v3[0] = ix*qw + iw*-qx + iy*-qz - iz*-qy; 265 | dst_v3[1] = iy*qw + iw*-qy + iz*-qx - ix*-qz; 266 | dst_v3[2] = iz*qw + iw*-qz + ix*-qy - iy*-qx; 267 | return dst_v3; 268 | }; 269 | 270 | 271 | 272 | DwQuat.toMat3_ref = function (q, dst_m3) { 273 | var x = q[0], y = q[1], z = q[2], w = q[3]; 274 | var x2 = x+x, y2 = y+y, z2 = z+z; 275 | var 276 | xx = x*x2, yy = y*y2, wx = w*x2, 277 | xy = x*y2, yz = y*z2, wy = w*y2, 278 | xz = x*z2, zz = z*z2, wz = w*z2; 279 | 280 | dst_m3[0] = 1 - (yy + zz); dst_m3[3] = xy - wz; dst_m3[6] = xz + wy; 281 | dst_m3[1] = xy + wz; dst_m3[4] = 1 - (xx + zz); dst_m3[7] = yz - wx; 282 | dst_m3[2] = xz - wy; dst_m3[5] = yz + wx; dst_m3[8] = 1 - (xx + yy); 283 | }; 284 | DwQuat.toMat3_new = function (q) { 285 | var dst_m3 = new Array(9); 286 | var x = q[0], y = q[1], z = q[2], w = q[3]; 287 | var x2 = x+x, y2 = y+y, z2 = z+z; 288 | var 289 | xx = x*x2, yy = y*y2, wx = w*x2, 290 | xy = x*y2, yz = y*z2, wy = w*y2, 291 | xz = x*z2, zz = z*z2, wz = w*z2; 292 | 293 | dst_m3[0] = 1 - (yy + zz); dst_m3[3] = xy - wz; dst_m3[6] = xz + wy; 294 | dst_m3[1] = xy + wz; dst_m3[4] = 1 - (xx + zz); dst_m3[7] = yz - wx; 295 | dst_m3[2] = xz - wy; dst_m3[5] = yz + wx; dst_m3[8] = 1 - (xx + yy); 296 | return dst_m3; 297 | }; 298 | 299 | 300 | DwQuat.toMat4_ref = function (q, dst_m4) { 301 | var x = q[0], y = q[1], z = q[2], w = q[3]; 302 | var x2 = x+x, y2 = y+y, z2 = z+z; 303 | var 304 | xx = x*x2, yy = y*y2, wx = w*x2, 305 | xy = x*y2, yz = y*z2, wy = w*y2, 306 | xz = x*z2, zz = z*z2, wz = w*z2; 307 | 308 | dst_m4[0] = 1 - (yy + zz); dst_m4[4] = xy - wz; dst_m4[ 8] = xz + wy; dst_m4[12] = 0; 309 | dst_m4[1] = xy + wz; dst_m4[5] = 1 - (xx + zz); dst_m4[ 9] = yz - wx; dst_m4[13] = 0; 310 | dst_m4[2] = xz - wy; dst_m4[6] = yz + wx; dst_m4[10] = 1 - (xx + yy); dst_m4[14] = 0; 311 | dst_m4[3] = 0; dst_m4[7] = 0; dst_m4[11] = 0; dst_m4[15] = 1; 312 | }; 313 | DwQuat.toMat4_ref = function (q) { 314 | var dst_m4 = new Array(16); 315 | var x = q[0], y = q[1], z = q[2], w = q[3]; 316 | var x2 = x+x, y2 = y+y, z2 = z+z; 317 | var 318 | xx = x*x2, yy = y*y2, wx = w*x2, 319 | xy = x*y2, yz = y*z2, wy = w*y2, 320 | xz = x*z2, zz = z*z2, wz = w*z2; 321 | 322 | dst_m4[0] = 1 - (yy + zz); dst_m4[4] = xy - wz; dst_m4[ 8] = xz + wy; dst_m4[12] = 0; 323 | dst_m4[1] = xy + wz; dst_m4[5] = 1 - (xx + zz); dst_m4[ 9] = yz - wx; dst_m4[13] = 0; 324 | dst_m4[2] = xz - wy; dst_m4[6] = yz + wx; dst_m4[10] = 1 - (xx + yy); dst_m4[14] = 0; 325 | dst_m4[3] = 0; dst_m4[7] = 0; dst_m4[11] = 0; dst_m4[15] = 1; 326 | return dst_m4; 327 | }; 328 | 329 | 330 | 331 | DwQuat.slerp_Version2_new = function(q1, q2, slerp) { 332 | var x1 = q1[0], y1 = q1[1], z1 = q1[2], w1 = q1[3]; 333 | var x2 = q2[0], y2 = q2[1], z2 = q2[2], w2 = q2[3]; 334 | 335 | var dot = x1*x2 + y1*y2 +z1*z2 +w1*w2; 336 | var theta = Math.acos(dot); 337 | var sinTheta = Math.sin(theta); 338 | 339 | var faca, facb; 340 | if (sinTheta > 0.001) { 341 | faca = Math.sin((1.0 - slerp) * theta) / sinTheta; 342 | facb = Math.sin( slerp * theta) / sinTheta; 343 | } else { 344 | faca = 1.0 - slerp; 345 | facb = slerp; 346 | } 347 | var quat_dst = [x1*faca + x2*facb, 348 | y1*faca + y2*facb, 349 | y1*faca + y2*facb, 350 | w1*faca + w2*facb]; 351 | return quat_dst; 352 | } 353 | 354 | 355 | // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ 356 | 357 | DwQuat.slerp_ref = function (q1, q2, slerp, dst_q4) { 358 | var x1 = q1[0], y1 = q1[1], z1 = q1[2], w1 = q1[3]; 359 | var x2 = q2[0], y2 = q2[1], z2 = q2[2], w2 = q2[3]; 360 | 361 | var dot = x1*x2 + y1*y2 +z1*z2 +w1*w2; 362 | if (Math.abs(dot) >= 1.0) { 363 | dst_q4[0] = x1; 364 | dst_q4[1] = y1; 365 | dst_q4[2] = y1; 366 | dst_q4[3] = w1; 367 | return ; 368 | } 369 | 370 | var dot_x_dot_inv = 1.0 - dot*dot; 371 | if ( dot_x_dot_inv < 0.000001) { 372 | dst_q4[0] = x1*0.5 + x2*0.5; 373 | dst_q4[1] = y1*0.5 + y2*0.5; 374 | dst_q4[2] = y1*0.5 + y2*0.5; 375 | dst_q4[3] = w1*0.5 + w2*0.5; 376 | return; 377 | } 378 | var sinHalfTheta = Math.sqrt(dot_x_dot_inv); 379 | var halfTheta = Math.acos(dot); 380 | var fac = halfTheta * slerp; 381 | var faca = Math.sin(halfTheta - fac) / sinHalfTheta; 382 | var facb = Math.sin( fac) / sinHalfTheta; 383 | 384 | dst_q4[0] = x1*faca + x2*facb; 385 | dst_q4[1] = y1*faca + y2*facb; 386 | dst_q4[2] = y1*faca + y2*facb; 387 | dst_q4[3] = w1*faca + w2*facb; 388 | }; 389 | DwQuat.slerp_new = function (q1, q2, slerp) { 390 | var x1 = q1[0], y1 = q1[1], z1 = q1[2], w1 = q1[3]; 391 | var x2 = q2[0], y2 = q2[1], z2 = q2[2], w2 = q2[3]; 392 | 393 | var dot = x1*x2 + y1*y2 +z1*z2 +w1*w2; 394 | if (Math.abs(dot) >= 1.0) 395 | return [x1, y1, z1, w1]; 396 | 397 | var dot_x_dot_inv = 1.0 - dot*dot; 398 | if ( dot_x_dot_inv < 0.000001) 399 | return [x1*0.5 + x2*0.5, y1*0.5 + y2*0.5], z1*0.5 + z2*0.5, w1*0.5 + w2*0.5; 400 | 401 | var sinHalfTheta = Math.sqrt(dot_x_dot_inv); 402 | var halfTheta = Math.acos(dot); 403 | var fac = halfTheta * slerp; 404 | var faca = Math.sin(halfTheta - fac) / sinHalfTheta; 405 | var facb = Math.sin( fac) / sinHalfTheta; 406 | 407 | return [x1*faca + x2*facb, y1*faca + y2*facb, z1*faca + z2*facb, w1*faca + w2*facb]; 408 | }; 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | DwQuat.fromEuler_new = function(order, alpha1, alpha2, alpha3) { 423 | var r1 = DwQuat.fromVec3(order[0], alpha1); 424 | var r2 = DwQuat.fromVec3(order[1], alpha2); 425 | var r3 = DwQuat.fromVec3(order[2], alpha3); 426 | 427 | DwQuat.mult_ref(r2, r3, r2); 428 | DwQuat.mult_ref(r1, r2, r1); 429 | var dst_q = r1; 430 | return dst_q; 431 | } 432 | 433 | DwQuat.fromEuler_ref = function(order, alpha1, alpha2, alpha3, dst_q4) { 434 | var r1 = DwQuat.fromVec3(order[0], alpha1); 435 | var r2 = DwQuat.fromVec3(order[1], alpha2); 436 | var r3 = DwQuat.fromVec3(order[2], alpha3); 437 | 438 | DwQuat.mult_ref(r3, r2, r2); 439 | DwQuat.mult_ref(r2, r1, dst_q4); 440 | } 441 | 442 | 443 | 444 | // no tested 445 | DwQuat.getEulerAngles = function(order, rotation){ 446 | if (order === DwRotationOrder.XYZ) { 447 | var v1 = DwQuat.apply_new (rotation, [0, 0, 1]); 448 | var v2 = DwQuat.applyInverse_new(rotation, [1, 0, 0]); // var v2 = DwQuat.multVec3_new(rotation, [1, 0, 0]); 449 | if ((v2[2] < -0.9999999999) || (v2[2] > 0.9999999999)) { 450 | return [0, 0, 0]; //Throw exception 451 | } 452 | return [ Math.atan2(-v1[1], v1[2]), 453 | Math.asin ( v2[2]), 454 | Math.atan2(-v2[1], v2[0]) ]; 455 | } 456 | } 457 | 458 | 459 | // TODO: compare to mult_new 460 | DwQuat.apply_new = function(q, v3) { 461 | var dst_v3 = new Array(3); 462 | var vx = v3[0], vy = v3[1], vz = v3[2]; 463 | var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; 464 | 465 | var s = qx*vx + qy*vy + qz*vz; 466 | var m0 = qw; 467 | 468 | dst_v3[0] = 2* (m0* (vx*m0 - (qy*vz - qz*vy)) + s*qx) - vx; 469 | dst_v3[1] = 2* (m0* (vy*m0 - (qz*vx - qx*vz)) + s*qy) - vy; 470 | dst_v3[2] = 2* (m0* (vz*m0 - (qx*vy - qy*vx)) + s*qz) - vz; 471 | return dst_v3; 472 | } 473 | 474 | DwQuat.applyInverse_new = function(q, v3) { 475 | var dst_v3 = new Array(3); 476 | var vx = v3[0], vy = v3[1], vz = v3[2]; 477 | var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; 478 | 479 | var s = qx*vx + qy*vy + qz*vz; 480 | var m0 = -qw; 481 | 482 | dst_v3[0] = 2* (m0* (vx*m0 - (qy*vz - qz*vy)) + s*qx) - vx; 483 | dst_v3[1] = 2* (m0* (vy*m0 - (qz*vx - qx*vz)) + s*qy) - vy; 484 | dst_v3[2] = 2* (m0* (vz*m0 - (qx*vy - qy*vx)) + s*qz) - vz; 485 | return dst_v3; 486 | } 487 | 488 | 489 | DwQuat.toStr = function (q) { 490 | var prec = 5; 491 | return "[quat xyz,w:"+q[0].toFixed(prec)+", "+q[1].toFixed(prec)+", "+q[2].toFixed(prec)+", "+q[3].toFixed(prec)+"]"; 492 | }; 493 | -------------------------------------------------------------------------------- /PixelVoronoi_KdTree_v05/libs/Dw/camera/DwCamera.js: -------------------------------------------------------------------------------- 1 | /** 2 | * project: Dw WebGL ToolKit 3 | * author: thomas diewald 4 | * date: 13.02.12 5 | * 6 | * description: camera, code is based on Peasycam (processing library) 7 | * http://mrfeinberg.com/peasycam/ 8 | */ 9 | 10 | 11 | 12 | function DwCamera(CTX, lookAt, distance){ 13 | this.ctx = CTX; 14 | this.mouse = this.ctx.mouse_info; 15 | this.key = this.ctx.key_info; 16 | this.LOOK = [0, 0, 1]; 17 | this.UP = [0, 1, 0]; 18 | 19 | 20 | this.minimumDistance = 1.001; 21 | this.maximumDistance = 1000000000; 22 | 23 | 24 | // update methods 25 | this.rotateX = new DwDampedAction(this, this.behave_rx); 26 | this.rotateY = new DwDampedAction(this, this.behave_ry); 27 | this.rotateZ = new DwDampedAction(this, this.behave_rz); 28 | this.dampedZoom = new DwDampedAction(this, this.behave_zoom); 29 | this.dampedPanX = new DwDampedAction(this, this.behave_panx); 30 | this.dampedPanY = new DwDampedAction(this, this.behave_pany); 31 | 32 | this.rotationInterps = new DwInterpolationManager(this, this.interpolation_Rotation, this.interpolationFinish_Rotation ); 33 | this.centerInterps = new DwInterpolationManager(this, this.interpolation_Center, this.interpolationFinish_Center ); 34 | this.distanceInterps = new DwInterpolationManager(this, this.interpolation_Distance, this.interpolationFinish_Distance ); 35 | 36 | 37 | // parameters for the camera orientation 38 | this.distance = distance; // double 39 | this.center = lookAt; // vec3 40 | this.rotation = DwQuat.identity_new();// quat4 41 | 42 | this.startDistance = distance; 43 | this.startCenter = DwVec3.copy_new(lookAt); 44 | 45 | // constrain on Key-Shift 46 | this.ConstraintX = 0; 47 | this.ConstraintY = 1; 48 | this.dragConstraint = -1; 49 | 50 | // assign functionality to mouseButtons 51 | this.wheelHandler = this.zoomWheelHandler; 52 | this.centerDragHandler = this.panHandler; 53 | this.leftDragHandler = this.rotateHandler; 54 | this.rightDraghandler = this.zoomHandler; 55 | this.resetOnDoubleClick = true; 56 | 57 | this.wheelScale = 1.0; 58 | 59 | // mouse can modify camera 60 | this.isActive = true; 61 | 62 | this.MATRIX_modelView = DwMat4.identity_new(); 63 | this.MATRIX_projection = DwMat4.perspective_new(45, this.ctx.VIEWPORT.width / this.ctx.VIEWPORT.height, 25, 1500.0); 64 | this.feed(); 65 | }; 66 | 67 | DwCamera.prototype.setActive = function(active) { 68 | if (active == this.isActive) { 69 | return; 70 | } 71 | this.isActive = active; 72 | // if (this.isActive) { 73 | // } else { 74 | // } 75 | }; 76 | 77 | DwCamera.prototype.update = function() { 78 | if( this.isActive !== true ) 79 | return; 80 | 81 | var m = this.mouse; 82 | var k = this.key; 83 | 84 | if (this.resetOnDoubleClick && m.doubleclicked) { 85 | this.reset(); 86 | } 87 | // else 88 | // if (m.mousereleased ) { 89 | // this.dragConstraint = -1; 90 | // } 91 | else 92 | if (m.mousepressed && k.keypressed) { 93 | var dx = m.mouseX - m.pmouseX; 94 | var dy = m.mouseY - m.pmouseY; 95 | // console.log("dx/dy = "+dx+", "+dy); 96 | dx /= 2; //TODO 97 | dy /= 2;//TODO 98 | // if (k.key == 67) { 99 | // if (this.dragConstraint === -1 && Math.abs(dx - dy) > 1) { 100 | // this.dragConstraint = Math.abs(dx) > Math.abs(dy) ? this.ConstraintX : this.Constraint.Y; 101 | // } 102 | // } else { 103 | // this.dragConstraint = -1; 104 | // } 105 | 106 | var button = m.button; 107 | 108 | if (button == m.lmb && k.shift) { 109 | this.centerDragHandler(dx, dy); 110 | } 111 | else if (button == m.lmb && k.alt) { 112 | this.leftDragHandler(dx, dy); 113 | } 114 | else if (button == m.lmb && k.ctrl) { 115 | this.rightDraghandler(dx, dy); 116 | } 117 | } 118 | 119 | // update damped rotations 120 | this.rotateX.update(); 121 | this.rotateY.update(); 122 | this.rotateZ.update(); 123 | // update damped zoom 124 | this.dampedZoom.update(); 125 | // update damped pan 126 | this.dampedPanX.update(); 127 | this.dampedPanY.update(); 128 | 129 | // update orientation (interpolated), only if its active 130 | this.rotationInterps.update(); 131 | this.centerInterps .update(); 132 | this.distanceInterps.update(); 133 | 134 | this.feed(); 135 | }; 136 | 137 | 138 | 139 | // BUILT THE FINAL MATRIX 140 | DwCamera.prototype.feed = function() { 141 | this.newCameraMatrix(this.center, this.rotation, this.distance); 142 | }; 143 | DwCamera.prototype.newCameraMatrix = function(center_v3, rotation_quat, distance) { 144 | var rup = DwQuat.multVec3_new(rotation_quat, this.UP); 145 | var pos = DwQuat.multVec3_new(rotation_quat, this.LOOK); 146 | DwVec3.scale_ref_slf(pos, distance); 147 | DwVec3.add_ref(pos, center_v3, pos); 148 | DwMat4.lookAt_ref(pos, center_v3, rup, this.MATRIX_modelView); 149 | }; 150 | 151 | 152 | 153 | // GET FINAL MODELVIEW MATRIX 154 | DwCamera.prototype.getMat_ModelView_cpy = function(){ 155 | return DwMat4.copy_new(this.MATRIX_modelView); 156 | }; 157 | // GET FINAL MATRIX 158 | DwCamera.prototype.getMat_ModelView_ref = function(){ 159 | return this.MATRIX_modelView; 160 | }; 161 | // GET FINAL PROJECTION MATRIX 162 | DwCamera.prototype.getMat_Projection_cpy = function(){ 163 | return DwMat4.copy_new(this.MATRIX_projection); 164 | }; 165 | // GET FINAL MATRIX 166 | DwCamera.prototype.getMat_Projection_ref = function(){ 167 | return this.MATRIX_projection; 168 | }; 169 | 170 | 171 | // ZOOM - PAN - ROTATION 172 | DwCamera.prototype.mouseZoom = function(delta) { 173 | this.safeSetDistance(this.distance + delta * Math.log(this.distance)); 174 | }; 175 | DwCamera.prototype.mousePan = function(dxMouse, dyMouse) { 176 | var panScale = Math.sqrt(this.distance * .005); 177 | this.pan( this.dragConstraint === this.ConstraintY ? 0 : -dxMouse * panScale, 178 | this.dragConstraint === this.ConstraintX ? 0 : dyMouse * panScale); //TODO changed -dyMouse to dyMouse 179 | }; 180 | DwCamera.prototype.mouseRotate = function(dx, dy) { 181 | // console.log("DwCameraArcBall.prototype.mouseRotate: cam.rotation = "+this.rotation); 182 | var u = DwVec3.scale_new(this.LOOK, 100 + .6 * this.startDistance); 183 | DwVec3.negate_ref_slf(u); 184 | 185 | var width = this.ctx.VIEWPORT.width; //TODO 186 | var height = this.ctx.VIEWPORT.height; //TODO 187 | 188 | var m = this.mouse; 189 | 190 | if (this.dragConstraint != this.ConstraintX ) { 191 | var rho = Math.abs((width *0.5) - m.mouseX) / (width *0.5); 192 | var adz = Math.abs(dy) * rho; 193 | var ady = Math.abs(dy) * (1 - rho); 194 | var ySign = dy < 0 ? -1 : 1; 195 | var vy = DwVec3.add_new(u, [0, ady, 0]); 196 | var vz = DwVec3.add_new(u, [0, adz, 0]); 197 | 198 | this.rotateX.impulse(DwVec3.angleBetween(u,vy) * ySign); 199 | this.rotateZ.impulse(DwVec3.angleBetween(u,vz) * -ySign * ( m.mouseX < width*0.5 ? -1 : 1)); 200 | } 201 | 202 | if (this.dragConstraint != this.ConstraintY ) { 203 | var eccentricity = Math.abs((height*0.5) - m.mouseY)/ (height*0.5); 204 | var xSign = dx > 0 ? -1 : 1; 205 | var adz = Math.abs(dx) * eccentricity; 206 | var adx = Math.abs(dx) * (1 - eccentricity); 207 | var vx = DwVec3.add_new(u, [adx, 0, 0]); 208 | var vz = DwVec3.add_new(u, [0, adz, 0]); 209 | this.rotateY.impulse(DwVec3.angleBetween(u,vx) * -xSign); //TODO changed -xSign to xSign 210 | this.rotateZ.impulse(DwVec3.angleBetween(u,vz) * xSign* (m.mouseY > height*0.5 ? -1 : 1)); 211 | } 212 | }; 213 | 214 | 215 | 216 | // DISTANCE 217 | DwCamera.prototype.safeSetDistance = function(distance) { 218 | this.distance = Math.min(this.maximumDistance, Math.max(this.minimumDistance, distance)); 219 | this.feed(); 220 | }; 221 | DwCamera.prototype.setMinimumDistance = function(minimumDistance) { 222 | if(minimumDistance <= 1 ) 223 | minimumDistance = 1.001; 224 | this.minimumDistance = minimumDistance; 225 | this.safeSetDistance(this.distance); 226 | }; 227 | DwCamera.prototype.setMaximumDistance = function(maximumDistance) { 228 | this.maximumDistance = maximumDistance; 229 | this.safeSetDistance(this.distance); 230 | }; 231 | DwCamera.prototype.getDistance = function() { 232 | return this.distance; 233 | }; 234 | DwCamera.prototype.setDistance = function(newDistance, animationTimeMillis) { 235 | animationTimeMillis = animationTimeMillis || 300; 236 | this.distanceInterps.start(this.distance, newDistance, animationTimeMillis); 237 | }; 238 | 239 | 240 | // CENTER 241 | DwCamera.prototype.getLookAt = function() { 242 | return DwVec3.copy_new(this.center); 243 | }; 244 | DwCamera.prototype.lookAt_xyz = function(xyz, animationTimeMillis) { 245 | animationTimeMillis = animationTimeMillis || 300; 246 | this.centerInterps.start(this.center, xyz, animationTimeMillis); 247 | }; 248 | DwCamera.prototype.lookAt_xyzd = function(xyz, distance, animationTimeMillis) { 249 | animationTimeMillis = animationTimeMillis || 300; 250 | this.lookAt_xyz(xyz, animationTimeMillis); 251 | this.setDistance(distance, animationTimeMillis); 252 | }; 253 | 254 | 255 | // EYE 256 | DwCamera.prototype.getPosition = function() { 257 | var pos = DwQuat.multVec3_new(this.rotation, this.LOOK); 258 | DwVec3.scale_ref_slf(pos, this.distance); 259 | DwVec3.add_ref(pos, this.center, pos); 260 | return pos; 261 | }; 262 | 263 | 264 | // RESET 265 | DwCamera.prototype.reset = function(animationTimeMillis) { 266 | animationTimeMillis = animationTimeMillis || 300; 267 | var state = new DwCameraState( DwQuat.identity_new(), this.startCenter, this.startDistance); 268 | this.setState(state, animationTimeMillis); 269 | }; 270 | 271 | // RESET ON DOUBLECLICK 272 | DwCamera.prototype.setResetOnDoubleClick = function(resetOnDoubleClick) { 273 | this.resetOnDoubleClick = resetOnDoubleClick; 274 | }; 275 | 276 | 277 | 278 | // APPLY ROTATIONS 279 | // for extern calls 280 | DwCamera.prototype.apply_rotateX = function(angle) { 281 | var q4 = DwQuat.fromVec3([1, 0, 0], angle); 282 | DwQuat.mult_ref(this.rotation, q4, this.rotation); 283 | this.feed(); 284 | }; 285 | DwCamera.prototype.apply_rotateY = function(angle) { 286 | var q4 = DwQuat.fromVec3([0, 1, 0], angle); 287 | DwQuat.mult_ref(this.rotation, q4, this.rotation); 288 | this.feed(); 289 | }; 290 | 291 | DwCamera.prototype.apply_rotateZ = function(angle) { 292 | var q4 = DwQuat.fromVec3([0, 0, 1], angle); 293 | DwQuat.mult_ref(this.rotation, q4, this.rotation); 294 | this.feed(); 295 | }; 296 | 297 | 298 | 299 | DwCamera.prototype.setRotations = function(pitch, yaw, roll) { 300 | this.rotationInterps.stop(); 301 | DwQuat.fromEuler_ref(DwRotationOrder.XYZ, pitch, yaw, roll, this.rotation); 302 | this.feed(); 303 | }; 304 | DwCamera.prototype.getRotations = function() { 305 | // try { 306 | return DwQuat.getEulerAngles(DwRotationOrder.XYZ, this.rotation); // returns[pitch, yaw, roll]; 307 | // } catch (e) { 308 | // } 309 | // try { 310 | // var angles = rotation.getAngles(RotationOrder.YXZ); 311 | // return angles; 312 | // } catch (e) { 313 | // } 314 | // try { 315 | // var angles = rotation.getAngles(RotationOrder.ZXY); 316 | // return angles; 317 | // } catch (e) { 318 | // } 319 | // return [0, 0, 0]; 320 | }; 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | DwCamera.prototype.pan = function(dx, dy) { 336 | var v3_rot = DwQuat.multVec3_new(this.rotation, [dx, dy, 0]); 337 | DwVec3.add_ref(this.center, v3_rot , this.center); 338 | }; 339 | 340 | 341 | 342 | DwCamera.prototype.panHandler = function(dx, dy) { 343 | this.dampedPanX.impulse(dx / 8.0); 344 | this.dampedPanY.impulse(dy / 8.0); 345 | }; 346 | DwCamera.prototype.rotateHandler = function(dx, dy) { 347 | this.mouseRotate(dx, dy); 348 | }; 349 | 350 | DwCamera.prototype.zoomHandler = function(dx, dy) { 351 | this.dampedZoom.impulse(dy / 10.0); 352 | }; 353 | 354 | DwCamera.prototype.zoomWheelHandler = function(delta) { 355 | this.dampedZoom.impulse(this.wheelScale * delta); 356 | }; 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | // callbacks for DampedAction 365 | DwCamera.prototype.behave_rx = function(cam, velocity){ 366 | DwQuat.mult_ref(cam.rotation, DwQuat.fromVec3([1, 0, 0], velocity), cam.rotation); 367 | }; 368 | DwCamera.prototype.behave_ry = function(cam, velocity){ 369 | DwQuat.mult_ref(cam.rotation, DwQuat.fromVec3([0, 1, 0], velocity), cam.rotation); 370 | }; 371 | DwCamera.prototype.behave_rz = function(cam, velocity){ 372 | DwQuat.mult_ref(cam.rotation, DwQuat.fromVec3([0, 0, 1], velocity), cam.rotation); 373 | }; 374 | 375 | DwCamera.prototype.behave_zoom = function(cam, velocity){ 376 | cam.mouseZoom(velocity); 377 | }; 378 | DwCamera.prototype.behave_panx = function(cam, velocity){ 379 | cam.mousePan(velocity, 0); 380 | }; 381 | DwCamera.prototype.behave_pany = function(cam, velocity){ 382 | cam.mousePan(0, velocity); 383 | }; 384 | 385 | 386 | 387 | // STATE 388 | DwCamera.prototype.getState = function() { 389 | return new DwCameraState(this.rotation, this.center, this.distance).getCopy(); 390 | }; 391 | DwCamera.prototype.setState = function(state, animationTimeMillis) { 392 | state = state || null; 393 | if( state == null ) 394 | return; 395 | 396 | state = state.getCopy(); // in case the original state would get changed 397 | animationTimeMillis = animationTimeMillis || 300; 398 | if (animationTimeMillis > 0) { 399 | // stop current rotations 400 | this.rotateX.stop(); 401 | this.rotateY.stop(); 402 | this.rotateZ.stop(); 403 | 404 | // check if given state is different to current state 405 | var current_state = this.getState(); 406 | var new_distance = !state.compareDistance(current_state); 407 | var new_center = !state.compareCenter (current_state); 408 | var new_rotation = !state.compareRotation(current_state); 409 | 410 | // start interpolated transformations 411 | if( new_rotation ) this.rotationInterps.start(this.rotation, state.rotation, animationTimeMillis ); 412 | if( new_center ) this.centerInterps .start(this.center , state.center , animationTimeMillis ); 413 | if( new_distance ) this.distanceInterps.start(this.distance, state.distance, animationTimeMillis ); 414 | } else { 415 | this.rotation = state.rotation; 416 | this.center = state.center; 417 | this.distance = state.distance; 418 | } 419 | this.feed(); 420 | }; 421 | 422 | 423 | // callbacks for interpolation (state change) 424 | DwCamera.prototype.interpolation_Rotation = function(cam, value_start, value_end, fac){ 425 | cam.rotation = DwQuat.slerp_new(value_start, value_end, fac); 426 | }; 427 | DwCamera.prototype.interpolationFinish_Rotation = function(cam, value_end){ 428 | cam.rotation = value_end; 429 | }; 430 | 431 | 432 | DwCamera.prototype.interpolation_Center = function(cam, value_start, value_end, fac){ 433 | cam.center = smooth_Vec3(value_start, value_end, fac); 434 | }; 435 | DwCamera.prototype.interpolationFinish_Center = function(cam, value_end){ 436 | cam.center = value_end; 437 | }; 438 | 439 | 440 | DwCamera.prototype.interpolation_Distance = function(cam, value_start, value_end, fac){ 441 | cam.distance = smooth_float(value_start, value_end, fac); 442 | }; 443 | DwCamera.prototype.interpolationFinish_Distance = function(cam, value_end){ 444 | cam.distance = value_end; 445 | }; 446 | 447 | 448 | function smooth_float(a, b, t) { 449 | var smooth = (t*t * (3 - 2*t)); 450 | return (b*smooth) + (a*(1 - smooth)); 451 | }; 452 | 453 | 454 | function smooth_Vec3(a_v3, b_v3, t) { 455 | return [ smooth_float(a_v3[0], b_v3[0], t), 456 | smooth_float(a_v3[1], b_v3[1], t), 457 | smooth_float(a_v3[2], b_v3[2], t)]; 458 | }; 459 | 460 | --------------------------------------------------------------------------------