@galacean/engine-core 1.1.0-beta.14 → 1.1.0-beta.16

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.
@@ -566,6 +566,9 @@ function _instanceof(left, right) {
566
566
  if (sourceProperty._cloneTo) {
567
567
  sourceProperty._cloneTo(targetOProperty);
568
568
  }
569
+ if (sourceProperty.copyFrom) {
570
+ targetOProperty.copyFrom(sourceProperty);
571
+ }
569
572
  break;
570
573
  }
571
574
  } else {
@@ -4208,7 +4211,11 @@ var ComponentCloner = /*#__PURE__*/ function() {
4208
4211
  }
4209
4212
  cloneEntity.layer = srcEntity.layer;
4210
4213
  cloneEntity._isActive = srcEntity._isActive;
4211
- cloneEntity.transform.localMatrix = srcEntity.transform.localMatrix;
4214
+ var cloneTransform = cloneEntity.transform;
4215
+ var srcTransform = srcEntity.transform;
4216
+ cloneTransform.position = srcTransform.position;
4217
+ cloneTransform.rotation = srcTransform.rotation;
4218
+ cloneTransform.scale = srcTransform.scale;
4212
4219
  var children = srcEntity._children;
4213
4220
  for(var i = 0, n = srcEntity._children.length; i < n; i++){
4214
4221
  cloneEntity.addChild(this._createCloneEntity(children[i]));
@@ -11777,8 +11784,8 @@ var PrimitiveType;
11777
11784
  function SkinnedMeshRenderer(entity) {
11778
11785
  var _this;
11779
11786
  _this = MeshRenderer1.call(this, entity) || this;
11780
- _this._jointDataCreateCache = new miniprogram.Vector2(-1, -1);
11781
11787
  _this._localBounds = new miniprogram.BoundingBox();
11788
+ _this._jointDataCreateCache = new miniprogram.Vector2(-1, -1);
11782
11789
  _this._skin = null;
11783
11790
  var rhi = _this.entity.engine._hardwareRenderer;
11784
11791
  var maxVertexUniformVectors = rhi.renderStates.getParameter(rhi.gl.MAX_VERTEX_UNIFORM_VECTORS);
@@ -12082,6 +12089,9 @@ var PrimitiveType;
12082
12089
  (function() {
12083
12090
  SkinnedMeshRenderer._jointMatrixProperty = ShaderProperty.getByName("renderer_JointMatrix");
12084
12091
  })();
12092
+ __decorate([
12093
+ deepClone
12094
+ ], SkinnedMeshRenderer.prototype, "_localBounds", void 0);
12085
12095
  __decorate([
12086
12096
  ignoreClone
12087
12097
  ], SkinnedMeshRenderer.prototype, "_jointDataCreateCache", void 0);
@@ -12094,9 +12104,6 @@ __decorate([
12094
12104
  __decorate([
12095
12105
  ignoreClone
12096
12106
  ], SkinnedMeshRenderer.prototype, "_rootBone", void 0);
12097
- __decorate([
12098
- ignoreClone
12099
- ], SkinnedMeshRenderer.prototype, "_localBounds", void 0);
12100
12107
  __decorate([
12101
12108
  ignoreClone
12102
12109
  ], SkinnedMeshRenderer.prototype, "_jointMatrices", void 0);
@@ -13224,12 +13231,12 @@ var /** @internal */ PromiseState;
13224
13231
  */ ResourceManager._addLoader = function _addLoader(type, loader, extNames) {
13225
13232
  this._loaders[type] = loader;
13226
13233
  for(var i = 0, len = extNames.length; i < len; i++){
13227
- this._extTypeMapping[extNames[i]] = type;
13234
+ this._extTypeMapping[extNames[i].toLowerCase()] = type;
13228
13235
  }
13229
13236
  };
13230
13237
  ResourceManager._getTypeByUrl = function _getTypeByUrl(url) {
13231
13238
  var path = url.split("?")[0];
13232
- return this._extTypeMapping[path.substring(path.lastIndexOf(".") + 1)];
13239
+ return this._extTypeMapping[path.substring(path.lastIndexOf(".") + 1).toLowerCase()];
13233
13240
  };
13234
13241
  return ResourceManager;
13235
13242
  }();
@@ -24486,9 +24493,7 @@ var DirtyFlag;
24486
24493
  this.property = property;
24487
24494
  this.component = target.getComponent(type);
24488
24495
  this.cureType = cureType;
24489
- var isBlendShape = _instanceof(this.component, SkinnedMeshRenderer);
24490
- // @todo: Temp solution with blendShape
24491
- this._isCopyMode = cureType._isCopyMode && !isBlendShape;
24496
+ this._isBlendShape = _instanceof(this.component, SkinnedMeshRenderer);
24492
24497
  var assemblerType = AnimationCurveOwner.getAssemblerType(type, property);
24493
24498
  this._assembler = new assemblerType();
24494
24499
  this._assembler.initialize(this);
@@ -24520,7 +24525,7 @@ var DirtyFlag;
24520
24525
  this._assembler.setTargetValue(this.defaultValue);
24521
24526
  };
24522
24527
  _proto.getEvaluateValue = function getEvaluateValue(out) {
24523
- if (this._isCopyMode) {
24528
+ if (this.cureType._isCopyMode) {
24524
24529
  this.cureType._setValue(this.baseEvaluateData.value, out);
24525
24530
  return out;
24526
24531
  } else {
@@ -24528,14 +24533,14 @@ var DirtyFlag;
24528
24533
  }
24529
24534
  };
24530
24535
  _proto.saveDefaultValue = function saveDefaultValue() {
24531
- if (this._isCopyMode) {
24536
+ if (this.cureType._isCopyMode) {
24532
24537
  this.cureType._setValue(this.referenceTargetValue, this.defaultValue);
24533
24538
  } else {
24534
24539
  this.defaultValue = this._assembler.getTargetValue();
24535
24540
  }
24536
24541
  };
24537
24542
  _proto.saveFixedPoseValue = function saveFixedPoseValue() {
24538
- if (this._isCopyMode) {
24543
+ if (this.cureType._isCopyMode) {
24539
24544
  this.cureType._setValue(this.referenceTargetValue, this.fixedPoseValue);
24540
24545
  } else {
24541
24546
  this.fixedPoseValue = this._assembler.getTargetValue();
@@ -24544,25 +24549,37 @@ var DirtyFlag;
24544
24549
  _proto.applyValue = function applyValue(value, weight, additive) {
24545
24550
  var cureType = this.cureType;
24546
24551
  if (additive) {
24547
- if (this._isCopyMode) {
24548
- cureType._additiveValue(value, weight, this.referenceTargetValue);
24552
+ var assembler = this._assembler;
24553
+ if (cureType._isCopyMode) {
24554
+ var additiveValue = cureType._additiveValue(value, weight, this.referenceTargetValue);
24555
+ // @todo: Temp solution with blendShape bug when multi SkinnedMeshRenderer in a entity. we need to run setTargetValue to solve it.
24556
+ if (this._isBlendShape) {
24557
+ assembler.setTargetValue(additiveValue);
24558
+ }
24549
24559
  } else {
24550
- var assembler = this._assembler;
24551
24560
  var originValue = assembler.getTargetValue();
24552
- var additiveValue = cureType._additiveValue(value, weight, originValue);
24553
- assembler.setTargetValue(additiveValue);
24561
+ var additiveValue1 = cureType._additiveValue(value, weight, originValue);
24562
+ assembler.setTargetValue(additiveValue1);
24554
24563
  }
24555
24564
  } else {
24556
24565
  if (weight === 1.0) {
24557
- if (this._isCopyMode) {
24566
+ if (cureType._isCopyMode) {
24558
24567
  cureType._setValue(value, this.referenceTargetValue);
24568
+ // @todo: Temp solution with blendShape bug when multi SkinnedMeshRenderer in a entity. we need to run setTargetValue to solve it.
24569
+ if (this._isBlendShape) {
24570
+ this._assembler.setTargetValue(this.referenceTargetValue);
24571
+ }
24559
24572
  } else {
24560
24573
  this._assembler.setTargetValue(value);
24561
24574
  }
24562
24575
  } else {
24563
- if (this._isCopyMode) {
24576
+ if (cureType._isCopyMode) {
24564
24577
  var targetValue = this.referenceTargetValue;
24565
24578
  cureType._lerpValue(targetValue, value, weight, targetValue);
24579
+ // @todo: Temp solution with blendShape bug when multi SkinnedMeshRenderer in a entity. we need to run setTargetValue to solve it.
24580
+ if (this._isBlendShape) {
24581
+ this._assembler.setTargetValue(targetValue);
24582
+ }
24566
24583
  } else {
24567
24584
  var originValue1 = this._assembler.getTargetValue();
24568
24585
  var lerpValue = cureType._lerpValue(originValue1, value, weight);
@@ -24572,7 +24589,7 @@ var DirtyFlag;
24572
24589
  }
24573
24590
  };
24574
24591
  _proto._lerpValue = function _lerpValue(srcValue, destValue, crossWeight) {
24575
- if (this._isCopyMode) {
24592
+ if (this.cureType._isCopyMode) {
24576
24593
  return this.cureType._lerpValue(srcValue, destValue, crossWeight, this.baseEvaluateData.value);
24577
24594
  } else {
24578
24595
  this.baseEvaluateData.value = this.cureType._lerpValue(srcValue, destValue, crossWeight);
@@ -27433,6 +27450,7 @@ exports.ParticleStopMode = void 0;
27433
27450
  context.camera._renderPipeline.pushRenderData(context, renderData);
27434
27451
  };
27435
27452
  _proto._onDestroy = function _onDestroy() {
27453
+ Renderer1.prototype._onDestroy.call(this);
27436
27454
  this.generator._destroy();
27437
27455
  };
27438
27456
  _create_class(ParticleRenderer, [
@@ -28032,8 +28050,8 @@ __decorate([
28032
28050
  /** The rate of particle emission. */ _this.rateOverTime = new ParticleCompositeCurve(10);
28033
28051
  /** The rate at which the emitter spawns new particles over distance. */ _this.rateOverDistance = new ParticleCompositeCurve(0);
28034
28052
  /** @internal */ _this._shapeRand = new miniprogram.Rand(0, ParticleRandomSubSeeds.Shape);
28053
+ /** @internal */ _this._frameRateTime = 0;
28035
28054
  _this._bursts = [];
28036
- _this._frameRateTime = 0;
28037
28055
  _this._currentBurstIndex = 0;
28038
28056
  _this._burstRand = new miniprogram.Rand(0, ParticleRandomSubSeeds.Burst);
28039
28057
  return _this;
@@ -28082,7 +28100,8 @@ __decorate([
28082
28100
  };
28083
28101
  /**
28084
28102
  * @internal
28085
- */ _proto._resetBurst = function _resetBurst() {
28103
+ */ _proto._reset = function _reset() {
28104
+ this._frameRateTime = 0;
28086
28105
  this._currentBurstIndex = 0;
28087
28106
  };
28088
28107
  _proto._emitByRateOverTime = function _emitByRateOverTime(playTime) {
@@ -29040,7 +29059,7 @@ __decorate([
29040
29059
  this._firstActiveElement = firstFreeElement;
29041
29060
  this._firstNewElement = firstFreeElement;
29042
29061
  this._playTime = 0;
29043
- this.emission._resetBurst();
29062
+ this.emission._reset();
29044
29063
  }
29045
29064
  }
29046
29065
  };
@@ -29075,19 +29094,23 @@ __decorate([
29075
29094
  /**
29076
29095
  * @internal
29077
29096
  */ _proto._update = function _update(elapsedTime) {
29097
+ var _this = this, main = _this.main, emission = _this.emission;
29098
+ var duration = main.duration;
29078
29099
  var lastPlayTime = this._playTime;
29079
29100
  this._playTime += elapsedTime;
29080
29101
  this._retireActiveParticles();
29081
29102
  this._freeRetiredParticles();
29082
- if (this.emission.enabled && this._isPlaying) {
29083
- this.emission._emit(lastPlayTime, this._playTime);
29084
- if (!this.main.isLoop && this._playTime > this.main.duration) {
29103
+ if (emission.enabled && this._isPlaying) {
29104
+ emission._emit(lastPlayTime, this._playTime);
29105
+ if (!main.isLoop && this._playTime > duration) {
29085
29106
  this._isPlaying = false;
29086
29107
  }
29087
29108
  }
29088
29109
  // Reset play time when is not playing and no active particles to avoid potential precision problems in GPU
29089
29110
  if (!this.isAlive) {
29090
- this._playTime = 0;
29111
+ var discardTime = Math.min(emission._frameRateTime, Math.floor(this._playTime / duration) * duration);
29112
+ this._playTime -= discardTime;
29113
+ emission._frameRateTime -= discardTime;
29091
29114
  }
29092
29115
  // Add new particles to vertex buffer when has wait process retired element or new particle
29093
29116
  //
package/dist/module.js CHANGED
@@ -561,6 +561,9 @@ function _instanceof(left, right) {
561
561
  if (sourceProperty._cloneTo) {
562
562
  sourceProperty._cloneTo(targetOProperty);
563
563
  }
564
+ if (sourceProperty.copyFrom) {
565
+ targetOProperty.copyFrom(sourceProperty);
566
+ }
564
567
  break;
565
568
  }
566
569
  } else {
@@ -4203,7 +4206,11 @@ var ComponentCloner = /*#__PURE__*/ function() {
4203
4206
  }
4204
4207
  cloneEntity.layer = srcEntity.layer;
4205
4208
  cloneEntity._isActive = srcEntity._isActive;
4206
- cloneEntity.transform.localMatrix = srcEntity.transform.localMatrix;
4209
+ var cloneTransform = cloneEntity.transform;
4210
+ var srcTransform = srcEntity.transform;
4211
+ cloneTransform.position = srcTransform.position;
4212
+ cloneTransform.rotation = srcTransform.rotation;
4213
+ cloneTransform.scale = srcTransform.scale;
4207
4214
  var children = srcEntity._children;
4208
4215
  for(var i = 0, n = srcEntity._children.length; i < n; i++){
4209
4216
  cloneEntity.addChild(this._createCloneEntity(children[i]));
@@ -11772,8 +11779,8 @@ var PrimitiveType;
11772
11779
  function SkinnedMeshRenderer(entity) {
11773
11780
  var _this;
11774
11781
  _this = MeshRenderer1.call(this, entity) || this;
11775
- _this._jointDataCreateCache = new Vector2(-1, -1);
11776
11782
  _this._localBounds = new BoundingBox();
11783
+ _this._jointDataCreateCache = new Vector2(-1, -1);
11777
11784
  _this._skin = null;
11778
11785
  var rhi = _this.entity.engine._hardwareRenderer;
11779
11786
  var maxVertexUniformVectors = rhi.renderStates.getParameter(rhi.gl.MAX_VERTEX_UNIFORM_VECTORS);
@@ -12077,6 +12084,9 @@ var PrimitiveType;
12077
12084
  (function() {
12078
12085
  SkinnedMeshRenderer._jointMatrixProperty = ShaderProperty.getByName("renderer_JointMatrix");
12079
12086
  })();
12087
+ __decorate([
12088
+ deepClone
12089
+ ], SkinnedMeshRenderer.prototype, "_localBounds", void 0);
12080
12090
  __decorate([
12081
12091
  ignoreClone
12082
12092
  ], SkinnedMeshRenderer.prototype, "_jointDataCreateCache", void 0);
@@ -12089,9 +12099,6 @@ __decorate([
12089
12099
  __decorate([
12090
12100
  ignoreClone
12091
12101
  ], SkinnedMeshRenderer.prototype, "_rootBone", void 0);
12092
- __decorate([
12093
- ignoreClone
12094
- ], SkinnedMeshRenderer.prototype, "_localBounds", void 0);
12095
12102
  __decorate([
12096
12103
  ignoreClone
12097
12104
  ], SkinnedMeshRenderer.prototype, "_jointMatrices", void 0);
@@ -13219,12 +13226,12 @@ var /** @internal */ PromiseState;
13219
13226
  */ ResourceManager._addLoader = function _addLoader(type, loader, extNames) {
13220
13227
  this._loaders[type] = loader;
13221
13228
  for(var i = 0, len = extNames.length; i < len; i++){
13222
- this._extTypeMapping[extNames[i]] = type;
13229
+ this._extTypeMapping[extNames[i].toLowerCase()] = type;
13223
13230
  }
13224
13231
  };
13225
13232
  ResourceManager._getTypeByUrl = function _getTypeByUrl(url) {
13226
13233
  var path = url.split("?")[0];
13227
- return this._extTypeMapping[path.substring(path.lastIndexOf(".") + 1)];
13234
+ return this._extTypeMapping[path.substring(path.lastIndexOf(".") + 1).toLowerCase()];
13228
13235
  };
13229
13236
  return ResourceManager;
13230
13237
  }();
@@ -24481,9 +24488,7 @@ var DirtyFlag;
24481
24488
  this.property = property;
24482
24489
  this.component = target.getComponent(type);
24483
24490
  this.cureType = cureType;
24484
- var isBlendShape = _instanceof(this.component, SkinnedMeshRenderer);
24485
- // @todo: Temp solution with blendShape
24486
- this._isCopyMode = cureType._isCopyMode && !isBlendShape;
24491
+ this._isBlendShape = _instanceof(this.component, SkinnedMeshRenderer);
24487
24492
  var assemblerType = AnimationCurveOwner.getAssemblerType(type, property);
24488
24493
  this._assembler = new assemblerType();
24489
24494
  this._assembler.initialize(this);
@@ -24515,7 +24520,7 @@ var DirtyFlag;
24515
24520
  this._assembler.setTargetValue(this.defaultValue);
24516
24521
  };
24517
24522
  _proto.getEvaluateValue = function getEvaluateValue(out) {
24518
- if (this._isCopyMode) {
24523
+ if (this.cureType._isCopyMode) {
24519
24524
  this.cureType._setValue(this.baseEvaluateData.value, out);
24520
24525
  return out;
24521
24526
  } else {
@@ -24523,14 +24528,14 @@ var DirtyFlag;
24523
24528
  }
24524
24529
  };
24525
24530
  _proto.saveDefaultValue = function saveDefaultValue() {
24526
- if (this._isCopyMode) {
24531
+ if (this.cureType._isCopyMode) {
24527
24532
  this.cureType._setValue(this.referenceTargetValue, this.defaultValue);
24528
24533
  } else {
24529
24534
  this.defaultValue = this._assembler.getTargetValue();
24530
24535
  }
24531
24536
  };
24532
24537
  _proto.saveFixedPoseValue = function saveFixedPoseValue() {
24533
- if (this._isCopyMode) {
24538
+ if (this.cureType._isCopyMode) {
24534
24539
  this.cureType._setValue(this.referenceTargetValue, this.fixedPoseValue);
24535
24540
  } else {
24536
24541
  this.fixedPoseValue = this._assembler.getTargetValue();
@@ -24539,25 +24544,37 @@ var DirtyFlag;
24539
24544
  _proto.applyValue = function applyValue(value, weight, additive) {
24540
24545
  var cureType = this.cureType;
24541
24546
  if (additive) {
24542
- if (this._isCopyMode) {
24543
- cureType._additiveValue(value, weight, this.referenceTargetValue);
24547
+ var assembler = this._assembler;
24548
+ if (cureType._isCopyMode) {
24549
+ var additiveValue = cureType._additiveValue(value, weight, this.referenceTargetValue);
24550
+ // @todo: Temp solution with blendShape bug when multi SkinnedMeshRenderer in a entity. we need to run setTargetValue to solve it.
24551
+ if (this._isBlendShape) {
24552
+ assembler.setTargetValue(additiveValue);
24553
+ }
24544
24554
  } else {
24545
- var assembler = this._assembler;
24546
24555
  var originValue = assembler.getTargetValue();
24547
- var additiveValue = cureType._additiveValue(value, weight, originValue);
24548
- assembler.setTargetValue(additiveValue);
24556
+ var additiveValue1 = cureType._additiveValue(value, weight, originValue);
24557
+ assembler.setTargetValue(additiveValue1);
24549
24558
  }
24550
24559
  } else {
24551
24560
  if (weight === 1.0) {
24552
- if (this._isCopyMode) {
24561
+ if (cureType._isCopyMode) {
24553
24562
  cureType._setValue(value, this.referenceTargetValue);
24563
+ // @todo: Temp solution with blendShape bug when multi SkinnedMeshRenderer in a entity. we need to run setTargetValue to solve it.
24564
+ if (this._isBlendShape) {
24565
+ this._assembler.setTargetValue(this.referenceTargetValue);
24566
+ }
24554
24567
  } else {
24555
24568
  this._assembler.setTargetValue(value);
24556
24569
  }
24557
24570
  } else {
24558
- if (this._isCopyMode) {
24571
+ if (cureType._isCopyMode) {
24559
24572
  var targetValue = this.referenceTargetValue;
24560
24573
  cureType._lerpValue(targetValue, value, weight, targetValue);
24574
+ // @todo: Temp solution with blendShape bug when multi SkinnedMeshRenderer in a entity. we need to run setTargetValue to solve it.
24575
+ if (this._isBlendShape) {
24576
+ this._assembler.setTargetValue(targetValue);
24577
+ }
24561
24578
  } else {
24562
24579
  var originValue1 = this._assembler.getTargetValue();
24563
24580
  var lerpValue = cureType._lerpValue(originValue1, value, weight);
@@ -24567,7 +24584,7 @@ var DirtyFlag;
24567
24584
  }
24568
24585
  };
24569
24586
  _proto._lerpValue = function _lerpValue(srcValue, destValue, crossWeight) {
24570
- if (this._isCopyMode) {
24587
+ if (this.cureType._isCopyMode) {
24571
24588
  return this.cureType._lerpValue(srcValue, destValue, crossWeight, this.baseEvaluateData.value);
24572
24589
  } else {
24573
24590
  this.baseEvaluateData.value = this.cureType._lerpValue(srcValue, destValue, crossWeight);
@@ -27428,6 +27445,7 @@ var ParticleStopMode;
27428
27445
  context.camera._renderPipeline.pushRenderData(context, renderData);
27429
27446
  };
27430
27447
  _proto._onDestroy = function _onDestroy() {
27448
+ Renderer1.prototype._onDestroy.call(this);
27431
27449
  this.generator._destroy();
27432
27450
  };
27433
27451
  _create_class(ParticleRenderer, [
@@ -28027,8 +28045,8 @@ __decorate([
28027
28045
  /** The rate of particle emission. */ _this.rateOverTime = new ParticleCompositeCurve(10);
28028
28046
  /** The rate at which the emitter spawns new particles over distance. */ _this.rateOverDistance = new ParticleCompositeCurve(0);
28029
28047
  /** @internal */ _this._shapeRand = new Rand(0, ParticleRandomSubSeeds.Shape);
28048
+ /** @internal */ _this._frameRateTime = 0;
28030
28049
  _this._bursts = [];
28031
- _this._frameRateTime = 0;
28032
28050
  _this._currentBurstIndex = 0;
28033
28051
  _this._burstRand = new Rand(0, ParticleRandomSubSeeds.Burst);
28034
28052
  return _this;
@@ -28077,7 +28095,8 @@ __decorate([
28077
28095
  };
28078
28096
  /**
28079
28097
  * @internal
28080
- */ _proto._resetBurst = function _resetBurst() {
28098
+ */ _proto._reset = function _reset() {
28099
+ this._frameRateTime = 0;
28081
28100
  this._currentBurstIndex = 0;
28082
28101
  };
28083
28102
  _proto._emitByRateOverTime = function _emitByRateOverTime(playTime) {
@@ -29035,7 +29054,7 @@ __decorate([
29035
29054
  this._firstActiveElement = firstFreeElement;
29036
29055
  this._firstNewElement = firstFreeElement;
29037
29056
  this._playTime = 0;
29038
- this.emission._resetBurst();
29057
+ this.emission._reset();
29039
29058
  }
29040
29059
  }
29041
29060
  };
@@ -29070,19 +29089,23 @@ __decorate([
29070
29089
  /**
29071
29090
  * @internal
29072
29091
  */ _proto._update = function _update(elapsedTime) {
29092
+ var _this = this, main = _this.main, emission = _this.emission;
29093
+ var duration = main.duration;
29073
29094
  var lastPlayTime = this._playTime;
29074
29095
  this._playTime += elapsedTime;
29075
29096
  this._retireActiveParticles();
29076
29097
  this._freeRetiredParticles();
29077
- if (this.emission.enabled && this._isPlaying) {
29078
- this.emission._emit(lastPlayTime, this._playTime);
29079
- if (!this.main.isLoop && this._playTime > this.main.duration) {
29098
+ if (emission.enabled && this._isPlaying) {
29099
+ emission._emit(lastPlayTime, this._playTime);
29100
+ if (!main.isLoop && this._playTime > duration) {
29080
29101
  this._isPlaying = false;
29081
29102
  }
29082
29103
  }
29083
29104
  // Reset play time when is not playing and no active particles to avoid potential precision problems in GPU
29084
29105
  if (!this.isAlive) {
29085
- this._playTime = 0;
29106
+ var discardTime = Math.min(emission._frameRateTime, Math.floor(this._playTime / duration) * duration);
29107
+ this._playTime -= discardTime;
29108
+ emission._frameRateTime -= discardTime;
29086
29109
  }
29087
29110
  // Add new particles to vertex buffer when has wait process retired element or new particle
29088
29111
  //