1"use strict"; 2 3// -------------------------------------------------------------------------------- 4// UI 5// -------------------------------------------------------------------------------- 6// TODO use PlaneFilter namespace? 7HexaLab.UI.plane_enabled = $('#plane_enabled') 8HexaLab.UI.plane_offset_slider = $('#plane_offset_slider').slider() 9HexaLab.UI.plane_offset_number = $('#plane_offset_number') 10HexaLab.UI.plane_nx = $('#plane_nx') 11HexaLab.UI.plane_ny = $('#plane_ny') 12HexaLab.UI.plane_nz = $('#plane_nz') 13HexaLab.UI.plane_snap_nx = $('#plane_snap_nx') 14HexaLab.UI.plane_snap_ny = $('#plane_snap_ny') 15HexaLab.UI.plane_snap_nz = $('#plane_snap_nz') 16HexaLab.UI.plane_swap = $('#plane_swap_sign') 17HexaLab.UI.plane_snap_camera = $('#plane_snap_camera') 18HexaLab.UI.plane_menu_content = $('#plane_menu *') 19 20HexaLab.UI.plane_menu_content.prop('disabled', true) 21HexaLab.UI.plane_offset_slider.slider('disable') 22 23 24// -------------------------------------------------------------------------------- 25// Filter class 26// -------------------------------------------------------------------------------- 27HexaLab.PlaneFilter = function () { 28 29 // Ctor 30 HexaLab.Filter.call(this, new Module.PlaneFilter(), 'Plane'); 31 32 // Listener 33 var self = this; 34 HexaLab.UI.plane_enabled.change(function () { 35 self.enable($(this).is(':checked')) 36 }) 37 HexaLab.UI.plane_nx.change(function () { 38 self.set_plane_normal(parseFloat(this.value), self.plane.normal.y, self.plane.normal.z) 39 }) 40 HexaLab.UI.plane_ny.change(function () { 41 self.set_plane_normal(self.plane.normal.x, parseFloat(this.value), self.plane.normal.z) 42 }) 43 HexaLab.UI.plane_nz.change(function () { 44 self.set_plane_normal(self.plane.normal.x, self.plane.normal.y, parseFloat(this.value)) 45 }) 46 HexaLab.UI.plane_offset_number.change(function () { 47 self.set_plane_offset(parseFloat(this.value)) 48 }) 49 HexaLab.UI.plane_offset_slider.slider({ 50 min: 0, 51 max: 1000 52 }).on('slide', function (e, ui) { 53 self.set_plane_offset(ui.value / 1000) 54 }).on('slidestart', function(e, ui) { 55 self.visible_color = true 56 self.visible_edge = true 57 self.update_visibility() 58 }).on('slidestop', function(e, ui) { 59 self.visible_color = false 60 self.visible_edge = false 61 self.update_visibility() 62 }) 63 HexaLab.UI.plane_snap_nx.on('click', function () { 64 self.set_plane_normal(1, 0, 0) 65 }) 66 HexaLab.UI.plane_snap_ny.on('click', function () { 67 self.set_plane_normal(0, 1, 0) 68 }) 69 HexaLab.UI.plane_snap_nz.on('click', function () { 70 self.set_plane_normal(0, 0, 1) 71 }) 72 HexaLab.UI.plane_swap.on('click', function () { 73 self.flip_plane(); 74 }) 75 76 HexaLab.UI.plane_snap_camera.on('dblclick', function (e) { 77 self.toggle_auto_plane_normal_on_rotate() 78 }) 79 80 HexaLab.UI.plane_snap_camera.on('click', function (e) { 81 self.set_plane_normal_as_view( e.ctrlKey || e.shiftKey || e.altKey , true ) 82 self.disable_auto_plane_normal_on_rotate() 83 }) 84 85 /*HexaLab.UI.plane_color.change(function () { 86 self.set_plane_color($(this).val()); 87 }) 88 HexaLab.UI.plane_opacity.slider().on('slide', function (e, ui) { 89 self.set_plane_opacity(ui.value / 100); 90 })*/ 91 92 // State 93 this.plane = { 94 material: new THREE.MeshBasicMaterial({ 95 transparent: true, 96 side: THREE.DoubleSide, 97 depthWrite: false 98 }), 99 mesh: new THREE.Mesh(), 100 edges: new THREE.LineSegments() 101 }; 102 103 self.visible_color = false 104 self.visible_edge = false 105 106 this.default_settings = { 107 enabled: false, 108 normal: new THREE.Vector3(1, 0, 0), 109 offset: 0, 110 opacity: 0.05, 111 color: "#56bbbb" 112 } 113}; 114 115HexaLab.PlaneFilter.prototype = Object.assign(Object.create(HexaLab.Filter.prototype), { 116 117 // Api 118 get_settings: function () { 119 const n = this.backend.get_plane_normal() 120 const s = { 121 enabled: this.backend.enabled, 122 normal: new THREE.Vector3(n.x(), n.y(), n.z()), 123 offset: this.backend.get_plane_offset(), 124 opacity: this.plane.material.opacity, 125 color: '#' + this.plane.material.color.getHexString() 126 } 127 n.delete() 128 return s 129 }, 130 131 set_settings: function (settings) {
132 this.enable(settings.enabled) 133 this.set_plane_normal(settings.normal.x, settings.normal.y, settings.normal.z) 134 this.set_plane_offset(settings.offset) 135 this.set_plane_opacity(settings.opacity) 136 this.set_plane_color(settings.color) 137 }, 138 139 on_mesh_change: function (mesh) { 140 this.nx = undefined; 141 this.object_mesh = mesh 142 143 HexaLab.app.viewer.remove_mesh(this.plane.mesh) 144 HexaLab.app.viewer.remove_mesh(this.plane.edges) 145 146 var geometry = new THREE.PlaneGeometry(this.object_mesh.get_aabb_diagonal(), this.object_mesh.get_aabb_diagonal()); 147 var edges = new THREE.EdgesGeometry(geometry) 148 149 this.plane.mesh = new THREE.Mesh(geometry, this.plane.material); 150 this.plane.edges = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ 151 color: this.plane.material.color, 152 transparent: true, 153 opacity: 0.0 // TODO differentiate between filter scene objects meshes and wireframe, draw meshes pre-ssao, wireframe post-ssao 154 })) 155 156 HexaLab.app.viewer.add_mesh(this.plane.mesh) 157 HexaLab.app.viewer.add_mesh(this.plane.edges) 158 159 this.update_visibility() 160 161 this.set_plane_opacity(this.default_settings.opacity) 162 this.set_plane_color(this.default_settings.color) 163 164 this.on_enabled_set(this.backend.enabled) 165 this.on_plane_normal_set(this.read_normal_from_backend()) 166 this.on_plane_offset_set(this.backend.get_plane_offset()) 167 168 this.update_mesh(); 169 170 HexaLab.UI.plane_menu_content.prop('disabled', false) 171 HexaLab.UI.plane_offset_slider.slider('enable') 172 }, 173 174 // misc 175 176 read_normal_from_backend: function () { 177 const n = this.backend.get_plane_normal() 178 const v = new THREE.Vector3(n.x(), n.y(), n.z()) 179 n.delete() 180 return v 181 }, 182 183 // system -> UI 184 185 on_enabled_set: function (bool) { 186 HexaLab.UI.plane_enabled.prop('checked', bool) 187 }, 188 189 on_plane_normal_set: function (normal) { 190 HexaLab.UI.plane_nx.val(normal.x.toFixed(2)) 191 HexaLab.UI.plane_ny.val(normal.y.toFixed(2)) 192 HexaLab.UI.plane_nz.val(normal.z.toFixed(2)) 193 }, 194 195 on_plane_offset_set: function (offset) { 196 HexaLab.UI.plane_offset_slider.slider('value', offset * 1000) 197 HexaLab.UI.plane_offset_number.val(offset.toFixed(3)) 198 }, 199 200 // State 201 202 nx : undefined, 203 ny : undefined, 204 nz : undefined, 205 offset : 0, 206 auto_set_normal : false, 207 208 enable: function (enabled) { 209 this.backend.enabled = enabled 210 this.update_visibility() 211 this.on_enabled_set(enabled) 212 HexaLab.app.queue_buffers_update() 213 }, 214 215 set_plane_normal: function (nx, ny, nz) { 216 this.nx = nx; 217 this.ny = ny; 218 this.nz = nz; 219 this.backend.set_plane_normal(nx, ny, nz) 220 const normal = new THREE.Vector3(nx, ny, nz) 221 this.on_plane_normal_set(normal) 222 this.update_mesh() 223 HexaLab.app.queue_buffers_update() 224 }, 225 226 toggle_auto_plane_normal_on_rotate( ){ 227 this.auto_set_normal = ! this.auto_set_normal; 228 if (this.auto_set_normal) 229 HexaLab.UI.plane_snap_camera.addClass("checked"); 230 else 231 HexaLab.UI.plane_snap_camera.removeClass("checked"); 232 }, 233 234 disable_auto_plane_normal_on_rotate( ){ 235 this.auto_set_normal = false; 236 HexaLab.UI.plane_snap_camera.removeClass("checked"); 237 }, 238 239 flip_plane: function(){ 240 this.set_plane_normal(-this.nx,-this.ny,-this.nz) 241 this.set_plane_offset( 1.0 - this.offset ); 242 //this.set_plane_offset(1 - this.backend.get_plane_offset()) 243 }, 244 set_plane_normal_as_view: function( snap_to_axis , maybe_flip){ 245 let camera_dir = new THREE.Vector3() 246 HexaLab.app.camera().getWorldDirection(camera_dir) 247 if (!closest_axis && (maybe_flip===true)) { 248 var dot = camera_dir.x*this.nx+camera_dir.y*this.ny+camera_dir.z*this.nz; 249 if (dot<-0.9) {this.flip_plane(); return;} 250 } 251 252 var closest_axis = function( dir ){ 253 var m = Math.max( Math.abs(dir.x), Math.max( Math.abs(dir.y), Math.abs(dir.z) ) ); 254 if ( dir.x == m ) return {x:1,y:0,z:0} 255 if ( dir.x == -m ) return {x:-1,y:0,z:0} 256 if ( dir.y == m ) return {x:0,y:1,z:0} 257 if ( dir.y == -m ) return {x:0,y:-1,z:0} 258 if ( dir.z == m ) return {x:0,y:0,z:1} 259 /*if ( dir.z == -m )*/ return {x:0,y:0,z:-1} 260 } 261 262 if (snap_to_axis) { 263 camera_dir = closest_axis( camera_dir ); 264 } 265 this.set_plane_normal(camera_dir.x, camera_dir.y, camera_dir.z) 266 }, 267 268 on_change_view: function() { 269 if (this.offset==0) this.nx = undefined; // forget current cut plane 270 else if (this.auto_set_normal) this.set_plane_normal_as_view(false); 271 272 }, 273 set_plane_offset: function (offset) { 274 this.offset = offset 275 if (offset!=0 && this.nx == undefined) this.set_plane_normal_as_view( true ) 276 this.backend.set_plane_offset(offset) 277 this.plane.world_offset = this.backend.get_plane_world_offset() 278 this.on_plane_offset_set(offset) 279 this.update_mesh()
280 HexaLab.app.queue_buffers_update() 281 }, 282 283 set_plane_opacity: function (opacity) { 284 this.plane.material.opacity = opacity 285 HexaLab.app.queue_canvas_update() 286 }, 287 288 set_plane_color: function (color) { 289 this.plane.material.color.set(color) 290 HexaLab.app.queue_canvas_update() 291 }, 292 293 update_visibility: function () { 294 if (this.backend.enabled) { 295 if (this.visible_color) { 296 this.plane.mesh.visible = true 297 } else { 298 this.plane.mesh.visible = false 299 } 300 if (this.visible_edge) { 301 this.plane.edges.visible = true 302 } else { 303 this.plane.edges.visible = false 304 } 305 } else { 306 if (this.plane.mesh) this.plane.mesh.visible = false 307 if (this.plane.edges) this.plane.edges.visible = false 308 } 309 HexaLab.app.queue_canvas_update() 310 }, 311 312 update_mesh: function () { 313 if (this.object_mesh) { 314 for (var x of [this.plane.mesh, this.plane.edges]) { 315 var pos = this.object_mesh.get_aabb_center() 316 x.position.set(pos.x(), pos.y(), pos.z()) 317 //x.position.set(0, 0, 0) 318 const n = this.backend.get_plane_normal() 319 const normal = new THREE.Vector3(n.x(), n.y(), n.z()) 320 n.delete() 321 var dir = new THREE.Vector3().addVectors(x.position, normal) 322 x.lookAt(dir) 323 x.translateZ(-this.plane.world_offset) 324 } 325 } 326 } 327}); 328 329HexaLab.filters.push(new HexaLab.PlaneFilter())
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.