Skip to content

Commit 15e8671

Browse files
authored
Fixes #39 Scene lighting needs improvement (#85)
* Add helpers for directional and hemisphere lights * Add lighting controls * Add helper toggle and make directional controls spherical * Improve lighting * Remove pointless directional light distance slider * Fix resize cursor * Remove Target folder * Reorganize folders * Refactor and lint CSS * Fix panda lighting
1 parent 070f3c8 commit 15e8671

File tree

5 files changed

+465
-128
lines changed

5 files changed

+465
-128
lines changed

examples/franka_panda_description/meshes/visual/link0.dae

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -50,92 +50,6 @@
5050
</extra>
5151
</camera>
5252
</library_cameras>
53-
<library_lights>
54-
<light id="Light-light" name="Light.007">
55-
<technique_common>
56-
<point>
57-
<color sid="color">1000 1000 1000</color>
58-
<constant_attenuation>1</constant_attenuation>
59-
<linear_attenuation>0</linear_attenuation>
60-
<quadratic_attenuation>0.00111109</quadratic_attenuation>
61-
</point>
62-
</technique_common>
63-
<extra>
64-
<technique profile="blender">
65-
<type sid="type" type="int">0</type>
66-
<flag sid="flag" type="int">0</flag>
67-
<mode sid="mode" type="int">1</mode>
68-
<gamma sid="blender_gamma" type="float">1</gamma>
69-
<red sid="red" type="float">1</red>
70-
<green sid="green" type="float">1</green>
71-
<blue sid="blue" type="float">1</blue>
72-
<shadow_r sid="blender_shadow_r" type="float">0</shadow_r>
73-
<shadow_g sid="blender_shadow_g" type="float">0</shadow_g>
74-
<shadow_b sid="blender_shadow_b" type="float">0</shadow_b>
75-
<energy sid="blender_energy" type="float">1000</energy>
76-
<dist sid="blender_dist" type="float">29.99998</dist>
77-
<spotsize sid="spotsize" type="float">75</spotsize>
78-
<spotblend sid="spotblend" type="float">0.15</spotblend>
79-
<att1 sid="att1" type="float">0</att1>
80-
<att2 sid="att2" type="float">1</att2>
81-
<falloff_type sid="falloff_type" type="int">2</falloff_type>
82-
<clipsta sid="clipsta" type="float">0.04999995</clipsta>
83-
<clipend sid="clipend" type="float">30.002</clipend>
84-
<bias sid="bias" type="float">1</bias>
85-
<soft sid="soft" type="float">3</soft>
86-
<bufsize sid="bufsize" type="int">2880</bufsize>
87-
<samp sid="samp" type="int">3</samp>
88-
<buffers sid="buffers" type="int">1</buffers>
89-
<area_shape sid="area_shape" type="int">1</area_shape>
90-
<area_size sid="area_size" type="float">0.1</area_size>
91-
<area_sizey sid="area_sizey" type="float">0.1</area_sizey>
92-
<area_sizez sid="area_sizez" type="float">1</area_sizez>
93-
</technique>
94-
</extra>
95-
</light>
96-
<light id="Light_001-light" name="Light.006">
97-
<technique_common>
98-
<point>
99-
<color sid="color">1000 1000 1000</color>
100-
<constant_attenuation>1</constant_attenuation>
101-
<linear_attenuation>0</linear_attenuation>
102-
<quadratic_attenuation>0.00111109</quadratic_attenuation>
103-
</point>
104-
</technique_common>
105-
<extra>
106-
<technique profile="blender">
107-
<type sid="type" type="int">0</type>
108-
<flag sid="flag" type="int">0</flag>
109-
<mode sid="mode" type="int">1</mode>
110-
<gamma sid="blender_gamma" type="float">1</gamma>
111-
<red sid="red" type="float">1</red>
112-
<green sid="green" type="float">1</green>
113-
<blue sid="blue" type="float">1</blue>
114-
<shadow_r sid="blender_shadow_r" type="float">0</shadow_r>
115-
<shadow_g sid="blender_shadow_g" type="float">0</shadow_g>
116-
<shadow_b sid="blender_shadow_b" type="float">0</shadow_b>
117-
<energy sid="blender_energy" type="float">1000</energy>
118-
<dist sid="blender_dist" type="float">29.99998</dist>
119-
<spotsize sid="spotsize" type="float">75</spotsize>
120-
<spotblend sid="spotblend" type="float">0.15</spotblend>
121-
<att1 sid="att1" type="float">0</att1>
122-
<att2 sid="att2" type="float">1</att2>
123-
<falloff_type sid="falloff_type" type="int">2</falloff_type>
124-
<clipsta sid="clipsta" type="float">0.04999995</clipsta>
125-
<clipend sid="clipend" type="float">30.002</clipend>
126-
<bias sid="bias" type="float">1</bias>
127-
<soft sid="soft" type="float">3</soft>
128-
<bufsize sid="bufsize" type="int">2880</bufsize>
129-
<samp sid="samp" type="int">3</samp>
130-
<buffers sid="buffers" type="int">1</buffers>
131-
<area_shape sid="area_shape" type="int">1</area_shape>
132-
<area_size sid="area_size" type="float">0.1</area_size>
133-
<area_sizey sid="area_sizey" type="float">0.1</area_sizey>
134-
<area_sizez sid="area_sizez" type="float">1</area_sizez>
135-
</technique>
136-
</extra>
137-
</light>
138-
</library_lights>
13953
<library_effects>
14054
<effect id="Part__Feature017_001_007-effect">
14155
<profile_COMMON>

src/controls.ts

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ export class URDFControls extends GUI {
2525
grid: {},
2626
height: {}
2727
},
28-
joints: {}
28+
joints: {},
29+
lights: {}
2930
};
3031

3132
/**
@@ -47,6 +48,9 @@ export class URDFControls extends GUI {
4748
});
4849

4950
// Create folders
51+
this._jointsFolder = this.addFolder('Joints');
52+
this._jointsFolder.domElement.setAttribute('class', 'dg joints-folder');
53+
5054
this._workspaceFolder = this.addFolder('Workspace');
5155
this._workspaceFolder.domElement.setAttribute(
5256
'class',
@@ -55,9 +59,6 @@ export class URDFControls extends GUI {
5559

5660
this._sceneFolder = this.addFolder('Scene');
5761
this._sceneFolder.domElement.setAttribute('class', 'dg scene-folder');
58-
59-
this._jointsFolder = this.addFolder('Joints');
60-
this._jointsFolder.domElement.setAttribute('class', 'dg joints-folder');
6162
}
6263

6364
/**
@@ -262,5 +263,133 @@ export class URDFControls extends GUI {
262263
document.addEventListener('mouseup', onMouseUp);
263264
}
264265
});
266+
267+
// Show resize cursor when hovering near left edge
268+
this.domElement.addEventListener('mousemove', (e: MouseEvent) => {
269+
const rect = this.domElement.getBoundingClientRect();
270+
const offsetX = e.clientX - rect.left;
271+
this.domElement.style.cursor =
272+
offsetX < grabZoneWidth || isResizing ? 'ew-resize' : 'auto';
273+
});
274+
this.domElement.addEventListener('mouseleave', () => {
275+
if (!isResizing) {
276+
this.domElement.style.cursor = 'auto';
277+
}
278+
});
279+
}
280+
281+
/**
282+
* Creates controls for the different lights in the scene
283+
*
284+
* @returns - The controls to trigger callbacks when light settings change
285+
*/
286+
createLightControls() {
287+
if (this._isEmpty(this.controls.lights)) {
288+
// Create subfolders for each light
289+
const directionalFolder =
290+
this._sceneFolder.addFolder('Directional Light');
291+
const ambientFolder = this._sceneFolder.addFolder('Ambient Light');
292+
const hemisphereFolder = this._sceneFolder.addFolder('Hemisphere Light');
293+
294+
// Initialize settings for each light type
295+
const directionalSettings = {
296+
Altitude: Math.PI / 4, // 45 degrees elevation
297+
Azimuth: Math.PI / 4, // 45 degrees around vertical axis
298+
Color: [255, 255, 255],
299+
Intensity: 1.0,
300+
ShowHelper: false
301+
};
302+
303+
const ambientSettings = {
304+
Color: [255, 255, 255],
305+
Intensity: 0.5
306+
};
307+
308+
const hemisphereSettings = {
309+
SkyColor: [255, 255, 255],
310+
GroundColor: [38, 50, 56],
311+
Intensity: 1.0,
312+
ShowHelper: false
313+
};
314+
315+
// Spherical coordinate angle limits and steps
316+
const minAngle = -Math.PI;
317+
const maxAngle = Math.PI;
318+
const angleStep = 0.01;
319+
320+
// Intensity limits and steps
321+
const minIntensity = 0;
322+
const maxIntensity = 10;
323+
const intensityStep = 0.1;
324+
325+
// Controls for directional light
326+
this.controls.lights.directional = {
327+
position: {
328+
altitude: directionalFolder.add(
329+
directionalSettings,
330+
'Altitude',
331+
minAngle,
332+
maxAngle,
333+
angleStep
334+
),
335+
azimuth: directionalFolder.add(
336+
directionalSettings,
337+
'Azimuth',
338+
minAngle,
339+
maxAngle,
340+
angleStep
341+
)
342+
},
343+
color: directionalFolder.addColor(directionalSettings, 'Color'),
344+
intensity: directionalFolder.add(
345+
directionalSettings,
346+
'Intensity',
347+
minIntensity,
348+
maxIntensity,
349+
intensityStep
350+
),
351+
showHelper: directionalFolder
352+
.add(directionalSettings, 'ShowHelper')
353+
.name('Show Helper')
354+
};
355+
356+
// Ambient light controls
357+
this.controls.lights.ambient = {
358+
color: ambientFolder.addColor(ambientSettings, 'Color'),
359+
intensity: ambientFolder.add(
360+
ambientSettings,
361+
'Intensity',
362+
minIntensity,
363+
maxIntensity,
364+
intensityStep
365+
)
366+
};
367+
368+
// Hemisphere light controls
369+
this.controls.lights.hemisphere = {
370+
skyColor: hemisphereFolder
371+
.addColor(hemisphereSettings, 'SkyColor')
372+
.name('Sky Color'),
373+
groundColor: hemisphereFolder
374+
.addColor(hemisphereSettings, 'GroundColor')
375+
.name('Ground Color'),
376+
intensity: hemisphereFolder.add(
377+
hemisphereSettings,
378+
'Intensity',
379+
minIntensity,
380+
maxIntensity,
381+
intensityStep
382+
),
383+
showHelper: hemisphereFolder
384+
.add(hemisphereSettings, 'ShowHelper')
385+
.name('Show Helper')
386+
};
387+
388+
// Open Scene (lights) and directional subfolder
389+
this._sceneFolder.open();
390+
directionalFolder.open();
391+
}
392+
393+
return this.controls.lights;
265394
}
266395
}

src/layout.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export class URDFLayout extends PanelLayout {
165165
this._setPathControls();
166166
this._setSceneControls();
167167
this._setJointControls();
168+
this._setLightControls();
168169
}
169170

170171
/**
@@ -214,6 +215,72 @@ export class URDFLayout extends PanelLayout {
214215
});
215216
}
216217

218+
/**
219+
* Set callback for changing directional light position in the controls panel.
220+
*/
221+
private _setLightControls(): void {
222+
const lightControl = this._controlsPanel.createLightControls();
223+
224+
// Directional light callbacks
225+
const directional = lightControl.directional;
226+
227+
// Position controls using spherical coordinates
228+
directional.position.altitude.onChange((newAltitude: number) => {
229+
const azimuth = directional.position.azimuth.getValue();
230+
this._renderer.setDirectionalLightPositionSpherical(newAltitude, azimuth);
231+
});
232+
233+
directional.position.azimuth.onChange((newAzimuth: number) => {
234+
const altitude = directional.position.altitude.getValue();
235+
this._renderer.setDirectionalLightPositionSpherical(altitude, newAzimuth);
236+
});
237+
238+
// Color and intensity controls
239+
directional.color.onChange((newColor: number[]) => {
240+
this._renderer.setDirectionalLightColor(newColor);
241+
});
242+
243+
directional.intensity.onChange((newIntensity: number) => {
244+
this._renderer.setDirectionalLightIntensity(newIntensity);
245+
});
246+
247+
// Helper visibility toggle for directional light
248+
directional.showHelper.onChange((visible: boolean) => {
249+
this._renderer.setDirectionalLightHelperVisibility(visible);
250+
});
251+
252+
// Ambient light callbacks
253+
const ambient = lightControl.ambient;
254+
255+
ambient.color.onChange((newColor: number[]) => {
256+
this._renderer.setAmbientLightColor(newColor);
257+
});
258+
259+
ambient.intensity.onChange((newIntensity: number) => {
260+
this._renderer.setAmbientLightIntensity(newIntensity);
261+
});
262+
263+
// Hemisphere light callbacks
264+
const hemisphere = lightControl.hemisphere;
265+
266+
hemisphere.skyColor.onChange((newColor: number[]) => {
267+
this._renderer.setHemisphereLightSkyColor(newColor);
268+
});
269+
270+
hemisphere.groundColor.onChange((newColor: number[]) => {
271+
this._renderer.setHemisphereLightGroundColor(newColor);
272+
});
273+
274+
hemisphere.intensity.onChange((newIntensity: number) => {
275+
this._renderer.setHemisphereLightIntensity(newIntensity);
276+
});
277+
278+
// Helper visibility toggle for hemisphere light
279+
hemisphere.showHelper.onChange((visible: boolean) => {
280+
this._renderer.setHemisphereLightHelperVisibility(visible);
281+
});
282+
}
283+
217284
/**
218285
* Set value for robot joint
219286
*

0 commit comments

Comments
 (0)