Skip to content

Commit bb4ec6d

Browse files
author
Léna Voinchet
committed
Add filling and dynamic opacity to lidar shape
1 parent 628ff00 commit bb4ec6d

File tree

1 file changed

+65
-29
lines changed

1 file changed

+65
-29
lines changed

js/scene/objects/sensors/Lidar.js

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Vector3,
1010
LineSegments,
1111
Color,
12+
DoubleSide,
1213
Group
1314
} from 'three';
1415

@@ -117,26 +118,47 @@ class Lidar{
117118

118119
buildRaysOutlineHelper()
119120
{
121+
const firstRayAngle = -Math.PI / 2 - (this.lidarType.fov / 2 * Math.PI / 180);
122+
const angularRes = this.lidarType.angularResolution;
123+
const angularResRad = angularRes * Math.PI / 180;
124+
const fovRad = this.lidarType.fov * Math.PI / 180;
125+
126+
// Computes dynamic opacity
127+
const resMin = 0.01;
128+
const resMax = 0.33;
129+
const opacityMin = 0.15;
130+
const opacityMax = 0.8;
131+
132+
const clampedRes = Math.max(resMin, Math.min(resMax, angularRes));
133+
const t = 1.0 - ((clampedRes - resMin) / (resMax - resMin));
134+
135+
const dynamicOpacity = opacityMin + t * (opacityMax - opacityMin);
136+
137+
// Creates materials for line + surface
120138
const material = new LineBasicMaterial({
121139
color: this.color,
122140
transparent: true,
123141
opacity: 1,
124142
linewidth: 1
125143
});
126144

127-
const firstRayAngle = -Math.PI / 2 - (this.lidarType.fov / 2 * Math.PI / 180);
128-
const angularResRad = this.lidarType.angularResolution * Math.PI / 180;
129-
const fovRad = this.lidarType.fov * Math.PI / 180;
145+
const fillMaterial = new MeshBasicMaterial({
146+
color: this.color,
147+
transparent: true,
148+
opacity: dynamicOpacity,
149+
side: DoubleSide
150+
});
151+
152+
const helperGroup = new Group();
153+
helperGroup.name = "LidarHelperGroup";
130154

131155
// Returns an empty line if fov or angular resolution is null
132156
if (fovRad <= 1e-6 || angularResRad <= 1e-6) {
133-
const emptyGeometry = new BufferGeometry();
134-
return new LineSegments(emptyGeometry, material);
157+
return helperGroup;
135158
}
136159

137160
// Computes the number of segments needed
138161
const numArcSegments = Math.max(1, Math.floor(fovRad / angularResRad));
139-
console.log(numArcSegments);
140162

141163
const arcPointsInner = [];
142164
const arcPointsOuter = [];
@@ -156,41 +178,55 @@ class Lidar{
156178
);
157179
}
158180

181+
// --- STEP 1 : BUILD OF LINE ---
159182
const lineVertices = []; // Array to store lines vertices
160183

161-
// Inside arc vertices
184+
// Inside and outside arcs
162185
for (let i = 0; i < numArcSegments; i++) {
163-
lineVertices.push(arcPointsInner[i].x, arcPointsInner[i].y, arcPointsInner[i].z);
164-
lineVertices.push(arcPointsInner[i+1].x, arcPointsInner[i+1].y, arcPointsInner[i+1].z);
186+
lineVertices.push(...arcPointsInner[i].toArray(), ...arcPointsInner[i + 1].toArray());
187+
lineVertices.push(...arcPointsOuter[i].toArray(), ...arcPointsOuter[i + 1].toArray());
165188
}
189+
// First and last lines (fov)
190+
lineVertices.push(...arcPointsInner[0].toArray(), ...arcPointsOuter[0].toArray());
191+
lineVertices.push(...arcPointsInner[numArcSegments].toArray(), ...arcPointsOuter[numArcSegments].toArray());
166192

167-
// Outside arc vertices
168-
for (let i = 0; i < numArcSegments; i++) {
169-
lineVertices.push(arcPointsOuter[i].x, arcPointsOuter[i].y, arcPointsOuter[i].z);
170-
lineVertices.push(arcPointsOuter[i+1].x, arcPointsOuter[i+1].y, arcPointsOuter[i+1].z);
193+
const lineGeometry = new BufferGeometry();
194+
if (lineVertices.length > 0) {
195+
lineGeometry.setAttribute('position', new BufferAttribute(new Float32Array(lineVertices), 3));
171196
}
172197

173-
// First radial line (start of Fov)
174-
if (arcPointsInner.length > 0 && arcPointsOuter.length > 0) {
175-
lineVertices.push(arcPointsInner[0].x, arcPointsInner[0].y, arcPointsInner[0].z);
176-
lineVertices.push(arcPointsOuter[0].x, arcPointsOuter[0].y, arcPointsOuter[0].z);
177-
}
198+
const lineHelper = new LineSegments(lineGeometry, material);
199+
lineHelper.name = "LidarRaysOutlineHelper"; // Name for debugg
200+
helperGroup.add(lineHelper);
201+
202+
// --- STEP 2: BUILD OF SURFACE ---
203+
const fillVertices = []; // Array to store surface vertices
204+
205+
for (let i = 0; i < numArcSegments; i++) {
206+
const p1 = arcPointsInner[i];
207+
const p2 = arcPointsOuter[i];
208+
const p3 = arcPointsInner[i+1];
209+
const p4 = arcPointsOuter[i+1];
210+
211+
// Premier triangle (p1, p2, p3)
212+
fillVertices.push(...p1.toArray(), ...p2.toArray(), ...p3.toArray());
213+
214+
// Deuxième triangle (p3, p2, p4)
215+
fillVertices.push(...p3.toArray(), ...p2.toArray(), ...p4.toArray());
178216

179-
// Last radial line (end of Fov)
180-
if (arcPointsInner.length > 0 && arcPointsOuter.length > 0) {
181-
const lastPointIndex = arcPointsInner.length - 1;
182-
lineVertices.push(arcPointsInner[lastPointIndex].x, arcPointsInner[lastPointIndex].y, arcPointsInner[lastPointIndex].z);
183-
lineVertices.push(arcPointsOuter[lastPointIndex].x, arcPointsOuter[lastPointIndex].y, arcPointsOuter[lastPointIndex].z);
184217
}
185218

186-
const geometry = new BufferGeometry();
187-
if (lineVertices.length > 0) {
188-
geometry.setAttribute('position', new BufferAttribute(new Float32Array(lineVertices), 3));
219+
const fillGeometry = new BufferGeometry();
220+
if (fillVertices.length > 0) {
221+
fillGeometry.setAttribute('position', new BufferAttribute(new Float32Array(fillVertices), 3));
189222
}
190223

191-
const lineHelper = new LineSegments(geometry, material);
192-
lineHelper.name = "LidarRaysOutlineHelper"; // Name for debugg
193-
return lineHelper;
224+
const fillMesh = new Mesh(fillGeometry, fillMaterial);
225+
fillMesh.name = "LidarFillHelper";
226+
helperGroup.add(fillMesh);
227+
228+
// --- STEP 3 : RETURN ---
229+
return helperGroup;
194230
}
195231

196232
updateTextPosition()

0 commit comments

Comments
 (0)