@galacean/engine-core 2.0.0-alpha.17 → 2.0.0-alpha.19

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/module.js CHANGED
@@ -4912,7 +4912,7 @@ var texture_sheet_animation_module = "#if defined(RENDERER_TSA_FRAME_CURVE) || d
4912
4912
 
4913
4913
  var force_over_lifetime_module = "#if defined(RENDERER_FOL_CONSTANT_MODE) || defined(RENDERER_FOL_CURVE_MODE)\n #define _FOL_MODULE_ENABLED\n#endif\n\n#ifdef _FOL_MODULE_ENABLED\n uniform int renderer_FOLSpace;\n\n #ifdef RENDERER_FOL_CONSTANT_MODE\n uniform vec3 renderer_FOLMaxConst;\n\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n uniform vec3 renderer_FOLMinConst;\n #endif\n\n #endif\n\n #ifdef RENDERER_FOL_CURVE_MODE\n uniform vec2 renderer_FOLMaxGradientX[4];\n uniform vec2 renderer_FOLMaxGradientY[4];\n uniform vec2 renderer_FOLMaxGradientZ[4];\n\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n uniform vec2 renderer_FOLMinGradientX[4];\n uniform vec2 renderer_FOLMinGradientY[4];\n uniform vec2 renderer_FOLMinGradientZ[4];\n #endif\n #endif\n\n // (tHat - t1) * (tHat - t1) * (tHat - t1) * (a2 - a1) / ((t2 - t1) * 6.0) + a1 * (tHat - t1) * (tHat - t1) * 0.5 + v1 * (tHat - t1);\n // to = tHat - t1; tr = t2 - t1\n float computeDisplacementIntegral(in float to, in float tr, in float a1, in float a2, in float v1) {\n return to * to * to * (a2 - a1) / (tr * 6.0) + a1 * to * to * 0.5 + v1 * to;\n }\n\n float evaluateForceParticleCurveCumulative(in vec2 keys[4], in float normalizedAge, out float velocityCumulative) {\n float cumulativeValue = 0.0;\n velocityCumulative = 0.0;\n\n for (int i = 1; i < 4; i++){\n vec2 key = keys[i];\n vec2 lastKey = keys[i - 1];\n float timeRange = (key.x - lastKey.x) * a_ShapePositionStartLifeTime.w;\n\n if (key.x >= normalizedAge){\n float timeOffset = (normalizedAge - lastKey.x) * a_ShapePositionStartLifeTime.w;\n cumulativeValue += computeDisplacementIntegral(timeOffset, timeRange, lastKey.y, key.y, velocityCumulative);\n\n float finalAcceleration = mix(lastKey.y, key.y, timeOffset / timeRange);\n velocityCumulative += 0.5 * timeOffset * (finalAcceleration + lastKey.y);\n break;\n } else { \n cumulativeValue += computeDisplacementIntegral(timeRange, timeRange, lastKey.y, key.y, velocityCumulative);\n velocityCumulative += 0.5 * timeRange * (lastKey.y + key.y);\n }\n }\n return cumulativeValue;\n }\n\n vec3 computeForcePositionOffset(in float normalizedAge, in float age, out vec3 velocityOffset) {\n vec3 forcePosition;\n\n #if defined(RENDERER_FOL_CONSTANT_MODE)\n vec3 forceAcceleration = renderer_FOLMaxConst;\n\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n forceAcceleration = mix(renderer_FOLMinConst, forceAcceleration, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n\n velocityOffset = forceAcceleration * age;\n\n forcePosition = 0.5 * forceAcceleration * age * age;\n #elif defined(RENDERER_FOL_CURVE_MODE)\n forcePosition = vec3(\n evaluateForceParticleCurveCumulative(renderer_FOLMaxGradientX, normalizedAge, velocityOffset.x),\n evaluateForceParticleCurveCumulative(renderer_FOLMaxGradientY, normalizedAge, velocityOffset.y),\n evaluateForceParticleCurveCumulative(renderer_FOLMaxGradientZ, normalizedAge, velocityOffset.z)\n );\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec3 minVelocityOffset;\n\n forcePosition = vec3(\n mix(evaluateForceParticleCurveCumulative(renderer_FOLMinGradientX, normalizedAge, minVelocityOffset.x), forcePosition.x, a_Random2.x),\n mix(evaluateForceParticleCurveCumulative(renderer_FOLMinGradientY, normalizedAge, minVelocityOffset.y), forcePosition.y, a_Random2.y),\n mix(evaluateForceParticleCurveCumulative(renderer_FOLMinGradientZ, normalizedAge, minVelocityOffset.z), forcePosition.z, a_Random2.z)\n );\n\n velocityOffset = mix(minVelocityOffset, velocityOffset, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n return forcePosition;\n }\n#endif"; // eslint-disable-line
4914
4914
 
4915
- var limit_velocity_over_lifetime_module = "#ifdef RENDERER_LVL_MODULE_ENABLED\n uniform int renderer_LVLSpace;\n uniform float renderer_LVLDampen;\n\n // Scalar limit\n #ifndef RENDERER_LVL_SEPARATE_AXES\n #ifdef RENDERER_LVL_LIMIT_CONSTANT_MODE\n uniform float renderer_LVLLimitMaxConst;\n #ifdef RENDERER_LVL_LIMIT_IS_RANDOM_TWO\n uniform float renderer_LVLLimitMinConst;\n #endif\n #endif\n #ifdef RENDERER_LVL_LIMIT_CURVE_MODE\n uniform vec2 renderer_LVLLimitMaxCurve[4];\n #ifdef RENDERER_LVL_LIMIT_IS_RANDOM_TWO\n uniform vec2 renderer_LVLLimitMinCurve[4];\n #endif\n #endif\n #endif\n\n // Per-axis limit\n #ifdef RENDERER_LVL_SEPARATE_AXES\n #ifdef RENDERER_LVL_LIMIT_CONSTANT_MODE\n uniform vec3 renderer_LVLLimitMaxConstVector;\n #ifdef RENDERER_LVL_LIMIT_IS_RANDOM_TWO\n uniform vec3 renderer_LVLLimitMinConstVector;\n #endif\n #endif\n #ifdef RENDERER_LVL_LIMIT_CURVE_MODE\n uniform vec2 renderer_LVLLimitXMaxCurve[4];\n uniform vec2 renderer_LVLLimitYMaxCurve[4];\n uniform vec2 renderer_LVLLimitZMaxCurve[4];\n #ifdef RENDERER_LVL_LIMIT_IS_RANDOM_TWO\n uniform vec2 renderer_LVLLimitXMinCurve[4];\n uniform vec2 renderer_LVLLimitYMinCurve[4];\n uniform vec2 renderer_LVLLimitZMinCurve[4];\n #endif\n #endif\n #endif\n\n // Drag curve\n #ifdef RENDERER_LVL_DRAG_CURVE_MODE\n uniform vec2 renderer_LVLDragMaxCurve[4];\n #ifdef RENDERER_LVL_DRAG_IS_RANDOM_TWO\n uniform vec2 renderer_LVLDragMinCurve[4];\n #endif\n #endif\n\n float evaluateLVLDrag(float normalizedAge, float dragRand) {\n #ifdef RENDERER_LVL_DRAG_CURVE_MODE\n float dragMax = evaluateParticleCurve(renderer_LVLDragMaxCurve, normalizedAge);\n #ifdef RENDERER_LVL_DRAG_IS_RANDOM_TWO\n float dragMin = evaluateParticleCurve(renderer_LVLDragMinCurve, normalizedAge);\n return mix(dragMin, dragMax, dragRand);\n #else\n return dragMax;\n #endif\n #else\n return mix(renderer_LVLDragConstant.x, renderer_LVLDragConstant.y, dragRand);\n #endif\n }\n\n vec3 applyLVLSpeedLimitTF(vec3 velocity, float normalizedAge, float limitRand, float effectiveDampen) {\n #ifdef RENDERER_LVL_SEPARATE_AXES\n vec3 limitValue;\n #ifdef RENDERER_LVL_LIMIT_CONSTANT_MODE\n limitValue = renderer_LVLLimitMaxConstVector;\n #ifdef RENDERER_LVL_LIMIT_IS_RANDOM_TWO\n limitValue = mix(renderer_LVLLimitMinConstVector, limitValue, limitRand);\n #endif\n #endif\n #ifdef RENDERER_LVL_LIMIT_CURVE_MODE\n limitValue = vec3(\n evaluateParticleCurve(renderer_LVLLimitXMaxCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLLimitYMaxCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLLimitZMaxCurve, normalizedAge)\n );\n #ifdef RENDERER_LVL_LIMIT_IS_RANDOM_TWO\n vec3 minLimitValue = vec3(\n evaluateParticleCurve(renderer_LVLLimitXMinCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLLimitYMinCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLLimitZMinCurve, normalizedAge)\n );\n limitValue = mix(minLimitValue, limitValue, limitRand);\n #endif\n #endif\n\n vec3 absVel = abs(velocity);\n vec3 excess = max(absVel - limitValue, vec3(0.0));\n velocity = sign(velocity) * (absVel - excess * effectiveDampen);\n #else\n float limitValue;\n #ifdef RENDERER_LVL_LIMIT_CONSTANT_MODE\n limitValue = renderer_LVLLimitMaxConst;\n #ifdef RENDERER_LVL_LIMIT_IS_RANDOM_TWO\n limitValue = mix(renderer_LVLLimitMinConst, limitValue, limitRand);\n #endif\n #endif\n #ifdef RENDERER_LVL_LIMIT_CURVE_MODE\n limitValue = evaluateParticleCurve(renderer_LVLLimitMaxCurve, normalizedAge);\n #ifdef RENDERER_LVL_LIMIT_IS_RANDOM_TWO\n float minLimitValue = evaluateParticleCurve(renderer_LVLLimitMinCurve, normalizedAge);\n limitValue = mix(minLimitValue, limitValue, limitRand);\n #endif\n #endif\n\n float speed = length(velocity);\n if (speed > limitValue && speed > 0.0) {\n float excess = speed - limitValue;\n velocity = velocity * ((speed - excess * effectiveDampen) / speed);\n }\n #endif\n return velocity;\n }\n\n#endif\n"; // eslint-disable-line
4915
+ var limit_velocity_over_lifetime_module = "#ifdef RENDERER_LVL_MODULE_ENABLED\n uniform int renderer_LVLSpace;\n uniform float renderer_LVLDampen;\n\n // Scalar limit\n #ifndef RENDERER_LVL_SEPARATE_AXES\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n uniform float renderer_LVLSpeedMaxConst;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n uniform float renderer_LVLSpeedMinConst;\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n uniform vec2 renderer_LVLSpeedMaxCurve[4];\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n uniform vec2 renderer_LVLSpeedMinCurve[4];\n #endif\n #endif\n #endif\n\n // Per-axis limit\n #ifdef RENDERER_LVL_SEPARATE_AXES\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n uniform vec3 renderer_LVLSpeedMaxConstVector;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n uniform vec3 renderer_LVLSpeedMinConstVector;\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n uniform vec2 renderer_LVLSpeedXMaxCurve[4];\n uniform vec2 renderer_LVLSpeedYMaxCurve[4];\n uniform vec2 renderer_LVLSpeedZMaxCurve[4];\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n uniform vec2 renderer_LVLSpeedXMinCurve[4];\n uniform vec2 renderer_LVLSpeedYMinCurve[4];\n uniform vec2 renderer_LVLSpeedZMinCurve[4];\n #endif\n #endif\n #endif\n\n // Drag curve\n #ifdef RENDERER_LVL_DRAG_CURVE_MODE\n uniform vec2 renderer_LVLDragMaxCurve[4];\n #ifdef RENDERER_LVL_DRAG_IS_RANDOM_TWO\n uniform vec2 renderer_LVLDragMinCurve[4];\n #endif\n #endif\n\n float evaluateLVLDrag(float normalizedAge, float dragRand) {\n #ifdef RENDERER_LVL_DRAG_CURVE_MODE\n float dragMax = evaluateParticleCurve(renderer_LVLDragMaxCurve, normalizedAge);\n #ifdef RENDERER_LVL_DRAG_IS_RANDOM_TWO\n float dragMin = evaluateParticleCurve(renderer_LVLDragMinCurve, normalizedAge);\n return mix(dragMin, dragMax, dragRand);\n #else\n return dragMax;\n #endif\n #else\n return mix(renderer_LVLDragConstant.x, renderer_LVLDragConstant.y, dragRand);\n #endif\n }\n\n vec3 applyLVLSpeedLimitTF(vec3 velocity, float normalizedAge, float limitRand, float effectiveDampen) {\n #ifdef RENDERER_LVL_SEPARATE_AXES\n vec3 limitSpeed;\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n limitSpeed = renderer_LVLSpeedMaxConstVector;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n limitSpeed = mix(renderer_LVLSpeedMinConstVector, limitSpeed, limitRand);\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n limitSpeed = vec3(\n evaluateParticleCurve(renderer_LVLSpeedXMaxCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedYMaxCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedZMaxCurve, normalizedAge)\n );\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n vec3 minLimitSpeed = vec3(\n evaluateParticleCurve(renderer_LVLSpeedXMinCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedYMinCurve, normalizedAge),\n evaluateParticleCurve(renderer_LVLSpeedZMinCurve, normalizedAge)\n );\n limitSpeed = mix(minLimitSpeed, limitSpeed, limitRand);\n #endif\n #endif\n\n vec3 absVel = abs(velocity);\n vec3 excess = max(absVel - limitSpeed, vec3(0.0));\n velocity = sign(velocity) * (absVel - excess * effectiveDampen);\n #else\n float limitSpeed;\n #ifdef RENDERER_LVL_SPEED_CONSTANT_MODE\n limitSpeed = renderer_LVLSpeedMaxConst;\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n limitSpeed = mix(renderer_LVLSpeedMinConst, limitSpeed, limitRand);\n #endif\n #endif\n #ifdef RENDERER_LVL_SPEED_CURVE_MODE\n limitSpeed = evaluateParticleCurve(renderer_LVLSpeedMaxCurve, normalizedAge);\n #ifdef RENDERER_LVL_SPEED_IS_RANDOM_TWO\n float minLimitSpeed = evaluateParticleCurve(renderer_LVLSpeedMinCurve, normalizedAge);\n limitSpeed = mix(minLimitSpeed, limitSpeed, limitRand);\n #endif\n #endif\n\n float speed = length(velocity);\n if (speed > limitSpeed && speed > 0.0) {\n float excess = speed - limitSpeed;\n velocity = velocity * ((speed - excess * effectiveDampen) / speed);\n }\n #endif\n return velocity;\n }\n\n#endif\n"; // eslint-disable-line
4916
4916
 
4917
4917
  var particle_feedback_simulation = "// Transform Feedback update shader for particle simulation.\n// Update order: VOL/FOL → Dampen → Drag → Position.\n// Runs once per particle per frame (no rasterization).\n\n// Previous frame TF data\nattribute vec3 a_FeedbackPosition;\nattribute vec3 a_FeedbackVelocity;\n\n// Per-particle instance data\nattribute vec4 a_ShapePositionStartLifeTime;\nattribute vec4 a_DirectionTime;\nattribute vec3 a_StartSize;\nattribute float a_StartSpeed;\nattribute vec4 a_Random0;\nattribute vec4 a_Random1;\nattribute vec3 a_SimulationWorldPosition;\nattribute vec4 a_SimulationWorldRotation;\nattribute vec4 a_Random2;\n\n// Uniforms\nuniform float renderer_CurrentTime;\nuniform float renderer_DeltaTime;\nuniform vec3 renderer_Gravity;\nuniform vec2 renderer_LVLDragConstant;\nuniform vec3 renderer_WorldPosition;\nuniform vec4 renderer_WorldRotation;\nuniform int renderer_SimulationSpace;\n\n// TF outputs\nvarying vec3 v_FeedbackPosition;\nvarying vec3 v_FeedbackVelocity;\n\n#include <particle_common>\n#include <velocity_over_lifetime_module>\n#include <force_over_lifetime_module>\n#include <limit_velocity_over_lifetime_module>\n\n// Get VOL instantaneous velocity at normalizedAge\nvec3 getVOLVelocity(float normalizedAge) {\n vec3 vel = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n #ifdef RENDERER_VOL_CONSTANT_MODE\n vel = renderer_VOLMaxConst;\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vel = mix(renderer_VOLMinConst, vel, a_Random1.yzw);\n #endif\n #endif\n #ifdef RENDERER_VOL_CURVE_MODE\n vel = vec3(\n evaluateParticleCurve(renderer_VOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec3 minVel = vec3(\n evaluateParticleCurve(renderer_VOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_VOLMinGradientZ, normalizedAge)\n );\n vel = mix(minVel, vel, a_Random1.yzw);\n #endif\n #endif\n #endif\n return vel;\n}\n\n// Get FOL instantaneous acceleration at normalizedAge\nvec3 getFOLAcceleration(float normalizedAge) {\n vec3 acc = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n #ifdef RENDERER_FOL_CONSTANT_MODE\n acc = renderer_FOLMaxConst;\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n acc = mix(renderer_FOLMinConst, acc, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n #ifdef RENDERER_FOL_CURVE_MODE\n acc = vec3(\n evaluateParticleCurve(renderer_FOLMaxGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMaxGradientZ, normalizedAge)\n );\n #ifdef RENDERER_FOL_IS_RANDOM_TWO\n vec3 minAcc = vec3(\n evaluateParticleCurve(renderer_FOLMinGradientX, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientY, normalizedAge),\n evaluateParticleCurve(renderer_FOLMinGradientZ, normalizedAge)\n );\n acc = mix(minAcc, acc, vec3(a_Random2.x, a_Random2.y, a_Random2.z));\n #endif\n #endif\n #endif\n return acc;\n}\n\nvoid main() {\n float age = renderer_CurrentTime - a_DirectionTime.w;\n float lifetime = a_ShapePositionStartLifeTime.w;\n float normalizedAge = age / lifetime;\n // Clamp to age on the first TF pass: particles emitted mid-frame have age < dt,\n // so using the full dt would over-integrate. Subsequent passes are unaffected (age >= dt).\n float dt = min(renderer_DeltaTime, age);\n\n // normalizedAge < 0.0: stale TF slot whose startTime is from a previous playback (e.g. after StopEmittingAndClear).\n if (normalizedAge >= 1.0 || normalizedAge < 0.0) {\n v_FeedbackPosition = a_FeedbackPosition;\n v_FeedbackVelocity = a_FeedbackVelocity;\n gl_Position = vec4(0.0);\n return;\n }\n\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = a_SimulationWorldRotation;\n }\n vec4 invWorldRotation = quaternionConjugate(worldRotation);\n\n // Read previous frame state (initialized by CPU on particle birth)\n vec3 localVelocity = a_FeedbackVelocity;\n\n // =====================================================\n // Step 1: Apply velocity module deltas (VOL + FOL + Gravity)\n // =====================================================\n\n // Gravity (world space)\n vec3 gravityDelta = renderer_Gravity * a_Random0.x * dt;\n\n // VOL instantaneous velocity (animated velocity, not persisted)\n vec3 volLocal = vec3(0.0);\n vec3 volWorld = vec3(0.0);\n #ifdef _VOL_MODULE_ENABLED\n vec3 vol = getVOLVelocity(normalizedAge);\n if (renderer_VOLSpace == 0) {\n volLocal = vol;\n } else {\n volWorld = vol;\n }\n #endif\n\n // FOL acceleration → velocity delta (always persisted, like gravity)\n vec3 folDeltaLocal = vec3(0.0);\n #ifdef _FOL_MODULE_ENABLED\n vec3 folAcc = getFOLAcceleration(normalizedAge);\n vec3 folVelDelta = folAcc * dt;\n if (renderer_FOLSpace == 0) {\n folDeltaLocal = folVelDelta;\n } else {\n // World FOL: convert to local and persist, same as gravity\n folDeltaLocal = rotationByQuaternions(folVelDelta, invWorldRotation);\n }\n #endif\n\n // Gravity and FOL contribute to base velocity (persisted, subject to dampen/drag).\n vec3 gravityLocal = rotationByQuaternions(gravityDelta, invWorldRotation);\n localVelocity += folDeltaLocal + gravityLocal;\n\n // =====================================================\n // Step 2 & 3: Dampen (Limit Velocity) + Drag\n // VOL must be projected into the LVL target space so that\n // limit/drag see the full velocity regardless of VOL.space vs LVL.space.\n // =====================================================\n #ifdef RENDERER_LVL_MODULE_ENABLED\n // Precompute VOL in both spaces\n vec3 volAsLocal = volLocal + rotationByQuaternions(volWorld, invWorldRotation);\n vec3 volAsWorld = rotationByQuaternions(volLocal, worldRotation) + volWorld;\n\n float limitRand = a_Random2.w;\n float dampen = renderer_LVLDampen;\n // Frame-rate independent dampen (30fps as reference)\n float effectiveDampen = 1.0 - pow(1.0 - dampen, dt * 30.0);\n\n if (renderer_LVLSpace == 0) {\n // Local space: total = base + all VOL projected to local\n vec3 totalLocal = localVelocity + volAsLocal;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalLocal, normalizedAge, limitRand, effectiveDampen);\n localVelocity = dampenedTotal - volAsLocal;\n } else {\n // World space: total = rotated base + all VOL projected to world\n vec3 totalWorld = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n vec3 dampenedTotal = applyLVLSpeedLimitTF(totalWorld, normalizedAge, limitRand, effectiveDampen);\n localVelocity = rotationByQuaternions(dampenedTotal - volAsWorld, invWorldRotation);\n }\n\n // Drag: same space as dampen\n {\n float dragCoeff = evaluateLVLDrag(normalizedAge, a_Random2.w);\n if (dragCoeff > 0.0) {\n vec3 totalVel;\n if (renderer_LVLSpace == 0) {\n totalVel = localVelocity + volAsLocal;\n } else {\n totalVel = rotationByQuaternions(localVelocity, worldRotation) + volAsWorld;\n }\n float velMagSqr = dot(totalVel, totalVel);\n float velMag = sqrt(velMagSqr);\n\n float drag = dragCoeff;\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_SIZE\n float maxDim = max(a_StartSize.x, max(a_StartSize.y, a_StartSize.z));\n float radius = maxDim * 0.5;\n drag *= 3.14159265 * radius * radius;\n #endif\n\n #ifdef RENDERER_LVL_DRAG_MULTIPLY_VELOCITY\n drag *= velMagSqr;\n #endif\n\n if (velMag > 0.0) {\n float newVelMag = max(0.0, velMag - drag * dt);\n vec3 draggedTotal = totalVel * (newVelMag / velMag);\n if (renderer_LVLSpace == 0) {\n localVelocity = draggedTotal - volAsLocal;\n } else {\n localVelocity = rotationByQuaternions(draggedTotal - volAsWorld, invWorldRotation);\n }\n }\n }\n }\n #endif\n\n // =====================================================\n // Step 4: Integrate position in simulation space\n // Local mode: position in local space, velocity rotated to local\n // World mode: position in world space, velocity rotated to world\n // =====================================================\n // FOL is now fully in localVelocity (both local and world-space FOL).\n // Only VOL overlay needs to be added here.\n vec3 totalVelocity;\n if (renderer_SimulationSpace == 0) {\n // Local: integrate in local space\n totalVelocity = localVelocity + volLocal\n + rotationByQuaternions(volWorld, invWorldRotation);\n } else {\n // World: integrate in world space\n totalVelocity = rotationByQuaternions(localVelocity + volLocal, worldRotation) + volWorld;\n }\n vec3 position = a_FeedbackPosition + totalVelocity * dt;\n\n v_FeedbackPosition = position;\n v_FeedbackVelocity = localVelocity;\n gl_Position = vec4(0.0);\n}\n"; // eslint-disable-line
4918
4918
 
@@ -13057,118 +13057,13 @@ __decorate([
13057
13057
  this._fixedTimeStep = 1 / 60;
13058
13058
  this._colliders = new DisorderedArray();
13059
13059
  this._gravity = new Vector3(0, -9.81, 0);
13060
- this._onContactEnter = function(nativeCollision) {
13061
- var physicalObjectsMap = Engine._physicalObjectsMap;
13062
- var shape0Id = nativeCollision.shape0Id, shape1Id = nativeCollision.shape1Id;
13063
- var shape1 = physicalObjectsMap[shape0Id];
13064
- var shape2 = physicalObjectsMap[shape1Id];
13065
- var collision = PhysicsScene._collision;
13066
- collision._nativeCollision = nativeCollision;
13067
- shape1.collider.entity._scripts.forEach(function(element) {
13068
- collision.shape = shape2;
13069
- element.onCollisionEnter(collision);
13070
- }, function(element, index) {
13071
- element._entityScriptsIndex = index;
13072
- });
13073
- shape2.collider.entity._scripts.forEach(function(element) {
13074
- collision.shape = shape1;
13075
- element.onCollisionEnter(collision);
13076
- }, function(element, index) {
13077
- element._entityScriptsIndex = index;
13078
- });
13079
- };
13080
- this._onContactExit = function(nativeCollision) {
13081
- var physicalObjectsMap = Engine._physicalObjectsMap;
13082
- var shape0Id = nativeCollision.shape0Id, shape1Id = nativeCollision.shape1Id;
13083
- var shape1 = physicalObjectsMap[shape0Id];
13084
- var shape2 = physicalObjectsMap[shape1Id];
13085
- var collision = PhysicsScene._collision;
13086
- collision._nativeCollision = nativeCollision;
13087
- shape1.collider.entity._scripts.forEach(function(element) {
13088
- collision.shape = shape2;
13089
- element.onCollisionExit(collision);
13090
- }, function(element, index) {
13091
- element._entityScriptsIndex = index;
13092
- });
13093
- shape2.collider.entity._scripts.forEach(function(element) {
13094
- collision.shape = shape1;
13095
- element.onCollisionExit(collision);
13096
- }, function(element, index) {
13097
- element._entityScriptsIndex = index;
13098
- });
13099
- };
13100
- this._onContactStay = function(nativeCollision) {
13101
- var physicalObjectsMap = Engine._physicalObjectsMap;
13102
- var shape0Id = nativeCollision.shape0Id, shape1Id = nativeCollision.shape1Id;
13103
- var shape1 = physicalObjectsMap[shape0Id];
13104
- var shape2 = physicalObjectsMap[shape1Id];
13105
- var collision = PhysicsScene._collision;
13106
- collision._nativeCollision = nativeCollision;
13107
- shape1.collider.entity._scripts.forEach(function(element) {
13108
- collision.shape = shape2;
13109
- element.onCollisionStay(collision);
13110
- }, function(element, index) {
13111
- element._entityScriptsIndex = index;
13112
- });
13113
- shape2.collider.entity._scripts.forEach(function(element) {
13114
- collision.shape = shape1;
13115
- element.onCollisionStay(collision);
13116
- }, function(element, index) {
13117
- element._entityScriptsIndex = index;
13118
- });
13119
- };
13120
- this._onTriggerEnter = function(obj1, obj2) {
13121
- var physicalObjectsMap = Engine._physicalObjectsMap;
13122
- var shape1 = physicalObjectsMap[obj1];
13123
- var shape2 = physicalObjectsMap[obj2];
13124
- shape1.collider.entity._scripts.forEach(function(element) {
13125
- element.onTriggerEnter(shape2);
13126
- }, function(element, index) {
13127
- element._entityScriptsIndex = index;
13128
- });
13129
- shape2.collider.entity._scripts.forEach(function(element) {
13130
- element.onTriggerEnter(shape1);
13131
- }, function(element, index) {
13132
- element._entityScriptsIndex = index;
13133
- });
13134
- };
13135
- this._onTriggerExit = function(obj1, obj2) {
13136
- var physicalObjectsMap = Engine._physicalObjectsMap;
13137
- var shape1 = physicalObjectsMap[obj1];
13138
- var shape2 = physicalObjectsMap[obj2];
13139
- shape1.collider.entity._scripts.forEach(function(element) {
13140
- element.onTriggerExit(shape2);
13141
- }, function(element, index) {
13142
- element._entityScriptsIndex = index;
13143
- });
13144
- shape2.collider.entity._scripts.forEach(function(element) {
13145
- element.onTriggerExit(shape1);
13146
- }, function(element, index) {
13147
- element._entityScriptsIndex = index;
13148
- });
13149
- };
13150
- this._onTriggerStay = function(obj1, obj2) {
13151
- var physicalObjectsMap = Engine._physicalObjectsMap;
13152
- var shape1 = physicalObjectsMap[obj1];
13153
- var shape2 = physicalObjectsMap[obj2];
13154
- shape1.collider.entity._scripts.forEach(function(element) {
13155
- element.onTriggerStay(shape2);
13156
- }, function(element, index) {
13157
- element._entityScriptsIndex = index;
13158
- });
13159
- shape2.collider.entity._scripts.forEach(function(element) {
13160
- element.onTriggerStay(shape1);
13161
- }, function(element, index) {
13162
- element._entityScriptsIndex = index;
13163
- });
13164
- };
13165
13060
  this._scene = scene;
13166
13061
  this._setGravity = this._setGravity.bind(this);
13167
13062
  //@ts-ignore
13168
13063
  this._gravity._onValueChanged = this._setGravity;
13169
13064
  var engine = scene.engine;
13170
13065
  if (engine._physicsInitialized) {
13171
- this._nativePhysicsScene = Engine._nativePhysics.createPhysicsScene(engine._nativePhysicsManager, this._onContactEnter, this._onContactExit, this._onContactStay, this._onTriggerEnter, this._onTriggerExit, this._onTriggerStay);
13066
+ this._nativePhysicsScene = Engine._nativePhysics.createPhysicsScene(engine._nativePhysicsManager);
13172
13067
  }
13173
13068
  }
13174
13069
  var _proto = PhysicsScene.prototype;
@@ -13380,6 +13275,7 @@ __decorate([
13380
13275
  this._callColliderOnUpdate();
13381
13276
  nativePhysicsManager.update(fixedTimeStep);
13382
13277
  this._callColliderOnLateUpdate();
13278
+ this._dispatchEvents(nativePhysicsManager.updateEvents());
13383
13279
  }
13384
13280
  };
13385
13281
  /**
@@ -13443,7 +13339,9 @@ __decorate([
13443
13339
  /**
13444
13340
  * @internal
13445
13341
  */ _proto._gc = function _gc() {
13342
+ var _this__nativePhysicsScene;
13446
13343
  this._colliders.garbageCollection();
13344
+ (_this__nativePhysicsScene = this._nativePhysicsScene) == null ? void 0 : _this__nativePhysicsScene.gc();
13447
13345
  };
13448
13346
  /**
13449
13347
  * @internal
@@ -13451,6 +13349,92 @@ __decorate([
13451
13349
  var _this__nativePhysicsScene;
13452
13350
  (_this__nativePhysicsScene = this._nativePhysicsScene) == null ? void 0 : _this__nativePhysicsScene.destroy();
13453
13351
  };
13352
+ _proto._dispatchEvents = function _dispatchEvents(events) {
13353
+ var _loop = function(i, n) {
13354
+ var _shape1_collider, _shape2_collider;
13355
+ var event = contactEvents[i];
13356
+ var shape1 = physicalObjectsMap[event.shape0Id];
13357
+ var shape2 = physicalObjectsMap[event.shape1Id];
13358
+ // entity.destroy() is deferred, so shapes/colliders stay valid through the dispatch loop
13359
+ // This guard covers synchronous removeShape()/clearShapes() which sets shape._collider = null
13360
+ if (!(shape1 == null ? void 0 : (_shape1_collider = shape1.collider) == null ? void 0 : _shape1_collider.entity) || !(shape2 == null ? void 0 : (_shape2_collider = shape2.collider) == null ? void 0 : _shape2_collider.entity)) return "continue";
13361
+ collision._nativeCollision = event;
13362
+ switch(event.state){
13363
+ case 0:
13364
+ shape1.collider.entity._scripts.forEach(function(element) {
13365
+ collision.shape = shape2;
13366
+ element.onCollisionEnter(collision);
13367
+ }, scriptIndexSetter);
13368
+ shape2.collider.entity._scripts.forEach(function(element) {
13369
+ collision.shape = shape1;
13370
+ element.onCollisionEnter(collision);
13371
+ }, scriptIndexSetter);
13372
+ break;
13373
+ case 1:
13374
+ shape1.collider.entity._scripts.forEach(function(element) {
13375
+ collision.shape = shape2;
13376
+ element.onCollisionStay(collision);
13377
+ }, scriptIndexSetter);
13378
+ shape2.collider.entity._scripts.forEach(function(element) {
13379
+ collision.shape = shape1;
13380
+ element.onCollisionStay(collision);
13381
+ }, scriptIndexSetter);
13382
+ break;
13383
+ case 2:
13384
+ shape1.collider.entity._scripts.forEach(function(element) {
13385
+ collision.shape = shape2;
13386
+ element.onCollisionExit(collision);
13387
+ }, scriptIndexSetter);
13388
+ shape2.collider.entity._scripts.forEach(function(element) {
13389
+ collision.shape = shape1;
13390
+ element.onCollisionExit(collision);
13391
+ }, scriptIndexSetter);
13392
+ break;
13393
+ }
13394
+ }, _loop1 = function(i1, n1) {
13395
+ var _shape1_collider, _shape2_collider;
13396
+ var event = triggerEvents[i1];
13397
+ var shape1 = physicalObjectsMap[event.index1];
13398
+ var shape2 = physicalObjectsMap[event.index2];
13399
+ // entity.destroy() is deferred, so shapes/colliders stay valid through the dispatch loop
13400
+ // This guard covers synchronous removeShape()/clearShapes() which sets shape._collider = null
13401
+ if (!(shape1 == null ? void 0 : (_shape1_collider = shape1.collider) == null ? void 0 : _shape1_collider.entity) || !(shape2 == null ? void 0 : (_shape2_collider = shape2.collider) == null ? void 0 : _shape2_collider.entity)) return "continue";
13402
+ switch(event.dispatchState){
13403
+ case 0:
13404
+ shape1.collider.entity._scripts.forEach(function(element) {
13405
+ element.onTriggerEnter(shape2);
13406
+ }, scriptIndexSetter);
13407
+ shape2.collider.entity._scripts.forEach(function(element) {
13408
+ element.onTriggerEnter(shape1);
13409
+ }, scriptIndexSetter);
13410
+ break;
13411
+ case 1:
13412
+ shape1.collider.entity._scripts.forEach(function(element) {
13413
+ element.onTriggerStay(shape2);
13414
+ }, scriptIndexSetter);
13415
+ shape2.collider.entity._scripts.forEach(function(element) {
13416
+ element.onTriggerStay(shape1);
13417
+ }, scriptIndexSetter);
13418
+ break;
13419
+ case 2:
13420
+ shape1.collider.entity._scripts.forEach(function(element) {
13421
+ element.onTriggerExit(shape2);
13422
+ }, scriptIndexSetter);
13423
+ shape2.collider.entity._scripts.forEach(function(element) {
13424
+ element.onTriggerExit(shape1);
13425
+ }, scriptIndexSetter);
13426
+ break;
13427
+ }
13428
+ };
13429
+ var physicalObjectsMap = Engine._physicalObjectsMap;
13430
+ var collision = PhysicsScene._collision;
13431
+ var scriptIndexSetter = PhysicsScene._scriptIndexSetter;
13432
+ var contactEvents = events.contactEvents, contactEventCount = events.contactEventCount, triggerEvents = events.triggerEvents;
13433
+ // Dispatch contact events
13434
+ for(var i = 0, n = contactEventCount; i < n; i++)_loop(i);
13435
+ // Dispatch trigger events
13436
+ for(var i1 = 0, n1 = triggerEvents.length; i1 < n1; i1++)_loop1(i1);
13437
+ };
13454
13438
  _proto._setGravity = function _setGravity() {
13455
13439
  this._nativePhysicsScene.setGravity(this._gravity);
13456
13440
  };
@@ -13510,6 +13494,9 @@ __decorate([
13510
13494
  }();
13511
13495
  PhysicsScene._collision = new Collision();
13512
13496
  PhysicsScene._identityQuaternion = new Quaternion(0, 0, 0, 1);
13497
+ PhysicsScene._scriptIndexSetter = function(element, index) {
13498
+ element._entityScriptsIndex = index;
13499
+ };
13513
13500
 
13514
13501
  /**
13515
13502
  * A static collider component that will not move.
@@ -27102,6 +27089,11 @@ ShaderPool.init();
27102
27089
  this._textSubRenderElementPool.garbageCollection();
27103
27090
  this._renderElementPool.garbageCollection();
27104
27091
  this._renderContext.garbageCollection();
27092
+ var scenes = this._sceneManager._scenes.getLoopArray();
27093
+ for(var i = 0, n = scenes.length; i < n; i++){
27094
+ var _scenes_i_physics, _scenes_i;
27095
+ (_scenes_i = scenes[i]) == null ? void 0 : (_scenes_i_physics = _scenes_i.physics) == null ? void 0 : _scenes_i_physics._gc();
27096
+ }
27105
27097
  };
27106
27098
  _create_class(Engine, [
27107
27099
  {
@@ -34966,10 +34958,10 @@ __decorate([
34966
34958
  _inherits(LimitVelocityOverLifetimeModule, ParticleGeneratorModule);
34967
34959
  function LimitVelocityOverLifetimeModule(generator) {
34968
34960
  var _this;
34969
- _this = ParticleGeneratorModule.call(this, generator) || this, /** @internal */ _this._limitRand = new Rand(0, ParticleRandomSubSeeds.LimitVelocityOverLifetime), _this._limitMinConstantVec = new Vector3(), _this._limitMaxConstantVec = new Vector3(), _this._dragConstantVec = new Vector2(), _this._separateAxes = false, _this._dampen = 1, _this._multiplyDragByParticleSize = false, _this._multiplyDragByParticleVelocity = false, _this._space = ParticleSimulationSpace.Local;
34970
- _this.limitX = new ParticleCompositeCurve(1);
34971
- _this.limitY = new ParticleCompositeCurve(1);
34972
- _this.limitZ = new ParticleCompositeCurve(1);
34961
+ _this = ParticleGeneratorModule.call(this, generator) || this, /** @internal */ _this._speedRand = new Rand(0, ParticleRandomSubSeeds.LimitVelocityOverLifetime), _this._speedMinConstantVec = new Vector3(), _this._speedMaxConstantVec = new Vector3(), _this._dragConstantVec = new Vector2(), _this._separateAxes = false, _this._dampen = 0, _this._multiplyDragByParticleSize = false, _this._multiplyDragByParticleVelocity = false, _this._space = ParticleSimulationSpace.Local;
34962
+ _this.speedX = new ParticleCompositeCurve(1);
34963
+ _this.speedY = new ParticleCompositeCurve(1);
34964
+ _this.speedZ = new ParticleCompositeCurve(1);
34973
34965
  _this.drag = new ParticleCompositeCurve(0);
34974
34966
  return _this;
34975
34967
  }
@@ -34981,19 +34973,19 @@ __decorate([
34981
34973
  };
34982
34974
  /**
34983
34975
  * @internal
34984
- */ _proto._isLimitRandomMode = function _isLimitRandomMode() {
34976
+ */ _proto._isSpeedRandomMode = function _isSpeedRandomMode() {
34985
34977
  if (this._separateAxes) {
34986
- return (this._limitX.mode === ParticleCurveMode.TwoConstants || this._limitX.mode === ParticleCurveMode.TwoCurves) && (this._limitY.mode === ParticleCurveMode.TwoConstants || this._limitY.mode === ParticleCurveMode.TwoCurves) && (this._limitZ.mode === ParticleCurveMode.TwoConstants || this._limitZ.mode === ParticleCurveMode.TwoCurves);
34978
+ return (this._speedX.mode === ParticleCurveMode.TwoConstants || this._speedX.mode === ParticleCurveMode.TwoCurves) && (this._speedY.mode === ParticleCurveMode.TwoConstants || this._speedY.mode === ParticleCurveMode.TwoCurves) && (this._speedZ.mode === ParticleCurveMode.TwoConstants || this._speedZ.mode === ParticleCurveMode.TwoCurves);
34987
34979
  }
34988
- return this._limitX.mode === ParticleCurveMode.TwoConstants || this._limitX.mode === ParticleCurveMode.TwoCurves;
34980
+ return this._speedX.mode === ParticleCurveMode.TwoConstants || this._speedX.mode === ParticleCurveMode.TwoCurves;
34989
34981
  };
34990
34982
  /**
34991
34983
  * @internal
34992
34984
  */ _proto._updateShaderData = function _updateShaderData(shaderData) {
34993
34985
  var enabledModuleMacro = null;
34994
34986
  var separateAxesMacro = null;
34995
- var limitModeMacro = null;
34996
- var limitRandomMacro = null;
34987
+ var speedModeMacro = null;
34988
+ var speedRandomMacro = null;
34997
34989
  var dragCurveMacro = null;
34998
34990
  var dragRandomMacro = null;
34999
34991
  var dragSizeMacro = null;
@@ -35004,16 +34996,16 @@ __decorate([
35004
34996
  shaderData.setFloat(LimitVelocityOverLifetimeModule._dampenProperty, this._dampen);
35005
34997
  // Space
35006
34998
  shaderData.setInt(LimitVelocityOverLifetimeModule._spaceProperty, this._space);
35007
- // Limit
34999
+ // Limit speed
35008
35000
  if (this._separateAxes) {
35009
35001
  separateAxesMacro = LimitVelocityOverLifetimeModule._separateAxesMacro;
35010
- var result = this._uploadSeparateAxisLimits(shaderData);
35011
- limitModeMacro = result.modeMacro;
35012
- limitRandomMacro = result.randomMacro;
35002
+ var result = this._uploadSeparateAxisSpeeds(shaderData);
35003
+ speedModeMacro = result.modeMacro;
35004
+ speedRandomMacro = result.randomMacro;
35013
35005
  } else {
35014
- var result1 = this._uploadScalarLimit(shaderData);
35015
- limitModeMacro = result1.modeMacro;
35016
- limitRandomMacro = result1.randomMacro;
35006
+ var result1 = this._uploadScalarSpeed(shaderData);
35007
+ speedModeMacro = result1.modeMacro;
35008
+ speedRandomMacro = result1.randomMacro;
35017
35009
  }
35018
35010
  // Drag
35019
35011
  var dragResult = this._uploadDrag(shaderData);
@@ -35029,8 +35021,8 @@ __decorate([
35029
35021
  }
35030
35022
  this._enabledModuleMacro = this._enableMacro(shaderData, this._enabledModuleMacro, enabledModuleMacro);
35031
35023
  this._separateAxesCachedMacro = this._enableMacro(shaderData, this._separateAxesCachedMacro, separateAxesMacro);
35032
- this._limitModeMacro = this._enableMacro(shaderData, this._limitModeMacro, limitModeMacro);
35033
- this._limitRandomMacro = this._enableMacro(shaderData, this._limitRandomMacro, limitRandomMacro);
35024
+ this._speedModeMacro = this._enableMacro(shaderData, this._speedModeMacro, speedModeMacro);
35025
+ this._speedRandomMacro = this._enableMacro(shaderData, this._speedRandomMacro, speedRandomMacro);
35034
35026
  this._dragCurveCachedMacro = this._enableMacro(shaderData, this._dragCurveCachedMacro, dragCurveMacro);
35035
35027
  this._dragRandomCachedMacro = this._enableMacro(shaderData, this._dragRandomCachedMacro, dragRandomMacro);
35036
35028
  this._dragSizeMacro = this._enableMacro(shaderData, this._dragSizeMacro, dragSizeMacro);
@@ -35039,26 +35031,26 @@ __decorate([
35039
35031
  /**
35040
35032
  * @internal
35041
35033
  */ _proto._resetRandomSeed = function _resetRandomSeed(seed) {
35042
- this._limitRand.reset(seed, ParticleRandomSubSeeds.LimitVelocityOverLifetime);
35034
+ this._speedRand.reset(seed, ParticleRandomSubSeeds.LimitVelocityOverLifetime);
35043
35035
  };
35044
- _proto._uploadScalarLimit = function _uploadScalarLimit(shaderData) {
35045
- var limitX = this._limitX;
35036
+ _proto._uploadScalarSpeed = function _uploadScalarSpeed(shaderData) {
35037
+ var speedX = this._speedX;
35046
35038
  var modeMacro = null;
35047
35039
  var randomMacro = null;
35048
- var isRandomCurveMode = limitX.mode === ParticleCurveMode.TwoCurves;
35049
- if (isRandomCurveMode || limitX.mode === ParticleCurveMode.Curve) {
35050
- shaderData.setFloatArray(LimitVelocityOverLifetimeModule._limitMaxCurveProperty, limitX.curveMax._getTypeArray());
35051
- modeMacro = LimitVelocityOverLifetimeModule._limitCurveModeMacro;
35040
+ var isRandomCurveMode = speedX.mode === ParticleCurveMode.TwoCurves;
35041
+ if (isRandomCurveMode || speedX.mode === ParticleCurveMode.Curve) {
35042
+ shaderData.setFloatArray(LimitVelocityOverLifetimeModule._speedMaxCurveProperty, speedX.curveMax._getTypeArray());
35043
+ modeMacro = LimitVelocityOverLifetimeModule._speedCurveModeMacro;
35052
35044
  if (isRandomCurveMode) {
35053
- shaderData.setFloatArray(LimitVelocityOverLifetimeModule._limitMinCurveProperty, limitX.curveMin._getTypeArray());
35054
- randomMacro = LimitVelocityOverLifetimeModule._limitIsRandomMacro;
35045
+ shaderData.setFloatArray(LimitVelocityOverLifetimeModule._speedMinCurveProperty, speedX.curveMin._getTypeArray());
35046
+ randomMacro = LimitVelocityOverLifetimeModule._speedIsRandomMacro;
35055
35047
  }
35056
35048
  } else {
35057
- shaderData.setFloat(LimitVelocityOverLifetimeModule._limitMaxConstProperty, limitX.constantMax);
35058
- modeMacro = LimitVelocityOverLifetimeModule._limitConstantModeMacro;
35059
- if (limitX.mode === ParticleCurveMode.TwoConstants) {
35060
- shaderData.setFloat(LimitVelocityOverLifetimeModule._limitMinConstProperty, limitX.constantMin);
35061
- randomMacro = LimitVelocityOverLifetimeModule._limitIsRandomMacro;
35049
+ shaderData.setFloat(LimitVelocityOverLifetimeModule._speedMaxConstProperty, speedX.constantMax);
35050
+ modeMacro = LimitVelocityOverLifetimeModule._speedConstantModeMacro;
35051
+ if (speedX.mode === ParticleCurveMode.TwoConstants) {
35052
+ shaderData.setFloat(LimitVelocityOverLifetimeModule._speedMinConstProperty, speedX.constantMin);
35053
+ randomMacro = LimitVelocityOverLifetimeModule._speedIsRandomMacro;
35062
35054
  }
35063
35055
  }
35064
35056
  return {
@@ -35066,34 +35058,34 @@ __decorate([
35066
35058
  randomMacro: randomMacro
35067
35059
  };
35068
35060
  };
35069
- _proto._uploadSeparateAxisLimits = function _uploadSeparateAxisLimits(shaderData) {
35070
- var limitX = this._limitX;
35071
- var limitY = this._limitY;
35072
- var limitZ = this._limitZ;
35061
+ _proto._uploadSeparateAxisSpeeds = function _uploadSeparateAxisSpeeds(shaderData) {
35062
+ var speedX = this._speedX;
35063
+ var speedY = this._speedY;
35064
+ var speedZ = this._speedZ;
35073
35065
  var modeMacro = null;
35074
35066
  var randomMacro = null;
35075
- var isRandomCurveMode = limitX.mode === ParticleCurveMode.TwoCurves && limitY.mode === ParticleCurveMode.TwoCurves && limitZ.mode === ParticleCurveMode.TwoCurves;
35076
- if (isRandomCurveMode || limitX.mode === ParticleCurveMode.Curve && limitY.mode === ParticleCurveMode.Curve && limitZ.mode === ParticleCurveMode.Curve) {
35077
- shaderData.setFloatArray(LimitVelocityOverLifetimeModule._limitXMaxCurveProperty, limitX.curveMax._getTypeArray());
35078
- shaderData.setFloatArray(LimitVelocityOverLifetimeModule._limitYMaxCurveProperty, limitY.curveMax._getTypeArray());
35079
- shaderData.setFloatArray(LimitVelocityOverLifetimeModule._limitZMaxCurveProperty, limitZ.curveMax._getTypeArray());
35080
- modeMacro = LimitVelocityOverLifetimeModule._limitCurveModeMacro;
35067
+ var isRandomCurveMode = speedX.mode === ParticleCurveMode.TwoCurves && speedY.mode === ParticleCurveMode.TwoCurves && speedZ.mode === ParticleCurveMode.TwoCurves;
35068
+ if (isRandomCurveMode || speedX.mode === ParticleCurveMode.Curve && speedY.mode === ParticleCurveMode.Curve && speedZ.mode === ParticleCurveMode.Curve) {
35069
+ shaderData.setFloatArray(LimitVelocityOverLifetimeModule._speedXMaxCurveProperty, speedX.curveMax._getTypeArray());
35070
+ shaderData.setFloatArray(LimitVelocityOverLifetimeModule._speedYMaxCurveProperty, speedY.curveMax._getTypeArray());
35071
+ shaderData.setFloatArray(LimitVelocityOverLifetimeModule._speedZMaxCurveProperty, speedZ.curveMax._getTypeArray());
35072
+ modeMacro = LimitVelocityOverLifetimeModule._speedCurveModeMacro;
35081
35073
  if (isRandomCurveMode) {
35082
- shaderData.setFloatArray(LimitVelocityOverLifetimeModule._limitXMinCurveProperty, limitX.curveMin._getTypeArray());
35083
- shaderData.setFloatArray(LimitVelocityOverLifetimeModule._limitYMinCurveProperty, limitY.curveMin._getTypeArray());
35084
- shaderData.setFloatArray(LimitVelocityOverLifetimeModule._limitZMinCurveProperty, limitZ.curveMin._getTypeArray());
35085
- randomMacro = LimitVelocityOverLifetimeModule._limitIsRandomMacro;
35074
+ shaderData.setFloatArray(LimitVelocityOverLifetimeModule._speedXMinCurveProperty, speedX.curveMin._getTypeArray());
35075
+ shaderData.setFloatArray(LimitVelocityOverLifetimeModule._speedYMinCurveProperty, speedY.curveMin._getTypeArray());
35076
+ shaderData.setFloatArray(LimitVelocityOverLifetimeModule._speedZMinCurveProperty, speedZ.curveMin._getTypeArray());
35077
+ randomMacro = LimitVelocityOverLifetimeModule._speedIsRandomMacro;
35086
35078
  }
35087
35079
  } else {
35088
- var constantMax = this._limitMaxConstantVec;
35089
- constantMax.set(limitX.constantMax, limitY.constantMax, limitZ.constantMax);
35090
- shaderData.setVector3(LimitVelocityOverLifetimeModule._limitMaxConstVecProperty, constantMax);
35091
- modeMacro = LimitVelocityOverLifetimeModule._limitConstantModeMacro;
35092
- if (limitX.mode === ParticleCurveMode.TwoConstants && limitY.mode === ParticleCurveMode.TwoConstants && limitZ.mode === ParticleCurveMode.TwoConstants) {
35093
- var constantMin = this._limitMinConstantVec;
35094
- constantMin.set(limitX.constantMin, limitY.constantMin, limitZ.constantMin);
35095
- shaderData.setVector3(LimitVelocityOverLifetimeModule._limitMinConstVecProperty, constantMin);
35096
- randomMacro = LimitVelocityOverLifetimeModule._limitIsRandomMacro;
35080
+ var constantMax = this._speedMaxConstantVec;
35081
+ constantMax.set(speedX.constantMax, speedY.constantMax, speedZ.constantMax);
35082
+ shaderData.setVector3(LimitVelocityOverLifetimeModule._speedMaxConstVecProperty, constantMax);
35083
+ modeMacro = LimitVelocityOverLifetimeModule._speedConstantModeMacro;
35084
+ if (speedX.mode === ParticleCurveMode.TwoConstants && speedY.mode === ParticleCurveMode.TwoConstants && speedZ.mode === ParticleCurveMode.TwoConstants) {
35085
+ var constantMin = this._speedMinConstantVec;
35086
+ constantMin.set(speedX.constantMin, speedY.constantMin, speedZ.constantMin);
35087
+ shaderData.setVector3(LimitVelocityOverLifetimeModule._speedMinConstVecProperty, constantMin);
35088
+ randomMacro = LimitVelocityOverLifetimeModule._speedIsRandomMacro;
35097
35089
  }
35098
35090
  }
35099
35091
  return {
@@ -35143,57 +35135,57 @@ __decorate([
35143
35135
  }
35144
35136
  },
35145
35137
  {
35146
- key: "limit",
35138
+ key: "speed",
35147
35139
  get: /**
35148
35140
  * Speed limit when separateAxes is false.
35149
35141
  */ function get() {
35150
- return this._limitX;
35142
+ return this._speedX;
35151
35143
  },
35152
35144
  set: function set(value) {
35153
- this.limitX = value;
35145
+ this.speedX = value;
35154
35146
  }
35155
35147
  },
35156
35148
  {
35157
- key: "limitX",
35149
+ key: "speedX",
35158
35150
  get: /**
35159
35151
  * Speed limit for the x-axis (or overall limit when separateAxes is false).
35160
35152
  */ function get() {
35161
- return this._limitX;
35153
+ return this._speedX;
35162
35154
  },
35163
35155
  set: function set(value) {
35164
- var lastValue = this._limitX;
35156
+ var lastValue = this._speedX;
35165
35157
  if (value !== lastValue) {
35166
- this._limitX = value;
35158
+ this._speedX = value;
35167
35159
  this._onCompositeCurveChange(lastValue, value);
35168
35160
  }
35169
35161
  }
35170
35162
  },
35171
35163
  {
35172
- key: "limitY",
35164
+ key: "speedY",
35173
35165
  get: /**
35174
35166
  * Speed limit for the y-axis.
35175
35167
  */ function get() {
35176
- return this._limitY;
35168
+ return this._speedY;
35177
35169
  },
35178
35170
  set: function set(value) {
35179
- var lastValue = this._limitY;
35171
+ var lastValue = this._speedY;
35180
35172
  if (value !== lastValue) {
35181
- this._limitY = value;
35173
+ this._speedY = value;
35182
35174
  this._onCompositeCurveChange(lastValue, value);
35183
35175
  }
35184
35176
  }
35185
35177
  },
35186
35178
  {
35187
- key: "limitZ",
35179
+ key: "speedZ",
35188
35180
  get: /**
35189
35181
  * Speed limit for the z-axis.
35190
35182
  */ function get() {
35191
- return this._limitZ;
35183
+ return this._speedZ;
35192
35184
  },
35193
35185
  set: function set(value) {
35194
- var lastValue = this._limitZ;
35186
+ var lastValue = this._speedZ;
35195
35187
  if (value !== lastValue) {
35196
- this._limitZ = value;
35188
+ this._speedZ = value;
35197
35189
  this._onCompositeCurveChange(lastValue, value);
35198
35190
  }
35199
35191
  }
@@ -35261,6 +35253,7 @@ __decorate([
35261
35253
  key: "space",
35262
35254
  get: /**
35263
35255
  * Specifies if the velocity limits are in local space or world space.
35256
+ * @remarks Only takes effect when 'separateAxes' is enabled.
35264
35257
  */ function get() {
35265
35258
  return this._space;
35266
35259
  },
@@ -35295,25 +35288,25 @@ __decorate([
35295
35288
  }(ParticleGeneratorModule);
35296
35289
  LimitVelocityOverLifetimeModule._enabledMacro = ShaderMacro.getByName("RENDERER_LVL_MODULE_ENABLED");
35297
35290
  LimitVelocityOverLifetimeModule._separateAxesMacro = ShaderMacro.getByName("RENDERER_LVL_SEPARATE_AXES");
35298
- LimitVelocityOverLifetimeModule._limitConstantModeMacro = ShaderMacro.getByName("RENDERER_LVL_LIMIT_CONSTANT_MODE");
35299
- LimitVelocityOverLifetimeModule._limitCurveModeMacro = ShaderMacro.getByName("RENDERER_LVL_LIMIT_CURVE_MODE");
35300
- LimitVelocityOverLifetimeModule._limitIsRandomMacro = ShaderMacro.getByName("RENDERER_LVL_LIMIT_IS_RANDOM_TWO");
35291
+ LimitVelocityOverLifetimeModule._speedConstantModeMacro = ShaderMacro.getByName("RENDERER_LVL_SPEED_CONSTANT_MODE");
35292
+ LimitVelocityOverLifetimeModule._speedCurveModeMacro = ShaderMacro.getByName("RENDERER_LVL_SPEED_CURVE_MODE");
35293
+ LimitVelocityOverLifetimeModule._speedIsRandomMacro = ShaderMacro.getByName("RENDERER_LVL_SPEED_IS_RANDOM_TWO");
35301
35294
  LimitVelocityOverLifetimeModule._dragCurveModeMacro = ShaderMacro.getByName("RENDERER_LVL_DRAG_CURVE_MODE");
35302
35295
  LimitVelocityOverLifetimeModule._dragIsRandomMacro = ShaderMacro.getByName("RENDERER_LVL_DRAG_IS_RANDOM_TWO");
35303
35296
  LimitVelocityOverLifetimeModule._multiplyDragBySizeMacro = ShaderMacro.getByName("RENDERER_LVL_DRAG_MULTIPLY_SIZE");
35304
35297
  LimitVelocityOverLifetimeModule._multiplyDragByVelocityMacro = ShaderMacro.getByName("RENDERER_LVL_DRAG_MULTIPLY_VELOCITY");
35305
- LimitVelocityOverLifetimeModule._limitMaxConstProperty = ShaderProperty.getByName("renderer_LVLLimitMaxConst");
35306
- LimitVelocityOverLifetimeModule._limitMinConstProperty = ShaderProperty.getByName("renderer_LVLLimitMinConst");
35307
- LimitVelocityOverLifetimeModule._limitMaxCurveProperty = ShaderProperty.getByName("renderer_LVLLimitMaxCurve");
35308
- LimitVelocityOverLifetimeModule._limitMinCurveProperty = ShaderProperty.getByName("renderer_LVLLimitMinCurve");
35309
- LimitVelocityOverLifetimeModule._limitMaxConstVecProperty = ShaderProperty.getByName("renderer_LVLLimitMaxConstVector");
35310
- LimitVelocityOverLifetimeModule._limitMinConstVecProperty = ShaderProperty.getByName("renderer_LVLLimitMinConstVector");
35311
- LimitVelocityOverLifetimeModule._limitXMaxCurveProperty = ShaderProperty.getByName("renderer_LVLLimitXMaxCurve");
35312
- LimitVelocityOverLifetimeModule._limitXMinCurveProperty = ShaderProperty.getByName("renderer_LVLLimitXMinCurve");
35313
- LimitVelocityOverLifetimeModule._limitYMaxCurveProperty = ShaderProperty.getByName("renderer_LVLLimitYMaxCurve");
35314
- LimitVelocityOverLifetimeModule._limitYMinCurveProperty = ShaderProperty.getByName("renderer_LVLLimitYMinCurve");
35315
- LimitVelocityOverLifetimeModule._limitZMaxCurveProperty = ShaderProperty.getByName("renderer_LVLLimitZMaxCurve");
35316
- LimitVelocityOverLifetimeModule._limitZMinCurveProperty = ShaderProperty.getByName("renderer_LVLLimitZMinCurve");
35298
+ LimitVelocityOverLifetimeModule._speedMaxConstProperty = ShaderProperty.getByName("renderer_LVLSpeedMaxConst");
35299
+ LimitVelocityOverLifetimeModule._speedMinConstProperty = ShaderProperty.getByName("renderer_LVLSpeedMinConst");
35300
+ LimitVelocityOverLifetimeModule._speedMaxCurveProperty = ShaderProperty.getByName("renderer_LVLSpeedMaxCurve");
35301
+ LimitVelocityOverLifetimeModule._speedMinCurveProperty = ShaderProperty.getByName("renderer_LVLSpeedMinCurve");
35302
+ LimitVelocityOverLifetimeModule._speedMaxConstVecProperty = ShaderProperty.getByName("renderer_LVLSpeedMaxConstVector");
35303
+ LimitVelocityOverLifetimeModule._speedMinConstVecProperty = ShaderProperty.getByName("renderer_LVLSpeedMinConstVector");
35304
+ LimitVelocityOverLifetimeModule._speedXMaxCurveProperty = ShaderProperty.getByName("renderer_LVLSpeedXMaxCurve");
35305
+ LimitVelocityOverLifetimeModule._speedXMinCurveProperty = ShaderProperty.getByName("renderer_LVLSpeedXMinCurve");
35306
+ LimitVelocityOverLifetimeModule._speedYMaxCurveProperty = ShaderProperty.getByName("renderer_LVLSpeedYMaxCurve");
35307
+ LimitVelocityOverLifetimeModule._speedYMinCurveProperty = ShaderProperty.getByName("renderer_LVLSpeedYMinCurve");
35308
+ LimitVelocityOverLifetimeModule._speedZMaxCurveProperty = ShaderProperty.getByName("renderer_LVLSpeedZMaxCurve");
35309
+ LimitVelocityOverLifetimeModule._speedZMinCurveProperty = ShaderProperty.getByName("renderer_LVLSpeedZMinCurve");
35317
35310
  LimitVelocityOverLifetimeModule._dampenProperty = ShaderProperty.getByName("renderer_LVLDampen");
35318
35311
  LimitVelocityOverLifetimeModule._dragConstantProperty = ShaderProperty.getByName("renderer_LVLDragConstant");
35319
35312
  LimitVelocityOverLifetimeModule._dragMaxCurveProperty = ShaderProperty.getByName("renderer_LVLDragMaxCurve");
@@ -35321,13 +35314,13 @@ LimitVelocityOverLifetimeModule._dragMinCurveProperty = ShaderProperty.getByName
35321
35314
  LimitVelocityOverLifetimeModule._spaceProperty = ShaderProperty.getByName("renderer_LVLSpace");
35322
35315
  __decorate([
35323
35316
  ignoreClone
35324
- ], LimitVelocityOverLifetimeModule.prototype, "_limitRand", void 0);
35317
+ ], LimitVelocityOverLifetimeModule.prototype, "_speedRand", void 0);
35325
35318
  __decorate([
35326
35319
  ignoreClone
35327
- ], LimitVelocityOverLifetimeModule.prototype, "_limitMinConstantVec", void 0);
35320
+ ], LimitVelocityOverLifetimeModule.prototype, "_speedMinConstantVec", void 0);
35328
35321
  __decorate([
35329
35322
  ignoreClone
35330
- ], LimitVelocityOverLifetimeModule.prototype, "_limitMaxConstantVec", void 0);
35323
+ ], LimitVelocityOverLifetimeModule.prototype, "_speedMaxConstantVec", void 0);
35331
35324
  __decorate([
35332
35325
  ignoreClone
35333
35326
  ], LimitVelocityOverLifetimeModule.prototype, "_dragConstantVec", void 0);
@@ -35339,10 +35332,10 @@ __decorate([
35339
35332
  ], LimitVelocityOverLifetimeModule.prototype, "_separateAxesCachedMacro", void 0);
35340
35333
  __decorate([
35341
35334
  ignoreClone
35342
- ], LimitVelocityOverLifetimeModule.prototype, "_limitModeMacro", void 0);
35335
+ ], LimitVelocityOverLifetimeModule.prototype, "_speedModeMacro", void 0);
35343
35336
  __decorate([
35344
35337
  ignoreClone
35345
- ], LimitVelocityOverLifetimeModule.prototype, "_limitRandomMacro", void 0);
35338
+ ], LimitVelocityOverLifetimeModule.prototype, "_speedRandomMacro", void 0);
35346
35339
  __decorate([
35347
35340
  ignoreClone
35348
35341
  ], LimitVelocityOverLifetimeModule.prototype, "_dragCurveCachedMacro", void 0);
@@ -35357,13 +35350,13 @@ __decorate([
35357
35350
  ], LimitVelocityOverLifetimeModule.prototype, "_dragVelocityMacro", void 0);
35358
35351
  __decorate([
35359
35352
  deepClone
35360
- ], LimitVelocityOverLifetimeModule.prototype, "_limitX", void 0);
35353
+ ], LimitVelocityOverLifetimeModule.prototype, "_speedX", void 0);
35361
35354
  __decorate([
35362
35355
  deepClone
35363
- ], LimitVelocityOverLifetimeModule.prototype, "_limitY", void 0);
35356
+ ], LimitVelocityOverLifetimeModule.prototype, "_speedY", void 0);
35364
35357
  __decorate([
35365
35358
  deepClone
35366
- ], LimitVelocityOverLifetimeModule.prototype, "_limitZ", void 0);
35359
+ ], LimitVelocityOverLifetimeModule.prototype, "_speedZ", void 0);
35367
35360
  __decorate([
35368
35361
  deepClone
35369
35362
  ], LimitVelocityOverLifetimeModule.prototype, "_drag", void 0);
@@ -37060,8 +37053,8 @@ __decorate([
37060
37053
  instanceVertices[offset + 40] = rand1.random();
37061
37054
  }
37062
37055
  var limitVelocityOverLifetime = this.limitVelocityOverLifetime;
37063
- if (limitVelocityOverLifetime.enabled && (limitVelocityOverLifetime._isLimitRandomMode() || limitVelocityOverLifetime._isDragRandomMode())) {
37064
- instanceVertices[offset + 41] = limitVelocityOverLifetime._limitRand.random();
37056
+ if (limitVelocityOverLifetime.enabled && (limitVelocityOverLifetime._isSpeedRandomMode() || limitVelocityOverLifetime._isDragRandomMode())) {
37057
+ instanceVertices[offset + 41] = limitVelocityOverLifetime._speedRand.random();
37065
37058
  }
37066
37059
  // Initialize feedback buffer for this particle
37067
37060
  if (this._useTransformFeedback) {