PageSourceSearch

https://www.hexalab.net/js/filters/plane_filter.js

js hexalab.net collected 2026-10-03 19:40:21 UTC 11,049 bytes, 329 lines download raw bytes

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.