@galacean/engine 0.0.0-experimental-2.0-game.11 → 0.0.0-experimental-2.0-game.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/browser.js CHANGED
@@ -10787,8 +10787,13 @@
10787
10787
  rotation._onValueChanged = target._onRotationChanged;
10788
10788
  // @ts-ignore
10789
10789
  scale._onValueChanged = target._onScaleChanged;
10790
- // When cloning, other components may obtain properties such as `rotationQuaternion` in the constructor, local related dirty flags need to be corrected
10790
+ // When cloning, other components may obtain properties such as `rotationQuaternion` in the constructor, local related dirty flags need to be corrected.
10791
+ // Earlier in this Entity's construction other components (e.g. DynamicCollider) may have queried
10792
+ // `worldPosition`, which clears the WorldPosition / WorldMatrix dirty flags as a side effect of caching
10793
+ // the computed value. After this _cloneTo writes new local values, those world-derived caches are stale,
10794
+ // so re-dirty them and notify listeners (Collider._updateFlag etc.) so subsequent reads recompute correctly.
10791
10795
  target._setDirtyFlagTrue(2 | 64);
10796
+ target._worldAssociatedChange(444);
10792
10797
  };
10793
10798
  _proto._onLocalMatrixChanging = function _onLocalMatrixChanging() {
10794
10799
  this._setDirtyFlagFalse(64);
@@ -25433,17 +25438,23 @@
25433
25438
  /**
25434
25439
  * @internal
25435
25440
  */ _proto._onUpdate = function _onUpdate() {
25441
+ var shapes = this._shapes;
25436
25442
  if (this._updateFlag.flag) {
25437
25443
  var transform = this.entity.transform;
25438
- this._nativeCollider.setWorldTransform(transform.worldPosition, transform.worldRotationQuaternion);
25444
+ this._syncEntityTransformToNative(transform.worldPosition, transform.worldRotationQuaternion);
25439
25445
  var worldScale = transform.lossyWorldScale;
25440
- var shapes = this._shapes;
25441
25446
  for(var i = 0, n = shapes.length; i < n; i++){
25442
25447
  var _shapes_i__nativeShape;
25443
25448
  (_shapes_i__nativeShape = shapes[i]._nativeShape) == null ? void 0 : _shapes_i__nativeShape.setWorldScale(worldScale);
25444
25449
  }
25445
25450
  this._updateFlag.flag = false;
25446
25451
  }
25452
+ // Drive per-shape physics update (e.g. MeshColliderShape retries pending
25453
+ // native shape creation when mesh data becomes accessible asynchronously).
25454
+ // No-op for shape types that don't override `_onPhysicsUpdate`.
25455
+ for(var i1 = 0, n1 = shapes.length; i1 < n1; i1++){
25456
+ shapes[i1]._onPhysicsUpdate();
25457
+ }
25447
25458
  };
25448
25459
  /**
25449
25460
  * @internal
@@ -25475,6 +25486,28 @@
25475
25486
  this._addNativeShape(this.shapes[i]);
25476
25487
  }
25477
25488
  this._setCollisionLayer();
25489
+ // Teleport native actor to entity's current world pose.
25490
+ // The native actor was created in constructor() with the entity's then-current
25491
+ // worldPosition/Rotation. On clone, the entity's transform fields are deep-cloned
25492
+ // AFTER the Component (and its native actor) are constructed, so the native actor's
25493
+ // pose lags behind the cloned entity transform until this sync.
25494
+ var transform = this.entity.transform;
25495
+ this._teleportToEntityTransform(transform.worldPosition, transform.worldRotationQuaternion);
25496
+ };
25497
+ /**
25498
+ * Teleport native actor to a world pose (instant, no implied velocity).
25499
+ * Used during initialization paths (clone) where the native actor must be re-aligned
25500
+ * with the entity transform after construction-time pose was based on stale defaults.
25501
+ */ _proto._teleportToEntityTransform = function _teleportToEntityTransform(worldPosition, worldRotation) {
25502
+ this._nativeCollider.setWorldTransform(worldPosition, worldRotation);
25503
+ };
25504
+ /**
25505
+ * Sync entity world transform to native actor for per-frame updates.
25506
+ * Default semantics: teleport (setGlobalPose). Subclasses override to express
25507
+ * physics-aware movement (e.g. DynamicCollider routes kinematic actors through
25508
+ * setKinematicTarget to generate contact events on swept motion).
25509
+ */ _proto._syncEntityTransformToNative = function _syncEntityTransformToNative(worldPosition, worldRotation) {
25510
+ this._nativeCollider.setWorldTransform(worldPosition, worldRotation);
25478
25511
  };
25479
25512
  /**
25480
25513
  * @internal
@@ -25632,6 +25665,9 @@
25632
25665
  this._nativeCollider.setUpDirection(this._upDirection);
25633
25666
  this._nativeCollider.setSlopeLimit(this._slopeLimit);
25634
25667
  };
25668
+ _proto._teleportToEntityTransform = function _teleportToEntityTransform(worldPosition, _worldRotation) {
25669
+ this._nativeCollider.setWorldPosition(worldPosition);
25670
+ };
25635
25671
  _proto._syncWorldPositionFromPhysicalSpace = function _syncWorldPositionFromPhysicalSpace() {
25636
25672
  this._nativeCollider.getWorldPosition(this.entity.transform.worldPosition);
25637
25673
  };
@@ -25731,7 +25767,7 @@
25731
25767
  this._staticFriction = 0.6;
25732
25768
  this._bounceCombine = PhysicsMaterialCombineMode.Average;
25733
25769
  this._frictionCombine = PhysicsMaterialCombineMode.Average;
25734
- this._nativeMaterial = Engine._nativePhysics.createPhysicsMaterial(this._staticFriction, this._dynamicFriction, this._bounciness, this._bounceCombine, this._frictionCombine);
25770
+ this._nativeMaterial = Engine._nativePhysics.createPhysicsMaterial(this._staticFriction, this._dynamicFriction, this._bounciness, this._frictionCombine, this._bounceCombine);
25735
25771
  }
25736
25772
  var _proto = PhysicsMaterial.prototype;
25737
25773
  /**
@@ -25740,6 +25776,21 @@
25740
25776
  !this._destroyed && this._nativeMaterial.destroy();
25741
25777
  this._destroyed = true;
25742
25778
  };
25779
+ /**
25780
+ * @internal
25781
+ */ _proto._cloneTo = function _cloneTo(target) {
25782
+ target._syncNative();
25783
+ };
25784
+ /**
25785
+ * @internal
25786
+ */ _proto._syncNative = function _syncNative() {
25787
+ var nativeMaterial = this._nativeMaterial;
25788
+ nativeMaterial.setStaticFriction(this._staticFriction);
25789
+ nativeMaterial.setDynamicFriction(this._dynamicFriction);
25790
+ nativeMaterial.setBounciness(this._bounciness);
25791
+ nativeMaterial.setFrictionCombine(this._frictionCombine);
25792
+ nativeMaterial.setBounceCombine(this._bounceCombine);
25793
+ };
25743
25794
  _create_class$2(PhysicsMaterial, [
25744
25795
  {
25745
25796
  key: "bounciness",
@@ -25814,6 +25865,9 @@
25814
25865
  ]);
25815
25866
  return PhysicsMaterial;
25816
25867
  }();
25868
+ __decorate$1([
25869
+ ignoreClone
25870
+ ], PhysicsMaterial.prototype, "_nativeMaterial", void 0);
25817
25871
  /**
25818
25872
  * Abstract class for collider shapes.
25819
25873
  */ var ColliderShape = /*#__PURE__*/ function() {
@@ -25865,6 +25919,16 @@
25865
25919
  };
25866
25920
  /**
25867
25921
  * @internal
25922
+ *
25923
+ * Called once per physics update tick by `Collider._onUpdate`. Base no-op.
25924
+ *
25925
+ * Subclasses can override for frame-driven maintenance. Currently used by
25926
+ * `MeshColliderShape` to retry native shape creation when mesh data becomes
25927
+ * accessible later or PhysX cooking previously failed due to transient state
25928
+ * (async resource loading, cook pipeline warmup, etc.).
25929
+ */ _proto._onPhysicsUpdate = function _onPhysicsUpdate() {};
25930
+ /**
25931
+ * @internal
25868
25932
  */ _proto._destroy = function _destroy() {
25869
25933
  if (this._nativeShape) {
25870
25934
  this._nativeShape.destroy();
@@ -26013,7 +26077,11 @@
26013
26077
  _inherits$2(MeshColliderShape, ColliderShape);
26014
26078
  function MeshColliderShape() {
26015
26079
  var _this;
26016
- _this = ColliderShape.apply(this, arguments) || this, _this._mesh = null, _this._isConvex = false, _this._positions = null, _this._indices = null, _this._cookingFlags = MeshColliderShapeCookingFlag.Cleaning | MeshColliderShapeCookingFlag.VertexWelding, _this._isShapeAttached = false;
26080
+ _this = ColliderShape.apply(this, arguments) || this, _this._mesh = null, _this._isConvex = false, _this._positions = null, _this._indices = null, _this._cookingFlags = MeshColliderShapeCookingFlag.Cleaning | MeshColliderShapeCookingFlag.VertexWelding, _this._isShapeAttached = false, /**
26081
+ * `true` if a native shape creation was attempted but failed (mesh data not yet
26082
+ * accessible, PhysX cooking transient failure, etc.). The `_onPhysicsUpdate` hook
26083
+ * will keep retrying every frame until creation succeeds.
26084
+ */ _this._pendingNativeShapeCreation = false;
26017
26085
  return _this;
26018
26086
  }
26019
26087
  var _proto = MeshColliderShape.prototype;
@@ -26097,9 +26165,12 @@
26097
26165
  }
26098
26166
  var nativeShape = Engine._nativePhysics.createMeshColliderShape(this._id, this._positions, this._indices, this._isConvex, this._material._nativeMaterial, this._cookingFlags);
26099
26167
  if (!nativeShape) {
26168
+ // Cook failed — `_onPhysicsUpdate` will retry next frame
26169
+ this._pendingNativeShapeCreation = true;
26100
26170
  return;
26101
26171
  }
26102
26172
  this._nativeShape = nativeShape;
26173
+ this._pendingNativeShapeCreation = false;
26103
26174
  // Sync base class properties (position, rotation, contactOffset, isTrigger, material)
26104
26175
  ColliderShape.prototype._syncNative.call(this);
26105
26176
  // If already attached to a collider, add the newly created native shape to it
@@ -26108,6 +26179,36 @@
26108
26179
  this._attachToCollider();
26109
26180
  }
26110
26181
  };
26182
+ /**
26183
+ * @internal
26184
+ * Retry hook: keep attempting `_createNativeShape` until it succeeds.
26185
+ *
26186
+ * Triggered every physics update tick by `Collider._onUpdate`. Handles the case
26187
+ * where `_cookMesh` fails on first attempt due to PhysX cooking pipeline timing
26188
+ * (the mesh data was extracted successfully at `set mesh` time, but the native
26189
+ * cook call returned null). No-op once a valid native shape exists.
26190
+ *
26191
+ * We DO NOT re-call `_extractMeshData` here — once `set mesh` finished, either:
26192
+ * - extraction succeeded → `_positions` is populated and we reuse it
26193
+ * - extraction failed → `_clearMeshData` cleared `_positions`, and `mesh.accessible`
26194
+ * won't recover (GPU upload is one-way), so re-extracting would fail again
26195
+ */ _proto._onPhysicsUpdate = function _onPhysicsUpdate() {
26196
+ if (!this._pendingNativeShapeCreation || !this._mesh || !this._positions) return;
26197
+ this._createNativeShape();
26198
+ };
26199
+ /**
26200
+ * @internal
26201
+ * After CloneManager deep-copies `_positions` / `_indices` / `_mesh` and remaps `_collider`,
26202
+ * the cloned shape still has no native PhysX shape because `_nativeShape` is `@ignoreClone`.
26203
+ * Cook a fresh native shape now using the already-cloned vertex/index buffers; on transient
26204
+ * cook failure `_createNativeShape` sets `_pendingNativeShapeCreation = true` and
26205
+ * `_onPhysicsUpdate` will retry next tick.
26206
+ */ _proto._cloneTo = function _cloneTo(target) {
26207
+ ColliderShape.prototype._cloneTo.call(this, target);
26208
+ if (target._positions) {
26209
+ target._createNativeShape();
26210
+ }
26211
+ };
26111
26212
  _create_class$2(MeshColliderShape, [
26112
26213
  {
26113
26214
  key: "cookingFlags",
@@ -26167,15 +26268,25 @@
26167
26268
  (_this__mesh = this._mesh) == null ? void 0 : _this__mesh._addReferCount(-1);
26168
26269
  value == null ? void 0 : value._addReferCount(1);
26169
26270
  this._mesh = value;
26170
- if (value && this._extractMeshData(value)) {
26171
- if (this._nativeShape) {
26172
- this._updateNativeShapeData();
26271
+ if (value) {
26272
+ if (this._extractMeshData(value)) {
26273
+ if (this._nativeShape) {
26274
+ this._updateNativeShapeData();
26275
+ } else {
26276
+ this._createNativeShape();
26277
+ }
26278
+ // _createNativeShape can fail silently (cookMesh transient failure); mark pending if so
26279
+ this._pendingNativeShapeCreation = !this._nativeShape;
26173
26280
  } else {
26174
- this._createNativeShape();
26281
+ // Mesh not yet accessible — keep pending so `_onPhysicsUpdate` retries later
26282
+ this._destroyNativeShape();
26283
+ this._clearMeshData();
26284
+ this._pendingNativeShapeCreation = true;
26175
26285
  }
26176
26286
  } else {
26177
26287
  this._destroyNativeShape();
26178
26288
  this._clearMeshData();
26289
+ this._pendingNativeShapeCreation = false;
26179
26290
  }
26180
26291
  }
26181
26292
  }
@@ -26219,6 +26330,27 @@
26219
26330
  */ _proto.applyTorque = function applyTorque(torque) {
26220
26331
  this._phasedActiveInScene && this._nativeCollider.addTorque(torque);
26221
26332
  };
26333
+ /**
26334
+ * Apply a force to the DynamicCollider at a given position in world space.
26335
+ * The force generates both linear acceleration through the center of mass and angular
26336
+ * acceleration about it (torque = (position - centerOfMass) × force).
26337
+ * @param force - The force to apply, in world space
26338
+ * @param position - The position where the force is applied, in world space
26339
+ */ _proto.applyForceAtPosition = function applyForceAtPosition(force, position) {
26340
+ if (!this._phasedActiveInScene) return;
26341
+ var nativeCollider = this._nativeCollider;
26342
+ var localCoM = DynamicCollider._tempVector3;
26343
+ nativeCollider.getCenterOfMass(localCoM);
26344
+ var transform = this.entity.transform;
26345
+ var worldCoM = DynamicCollider._tempVector3_1;
26346
+ Vector3.transformByQuat(localCoM, transform.worldRotationQuaternion, worldCoM);
26347
+ worldCoM.add(transform.worldPosition);
26348
+ var torque = DynamicCollider._tempVector3_2;
26349
+ Vector3.subtract(position, worldCoM, torque);
26350
+ Vector3.cross(torque, force, torque);
26351
+ nativeCollider.addForce(force);
26352
+ nativeCollider.addTorque(torque);
26353
+ };
26222
26354
  _proto.move = function move(positionOrRotation, rotation) {
26223
26355
  if (!this._isKinematic) {
26224
26356
  console.warn("DynamicCollider: move() is only supported when isKinematic is true.");
@@ -26252,6 +26384,31 @@
26252
26384
  Collider.prototype.addShape.call(this, shape);
26253
26385
  };
26254
26386
  /**
26387
+ * Route per-frame entity → native transform sync to the correct physics API based
26388
+ * on kinematic state.
26389
+ *
26390
+ * PhysX 4.x docs (PxRigidDynamic):
26391
+ * "If you intend to move a kinematic actor with [setGlobalPose] and want
26392
+ * collision detection, use setKinematicTarget() instead."
26393
+ *
26394
+ * setGlobalPose is a teleport: PhysX skips contact detection between the old
26395
+ * and new pose, so two kinematic actors moved onto each other via entity.transform
26396
+ * mutation would NOT produce onCollisionEnter / onCollisionStay events even when
26397
+ * scene.kineKineFilteringMode = eKEEP. Routing the per-frame sync through
26398
+ * IDynamicCollider.move() (which the PhysX backend implements as
26399
+ * setKinematicTarget) tells PhysX the actor is animating to the target during the
26400
+ * next simulate(), enabling sweep contact detection for kine-kine and kine-dynamic
26401
+ * pairs alike.
26402
+ *
26403
+ * @internal
26404
+ */ _proto._syncEntityTransformToNative = function _syncEntityTransformToNative(worldPosition, worldRotation) {
26405
+ if (this._isKinematic) {
26406
+ this._nativeCollider.move(worldPosition, worldRotation);
26407
+ } else {
26408
+ Collider.prototype._syncEntityTransformToNative.call(this, worldPosition, worldRotation);
26409
+ }
26410
+ };
26411
+ /**
26255
26412
  * @internal
26256
26413
  */ _proto._onLateUpdate = function _onLateUpdate() {
26257
26414
  var transform = this.entity.transform;
@@ -26625,6 +26782,8 @@
26625
26782
  return DynamicCollider;
26626
26783
  }(exports.Collider);
26627
26784
  DynamicCollider._tempVector3 = new Vector3();
26785
+ DynamicCollider._tempVector3_1 = new Vector3();
26786
+ DynamicCollider._tempVector3_2 = new Vector3();
26628
26787
  DynamicCollider._tempQuat = new Quaternion();
26629
26788
  __decorate$1([
26630
26789
  ignoreClone
@@ -56171,7 +56330,7 @@
56171
56330
  ], EXT_texture_webp);
56172
56331
 
56173
56332
  //@ts-ignore
56174
- var version = "0.0.0-experimental-2.0-game.11";
56333
+ var version = "0.0.0-experimental-2.0-game.12";
56175
56334
  console.log("Galacean Engine Version: " + version);
56176
56335
  for(var key in CoreObjects){
56177
56336
  Loader.registerClass(key, CoreObjects[key]);