MikaFil commited on
Commit
383fa47
·
verified ·
1 Parent(s): 3018fcd

Update deplacement_dans_env/ctrl_camera_pr_env.js

Browse files
deplacement_dans_env/ctrl_camera_pr_env.js CHANGED
@@ -35,13 +35,10 @@ FreeCamera.attributes.add('maxStepDistance', { type: 'number', default: 0.20, ti
35
  FreeCamera.attributes.add('maxResolveIters', { type: 'number', default: 6, title: 'Max resolve iterations per step' });
36
 
37
  // Construction des colliders
38
- // IMPORTANT: garder très petit; on n'"épaissit" plus agressivement pour l'indoor
39
  FreeCamera.attributes.add('inflateBias', { type: 'number', default: 0.0, title: 'Extra inflate (m, tiny)' });
40
- // On ne merge presque pas : uniquement si recouvrement réel (tolérance numérique)
41
  FreeCamera.attributes.add('mergeGap', { type: 'number', default: 0.0, title: 'Merge AABBs gap (0 = pas de gap)' });
42
 
43
- // Filtrage "anti-coquille" : on supprime toute AABB dont la taille est trop proche de l’AABB monde
44
- // Par axe: if halfExtents >= worldHalfExtents * (1 - globalCullFrac) => on la considère "quasi globale".
45
  FreeCamera.attributes.add('globalCullFrac', { type: 'number', default: 0.08, title: 'Cull near-global AABBs (0.08=8%)' });
46
 
47
  // Bounding Box globale optionnelle (Xmin..Zmax)
@@ -86,9 +83,9 @@ FreeCamera.prototype.initialize = function () {
86
  this.state = this.app.systems.script.app.freeCamState;
87
 
88
  // colliders
89
- this._buildIndoorSafeColliders(); // <= clé de la correction
90
 
91
- // Forcer une passe de résolution initiale (si on spawn “dans” un mur)
92
  var p = this.entity.getPosition().clone();
93
  p = this._moveSweptTo(p, p);
94
  this._clampPosition(p);
@@ -151,7 +148,7 @@ FreeCamera.prototype._buildIndoorSafeColliders = function () {
151
  for (var j = 1; j < boxes.length; j++) world.add(boxes[j]);
152
 
153
  // 3) Filtrer les AABBs "quasi globales" (anti-coquille)
154
- var frac = pc.math.clamp(this.globalCullFrac, 0, 0.49); // max 49% de tolérance
155
  var wh = world.halfExtents;
156
  var filtered = [];
157
  for (var k = 0; k < boxes.length; k++) {
@@ -163,10 +160,10 @@ FreeCamera.prototype._buildIndoorSafeColliders = function () {
163
  if (!nearGlobal) filtered.push(boxes[k]);
164
  }
165
 
166
- // 4) Optionnel : petit merge *strict* (uniquement si chevauchement réel)
167
  var merged = this._mergeAabbs(filtered, Math.max(0, this.mergeGap || 0));
168
 
169
- // 5) Gonfler très légèrement (epsilon), pas du rayon complet — le rayon est traité par la résolution
170
  var inflate = Math.max(0, this.inflateBias || 0);
171
  for (var m = 0; m < merged.length; m++) {
172
  merged[m].halfExtents.add(new pc.Vec3(inflate, inflate, inflate));
@@ -178,7 +175,6 @@ FreeCamera.prototype._buildIndoorSafeColliders = function () {
178
  this._worldAabb = world;
179
  this._useCollision = true;
180
  } else {
181
- // Aucun collider utile après filtrage : on désactive les collisions pour ne pas bloquer
182
  this._colliders = [];
183
  this._useCollision = false;
184
  console.warn('[orbitCamera] Aucun collider utile trouvé (désactivation des collisions)');
@@ -215,11 +211,27 @@ FreeCamera.prototype._mergeAabbs = function (boxes, gap) {
215
  if (overlap(acc, out[j], tol)) {
216
  var aMin = acc.getMin(), aMax = acc.getMax();
217
  var bMin = out[j].getMin(), bMax = out[j].getMax();
218
- var nMin = new pc.Vec3(Math.min(aMin.x, bMin.x), Math.min(aMin.y, bMin.y), Math.min(aMin.z, bMin.z));
219
- var nMax = new pc.Vec3(Math.max(aMax.x, bMax.x), Math.max(aMax.y, bMax.y), Math.max(aMax.z, bMax.z));
220
- var c = nMin.clone().add(nMax).mulScalar(0.5);
221
- var h = nMax.clone().sub(c).abs();
222
- acc = new pc.BoundingBox(c, h);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  used[j] = true;
224
  changed = true;
225
  }
@@ -247,7 +259,7 @@ FreeCamera.prototype._clampPosition = function (p) {
247
 
248
  // ======================== Mouvement swept + résolution =====================
249
  FreeCamera.prototype._moveSweptTo = function (from, to) {
250
- if (!this._useCollision) return to.clone(); // collisions désactivées => pas de blocage
251
 
252
  var maxStep = Math.max(0.01, this.maxStepDistance || 0.2);
253
  var delta = to.clone().sub(from);
@@ -287,7 +299,7 @@ FreeCamera.prototype._resolveCollisions = function (pos, maxIters) {
287
  var aabb = this._colliders[i].aabb;
288
  var min = aabb.getMin(); var max = aabb.getMax();
289
 
290
- // Calcul du point le plus proche
291
  var cx = pc.math.clamp(p.x, min.x, max.x);
292
  var cy = pc.math.clamp(p.y, min.y, max.y);
293
  var cz = pc.math.clamp(p.z, min.z, max.z);
@@ -295,7 +307,6 @@ FreeCamera.prototype._resolveCollisions = function (pos, maxIters) {
295
  var dx = p.x - cx, dy = p.y - cy, dz = p.z - cz;
296
  var distSq = dx*dx + dy*dy + dz*dz;
297
 
298
- // Collision sphère vs AABB (AABB non "gonflée" au rayon ; on le traite ici)
299
  if (distSq < (R*R)) {
300
  var dist = Math.sqrt(Math.max(distSq, 1e-12));
301
  var pen = R - dist + eps;
@@ -305,7 +316,7 @@ FreeCamera.prototype._resolveCollisions = function (pos, maxIters) {
305
  p.y += (dy / dist) * pen;
306
  p.z += (dz / dist) * pen;
307
  } else {
308
- // au même point : pousse vers l'axe de plus faible sortie
309
  var ex = Math.min(Math.abs(p.x - min.x), Math.abs(max.x - p.x));
310
  var ey = Math.min(Math.abs(p.y - min.y), Math.abs(max.y - p.y));
311
  var ez = Math.min(Math.abs(p.z - min.z), Math.abs(max.z - p.z));
 
35
  FreeCamera.attributes.add('maxResolveIters', { type: 'number', default: 6, title: 'Max resolve iterations per step' });
36
 
37
  // Construction des colliders
 
38
  FreeCamera.attributes.add('inflateBias', { type: 'number', default: 0.0, title: 'Extra inflate (m, tiny)' });
 
39
  FreeCamera.attributes.add('mergeGap', { type: 'number', default: 0.0, title: 'Merge AABBs gap (0 = pas de gap)' });
40
 
41
+ // Filtrage "anti-coquille"
 
42
  FreeCamera.attributes.add('globalCullFrac', { type: 'number', default: 0.08, title: 'Cull near-global AABBs (0.08=8%)' });
43
 
44
  // Bounding Box globale optionnelle (Xmin..Zmax)
 
83
  this.state = this.app.systems.script.app.freeCamState;
84
 
85
  // colliders
86
+ this._buildIndoorSafeColliders();
87
 
88
+ // Forcer une passe de résolution initiale
89
  var p = this.entity.getPosition().clone();
90
  p = this._moveSweptTo(p, p);
91
  this._clampPosition(p);
 
148
  for (var j = 1; j < boxes.length; j++) world.add(boxes[j]);
149
 
150
  // 3) Filtrer les AABBs "quasi globales" (anti-coquille)
151
+ var frac = pc.math.clamp(this.globalCullFrac, 0, 0.49);
152
  var wh = world.halfExtents;
153
  var filtered = [];
154
  for (var k = 0; k < boxes.length; k++) {
 
160
  if (!nearGlobal) filtered.push(boxes[k]);
161
  }
162
 
163
+ // 4) Merge strict (chevauchement réel uniquement, gap ~ 0)
164
  var merged = this._mergeAabbs(filtered, Math.max(0, this.mergeGap || 0));
165
 
166
+ // 5) Petit gonflage (epsilon), pas du rayon
167
  var inflate = Math.max(0, this.inflateBias || 0);
168
  for (var m = 0; m < merged.length; m++) {
169
  merged[m].halfExtents.add(new pc.Vec3(inflate, inflate, inflate));
 
175
  this._worldAabb = world;
176
  this._useCollision = true;
177
  } else {
 
178
  this._colliders = [];
179
  this._useCollision = false;
180
  console.warn('[orbitCamera] Aucun collider utile trouvé (désactivation des collisions)');
 
211
  if (overlap(acc, out[j], tol)) {
212
  var aMin = acc.getMin(), aMax = acc.getMax();
213
  var bMin = out[j].getMin(), bMax = out[j].getMax();
214
+
215
+ var nMin = new pc.Vec3(
216
+ Math.min(aMin.x, bMin.x),
217
+ Math.min(aMin.y, bMin.y),
218
+ Math.min(aMin.z, bMin.z)
219
+ );
220
+ var nMax = new pc.Vec3(
221
+ Math.max(aMax.x, bMax.x),
222
+ Math.max(aMax.y, bMax.y),
223
+ Math.max(aMax.z, bMax.z)
224
+ );
225
+ var nCenter = nMin.clone().add(nMax).mulScalar(0.5);
226
+
227
+ // ❗️Pas de .abs() sur pc.Vec3 : calculer composante par composante
228
+ var nHalf = new pc.Vec3(
229
+ Math.abs(nMax.x - nCenter.x),
230
+ Math.abs(nMax.y - nCenter.y),
231
+ Math.abs(nMax.z - nCenter.z)
232
+ );
233
+
234
+ acc = new pc.BoundingBox(nCenter, nHalf);
235
  used[j] = true;
236
  changed = true;
237
  }
 
259
 
260
  // ======================== Mouvement swept + résolution =====================
261
  FreeCamera.prototype._moveSweptTo = function (from, to) {
262
+ if (!this._useCollision) return to.clone();
263
 
264
  var maxStep = Math.max(0.01, this.maxStepDistance || 0.2);
265
  var delta = to.clone().sub(from);
 
299
  var aabb = this._colliders[i].aabb;
300
  var min = aabb.getMin(); var max = aabb.getMax();
301
 
302
+ // Point le plus proche sur l'AABB
303
  var cx = pc.math.clamp(p.x, min.x, max.x);
304
  var cy = pc.math.clamp(p.y, min.y, max.y);
305
  var cz = pc.math.clamp(p.z, min.z, max.z);
 
307
  var dx = p.x - cx, dy = p.y - cy, dz = p.z - cz;
308
  var distSq = dx*dx + dy*dy + dz*dz;
309
 
 
310
  if (distSq < (R*R)) {
311
  var dist = Math.sqrt(Math.max(distSq, 1e-12));
312
  var pen = R - dist + eps;
 
316
  p.y += (dy / dist) * pen;
317
  p.z += (dz / dist) * pen;
318
  } else {
319
+ // pousser selon l'axe le plus "proche"
320
  var ex = Math.min(Math.abs(p.x - min.x), Math.abs(max.x - p.x));
321
  var ey = Math.min(Math.abs(p.y - min.y), Math.abs(max.y - p.y));
322
  var ez = Math.min(Math.abs(p.z - min.z), Math.abs(max.z - p.z));