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

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/main.js CHANGED
@@ -5759,8 +5759,13 @@ function dependentComponents(componentOrComponents, dependentMode) {
5759
5759
  rotation._onValueChanged = target._onRotationChanged;
5760
5760
  // @ts-ignore
5761
5761
  scale._onValueChanged = target._onScaleChanged;
5762
- // When cloning, other components may obtain properties such as `rotationQuaternion` in the constructor, local related dirty flags need to be corrected
5762
+ // When cloning, other components may obtain properties such as `rotationQuaternion` in the constructor, local related dirty flags need to be corrected.
5763
+ // Earlier in this Entity's construction other components (e.g. DynamicCollider) may have queried
5764
+ // `worldPosition`, which clears the WorldPosition / WorldMatrix dirty flags as a side effect of caching
5765
+ // the computed value. After this _cloneTo writes new local values, those world-derived caches are stale,
5766
+ // so re-dirty them and notify listeners (Collider._updateFlag etc.) so subsequent reads recompute correctly.
5763
5767
  target._setDirtyFlagTrue(2 | 64);
5768
+ target._worldAssociatedChange(444);
5764
5769
  };
5765
5770
  _proto._onLocalMatrixChanging = function _onLocalMatrixChanging() {
5766
5771
  this._setDirtyFlagFalse(64);
@@ -7796,7 +7801,13 @@ ShaderFactory._std140TypeInfoMap = {
7796
7801
  };
7797
7802
  ShaderFactory._has300OutInFragReg = /\bout\s+(?:\w+\s+)?vec4\s+\w+\s*;/;
7798
7803
  ShaderFactory._precisionStr = "\n#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n precision highp int;\n#else\n precision mediump float;\n precision mediump int;\n#endif\n";
7799
- ShaderFactory._derivedDefines = "#define renderer_MVMat (camera_ViewMat * renderer_ModelMat)\n#define renderer_MVPMat (camera_VPMat * renderer_ModelMat)\n#define renderer_NormalMat mat4(transpose(inverse(mat3(renderer_ModelMat))))";
7804
+ // Derived built-ins re-exposed on top of `renderer_ModelMat`.
7805
+ // `renderer_NormalMat` uses the cofactor (cross-product) form, which algebraically equals
7806
+ // `det(M) · transpose(inverse(M))`. After `normalize()` it's directionally identical to the
7807
+ // classic `transpose(inverse(M))`, but stays NaN-free when `M` is singular (e.g. any scale
7808
+ // axis is 0 — common in animations that pop / hide via scale). `sign(det)` (`s` below)
7809
+ // keeps mirrored matrices facing the right way
7810
+ ShaderFactory._derivedDefines = "mat3 _normalMatFromModel(mat3 m) {\n vec3 c0 = cross(m[1], m[2]);\n vec3 c1 = cross(m[2], m[0]);\n vec3 c2 = cross(m[0], m[1]);\n float s = (dot(m[0], c0) < 0.0) ? -1.0 : 1.0;\n return mat3(c0 * s, c1 * s, c2 * s);\n}\n#define renderer_MVMat (camera_ViewMat * renderer_ModelMat)\n#define renderer_MVPMat (camera_VPMat * renderer_ModelMat)\n#define renderer_NormalMat mat4(_normalMatFromModel(mat3(renderer_ModelMat)))";
7800
7811
  // Built-in renderer uniforms. value=true means derived (remove but not added to UBO)
7801
7812
  ShaderFactory._builtinRendererUniforms = {
7802
7813
  renderer_ModelMat: false,
@@ -19114,7 +19125,7 @@ RenderContext._flipYViewProjectionMatrix = new engineMath.Matrix();
19114
19125
  /** Scene. */ AssetType["Scene"] = "Scene";
19115
19126
  /** Font. */ AssetType["Font"] = "Font";
19116
19127
  /** Source Font, include ttf, otf and woff. */ AssetType["SourceFont"] = "SourceFont";
19117
- /** AudioClip, include ogg, wav and mp3. */ AssetType["Audio"] = "Audio";
19128
+ /** AudioClip, include ogg, wav, mp3, m4a, aac and flac. */ AssetType["Audio"] = "Audio";
19118
19129
  /** Project asset. */ AssetType["Project"] = "project";
19119
19130
  /** PhysicsMaterial. */ AssetType["PhysicsMaterial"] = "PhysicsMaterial";
19120
19131
  /** RenderTarget. */ AssetType["RenderTarget"] = "RenderTarget";
@@ -20591,17 +20602,23 @@ exports.Collider = /*#__PURE__*/ function(Component) {
20591
20602
  /**
20592
20603
  * @internal
20593
20604
  */ _proto._onUpdate = function _onUpdate() {
20605
+ var shapes = this._shapes;
20594
20606
  if (this._updateFlag.flag) {
20595
20607
  var transform = this.entity.transform;
20596
- this._nativeCollider.setWorldTransform(transform.worldPosition, transform.worldRotationQuaternion);
20608
+ this._syncEntityTransformToNative(transform.worldPosition, transform.worldRotationQuaternion);
20597
20609
  var worldScale = transform.lossyWorldScale;
20598
- var shapes = this._shapes;
20599
20610
  for(var i = 0, n = shapes.length; i < n; i++){
20600
20611
  var _shapes_i__nativeShape;
20601
20612
  (_shapes_i__nativeShape = shapes[i]._nativeShape) == null ? void 0 : _shapes_i__nativeShape.setWorldScale(worldScale);
20602
20613
  }
20603
20614
  this._updateFlag.flag = false;
20604
20615
  }
20616
+ // Drive per-shape physics update (e.g. MeshColliderShape retries pending
20617
+ // native shape creation when mesh data becomes accessible asynchronously).
20618
+ // No-op for shape types that don't override `_onPhysicsUpdate`.
20619
+ for(var i1 = 0, n1 = shapes.length; i1 < n1; i1++){
20620
+ shapes[i1]._onPhysicsUpdate();
20621
+ }
20605
20622
  };
20606
20623
  /**
20607
20624
  * @internal
@@ -20633,6 +20650,28 @@ exports.Collider = /*#__PURE__*/ function(Component) {
20633
20650
  this._addNativeShape(this.shapes[i]);
20634
20651
  }
20635
20652
  this._setCollisionLayer();
20653
+ // Teleport native actor to entity's current world pose.
20654
+ // The native actor was created in constructor() with the entity's then-current
20655
+ // worldPosition/Rotation. On clone, the entity's transform fields are deep-cloned
20656
+ // AFTER the Component (and its native actor) are constructed, so the native actor's
20657
+ // pose lags behind the cloned entity transform until this sync.
20658
+ var transform = this.entity.transform;
20659
+ this._teleportToEntityTransform(transform.worldPosition, transform.worldRotationQuaternion);
20660
+ };
20661
+ /**
20662
+ * Teleport native actor to a world pose (instant, no implied velocity).
20663
+ * Used during initialization paths (clone) where the native actor must be re-aligned
20664
+ * with the entity transform after construction-time pose was based on stale defaults.
20665
+ */ _proto._teleportToEntityTransform = function _teleportToEntityTransform(worldPosition, worldRotation) {
20666
+ this._nativeCollider.setWorldTransform(worldPosition, worldRotation);
20667
+ };
20668
+ /**
20669
+ * Sync entity world transform to native actor for per-frame updates.
20670
+ * Default semantics: teleport (setGlobalPose). Subclasses override to express
20671
+ * physics-aware movement (e.g. DynamicCollider routes kinematic actors through
20672
+ * setKinematicTarget to generate contact events on swept motion).
20673
+ */ _proto._syncEntityTransformToNative = function _syncEntityTransformToNative(worldPosition, worldRotation) {
20674
+ this._nativeCollider.setWorldTransform(worldPosition, worldRotation);
20636
20675
  };
20637
20676
  /**
20638
20677
  * @internal
@@ -20792,6 +20831,9 @@ exports.Collider = __decorate([
20792
20831
  this._nativeCollider.setUpDirection(this._upDirection);
20793
20832
  this._nativeCollider.setSlopeLimit(this._slopeLimit);
20794
20833
  };
20834
+ _proto._teleportToEntityTransform = function _teleportToEntityTransform(worldPosition, _worldRotation) {
20835
+ this._nativeCollider.setWorldPosition(worldPosition);
20836
+ };
20795
20837
  _proto._syncWorldPositionFromPhysicalSpace = function _syncWorldPositionFromPhysicalSpace() {
20796
20838
  this._nativeCollider.getWorldPosition(this.entity.transform.worldPosition);
20797
20839
  };
@@ -20894,7 +20936,7 @@ __decorate([
20894
20936
  this._staticFriction = 0.6;
20895
20937
  this._bounceCombine = PhysicsMaterialCombineMode.Average;
20896
20938
  this._frictionCombine = PhysicsMaterialCombineMode.Average;
20897
- this._nativeMaterial = Engine._nativePhysics.createPhysicsMaterial(this._staticFriction, this._dynamicFriction, this._bounciness, this._bounceCombine, this._frictionCombine);
20939
+ this._nativeMaterial = Engine._nativePhysics.createPhysicsMaterial(this._staticFriction, this._dynamicFriction, this._bounciness, this._frictionCombine, this._bounceCombine);
20898
20940
  }
20899
20941
  var _proto = PhysicsMaterial.prototype;
20900
20942
  /**
@@ -20903,6 +20945,21 @@ __decorate([
20903
20945
  !this._destroyed && this._nativeMaterial.destroy();
20904
20946
  this._destroyed = true;
20905
20947
  };
20948
+ /**
20949
+ * @internal
20950
+ */ _proto._cloneTo = function _cloneTo(target) {
20951
+ target._syncNative();
20952
+ };
20953
+ /**
20954
+ * @internal
20955
+ */ _proto._syncNative = function _syncNative() {
20956
+ var nativeMaterial = this._nativeMaterial;
20957
+ nativeMaterial.setStaticFriction(this._staticFriction);
20958
+ nativeMaterial.setDynamicFriction(this._dynamicFriction);
20959
+ nativeMaterial.setBounciness(this._bounciness);
20960
+ nativeMaterial.setFrictionCombine(this._frictionCombine);
20961
+ nativeMaterial.setBounceCombine(this._bounceCombine);
20962
+ };
20906
20963
  _create_class(PhysicsMaterial, [
20907
20964
  {
20908
20965
  key: "bounciness",
@@ -20977,6 +21034,9 @@ __decorate([
20977
21034
  ]);
20978
21035
  return PhysicsMaterial;
20979
21036
  }();
21037
+ __decorate([
21038
+ ignoreClone
21039
+ ], PhysicsMaterial.prototype, "_nativeMaterial", void 0);
20980
21040
 
20981
21041
  /**
20982
21042
  * Abstract class for collider shapes.
@@ -21029,6 +21089,16 @@ __decorate([
21029
21089
  };
21030
21090
  /**
21031
21091
  * @internal
21092
+ *
21093
+ * Called once per physics update tick by `Collider._onUpdate`. Base no-op.
21094
+ *
21095
+ * Subclasses can override for frame-driven maintenance. Currently used by
21096
+ * `MeshColliderShape` to retry native shape creation when mesh data becomes
21097
+ * accessible later or PhysX cooking previously failed due to transient state
21098
+ * (async resource loading, cook pipeline warmup, etc.).
21099
+ */ _proto._onPhysicsUpdate = function _onPhysicsUpdate() {};
21100
+ /**
21101
+ * @internal
21032
21102
  */ _proto._destroy = function _destroy() {
21033
21103
  if (this._nativeShape) {
21034
21104
  this._nativeShape.destroy();
@@ -21178,7 +21248,11 @@ __decorate([
21178
21248
  _inherits(MeshColliderShape, ColliderShape);
21179
21249
  function MeshColliderShape() {
21180
21250
  var _this;
21181
- _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;
21251
+ _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, /**
21252
+ * `true` if a native shape creation was attempted but failed (mesh data not yet
21253
+ * accessible, PhysX cooking transient failure, etc.). The `_onPhysicsUpdate` hook
21254
+ * will keep retrying every frame until creation succeeds.
21255
+ */ _this._pendingNativeShapeCreation = false;
21182
21256
  return _this;
21183
21257
  }
21184
21258
  var _proto = MeshColliderShape.prototype;
@@ -21262,9 +21336,12 @@ __decorate([
21262
21336
  }
21263
21337
  var nativeShape = Engine._nativePhysics.createMeshColliderShape(this._id, this._positions, this._indices, this._isConvex, this._material._nativeMaterial, this._cookingFlags);
21264
21338
  if (!nativeShape) {
21339
+ // Cook failed — `_onPhysicsUpdate` will retry next frame
21340
+ this._pendingNativeShapeCreation = true;
21265
21341
  return;
21266
21342
  }
21267
21343
  this._nativeShape = nativeShape;
21344
+ this._pendingNativeShapeCreation = false;
21268
21345
  // Sync base class properties (position, rotation, contactOffset, isTrigger, material)
21269
21346
  ColliderShape.prototype._syncNative.call(this);
21270
21347
  // If already attached to a collider, add the newly created native shape to it
@@ -21273,6 +21350,36 @@ __decorate([
21273
21350
  this._attachToCollider();
21274
21351
  }
21275
21352
  };
21353
+ /**
21354
+ * @internal
21355
+ * Retry hook: keep attempting `_createNativeShape` until it succeeds.
21356
+ *
21357
+ * Triggered every physics update tick by `Collider._onUpdate`. Handles the case
21358
+ * where `_cookMesh` fails on first attempt due to PhysX cooking pipeline timing
21359
+ * (the mesh data was extracted successfully at `set mesh` time, but the native
21360
+ * cook call returned null). No-op once a valid native shape exists.
21361
+ *
21362
+ * We DO NOT re-call `_extractMeshData` here — once `set mesh` finished, either:
21363
+ * - extraction succeeded → `_positions` is populated and we reuse it
21364
+ * - extraction failed → `_clearMeshData` cleared `_positions`, and `mesh.accessible`
21365
+ * won't recover (GPU upload is one-way), so re-extracting would fail again
21366
+ */ _proto._onPhysicsUpdate = function _onPhysicsUpdate() {
21367
+ if (!this._pendingNativeShapeCreation || !this._mesh || !this._positions) return;
21368
+ this._createNativeShape();
21369
+ };
21370
+ /**
21371
+ * @internal
21372
+ * After CloneManager deep-copies `_positions` / `_indices` / `_mesh` and remaps `_collider`,
21373
+ * the cloned shape still has no native PhysX shape because `_nativeShape` is `@ignoreClone`.
21374
+ * Cook a fresh native shape now using the already-cloned vertex/index buffers; on transient
21375
+ * cook failure `_createNativeShape` sets `_pendingNativeShapeCreation = true` and
21376
+ * `_onPhysicsUpdate` will retry next tick.
21377
+ */ _proto._cloneTo = function _cloneTo(target) {
21378
+ ColliderShape.prototype._cloneTo.call(this, target);
21379
+ if (target._positions) {
21380
+ target._createNativeShape();
21381
+ }
21382
+ };
21276
21383
  _create_class(MeshColliderShape, [
21277
21384
  {
21278
21385
  key: "cookingFlags",
@@ -21332,15 +21439,25 @@ __decorate([
21332
21439
  (_this__mesh = this._mesh) == null ? void 0 : _this__mesh._addReferCount(-1);
21333
21440
  value == null ? void 0 : value._addReferCount(1);
21334
21441
  this._mesh = value;
21335
- if (value && this._extractMeshData(value)) {
21336
- if (this._nativeShape) {
21337
- this._updateNativeShapeData();
21442
+ if (value) {
21443
+ if (this._extractMeshData(value)) {
21444
+ if (this._nativeShape) {
21445
+ this._updateNativeShapeData();
21446
+ } else {
21447
+ this._createNativeShape();
21448
+ }
21449
+ // _createNativeShape can fail silently (cookMesh transient failure); mark pending if so
21450
+ this._pendingNativeShapeCreation = !this._nativeShape;
21338
21451
  } else {
21339
- this._createNativeShape();
21452
+ // Mesh not yet accessible — keep pending so `_onPhysicsUpdate` retries later
21453
+ this._destroyNativeShape();
21454
+ this._clearMeshData();
21455
+ this._pendingNativeShapeCreation = true;
21340
21456
  }
21341
21457
  } else {
21342
21458
  this._destroyNativeShape();
21343
21459
  this._clearMeshData();
21460
+ this._pendingNativeShapeCreation = false;
21344
21461
  }
21345
21462
  }
21346
21463
  }
@@ -21385,6 +21502,27 @@ __decorate([
21385
21502
  */ _proto.applyTorque = function applyTorque(torque) {
21386
21503
  this._phasedActiveInScene && this._nativeCollider.addTorque(torque);
21387
21504
  };
21505
+ /**
21506
+ * Apply a force to the DynamicCollider at a given position in world space.
21507
+ * The force generates both linear acceleration through the center of mass and angular
21508
+ * acceleration about it (torque = (position - centerOfMass) × force).
21509
+ * @param force - The force to apply, in world space
21510
+ * @param position - The position where the force is applied, in world space
21511
+ */ _proto.applyForceAtPosition = function applyForceAtPosition(force, position) {
21512
+ if (!this._phasedActiveInScene) return;
21513
+ var nativeCollider = this._nativeCollider;
21514
+ var localCoM = DynamicCollider._tempVector3;
21515
+ nativeCollider.getCenterOfMass(localCoM);
21516
+ var transform = this.entity.transform;
21517
+ var worldCoM = DynamicCollider._tempVector3_1;
21518
+ engineMath.Vector3.transformByQuat(localCoM, transform.worldRotationQuaternion, worldCoM);
21519
+ worldCoM.add(transform.worldPosition);
21520
+ var torque = DynamicCollider._tempVector3_2;
21521
+ engineMath.Vector3.subtract(position, worldCoM, torque);
21522
+ engineMath.Vector3.cross(torque, force, torque);
21523
+ nativeCollider.addForce(force);
21524
+ nativeCollider.addTorque(torque);
21525
+ };
21388
21526
  _proto.move = function move(positionOrRotation, rotation) {
21389
21527
  if (!this._isKinematic) {
21390
21528
  console.warn("DynamicCollider: move() is only supported when isKinematic is true.");
@@ -21418,6 +21556,31 @@ __decorate([
21418
21556
  Collider.prototype.addShape.call(this, shape);
21419
21557
  };
21420
21558
  /**
21559
+ * Route per-frame entity → native transform sync to the correct physics API based
21560
+ * on kinematic state.
21561
+ *
21562
+ * PhysX 4.x docs (PxRigidDynamic):
21563
+ * "If you intend to move a kinematic actor with [setGlobalPose] and want
21564
+ * collision detection, use setKinematicTarget() instead."
21565
+ *
21566
+ * setGlobalPose is a teleport: PhysX skips contact detection between the old
21567
+ * and new pose, so two kinematic actors moved onto each other via entity.transform
21568
+ * mutation would NOT produce onCollisionEnter / onCollisionStay events even when
21569
+ * scene.kineKineFilteringMode = eKEEP. Routing the per-frame sync through
21570
+ * IDynamicCollider.move() (which the PhysX backend implements as
21571
+ * setKinematicTarget) tells PhysX the actor is animating to the target during the
21572
+ * next simulate(), enabling sweep contact detection for kine-kine and kine-dynamic
21573
+ * pairs alike.
21574
+ *
21575
+ * @internal
21576
+ */ _proto._syncEntityTransformToNative = function _syncEntityTransformToNative(worldPosition, worldRotation) {
21577
+ if (this._isKinematic) {
21578
+ this._nativeCollider.move(worldPosition, worldRotation);
21579
+ } else {
21580
+ Collider.prototype._syncEntityTransformToNative.call(this, worldPosition, worldRotation);
21581
+ }
21582
+ };
21583
+ /**
21421
21584
  * @internal
21422
21585
  */ _proto._onLateUpdate = function _onLateUpdate() {
21423
21586
  var transform = this.entity.transform;
@@ -21791,6 +21954,8 @@ __decorate([
21791
21954
  return DynamicCollider;
21792
21955
  }(exports.Collider);
21793
21956
  DynamicCollider._tempVector3 = new engineMath.Vector3();
21957
+ DynamicCollider._tempVector3_1 = new engineMath.Vector3();
21958
+ DynamicCollider._tempVector3_2 = new engineMath.Vector3();
21794
21959
  DynamicCollider._tempQuat = new engineMath.Quaternion();
21795
21960
  __decorate([
21796
21961
  ignoreClone
@@ -21870,8 +22035,7 @@ __decorate([
21870
22035
  * You need to obtain the actual number of contact points from the function's return value.
21871
22036
  */ _proto.getContacts = function getContacts(outContacts) {
21872
22037
  var nativeCollision = this._nativeCollision;
21873
- var smallerShapeId = Math.min(nativeCollision.shape0Id, nativeCollision.shape1Id);
21874
- var factor = this.shape.id === smallerShapeId ? 1 : -1;
22038
+ var factor = this.shape.id === nativeCollision.shape1Id ? 1 : -1;
21875
22039
  var nativeContactPoints = nativeCollision.getContacts();
21876
22040
  var length = nativeContactPoints.size();
21877
22041
  for(var i = 0; i < length; i++){
@@ -33537,8 +33701,8 @@ function _type_of(obj) {
33537
33701
  if (this._tryCrossFadeInterrupt(layerData, transitionDuration, destState, deltaTime, aniUpdate)) {
33538
33702
  return;
33539
33703
  }
33540
- var srcPlaySpeed = srcState.speed * speed;
33541
- var dstPlaySpeed = destState.speed * speed;
33704
+ var srcPlaySpeed = srcPlayData.speed * speed;
33705
+ var dstPlaySpeed = destPlayData.speed * speed;
33542
33706
  var dstPlayDeltaTime = dstPlaySpeed * deltaTime;
33543
33707
  srcPlayData && srcPlayData.updateOrientation(srcPlaySpeed * deltaTime);
33544
33708
  destPlayData && destPlayData.updateOrientation(dstPlayDeltaTime);