MikaFil commited on
Commit
6c6c471
·
verified ·
1 Parent(s): f0e1251

Update deplacement_dans_env/ctrl_camera_pr_env.js

Browse files
deplacement_dans_env/ctrl_camera_pr_env.js CHANGED
@@ -1,11 +1,10 @@
1
  // ctrl_camera_pr_env.js
2
  // ============================================================================
3
- // ORBIT CAMERA + INPUTS (PlayCanvas) — version bbox "rotation-libre"
4
  // - Zoom : uniquement un minimum (pas de maxZoom)
5
- // - Bounding Box : on contraint UNIQUEMENT la position caméra
6
- // -> si la position sort, on la clampe puis on décale le pivot
7
- // pour conserver l'orientation ET la distance (orbite fluide).
8
- // - minY : altitude mini de la caméra (appliquée comme une "box" horizontale)
9
  // ============================================================================
10
 
11
  var OrbitCamera = pc.createScript('orbitCamera');
@@ -16,8 +15,9 @@ OrbitCamera.attributes.add('distanceMin', { type: 'number', default: 1, titl
16
  OrbitCamera.attributes.add('pitchAngleMax', { type: 'number', default: 90, title: 'Pitch Angle Max (degrees)' });
17
  OrbitCamera.attributes.add('pitchAngleMin', { type: 'number', default: 0, title: 'Pitch Angle Min (degrees)' });
18
 
19
- OrbitCamera.attributes.add('yawAngleMax', { type: 'number', default: 360, title: 'Yaw Angle Max (degrees)' });
20
- OrbitCamera.attributes.add('yawAngleMin', { type: 'number', default: -360,title: 'Yaw Angle Min (degrees)' });
 
21
 
22
  OrbitCamera.attributes.add('minY', { type: 'number', default: 0, title: 'Minimum Y (camera world Y)' });
23
 
@@ -51,7 +51,10 @@ Object.defineProperty(OrbitCamera.prototype, 'pitch', {
51
 
52
  Object.defineProperty(OrbitCamera.prototype, 'yaw', {
53
  get: function () { return this._targetYaw; },
54
- set: function (value) { this._targetYaw = this._clampYawAngle(value); }
 
 
 
55
  });
56
 
57
  Object.defineProperty(OrbitCamera.prototype, 'pivotPoint', {
@@ -196,22 +199,20 @@ OrbitCamera.prototype._updatePosition = function () {
196
  var forward = this.entity.forward.clone(); // direction de visée
197
  var desired = this._pivotPoint.clone().add(forward.clone().mulScalar(-this._distance));
198
 
199
- // 3) applique minY (comme un plan horizontal)
200
  if (desired.y < this.minY) {
201
  desired.y = this.minY;
202
  }
203
 
204
  // 4) contraint UNIQUEMENT la position caméra à la bbox
205
  var clamped = desired.clone();
206
- var wasClamped = this._applyBoundingBox(clamped); // retourne true si clamp effectué
207
 
208
- // 5) positionne la caméra
209
  this.entity.setPosition(clamped);
210
 
211
- // 6) si clamp (bbox ou minY), on recalcule un pivot cohérent sur le même rayon
212
- // (préserve orientation + distance => rotation reste fluide au contact)
213
  if (wasClamped || clamped.y !== desired.y) {
214
- // forward pointe de la caméra vers la scène
215
  // pos = pivot - forward * distance => pivot = pos + forward * distance
216
  this._pivotPoint.copy(clamped.clone().add(forward.mulScalar(this._distance)));
217
  }
@@ -266,7 +267,8 @@ OrbitCamera.prototype._buildAabb = function (entity) {
266
  OrbitCamera.prototype._calcYaw = function (quat) {
267
  var transformedForward = new pc.Vec3();
268
  quat.transformVector(pc.Vec3.FORWARD, transformedForward);
269
- return Math.atan2(-transformedForward.x, -transformedForward.z) * pc.math.RAD_TO_DEG;
 
270
  };
271
 
272
  OrbitCamera.prototype._clampDistance = function (distance) {
@@ -277,9 +279,8 @@ OrbitCamera.prototype._clampPitchAngle = function (pitch) {
277
  return pc.math.clamp(pitch, this.pitchAngleMin, this.pitchAngleMax);
278
  };
279
 
280
- OrbitCamera.prototype._clampYawAngle = function (yaw) {
281
- return pc.math.clamp(yaw, -this.yawAngleMax, -this.yawAngleMin);
282
- };
283
 
284
  OrbitCamera.quatWithoutYaw = new pc.Quat();
285
  OrbitCamera.yawOffset = new pc.Quat();
@@ -299,20 +300,14 @@ OrbitCamera.prototype._bboxEnabled = function () {
299
  return (this.Xmin < this.Xmax) && (this.Ymin < this.Ymax) && (this.Zmin < this.Zmax);
300
  };
301
 
302
- /**
303
- * Contrainte position caméra à la bbox.
304
- * @returns {boolean} true si un clamp a été appliqué
305
- */
306
- OrbitCamera.prototype._applyBoundingBox = function (v3 /* camera position */) {
307
  if (!this._bboxEnabled()) return false;
308
-
309
  var clamped = false;
310
  var nx = pc.math.clamp(v3.x, this.Xmin, this.Xmax);
311
  var ny = pc.math.clamp(v3.y, this.Ymin, this.Ymax);
312
  var nz = pc.math.clamp(v3.z, this.Zmin, this.Zmax);
313
-
314
  if (nx !== v3.x || ny !== v3.y || nz !== v3.z) clamped = true;
315
-
316
  v3.x = nx; v3.y = ny; v3.z = nz;
317
  return clamped;
318
  };
@@ -368,15 +363,13 @@ OrbitCameraInputMouse.prototype.pan = function (screenPoint) {
368
 
369
  worldDiff.sub2(toWorldPoint, fromWorldPoint);
370
 
371
- // Enforce minY via test sur la position caméra résultante
372
  var proposedPivot = this.orbitCamera.pivotPoint.clone().add(worldDiff);
373
-
374
- // calcule Y caméra si on acceptait ce pivot (sans bbox ici)
375
  var camY = this.orbitCamera.worldCameraYForPivot(proposedPivot);
 
376
  if (camY >= this.orbitCamera.minY - 1e-4) {
377
  this.orbitCamera.pivotPoint.copy(proposedPivot);
378
  } else {
379
- // Essai horizontal-only
380
  worldDiff.y = 0;
381
  proposedPivot = this.orbitCamera.pivotPoint.clone().add(worldDiff);
382
  camY = this.orbitCamera.worldCameraYForPivot(proposedPivot);
@@ -406,8 +399,10 @@ OrbitCameraInputMouse.prototype.onMouseMove = function (event) {
406
  if (this.lookButtonDown) {
407
  var sens = this.orbitSensitivity;
408
 
409
- var deltaPitch = event.dy * sens; // mouse up (dy < 0) raises pitch
410
  var deltaYaw = event.dx * sens;
 
 
411
 
412
  var currPitch = this.orbitCamera.pitch;
413
  var currYaw = this.orbitCamera.yaw;
@@ -420,22 +415,26 @@ OrbitCameraInputMouse.prototype.onMouseMove = function (event) {
420
  camQuat.transformVector(pc.Vec3.FORWARD, forward);
421
  var preY = currPivot.y + (-forward.y) * currDist;
422
 
 
 
 
423
  var proposedPitch = currPitch - deltaPitch;
424
- var testQuat = new pc.Quat();
425
- testQuat.setFromEulerAngles(proposedPitch, currYaw, 0);
426
- var testForward = new pc.Vec3();
427
- testQuat.transformVector(pc.Vec3.FORWARD, testForward);
 
428
  var proposedY = currPivot.y + (-testForward.y) * currDist;
429
 
430
  var minY = this.orbitCamera.minY;
431
  var wouldGoBelow = proposedY < minY - 1e-4;
432
 
433
- if (wouldGoBelow && (proposedY < preY)) {
434
- this.orbitCamera.yaw = currYaw - deltaYaw;
435
- } else {
436
  this.orbitCamera.pitch = proposedPitch;
437
- this.orbitCamera.yaw = currYaw - deltaYaw;
438
  }
 
 
 
439
  } else if (this.panButtonDown) {
440
  this.pan(new pc.Vec2(event.x, event.y));
441
  }
@@ -549,36 +548,33 @@ OrbitCameraInputTouch.prototype.onTouchMove = function (event) {
549
  var touch = touches[0];
550
  var sens = this.orbitSensitivity;
551
 
552
- var deltaPitch = (touch.y - this.lastTouchPoint.y) * sens;
553
  var deltaYaw = (touch.x - this.lastTouchPoint.x) * sens;
 
554
 
555
  var currPitch = this.orbitCamera.pitch;
556
  var currYaw = this.orbitCamera.yaw;
557
  var currDist = this.orbitCamera.distance;
558
  var currPivot = this.orbitCamera.pivotPoint.clone();
559
 
560
- var camQuat = new pc.Quat();
561
- camQuat.setFromEulerAngles(currPitch, currYaw, 0);
562
- var forward = new pc.Vec3();
563
- camQuat.transformVector(pc.Vec3.FORWARD, forward);
564
  var preY = currPivot.y + (-forward.y) * currDist;
565
 
 
566
  var proposedPitch = currPitch - deltaPitch;
567
- var testQuat = new pc.Quat();
568
- testQuat.setFromEulerAngles(proposedPitch, currYaw, 0);
569
- var testForward = new pc.Vec3();
570
- testQuat.transformVector(pc.Vec3.FORWARD, testForward);
571
  var proposedY = currPivot.y + (-testForward.y) * currDist;
572
 
573
  var minY = this.orbitCamera.minY;
574
  var wouldGoBelow = proposedY < minY - 1e-4;
575
 
576
- if (wouldGoBelow && (proposedY < preY)) {
577
- this.orbitCamera.yaw = currYaw - deltaYaw;
578
- } else {
579
  this.orbitCamera.pitch = proposedPitch;
580
- this.orbitCamera.yaw = currYaw - deltaYaw;
581
  }
 
582
 
583
  this.lastTouchPoint.set(touch.x, touch.y);
584
  } else if (touches.length === 2) {
@@ -596,7 +592,7 @@ OrbitCameraInputTouch.prototype.onTouchMove = function (event) {
596
 
597
  // =================== Orbit Camera Input Keyboard ========================
598
  // Flèches : déplacement avant/arrière & droite/gauche (repère caméra, 3D)
599
- // Ctrl+flèches : orbiter autour du pivot (avec test minY)
600
  // Maj+flèches : rotation libre sur place (pas de limites yaw/pitch)
601
  var OrbitCameraInputKeyboard = pc.createScript('orbitCameraInputKeyboard');
602
 
@@ -628,14 +624,15 @@ OrbitCameraInputKeyboard.prototype.update = function (dt) {
628
 
629
  // -------- Ctrl + flèches : ORBIT autour du pivot --------
630
  if (ctrl && (up || dn || lt || rt)) {
631
- var yawDir = (rt ? 1 : 0) - (lt ? 1 : 0);
632
- var pitchDir = (up ? 1 : 0) - (dn ? 1 : 0);
 
633
 
634
- if (yawDir !== 0) {
635
- this.orbitCamera.yaw = this.orbitCamera.yaw + yawDir * this.orbitYawSpeedDeg * dt;
636
  }
637
 
638
- if (pitchDir !== 0) {
639
  var currPitch = this.orbitCamera.pitch;
640
  var currYaw = this.orbitCamera.yaw;
641
  var currDist = this.orbitCamera.distance;
@@ -645,7 +642,7 @@ OrbitCameraInputKeyboard.prototype.update = function (dt) {
645
  var forward = new pc.Vec3(); camQuat.transformVector(pc.Vec3.FORWARD, forward);
646
  var preY = currPivot.y + (-forward.y) * currDist;
647
 
648
- var testPitch = currPitch + pitchDir * this.orbitPitchSpeedDeg * dt;
649
  var testQuat = new pc.Quat().setFromEulerAngles(testPitch, currYaw, 0);
650
  var testForward = new pc.Vec3(); testQuat.transformVector(pc.Vec3.FORWARD, testForward);
651
  var proposedY = currPivot.y + (-testForward.y) * currDist;
@@ -662,8 +659,8 @@ OrbitCameraInputKeyboard.prototype.update = function (dt) {
662
 
663
  // -------- Maj + flèches : ROTATION SUR PLACE --------
664
  if (shift && (up || dn || lt || rt)) {
665
- var yawDirR = (rt ? 1 : 0) - (lt ? 1 : 0);
666
- var pitchDirR = (up ? 1 : 0) - (dn ? 1 : 0);
667
 
668
  var camPos = this.entity.getPosition().clone();
669
  var dist = this.orbitCamera._distance;
 
1
  // ctrl_camera_pr_env.js
2
  // ============================================================================
3
+ // ORBIT CAMERA + INPUTS (PlayCanvas) — bbox + rotation libre & sens corrigés
4
  // - Zoom : uniquement un minimum (pas de maxZoom)
5
+ // - Bounding Box : clamp SEULEMENT la position caméra, jamais l'orientation
6
+ // - Yaw : pas de clamp -> rotations illimitées (±2000° etc.)
7
+ // - Pitch : clamp via min/max (configurable), minY préservé
 
8
  // ============================================================================
9
 
10
  var OrbitCamera = pc.createScript('orbitCamera');
 
15
  OrbitCamera.attributes.add('pitchAngleMax', { type: 'number', default: 90, title: 'Pitch Angle Max (degrees)' });
16
  OrbitCamera.attributes.add('pitchAngleMin', { type: 'number', default: 0, title: 'Pitch Angle Min (degrees)' });
17
 
18
+ // NB: gardés pour compat, mais non utilisés pour brider le yaw (rotation libre)
19
+ OrbitCamera.attributes.add('yawAngleMax', { type: 'number', default: 360, title: 'Yaw Angle Max (unused clamp)' });
20
+ OrbitCamera.attributes.add('yawAngleMin', { type: 'number', default: -360, title: 'Yaw Angle Min (unused clamp)' });
21
 
22
  OrbitCamera.attributes.add('minY', { type: 'number', default: 0, title: 'Minimum Y (camera world Y)' });
23
 
 
51
 
52
  Object.defineProperty(OrbitCamera.prototype, 'yaw', {
53
  get: function () { return this._targetYaw; },
54
+ set: function (value) {
55
+ // Yaw LIBRE : pas de clamp pour permettre ±2000°, etc.
56
+ this._targetYaw = value;
57
+ }
58
  });
59
 
60
  Object.defineProperty(OrbitCamera.prototype, 'pivotPoint', {
 
199
  var forward = this.entity.forward.clone(); // direction de visée
200
  var desired = this._pivotPoint.clone().add(forward.clone().mulScalar(-this._distance));
201
 
202
+ // 3) applique minY (plan horizontal)
203
  if (desired.y < this.minY) {
204
  desired.y = this.minY;
205
  }
206
 
207
  // 4) contraint UNIQUEMENT la position caméra à la bbox
208
  var clamped = desired.clone();
209
+ var wasClamped = this._applyBoundingBox(clamped); // true si clamp
210
 
211
+ // 5) place la caméra
212
  this.entity.setPosition(clamped);
213
 
214
+ // 6) si clamp (bbox/minY), recalcule un pivot cohérent sur le même rayon
 
215
  if (wasClamped || clamped.y !== desired.y) {
 
216
  // pos = pivot - forward * distance => pivot = pos + forward * distance
217
  this._pivotPoint.copy(clamped.clone().add(forward.mulScalar(this._distance)));
218
  }
 
267
  OrbitCamera.prototype._calcYaw = function (quat) {
268
  var transformedForward = new pc.Vec3();
269
  quat.transformVector(pc.Vec3.FORWARD, transformedForward);
270
+ // Convention: yaw croissant = rotation CCW vue de dessus
271
+ return Math.atan2(transformedForward.x, transformedForward.z) * pc.math.RAD_TO_DEG;
272
  };
273
 
274
  OrbitCamera.prototype._clampDistance = function (distance) {
 
279
  return pc.math.clamp(pitch, this.pitchAngleMin, this.pitchAngleMax);
280
  };
281
 
282
+ // Yaw: pas de clamp (rotation libre)
283
+ OrbitCamera.prototype._clampYawAngle = function (yaw) { return yaw; };
 
284
 
285
  OrbitCamera.quatWithoutYaw = new pc.Quat();
286
  OrbitCamera.yawOffset = new pc.Quat();
 
300
  return (this.Xmin < this.Xmax) && (this.Ymin < this.Ymax) && (this.Zmin < this.Zmax);
301
  };
302
 
303
+ /** Clamp position caméra à la bbox. @returns {boolean} true si clamp appliqué */
304
+ OrbitCamera.prototype._applyBoundingBox = function (v3) {
 
 
 
305
  if (!this._bboxEnabled()) return false;
 
306
  var clamped = false;
307
  var nx = pc.math.clamp(v3.x, this.Xmin, this.Xmax);
308
  var ny = pc.math.clamp(v3.y, this.Ymin, this.Ymax);
309
  var nz = pc.math.clamp(v3.z, this.Zmin, this.Zmax);
 
310
  if (nx !== v3.x || ny !== v3.y || nz !== v3.z) clamped = true;
 
311
  v3.x = nx; v3.y = ny; v3.z = nz;
312
  return clamped;
313
  };
 
363
 
364
  worldDiff.sub2(toWorldPoint, fromWorldPoint);
365
 
366
+ // minY via test sur la position caméra résultante
367
  var proposedPivot = this.orbitCamera.pivotPoint.clone().add(worldDiff);
 
 
368
  var camY = this.orbitCamera.worldCameraYForPivot(proposedPivot);
369
+
370
  if (camY >= this.orbitCamera.minY - 1e-4) {
371
  this.orbitCamera.pivotPoint.copy(proposedPivot);
372
  } else {
 
373
  worldDiff.y = 0;
374
  proposedPivot = this.orbitCamera.pivotPoint.clone().add(worldDiff);
375
  camY = this.orbitCamera.worldCameraYForPivot(proposedPivot);
 
399
  if (this.lookButtonDown) {
400
  var sens = this.orbitSensitivity;
401
 
402
+ // Souris : droite => orbite à droite ; gauche => orbite à gauche
403
  var deltaYaw = event.dx * sens;
404
+ // Pitch : dy<0 (monte) => pitch augmente (look up)
405
+ var deltaPitch = event.dy * sens;
406
 
407
  var currPitch = this.orbitCamera.pitch;
408
  var currYaw = this.orbitCamera.yaw;
 
415
  camQuat.transformVector(pc.Vec3.FORWARD, forward);
416
  var preY = currPivot.y + (-forward.y) * currDist;
417
 
418
+ // Conventions:
419
+ // - Yaw: +deltaYaw = tourner gauche (CCW). On veut "drag droite => tourner droite (CW)" -> yaw -= deltaYaw
420
+ // - Pitch: "drag haut (dy<0) => look up" -> pitch -= deltaPitch (car deltaPitch<0)
421
  var proposedPitch = currPitch - deltaPitch;
422
+ var proposedYaw = currYaw - deltaYaw;
423
+
424
+ // Vérif minY pour pitch uniquement (comme avant)
425
+ var testQuat = new pc.Quat().setFromEulerAngles(proposedPitch, currYaw, 0);
426
+ var testForward = new pc.Vec3(); testQuat.transformVector(pc.Vec3.FORWARD, testForward);
427
  var proposedY = currPivot.y + (-testForward.y) * currDist;
428
 
429
  var minY = this.orbitCamera.minY;
430
  var wouldGoBelow = proposedY < minY - 1e-4;
431
 
432
+ if (!(wouldGoBelow && (proposedY < preY))) {
 
 
433
  this.orbitCamera.pitch = proposedPitch;
 
434
  }
435
+ // Yaw toujours libre
436
+ this.orbitCamera.yaw = proposedYaw;
437
+
438
  } else if (this.panButtonDown) {
439
  this.pan(new pc.Vec2(event.x, event.y));
440
  }
 
548
  var touch = touches[0];
549
  var sens = this.orbitSensitivity;
550
 
 
551
  var deltaYaw = (touch.x - this.lastTouchPoint.x) * sens;
552
+ var deltaPitch = (touch.y - this.lastTouchPoint.y) * sens;
553
 
554
  var currPitch = this.orbitCamera.pitch;
555
  var currYaw = this.orbitCamera.yaw;
556
  var currDist = this.orbitCamera.distance;
557
  var currPivot = this.orbitCamera.pivotPoint.clone();
558
 
559
+ var camQuat = new pc.Quat().setFromEulerAngles(currPitch, currYaw, 0);
560
+ var forward = new pc.Vec3(); camQuat.transformVector(pc.Vec3.FORWARD, forward);
 
 
561
  var preY = currPivot.y + (-forward.y) * currDist;
562
 
563
+ // mêmes conventions que souris
564
  var proposedPitch = currPitch - deltaPitch;
565
+ var proposedYaw = currYaw - deltaYaw;
566
+
567
+ var testQuat = new pc.Quat().setFromEulerAngles(proposedPitch, currYaw, 0);
568
+ var testForward = new pc.Vec3(); testQuat.transformVector(pc.Vec3.FORWARD, testForward);
569
  var proposedY = currPivot.y + (-testForward.y) * currDist;
570
 
571
  var minY = this.orbitCamera.minY;
572
  var wouldGoBelow = proposedY < minY - 1e-4;
573
 
574
+ if (!(wouldGoBelow && (proposedY < preY))) {
 
 
575
  this.orbitCamera.pitch = proposedPitch;
 
576
  }
577
+ this.orbitCamera.yaw = proposedYaw;
578
 
579
  this.lastTouchPoint.set(touch.x, touch.y);
580
  } else if (touches.length === 2) {
 
592
 
593
  // =================== Orbit Camera Input Keyboard ========================
594
  // Flèches : déplacement avant/arrière & droite/gauche (repère caméra, 3D)
595
+ // Ctrl+flèches : orbiter autour du pivot (sens conforme ← CCW / → CW)
596
  // Maj+flèches : rotation libre sur place (pas de limites yaw/pitch)
597
  var OrbitCameraInputKeyboard = pc.createScript('orbitCameraInputKeyboard');
598
 
 
624
 
625
  // -------- Ctrl + flèches : ORBIT autour du pivot --------
626
  if (ctrl && (up || dn || lt || rt)) {
627
+ // Convention : ← = CCW => yaw augmente ; = CW => yaw diminue
628
+ var yawDirLeftRight = (lt ? 1 : 0) - (rt ? 1 : 0); // ← +1, → -1
629
+ var pitchDirUpDown = (up ? 1 : 0) - (dn ? 1 : 0); // ↑ +1, ↓ -1
630
 
631
+ if (yawDirLeftRight !== 0) {
632
+ this.orbitCamera.yaw = this.orbitCamera.yaw + yawDirLeftRight * this.orbitYawSpeedDeg * dt;
633
  }
634
 
635
+ if (pitchDirUpDown !== 0) {
636
  var currPitch = this.orbitCamera.pitch;
637
  var currYaw = this.orbitCamera.yaw;
638
  var currDist = this.orbitCamera.distance;
 
642
  var forward = new pc.Vec3(); camQuat.transformVector(pc.Vec3.FORWARD, forward);
643
  var preY = currPivot.y + (-forward.y) * currDist;
644
 
645
+ var testPitch = currPitch + pitchDirUpDown * this.orbitPitchSpeedDeg * dt;
646
  var testQuat = new pc.Quat().setFromEulerAngles(testPitch, currYaw, 0);
647
  var testForward = new pc.Vec3(); testQuat.transformVector(pc.Vec3.FORWARD, testForward);
648
  var proposedY = currPivot.y + (-testForward.y) * currDist;
 
659
 
660
  // -------- Maj + flèches : ROTATION SUR PLACE --------
661
  if (shift && (up || dn || lt || rt)) {
662
+ var yawDirR = (lt ? 1 : 0) - (rt ? 1 : 0); // ← +1 (CCW), → -1 (CW)
663
+ var pitchDirR = (up ? 1 : 0) - (dn ? 1 : 0); // ↑ +1, ↓ -1
664
 
665
  var camPos = this.entity.getPosition().clone();
666
  var dist = this.orbitCamera._distance;