@galacean/engine-core 1.6.11 → 1.6.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/module.js CHANGED
@@ -612,87 +612,6 @@ var Logger = {
612
612
  }
613
613
  };
614
614
 
615
- /**
616
- * Data type enumeration
617
- */ var DataType = /*#__PURE__*/ function(DataType) {
618
- /** Float */ DataType[DataType["FLOAT"] = 5126] = "FLOAT";
619
- /** Floating-point two-dimensional vector */ DataType[DataType["FLOAT_VEC2"] = 35664] = "FLOAT_VEC2";
620
- /** Floating-point three-dimensional vector */ DataType[DataType["FLOAT_VEC3"] = 35665] = "FLOAT_VEC3";
621
- /** Floating-point four-dimensional vector */ DataType[DataType["FLOAT_VEC4"] = 35666] = "FLOAT_VEC4";
622
- /** Integer */ DataType[DataType["INT"] = 5124] = "INT";
623
- /** Integer two-dimensional vector */ DataType[DataType["INT_VEC2"] = 35667] = "INT_VEC2";
624
- /** Integer three-dimensional vector */ DataType[DataType["INT_VEC3"] = 35668] = "INT_VEC3";
625
- /** Integer four-dimensional vector */ DataType[DataType["INT_VEC4"] = 35669] = "INT_VEC4";
626
- /** Boolean */ DataType[DataType["BOOL"] = 35670] = "BOOL";
627
- /** Boolean two-dimensional vector */ DataType[DataType["BOOL_VEC2"] = 35671] = "BOOL_VEC2";
628
- /** Boolean three-dimensional vector */ DataType[DataType["BOOL_VEC3"] = 35672] = "BOOL_VEC3";
629
- /** Boolean four-dimensional vector */ DataType[DataType["BOOL_VEC4"] = 35673] = "BOOL_VEC4";
630
- /** Second-order matrix */ DataType[DataType["FLOAT_MAT2"] = 35674] = "FLOAT_MAT2";
631
- /** Third-order matrix */ DataType[DataType["FLOAT_MAT3"] = 35675] = "FLOAT_MAT3";
632
- /** Fourth-order matrix */ DataType[DataType["FLOAT_MAT4"] = 35676] = "FLOAT_MAT4";
633
- /** Float array */ DataType[DataType["FLOAT_ARRAY"] = 35677] = "FLOAT_ARRAY";
634
- /** Floating-point two-dimensional vector array */ DataType[DataType["FLOAT_VEC2_ARRAY"] = 100000] = "FLOAT_VEC2_ARRAY";
635
- /** Floating-point three-dimensional vector array */ DataType[DataType["FLOAT_VEC3_ARRAY"] = 100001] = "FLOAT_VEC3_ARRAY";
636
- /** Floating-point four-dimensional vector array */ DataType[DataType["FLOAT_VEC4_ARRAY"] = 100002] = "FLOAT_VEC4_ARRAY";
637
- /** Integer array */ DataType[DataType["INT_ARRAY"] = 100003] = "INT_ARRAY";
638
- /** Integer two-dimensional vector array */ DataType[DataType["INT_VEC2_ARRAY"] = 100004] = "INT_VEC2_ARRAY";
639
- /** Integer three-dimensional vector array */ DataType[DataType["INT_VEC3_ARRAY"] = 100005] = "INT_VEC3_ARRAY";
640
- /** Integer four-dimensional vector array */ DataType[DataType["INT_VEC4_ARRAY"] = 100006] = "INT_VEC4_ARRAY";
641
- /** Second-order matrix array */ DataType[DataType["FLOAT_MAT2_ARRAY"] = 100007] = "FLOAT_MAT2_ARRAY";
642
- /** Third-order matrix array */ DataType[DataType["FLOAT_MAT3_ARRAY"] = 100008] = "FLOAT_MAT3_ARRAY";
643
- /** Fourth-order matrix array */ DataType[DataType["FLOAT_MAT4_ARRAY"] = 100009] = "FLOAT_MAT4_ARRAY";
644
- /** 2D texture sampler array */ DataType[DataType["SAMPLER_2D_ARRAY"] = 100010] = "SAMPLER_2D_ARRAY";
645
- /** Cube map texture sampler array */ DataType[DataType["SAMPLER_CUBE_ARRAY"] = 100011] = "SAMPLER_CUBE_ARRAY";
646
- /** 2D sampler */ DataType[DataType["SAMPLER_2D"] = 35678] = "SAMPLER_2D";
647
- /** Cube map Texture sampler */ DataType[DataType["SAMPLER_CUBE"] = 35680] = "SAMPLER_CUBE";
648
- /** Byte */ DataType[DataType["BYTE"] = 5120] = "BYTE";
649
- /** Unsigned byte */ DataType[DataType["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE";
650
- /** Short */ DataType[DataType["SHORT"] = 5122] = "SHORT";
651
- /** Unsigned short */ DataType[DataType["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT";
652
- /** Unsigned int */ DataType[DataType["UNSIGNED_INT"] = 5125] = "UNSIGNED_INT"; // gl.UNSIGNED_INT
653
- return DataType;
654
- }({});
655
- /**
656
- * GL Capabilities
657
- * Some capabilities can be smoothed out by extension, and some capabilities must use WebGL 2.0.
658
- * */ var GLCapabilityType = /*#__PURE__*/ function(GLCapabilityType) {
659
- GLCapabilityType["shaderVertexID"] = "shaderVertexID";
660
- GLCapabilityType["standardDerivatives"] = "OES_standard_derivatives";
661
- GLCapabilityType["shaderTextureLod"] = "EXT_shader_texture_lod";
662
- GLCapabilityType["elementIndexUint"] = "OES_element_index_uint";
663
- GLCapabilityType["depthTexture"] = "WEBGL_depth_texture";
664
- GLCapabilityType["drawBuffers"] = "WEBGL_draw_buffers";
665
- GLCapabilityType["vertexArrayObject"] = "OES_vertex_array_object";
666
- GLCapabilityType["instancedArrays"] = "ANGLE_instanced_arrays";
667
- GLCapabilityType["multipleSample"] = "multipleSampleOnlySupportedInWebGL2";
668
- GLCapabilityType["textureFloat"] = "OES_texture_float";
669
- GLCapabilityType["textureFloatLinear"] = "OES_texture_float_linear";
670
- GLCapabilityType["textureHalfFloat"] = "OES_texture_half_float";
671
- GLCapabilityType["textureHalfFloatLinear"] = "OES_texture_half_float_linear";
672
- GLCapabilityType["WEBGL_colorBufferFloat"] = "WEBGL_color_buffer_float";
673
- GLCapabilityType["colorBufferFloat"] = "EXT_color_buffer_float";
674
- GLCapabilityType["colorBufferHalfFloat"] = "EXT_color_buffer_half_float";
675
- GLCapabilityType["textureFilterAnisotropic"] = "EXT_texture_filter_anisotropic";
676
- GLCapabilityType["blendMinMax"] = "EXT_blend_minmax";
677
- GLCapabilityType["fragDepth"] = "EXT_frag_depth";
678
- GLCapabilityType["astc"] = "WEBGL_compressed_texture_astc";
679
- GLCapabilityType["astc_webkit"] = "WEBKIT_WEBGL_compressed_texture_astc";
680
- GLCapabilityType["astc_hdr"] = "WEBGL_compressed_texture_astc_hdr";
681
- GLCapabilityType["etc"] = "WEBGL_compressed_texture_etc";
682
- GLCapabilityType["etc_webkit"] = "WEBKIT_WEBGL_compressed_texture_etc";
683
- GLCapabilityType["etc1"] = "WEBGL_compressed_texture_etc1";
684
- GLCapabilityType["etc1_webkit"] = "WEBKIT_WEBGL_compressed_texture_etc1";
685
- GLCapabilityType["pvrtc"] = "WEBGL_compressed_texture_pvrtc";
686
- GLCapabilityType["pvrtc_webkit"] = "WEBKIT_WEBGL_compressed_texture_pvrtc";
687
- GLCapabilityType["s3tc"] = "WEBGL_compressed_texture_s3tc";
688
- GLCapabilityType["s3tc_webkit"] = "WEBKIT_WEBGL_compressed_texture_s3tc";
689
- GLCapabilityType["s3tc_srgb"] = "WEBGL_compressed_texture_s3tc_srgb";
690
- GLCapabilityType["bptc"] = "EXT_texture_compression_bptc";
691
- GLCapabilityType["WEBGL_lose_context"] = "WEBGL_lose_context";
692
- GLCapabilityType["sRGB"] = "EXT_sRGB";
693
- return GLCapabilityType;
694
- }({});
695
-
696
615
  var AssetPromise = /*#__PURE__*/ function() {
697
616
  function AssetPromise(executor) {
698
617
  var _this = this;
@@ -880,10 +799,99 @@ var AssetPromise = /*#__PURE__*/ function() {
880
799
  return AssetPromise;
881
800
  }();
882
801
 
802
+ /**
803
+ * Data type enumeration
804
+ */ var DataType = /*#__PURE__*/ function(DataType) {
805
+ /** Float */ DataType[DataType["FLOAT"] = 5126] = "FLOAT";
806
+ /** Floating-point two-dimensional vector */ DataType[DataType["FLOAT_VEC2"] = 35664] = "FLOAT_VEC2";
807
+ /** Floating-point three-dimensional vector */ DataType[DataType["FLOAT_VEC3"] = 35665] = "FLOAT_VEC3";
808
+ /** Floating-point four-dimensional vector */ DataType[DataType["FLOAT_VEC4"] = 35666] = "FLOAT_VEC4";
809
+ /** Integer */ DataType[DataType["INT"] = 5124] = "INT";
810
+ /** Integer two-dimensional vector */ DataType[DataType["INT_VEC2"] = 35667] = "INT_VEC2";
811
+ /** Integer three-dimensional vector */ DataType[DataType["INT_VEC3"] = 35668] = "INT_VEC3";
812
+ /** Integer four-dimensional vector */ DataType[DataType["INT_VEC4"] = 35669] = "INT_VEC4";
813
+ /** Boolean */ DataType[DataType["BOOL"] = 35670] = "BOOL";
814
+ /** Boolean two-dimensional vector */ DataType[DataType["BOOL_VEC2"] = 35671] = "BOOL_VEC2";
815
+ /** Boolean three-dimensional vector */ DataType[DataType["BOOL_VEC3"] = 35672] = "BOOL_VEC3";
816
+ /** Boolean four-dimensional vector */ DataType[DataType["BOOL_VEC4"] = 35673] = "BOOL_VEC4";
817
+ /** Second-order matrix */ DataType[DataType["FLOAT_MAT2"] = 35674] = "FLOAT_MAT2";
818
+ /** Third-order matrix */ DataType[DataType["FLOAT_MAT3"] = 35675] = "FLOAT_MAT3";
819
+ /** Fourth-order matrix */ DataType[DataType["FLOAT_MAT4"] = 35676] = "FLOAT_MAT4";
820
+ /** Float array */ DataType[DataType["FLOAT_ARRAY"] = 35677] = "FLOAT_ARRAY";
821
+ /** Floating-point two-dimensional vector array */ DataType[DataType["FLOAT_VEC2_ARRAY"] = 100000] = "FLOAT_VEC2_ARRAY";
822
+ /** Floating-point three-dimensional vector array */ DataType[DataType["FLOAT_VEC3_ARRAY"] = 100001] = "FLOAT_VEC3_ARRAY";
823
+ /** Floating-point four-dimensional vector array */ DataType[DataType["FLOAT_VEC4_ARRAY"] = 100002] = "FLOAT_VEC4_ARRAY";
824
+ /** Integer array */ DataType[DataType["INT_ARRAY"] = 100003] = "INT_ARRAY";
825
+ /** Integer two-dimensional vector array */ DataType[DataType["INT_VEC2_ARRAY"] = 100004] = "INT_VEC2_ARRAY";
826
+ /** Integer three-dimensional vector array */ DataType[DataType["INT_VEC3_ARRAY"] = 100005] = "INT_VEC3_ARRAY";
827
+ /** Integer four-dimensional vector array */ DataType[DataType["INT_VEC4_ARRAY"] = 100006] = "INT_VEC4_ARRAY";
828
+ /** Second-order matrix array */ DataType[DataType["FLOAT_MAT2_ARRAY"] = 100007] = "FLOAT_MAT2_ARRAY";
829
+ /** Third-order matrix array */ DataType[DataType["FLOAT_MAT3_ARRAY"] = 100008] = "FLOAT_MAT3_ARRAY";
830
+ /** Fourth-order matrix array */ DataType[DataType["FLOAT_MAT4_ARRAY"] = 100009] = "FLOAT_MAT4_ARRAY";
831
+ /** 2D texture sampler array */ DataType[DataType["SAMPLER_2D_ARRAY"] = 100010] = "SAMPLER_2D_ARRAY";
832
+ /** Cube map texture sampler array */ DataType[DataType["SAMPLER_CUBE_ARRAY"] = 100011] = "SAMPLER_CUBE_ARRAY";
833
+ /** 2D sampler */ DataType[DataType["SAMPLER_2D"] = 35678] = "SAMPLER_2D";
834
+ /** Cube map Texture sampler */ DataType[DataType["SAMPLER_CUBE"] = 35680] = "SAMPLER_CUBE";
835
+ /** Byte */ DataType[DataType["BYTE"] = 5120] = "BYTE";
836
+ /** Unsigned byte */ DataType[DataType["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE";
837
+ /** Short */ DataType[DataType["SHORT"] = 5122] = "SHORT";
838
+ /** Unsigned short */ DataType[DataType["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT";
839
+ /** Unsigned int */ DataType[DataType["UNSIGNED_INT"] = 5125] = "UNSIGNED_INT"; // gl.UNSIGNED_INT
840
+ return DataType;
841
+ }({});
842
+ /**
843
+ * GL Capabilities
844
+ * Some capabilities can be smoothed out by extension, and some capabilities must use WebGL 2.0.
845
+ * */ var GLCapabilityType = /*#__PURE__*/ function(GLCapabilityType) {
846
+ GLCapabilityType["shaderVertexID"] = "shaderVertexID";
847
+ GLCapabilityType["standardDerivatives"] = "OES_standard_derivatives";
848
+ GLCapabilityType["shaderTextureLod"] = "EXT_shader_texture_lod";
849
+ GLCapabilityType["elementIndexUint"] = "OES_element_index_uint";
850
+ GLCapabilityType["depthTexture"] = "WEBGL_depth_texture";
851
+ GLCapabilityType["drawBuffers"] = "WEBGL_draw_buffers";
852
+ GLCapabilityType["vertexArrayObject"] = "OES_vertex_array_object";
853
+ GLCapabilityType["instancedArrays"] = "ANGLE_instanced_arrays";
854
+ GLCapabilityType["multipleSample"] = "multipleSampleOnlySupportedInWebGL2";
855
+ GLCapabilityType["textureFloat"] = "OES_texture_float";
856
+ GLCapabilityType["textureFloatLinear"] = "OES_texture_float_linear";
857
+ GLCapabilityType["textureHalfFloat"] = "OES_texture_half_float";
858
+ GLCapabilityType["textureHalfFloatLinear"] = "OES_texture_half_float_linear";
859
+ GLCapabilityType["WEBGL_colorBufferFloat"] = "WEBGL_color_buffer_float";
860
+ GLCapabilityType["colorBufferFloat"] = "EXT_color_buffer_float";
861
+ GLCapabilityType["colorBufferHalfFloat"] = "EXT_color_buffer_half_float";
862
+ GLCapabilityType["textureFilterAnisotropic"] = "EXT_texture_filter_anisotropic";
863
+ GLCapabilityType["blendMinMax"] = "EXT_blend_minmax";
864
+ GLCapabilityType["fragDepth"] = "EXT_frag_depth";
865
+ GLCapabilityType["astc"] = "WEBGL_compressed_texture_astc";
866
+ GLCapabilityType["astc_webkit"] = "WEBKIT_WEBGL_compressed_texture_astc";
867
+ GLCapabilityType["astc_hdr"] = "WEBGL_compressed_texture_astc_hdr";
868
+ GLCapabilityType["etc"] = "WEBGL_compressed_texture_etc";
869
+ GLCapabilityType["etc_webkit"] = "WEBKIT_WEBGL_compressed_texture_etc";
870
+ GLCapabilityType["etc1"] = "WEBGL_compressed_texture_etc1";
871
+ GLCapabilityType["etc1_webkit"] = "WEBKIT_WEBGL_compressed_texture_etc1";
872
+ GLCapabilityType["pvrtc"] = "WEBGL_compressed_texture_pvrtc";
873
+ GLCapabilityType["pvrtc_webkit"] = "WEBKIT_WEBGL_compressed_texture_pvrtc";
874
+ GLCapabilityType["s3tc"] = "WEBGL_compressed_texture_s3tc";
875
+ GLCapabilityType["s3tc_webkit"] = "WEBKIT_WEBGL_compressed_texture_s3tc";
876
+ GLCapabilityType["s3tc_srgb"] = "WEBGL_compressed_texture_s3tc_srgb";
877
+ GLCapabilityType["bptc"] = "EXT_texture_compression_bptc";
878
+ GLCapabilityType["WEBGL_lose_context"] = "WEBGL_lose_context";
879
+ GLCapabilityType["sRGB"] = "EXT_sRGB";
880
+ return GLCapabilityType;
881
+ }({});
882
+
883
883
  /**
884
884
  * Access operating system, platform and hardware information.
885
885
  */ var SystemInfo = /*#__PURE__*/ function() {
886
886
  function SystemInfo() {}
887
+ SystemInfo._parseAppleMobileOSVersion = function _parseAppleMobileOSVersion(userAgent, osPrefix) {
888
+ // Since iOS 26, Safari freezes UA OS version at 18.6, so Version/xx is more reliable
889
+ // Use Version/ if available, otherwise fallback to OS version
890
+ var v = userAgent.match(/Version\/(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
891
+ if (v) return osPrefix + " " + v[1] + "." + (v[2] || 0) + "." + (v[3] || 0);
892
+ v = userAgent.match(/OS (\d+)_(\d+)(?:_(\d+))?/);
893
+ return v ? osPrefix + " " + v[1] + "." + v[2] + "." + (v[3] || 0) : osPrefix;
894
+ };
887
895
  /**
888
896
  * @internal
889
897
  */ SystemInfo._initialize = function _initialize() {
@@ -905,12 +913,10 @@ var AssetPromise = /*#__PURE__*/ function() {
905
913
  var v;
906
914
  switch(SystemInfo.platform){
907
915
  case Platform.IPhone:
908
- v = userAgent.match(/OS (\d+)_?(\d+)?_?(\d+)?/);
909
- this.operatingSystem = v ? "iPhone OS " + v[1] + "." + (v[2] || 0) + "." + (v[3] || 0) : "iPhone OS";
916
+ this.operatingSystem = this._parseAppleMobileOSVersion(userAgent, "iPhone OS");
910
917
  break;
911
918
  case Platform.IPad:
912
- v = userAgent.match(/OS (\d+)_?(\d+)?_?(\d+)?/);
913
- this.operatingSystem = v ? "iPad OS " + v[1] + "." + (v[2] || 0) + "." + (v[3] || 0) : "iPad OS";
919
+ this.operatingSystem = this._parseAppleMobileOSVersion(userAgent, "iPad OS");
914
920
  break;
915
921
  case Platform.Android:
916
922
  v = userAgent.match(/Android (\d+).?(\d+)?.?(\d+)?/);
@@ -3008,12 +3014,13 @@ var Utils = /*#__PURE__*/ function() {
3008
3014
  if (Utils.isBase64Url(relativeUrl)) {
3009
3015
  return relativeUrl;
3010
3016
  }
3011
- if (!/^https?:/.test(baseUrl)) {
3012
- var fileSchema = "file://";
3013
- baseUrl = fileSchema + baseUrl;
3014
- return new URL(relativeUrl, baseUrl).href.substring(fileSchema.length);
3017
+ if (Utils.isAbsoluteUrl(baseUrl)) {
3018
+ return relativeUrl ? new URL(relativeUrl, baseUrl).href : baseUrl;
3015
3019
  }
3016
- return relativeUrl ? new URL(relativeUrl, baseUrl).href : baseUrl;
3020
+ var head = "file://";
3021
+ var encodedBaseUrl = head + this._encodePathComponents(baseUrl);
3022
+ var encodedRelativeUrl = this._encodePathComponents(relativeUrl);
3023
+ return decodeURIComponent(new URL(encodedRelativeUrl, encodedBaseUrl).href.slice(head.length));
3017
3024
  };
3018
3025
  /**
3019
3026
  * @internal
@@ -3172,6 +3179,9 @@ var Utils = /*#__PURE__*/ function() {
3172
3179
  a[j + 1] = element;
3173
3180
  }
3174
3181
  };
3182
+ Utils._encodePathComponents = function _encodePathComponents(path) {
3183
+ return path.split("/").map(encodeURIComponent).join("/");
3184
+ };
3175
3185
  return Utils;
3176
3186
  }();
3177
3187
  var charCodeOfDot$1 = ".".charCodeAt(0);
@@ -4721,11 +4731,11 @@ var ShadowLib = {
4721
4731
  ShadowVertex: ShadowVertex
4722
4732
  };
4723
4733
 
4724
- var particle_common = "\n\nvec3 rotationByEuler(in vec3 vector, in vec3 rot) {\n float halfRoll = rot.z * 0.5;\n float halfPitch = rot.x * 0.5;\n float halfYaw = rot.y * 0.5;\n\n float sinRoll = sin(halfRoll);\n float cosRoll = cos(halfRoll);\n float sinPitch = sin(halfPitch);\n float cosPitch = cos(halfPitch);\n float sinYaw = sin(halfYaw);\n float cosYaw = cos(halfYaw);\n\n float quaX = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);\n float quaY = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);\n float quaZ = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);\n float quaW = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);\n\n // vec4 q=vec4(quaX,quaY,quaZ,quaW);\n // vec3 temp = cross(q.xyz, vector) + q.w * vector;\n // return (cross(temp, -q.xyz) + dot(q.xyz,vector) * q.xyz + q.w * temp);\n\n float x = quaX + quaX;\n float y = quaY + quaY;\n float z = quaZ + quaZ;\n float wx = quaW * x;\n float wy = quaW * y;\n float wz = quaW * z;\n float xx = quaX * x;\n float xy = quaX * y;\n float xz = quaX * z;\n float yy = quaY * y;\n float yz = quaY * z;\n float zz = quaZ * z;\n\n return vec3(((vector.x * ((1.0 - yy) - zz)) + (vector.y * (xy - wz))) + (vector.z * (xz + wy)),\n\t((vector.x * (xy + wz)) + (vector.y * ((1.0 - xx) - zz))) + (vector.z * (yz - wx)),\n\t((vector.x * (xz - wy)) + (vector.y * (yz + wx))) + (vector.z * ((1.0 - xx) - yy)));\n}\n\n//假定axis已经归一化\nvec3 rotationByAxis(in vec3 vector, in vec3 axis, in float angle) {\n float halfAngle = angle * 0.5;\n float sin = sin(halfAngle);\n\n float quaX = axis.x * sin;\n float quaY = axis.y * sin;\n float quaZ = axis.z * sin;\n float quaW = cos(halfAngle);\n\n // vec4 q=vec4(quaX,quaY,quaZ,quaW);\n // vec3 temp = cross(q.xyz, vector) + q.w * vector;\n // return (cross(temp, -q.xyz) + dot(q.xyz,vector) * q.xyz + q.w * temp);\n\n float x = quaX + quaX;\n float y = quaY + quaY;\n float z = quaZ + quaZ;\n float wx = quaW * x;\n float wy = quaW * y;\n float wz = quaW * z;\n float xx = quaX * x;\n float xy = quaX * y;\n float xz = quaX * z;\n float yy = quaY * y;\n float yz = quaY * z;\n float zz = quaZ * z;\n\n return vec3(((vector.x * ((1.0 - yy) - zz)) + (vector.y * (xy - wz))) + (vector.z * (xz + wy)),\n\t((vector.x * (xy + wz)) + (vector.y * ((1.0 - xx) - zz))) + (vector.z * (yz - wx)),\n\t((vector.x * (xz - wy)) + (vector.y * (yz + wx))) + (vector.z * ((1.0 - xx) - yy)));\n}\n\nvec3 rotationByQuaternions(in vec3 v, in vec4 q) {\n return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n\n\nfloat evaluateParticleCurve(in vec2 keys[4], in float normalizedAge) {\n float value;\n for (int i = 1; i < 4; i++) {\n vec2 key = keys[i];\n float time = key.x;\n if (time >= normalizedAge) {\n vec2 lastKey = keys[i - 1];\n float lastTime = lastKey.x;\n float age = (normalizedAge - lastTime) / (time - lastTime);\n value = mix(lastKey.y, key.y, age);\n break;\n }\n }\n return value;\n}\n\nfloat evaluateParticleCurveCumulative(in vec2 keys[4], in float normalizedAge, out float currentValue){\n float cumulativeValue = 0.0;\n for (int i = 1; i < 4; i++){\n\t vec2 key = keys[i];\n\t float time = key.x;\n\t vec2 lastKey = keys[i - 1];\n\t float lastValue = lastKey.y;\n\n\t if (time >= normalizedAge){\n\t\t float lastTime = lastKey.x;\n float offsetTime = normalizedAge - lastTime;\n\t\t float age = offsetTime / (time - lastTime);\n currentValue = mix(lastValue, key.y, age);\n\t\t cumulativeValue += (lastValue + currentValue) * 0.5 * offsetTime;\n\t\t break;\n\t\t}\n\t else{\n\t\t cumulativeValue += (lastValue + key.y) * 0.5 * (time - lastKey.x);\n\t\t}\n\t}\n return cumulativeValue;\n}"; // eslint-disable-line
4734
+ var particle_common = "vec3 rotationByQuaternions(in vec3 v, in vec4 q) {\n return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n}\n\nvec3 rotationByEuler(in vec3 vector, in vec3 rot) {\n float halfRoll = rot.z * 0.5;\n float halfPitch = rot.x * 0.5;\n float halfYaw = rot.y * 0.5;\n\n float sinRoll = sin(halfRoll);\n float cosRoll = cos(halfRoll);\n float sinPitch = sin(halfPitch);\n float cosPitch = cos(halfPitch);\n float sinYaw = sin(halfYaw);\n float cosYaw = cos(halfYaw);\n\n float cosYawPitch = cosYaw * cosPitch;\n float sinYawPitch = sinYaw * sinPitch;\n\n float quaX = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);\n float quaY = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);\n float quaZ = (cosYawPitch * sinRoll) - (sinYawPitch * cosRoll);\n float quaW = (cosYawPitch * cosRoll) + (sinYawPitch * sinRoll);\n\n return rotationByQuaternions(vector, vec4(quaX, quaY, quaZ, quaW));\n}\n\n// Assume axis is normalized\nvec3 rotationByAxis(in vec3 vector, in vec3 axis, in float angle) {\n float halfAngle = angle * 0.5;\n float s = sin(halfAngle);\n\n return rotationByQuaternions(vector, vec4(axis * s, cos(halfAngle)));\n}\n\n\nfloat evaluateParticleCurve(in vec2 keys[4], in float normalizedAge) {\n float value;\n for (int i = 1; i < 4; i++) {\n vec2 key = keys[i];\n float time = key.x;\n if (time >= normalizedAge) {\n vec2 lastKey = keys[i - 1];\n float lastTime = lastKey.x;\n float age = (normalizedAge - lastTime) / (time - lastTime);\n value = mix(lastKey.y, key.y, age);\n break;\n }\n }\n return value;\n}\n\nfloat evaluateParticleCurveCumulative(in vec2 keys[4], in float normalizedAge, out float currentValue){\n float cumulativeValue = 0.0;\n for (int i = 1; i < 4; i++){\n\t vec2 key = keys[i];\n\t float time = key.x;\n\t vec2 lastKey = keys[i - 1];\n\t float lastValue = lastKey.y;\n\n\t if (time >= normalizedAge){\n\t\t float lastTime = lastKey.x;\n float offsetTime = normalizedAge - lastTime;\n\t\t float age = offsetTime / (time - lastTime);\n currentValue = mix(lastValue, key.y, age);\n\t\t cumulativeValue += (lastValue + currentValue) * 0.5 * offsetTime;\n\t\t break;\n\t\t}\n\t else{\n\t\t cumulativeValue += (lastValue + key.y) * 0.5 * (time - lastKey.x);\n\t\t}\n\t}\n return cumulativeValue;\n}"; // eslint-disable-line
4725
4735
 
4726
4736
  var velocity_over_lifetime_module = "#if defined(RENDERER_VOL_CONSTANT_MODE) || defined(RENDERER_VOL_CURVE_MODE)\n #define _VOL_MODULE_ENABLED\n#endif\n\n#ifdef _VOL_MODULE_ENABLED\n uniform int renderer_VOLSpace;\n\n #ifdef RENDERER_VOL_CONSTANT_MODE\n uniform vec3 renderer_VOLMaxConst;\n\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n uniform vec3 renderer_VOLMinConst;\n #endif\n #endif\n\n #ifdef RENDERER_VOL_CURVE_MODE\n uniform vec2 renderer_VOLMaxGradientX[4]; // x:time y:value\n uniform vec2 renderer_VOLMaxGradientY[4]; // x:time y:value\n uniform vec2 renderer_VOLMaxGradientZ[4]; // x:time y:value\n\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n uniform vec2 renderer_VOLMinGradientX[4]; // x:time y:value\n uniform vec2 renderer_VOLMinGradientY[4]; // x:time y:value\n uniform vec2 renderer_VOLMinGradientZ[4]; // x:time y:value\n #endif\n #endif\n\n\n vec3 computeVelocityPositionOffset(in float normalizedAge, in float age, out vec3 currentVelocity) {\n vec3 velocityPosition;\n\n #ifdef RENDERER_VOL_CONSTANT_MODE\n currentVelocity = renderer_VOLMaxConst;\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n currentVelocity = mix(renderer_VOLMinConst, currentVelocity, a_Random1.yzw);\n #endif\n\n velocityPosition = currentVelocity * age;\n #endif\n\n #ifdef RENDERER_VOL_CURVE_MODE\n velocityPosition = vec3(\n evaluateParticleCurveCumulative(renderer_VOLMaxGradientX, normalizedAge, currentVelocity.x),\n evaluateParticleCurveCumulative(renderer_VOLMaxGradientY, normalizedAge, currentVelocity.y),\n evaluateParticleCurveCumulative(renderer_VOLMaxGradientZ, normalizedAge, currentVelocity.z));\n\n #ifdef RENDERER_VOL_IS_RANDOM_TWO\n vec3 minCurrentVelocity;\n vec3 minVelocityPosition = vec3(\n evaluateParticleCurveCumulative(renderer_VOLMinGradientX, normalizedAge, minCurrentVelocity.x),\n evaluateParticleCurveCumulative(renderer_VOLMinGradientY, normalizedAge, minCurrentVelocity.y),\n evaluateParticleCurveCumulative(renderer_VOLMinGradientZ, normalizedAge, minCurrentVelocity.z));\n\n currentVelocity = mix(minCurrentVelocity, currentVelocity, a_Random1.yzw);\n velocityPosition = mix(minVelocityPosition, velocityPosition, a_Random1.yzw);\n #endif\n\n velocityPosition *= vec3(a_ShapePositionStartLifeTime.w);\n #endif\n return velocityPosition;\n }\n#endif\n"; // eslint-disable-line
4727
4737
 
4728
- var rotation_over_lifetime_module = "#if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #ifdef RENDERER_ROL_CURVE_MODE\n uniform vec2 renderer_ROLMaxCurveZ[4];\n // #ifdef RENDERER_ROL_IS_SEPARATE\n // uniform vec2 renderer_ROLMaxCurveX[4];\n // uniform vec2 renderer_ROLMaxCurveY[4];\n // #endif\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n uniform vec2 renderer_ROLMinCurveZ[4];\n // #ifdef RENDERER_ROL_IS_SEPARATE\n // uniform vec2 renderer_ROLMinCurveX[4];\n // uniform vec2 renderer_ROLMinCurveY[4];\n // #endif\n #endif\n #else\n uniform vec3 renderer_ROLMaxConst;\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n uniform vec3 renderer_ROLMinConst;\n #endif\n #endif\n#endif\n\nfloat computeParticleRotationFloat(in float rotation, in float age, in float normalizedAge) {\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #ifdef RENDERER_ROL_CURVE_MODE\n float currentValue;\n float lifeRotation = evaluateParticleCurveCumulative(renderer_ROLMaxCurveZ, normalizedAge, currentValue);\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n lifeRotation = mix(evaluateParticleCurveCumulative(renderer_ROLMinCurveZ, normalizedAge, currentValue), lifeRotation, a_Random0.w);\n #endif\n rotation += lifeRotation * a_ShapePositionStartLifeTime.w;\n #else\n float lifeRotation = renderer_ROLMaxConst.z;\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n lifeRotation = mix(renderer_ROLMinConst.z, lifeRotation, a_Random0.w);\n #endif\n rotation += lifeRotation * age;\n #endif\n #endif\n return rotation;\n}\n\n\n#if defined(RENDERER_MODE_MESH) && (defined(ROTATION_OVER_LIFETIME) || defined(ROTATION_OVER_LIFETIME_SEPARATE))\nvec3 computeParticleRotationVec3(in vec3 rotation,\n in float age,\n in float normalizedAge) {\n#ifdef ROTATION_OVER_LIFETIME\n #ifdef ROTATION_OVER_LIFETIME_CONSTANT\n float ageRot = u_ROLAngularVelocityConst * age;\n rotation += ageRot;\n #endif\n #ifdef ROTATION_OVER_LIFETIME_CURVE\n rotation += getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient, normalizedAge);\n #endif\n #ifdef ROTATION_OVER_LIFETIME_RANDOM_CONSTANTS\n float ageRot = mix(u_ROLAngularVelocityConst, u_ROLAngularVelocityConstMax, a_Random0.w) * age;\n rotation += ageRot;\n #endif\n #ifdef ROTATION_OVER_LIFETIME_RANDOM_CURVES\n rotation += mix(\n getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient, normalizedAge),\n getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMax,\n normalizedAge),\n a_Random0.w);\n #endif\n#endif\n\n#ifdef ROTATION_OVER_LIFETIME_SEPARATE\n #ifdef ROTATION_OVER_LIFETIME_CONSTANT\n vec3 ageRot = u_ROLAngularVelocityConstSeparate * age;\n rotation += ageRot;\n #endif\n #ifdef ROTATION_OVER_LIFETIME_CURVE\n rotation += vec3(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientX,\n normalizedAge),\n getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientY,\n normalizedAge),\n getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,\n normalizedAge));\n #endif\n #ifdef ROTATION_OVER_LIFETIME_RANDOM_CONSTANTS\n vec3 ageRot = mix(u_ROLAngularVelocityConstSeparate,\n renderer_ROLMaxConst,\n a_Random0.w)\n * age;\n rotation += ageRot;\n #endif\n #ifdef ROTATION_OVER_LIFETIME_RANDOM_CURVES\n rotation += vec3(mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientX,\n normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveX,\n normalizedAge),\n a_Random0.w),\n mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientY,\n normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveY,\n normalizedAge),\n a_Random0.w),\n mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,\n normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveZ,\n normalizedAge),\n a_Random0.w));\n #endif\n#endif\n return rotation;\n}\n#endif\n"; // eslint-disable-line
4738
+ var rotation_over_lifetime_module = "#if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #ifdef RENDERER_ROL_CURVE_MODE\n uniform vec2 renderer_ROLMaxCurveZ[4];\n // #ifdef RENDERER_ROL_IS_SEPARATE\n // uniform vec2 renderer_ROLMaxCurveX[4];\n // uniform vec2 renderer_ROLMaxCurveY[4];\n // #endif\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n uniform vec2 renderer_ROLMinCurveZ[4];\n // #ifdef RENDERER_ROL_IS_SEPARATE\n // uniform vec2 renderer_ROLMinCurveX[4];\n // uniform vec2 renderer_ROLMinCurveY[4];\n // #endif\n #endif\n #else\n uniform vec3 renderer_ROLMaxConst;\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n uniform vec3 renderer_ROLMinConst;\n #endif\n #endif\n#endif\n\nfloat computeParticleRotationFloat(in float rotation, in float age, in float normalizedAge) {\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #ifdef RENDERER_ROL_CURVE_MODE\n float currentValue;\n float lifeRotation = evaluateParticleCurveCumulative(renderer_ROLMaxCurveZ, normalizedAge, currentValue);\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n lifeRotation = mix(evaluateParticleCurveCumulative(renderer_ROLMinCurveZ, normalizedAge, currentValue), lifeRotation, a_Random0.w);\n #endif\n rotation += lifeRotation * a_ShapePositionStartLifeTime.w;\n #else\n float lifeRotation = renderer_ROLMaxConst.z;\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n lifeRotation = mix(renderer_ROLMinConst.z, lifeRotation, a_Random0.w);\n #endif\n rotation += lifeRotation * age;\n #endif\n #endif\n return rotation;\n}\n\n\n#if defined(RENDERER_MODE_MESH) && (defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE))\nvec3 computeParticleRotationVec3(in vec3 rotation, in float age, in float normalizedAge) {\n #ifdef RENDERER_ROL_IS_SEPARATE\n #ifdef RENDERER_ROL_CONSTANT_MODE\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n vec3 ageRot = mix(renderer_ROLMinConst, renderer_ROLMaxConst, a_Random0.w) * age;\n #else\n vec3 ageRot = renderer_ROLMaxConst * age;\n #endif\n rotation += ageRot;\n #endif\n #ifdef RENDERER_ROL_CURVE_MODE\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n rotation += vec3(\n mix(getTotalValueFromGradientFloat(renderer_ROLMinCurveX, normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveX, normalizedAge), a_Random0.w),\n mix(getTotalValueFromGradientFloat(renderer_ROLMinCurveY, normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveY, normalizedAge), a_Random0.w),\n mix(getTotalValueFromGradientFloat(renderer_ROLMinCurveZ, normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveZ, normalizedAge), a_Random0.w));\n #else\n rotation += vec3(getTotalValueFromGradientFloat(renderer_ROLMaxCurveX, normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveY, normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveZ, normalizedAge));\n #endif\n #endif\n #else\n #ifdef RENDERER_ROL_CONSTANT_MODE\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n float ageRot = mix(renderer_ROLMinConst.z, renderer_ROLMaxConst.z, a_Random0.w) * age;\n #else\n float ageRot = renderer_ROLMaxConst.z * age;\n #endif\n rotation += ageRot;\n #endif\n\n #ifdef RENDERER_ROL_CURVE_MODE\n #ifdef RENDERER_ROL_IS_RANDOM_TWO\n rotation += mix(\n getTotalValueFromGradientFloat(renderer_ROLMinCurveZ, normalizedAge),\n getTotalValueFromGradientFloat(renderer_ROLMaxCurveZ, normalizedAge),\n a_Random0.w);\n #else\n rotation += getTotalValueFromGradientFloat(renderer_ROLMaxCurveZ, normalizedAge);\n #endif\n #endif\n #endif\n return rotation;\n}\n#endif\n"; // eslint-disable-line
4729
4739
 
4730
4740
  var size_over_lifetime_module = "#ifdef RENDERER_SOL_CURVE_MODE\n uniform vec2 renderer_SOLMaxCurveX[4]; // x:time y:value\n #ifdef RENDERER_SOL_IS_SEPARATE\n uniform vec2 renderer_SOLMaxCurveY[4]; // x:time y:value\n uniform vec2 renderer_SOLMaxCurveZ[4]; // x:time y:value\n #endif\n\n #ifdef RENDERER_SOL_IS_RANDOM_TWO\n uniform vec2 renderer_SOLMinCurveX[4]; // x:time y:value\n #ifdef RENDERER_SOL_IS_SEPARATE\n uniform vec2 renderer_SOLMinCurveY[4]; // x:time y:value\n uniform vec2 renderer_SOLMinCurveZ[4]; // x:time y:value\n #endif\n #endif\n#endif\n\nvec2 computeParticleSizeBillboard(in vec2 size, in float normalizedAge) {\n #ifdef RENDERER_SOL_CURVE_MODE\n float lifeSizeX = evaluateParticleCurve(renderer_SOLMaxCurveX, normalizedAge);\n #ifdef RENDERER_SOL_IS_RANDOM_TWO\n lifeSizeX = mix(evaluateParticleCurve(renderer_SOLMinCurveX, normalizedAge), lifeSizeX, a_Random0.z);\n #endif\n\n #ifdef RENDERER_SOL_IS_SEPARATE\n float lifeSizeY = evaluateParticleCurve(renderer_SOLMaxCurveY, normalizedAge);\n #ifdef RENDERER_SOL_IS_RANDOM_TWO\n lifeSizeY = mix(evaluateParticleCurve(renderer_SOLMinCurveY, normalizedAge), lifeSizeY, a_Random0.z);\n #endif\n size *= vec2(lifeSizeX, lifeSizeY);\n #else\n size *= lifeSizeX;\n #endif\n #endif\n return size;\n}\n\n#ifdef RENDERER_MODE_MESH\n vec3 computeParticleSizeMesh(in vec3 size, in float normalizedAge) {\n #ifdef RENDERER_SOL_CURVE\n size *= evaluateParticleCurve(renderer_SOLMaxCurveX, normalizedAge);\n #endif\n #ifdef RENDERER_SOL_RANDOM_CURVES\n size *= mix(evaluateParticleCurve(renderer_SOLMaxCurveX, normalizedAge),\n evaluateParticleCurve(u_SOLSizeGradientMax, normalizedAge),\n a_Random0.z);\n #endif\n #ifdef RENDERER_SOL_CURVE_SEPARATE\n size *= vec3(evaluateParticleCurve(renderer_SOLMinCurveX, normalizedAge),\n evaluateParticleCurve(renderer_SOLMinCurveY, normalizedAge),\n evaluateParticleCurve(renderer_SOLMinCurveZ, normalizedAge));\n #endif\n #ifdef RENDERER_SOL_RANDOM_CURVES_SEPARATE\n size *= vec3(mix(evaluateParticleCurve(renderer_SOLMinCurveX, normalizedAge),\n evaluateParticleCurve(renderer_SOLMaxCurveX, normalizedAge),\n a_Random0.z),\n mix(evaluateParticleCurve(renderer_SOLMinCurveY, normalizedAge),\n evaluateParticleCurve(renderer_SOLMaxCurveY, normalizedAge),\n a_Random0.z),\n mix(evaluateParticleCurve(renderer_SOLMinCurveZ, normalizedAge),\n evaluateParticleCurve(renderer_SOLMaxCurveZ, normalizedAge),\n a_Random0.z));\n #endif\n return size;\n }\n#endif"; // eslint-disable-line
4731
4741
 
@@ -4743,7 +4753,7 @@ var vertical_billboard = "#ifdef RENDERER_MODE_VERTICAL_BILLBOARD\n\tvec2 corner
4743
4753
 
4744
4754
  var horizontal_billboard = "#ifdef RENDERER_MODE_HORIZONTAL_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy; // Billboard模式z轴无效\n\tconst vec3 cameraUpVector = vec3(0.0, 0.0, 1.0);\n\tconst vec3 sideVector = vec3(-1.0, 0.0, 0.0);\n\n\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge);\n\tfloat c = cos(rot);\n\tfloat s = sin(rot);\n\tmat2 rotation = mat2(c, -s, s, c);\n\tcorner = rotation * corner * cos(0.78539816339744830961566084581988); // TODO:临时缩小cos45,不确定U3D原因\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n\tcenter += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * cameraUpVector);\n#endif"; // eslint-disable-line
4745
4755
 
4746
- var particle_mesh = "#ifdef RENDERER_MODE_MESH\n\tvec3 size = computeParticleSizeMesh(a_StartSize, normalizedAge);\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n if (renderer_ThreeDStartRotation) {\n vec3 rotation = vec3(\n a_StartRotation0.xy,\n computeParticleRotationFloat(a_StartRotation0.z, age, normalizedAge));\n center += rotationByQuaternions(\n renderer_SizeScale * rotationByEuler(a_MeshPosition * size, rotation),\n worldRotation);\n } else {\n #ifdef RENDERER_ROL_IS_SEPARATE\n float angle = computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge);\n if (a_ShapePositionStartLifeTime.x != 0.0 || a_ShapePositionStartLifeTime.y != 0.0) {\n center += (rotationByQuaternions(\n rotationByAxis(\n renderer_SizeScale * a_MeshPosition * size,\n normalize(cross(vec3(0.0, 0.0, 1.0),\n vec3(a_ShapePositionStartLifeTime.xy, 0.0))),\n angle),\n worldRotation)); //已验证\n } else {\n #ifdef SHAPE\n center += renderer_SizeScale.xzy * (rotationByQuaternions(rotationByAxis(a_MeshPosition * size, vec3(0.0, -1.0, 0.0), angle), worldRotation));\n #else\n if (renderer_SimulationSpace == 1)\n center += rotationByAxis(renderer_SizeScale * a_MeshPosition * size,\n vec3(0.0, 0.0, -1.0),\n angle); //已验证\n else if (renderer_SimulationSpace == 0)\n center += rotationByQuaternions(\n renderer_SizeScale * rotationByAxis(a_MeshPosition * size, vec3(0.0, 0.0, -1.0), angle),\n worldRotation); //已验证\n #endif\n }\n #endif\n #ifdef ROTATION_OVER_LIFETIME_SEPARATE\n // TODO:是否应合并if(renderer_ThreeDStartRotation)分支代码,待测试\n vec3 angle = computeParticleRotationVec3(\n vec3(0.0, 0.0, -a_StartRotation0.x), age, normalizedAge);\n center += (rotationByQuaternions(\n rotationByEuler(renderer_SizeScale * a_MeshPosition * size,\n vec3(angle.x, angle.y, angle.z)),\n worldRotation)); //已验证\n #endif\n }\n #else\n if (renderer_ThreeDStartRotation) {\n center += rotationByQuaternions(\n renderer_SizeScale * rotationByEuler(a_MeshPosition * size, a_StartRotation0),\n worldRotation); //已验证\n } else {\n if (a_ShapePositionStartLifeTime.x != 0.0 || a_ShapePositionStartLifeTime.y != 0.0) {\n if (renderer_SimulationSpace == 1)\n center += rotationByAxis(\n renderer_SizeScale * a_MeshPosition * size,\n normalize(cross(vec3(0.0, 0.0, 1.0),\n vec3(a_ShapePositionStartLifeTime.xy, 0.0))),\n a_StartRotation0.x);\n else if (renderer_SimulationSpace == 0)\n center += (rotationByQuaternions(\n renderer_SizeScale * rotationByAxis(a_MeshPosition * size, normalize(cross(vec3(0.0, 0.0, 1.0),\n vec3(a_ShapePositionStartLifeTime.xy, 0.0))), a_StartRotation0.x),\n worldRotation)); //已验证\n } else {\n #ifdef SHAPE\n if (renderer_SimulationSpace == 1)\n center += renderer_SizeScale * rotationByAxis(a_MeshPosition * size, vec3(0.0, -1.0, 0.0), a_StartRotation0.x);\n else if (renderer_SimulationSpace == 0)\n center += rotationByQuaternions(\n renderer_SizeScale * rotationByAxis(a_MeshPosition * size, vec3(0.0, -1.0, 0.0), a_StartRotation0.x),\n worldRotation);\n #else\n if (renderer_SimulationSpace == 1)\n center += rotationByAxis(renderer_SizeScale * a_MeshPosition * size,\n vec3(0.0, 0.0, -1.0),\n a_StartRotation0.x);\n else if (renderer_SimulationSpace == 0)\n center += rotationByQuaternions(\n renderer_SizeScale * rotationByAxis(a_MeshPosition * size, vec3(0.0, 0.0, -1.0), a_StartRotation0.x),\n worldRotation); //已验证\n #endif\n }\n }\n #endif\n\tv_MeshColor = a_MeshColor;\n#endif"; // eslint-disable-line
4756
+ var particle_mesh = "// Only support local alignment mode\n#ifdef RENDERER_MODE_MESH\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #define RENDERER_ROL_ENABLED\n #endif\n\n\tvec3 size = computeParticleSizeMesh(a_StartSize, normalizedAge);\n\n bool is3DRotation = renderer_ThreeDStartRotation;\n #if defined(RENDERER_ROL_ENABLED) && defined(RENDERER_ROL_IS_SEPARATE)\n is3DRotation = true;\n #endif\n\n if (is3DRotation) {\n #ifdef RENDERER_ROL_ENABLED\n vec3 startRotation = renderer_ThreeDStartRotation ? a_StartRotation0 : vec3(0.0, 0.0, a_StartRotation0.x);\n vec3 rotation = computeParticleRotationVec3(startRotation, age, normalizedAge);\n #else\n vec3 rotation = a_StartRotation0;\n #endif\n // 3D Start Rotation is same in local and world simulation space\n center += rotationByQuaternions(renderer_SizeScale * rotationByEuler(POSITION * size, rotation), worldRotation);\n } else {\n #ifdef RENDERER_ROL_ENABLED\n float angle = computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge);\n #else\n float angle = a_StartRotation0.x;\n #endif\n #ifdef RENDERER_EMISSION_SHAPE\n // Axis is side vector of emit position look at zero\n vec3 axis = vec3(a_ShapePositionStartLifeTime.xy, 0.0);\n if (renderer_SimulationSpace == 1){\n axis = rotationByQuaternions(axis, worldRotation);\n }\n vec3 crossResult = cross(axis, vec3(0.0, 0.0, -1.0));\n float crossLen = length(crossResult);\n vec3 rotateAxis = crossLen > 0.0001 ? crossResult / crossLen : vec3(0.0, 1.0, 0.0);\n #else\n // Axis is negative z\n vec3 rotateAxis = vec3(0.0, 0.0, -1.0);\n #endif\n center += rotationByQuaternions(renderer_SizeScale *rotationByAxis(POSITION * size, rotateAxis, angle), worldRotation);\n }\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n\t\tv_MeshColor = COLOR_0;\n\t#endif\n#endif"; // eslint-disable-line
4747
4757
 
4748
4758
  var ParticleShaderLib = {
4749
4759
  particle_common: particle_common,
@@ -19129,11 +19139,11 @@ var BlendShapeFrameDirty = /*#__PURE__*/ function(BlendShapeFrameDirty) {
19129
19139
  ]);
19130
19140
  return MeshRenderer;
19131
19141
  }(Renderer);
19142
+ /** @internal */ MeshRenderer._enableVertexColorMacro = ShaderMacro.getByName("RENDERER_ENABLE_VERTEXCOLOR");
19132
19143
  MeshRenderer._uvMacro = ShaderMacro.getByName("RENDERER_HAS_UV");
19133
19144
  MeshRenderer._uv1Macro = ShaderMacro.getByName("RENDERER_HAS_UV1");
19134
19145
  MeshRenderer._normalMacro = ShaderMacro.getByName("RENDERER_HAS_NORMAL");
19135
19146
  MeshRenderer._tangentMacro = ShaderMacro.getByName("RENDERER_HAS_TANGENT");
19136
- MeshRenderer._enableVertexColorMacro = ShaderMacro.getByName("RENDERER_ENABLE_VERTEXCOLOR");
19137
19147
  __decorate([
19138
19148
  ignoreClone
19139
19149
  ], MeshRenderer.prototype, "_mesh", void 0);
@@ -25780,9 +25790,9 @@ var depthOnlyFs = "void main() {\n}"; // eslint-disable-line
25780
25790
 
25781
25791
  var depthOnlyVs = "#define MATERIAL_OMIT_NORMAL\n#include <common>\n#include <common_vert>\n#include <blendShape_input>\nuniform mat4 camera_VPMat;\n\n\nvoid main() {\n\n #include <begin_position_vert>\n #include <blendShape_vert>\n #include <skinning_vert>\n #include <position_vert>\n\n}\n"; // eslint-disable-line
25782
25792
 
25783
- var particleFs = "#include <common>\n\nvarying vec4 v_Color;\nvarying vec2 v_TextureCoordinate;\nuniform sampler2D material_BaseTexture;\nuniform vec4 material_BaseColor;\n \nuniform mediump vec3 material_EmissiveColor;\n#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n uniform sampler2D material_EmissiveTexture;\n#endif\n\n#ifdef RENDERER_MODE_MESH\n\tvarying vec4 v_MeshColor;\n#endif\n\nvoid main() {\n\tvec4 color = material_BaseColor * v_Color;\n\n\t#ifdef RENDERER_MODE_MESH\n\t\tcolor *= v_MeshColor;\n\t#endif\n\n\t#ifdef MATERIAL_HAS_BASETEXTURE\n\t\tcolor *= texture2DSRGB(material_BaseTexture, v_TextureCoordinate);\n\t#endif\n\t\n\t// Emissive\n\tvec3 emissiveRadiance = material_EmissiveColor;\n\t#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n\t\temissiveRadiance *= texture2DSRGB(material_EmissiveTexture, v_TextureCoordinate).rgb;\n\t#endif\n\n\tcolor.rgb += emissiveRadiance;\n\n\tgl_FragColor = color;\n}"; // eslint-disable-line
25793
+ var particleFs = "#include <common>\n\nvarying vec4 v_Color;\nvarying vec2 v_TextureCoordinate;\nuniform sampler2D material_BaseTexture;\nuniform vec4 material_BaseColor;\n \nuniform mediump vec3 material_EmissiveColor;\n#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n uniform sampler2D material_EmissiveTexture;\n#endif\n\n#ifdef RENDERER_MODE_MESH\n\tvarying vec4 v_MeshColor;\n#endif\n\nvoid main() {\n\tvec4 color = material_BaseColor * v_Color;\n\n\t#if defined(RENDERER_MODE_MESH) && defined(RENDERER_ENABLE_VERTEXCOLOR)\n\t\tcolor *= v_MeshColor;\n\t#endif\n\n\t#ifdef MATERIAL_HAS_BASETEXTURE\n\t\tcolor *= texture2DSRGB(material_BaseTexture, v_TextureCoordinate);\n\t#endif\n\t\n\t// Emissive\n\tvec3 emissiveRadiance = material_EmissiveColor;\n\t#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n\t\temissiveRadiance *= texture2DSRGB(material_EmissiveTexture, v_TextureCoordinate).rgb;\n\t#endif\n\n\tcolor.rgb += emissiveRadiance;\n\n\tgl_FragColor = color;\n}"; // eslint-disable-line
25784
25794
 
25785
- var particleVs = "#if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n attribute vec4 a_CornerTextureCoordinate;\n#endif\n\n#ifdef RENDERER_MODE_MESH\n attribute vec3 a_MeshPosition;\n attribute vec4 a_MeshColor;\n attribute vec2 a_MeshTextureCoordinate;\n varying vec4 v_MeshColor;\n#endif\n\nattribute vec4 a_ShapePositionStartLifeTime;\nattribute vec4 a_DirectionTime;\nattribute vec4 a_StartColor;\nattribute vec3 a_StartSize;\nattribute vec3 a_StartRotation0;\nattribute float a_StartSpeed;\n\n//#if defined(COLOR_OVER_LIFETIME) || defined(RENDERER_COL_RANDOM_GRADIENTS) || defined(RENDERER_SOL_RANDOM_CURVES) || defined(RENDERER_SOL_RANDOM_CURVES_SEPARATE) || defined(ROTATION_OVER_LIFE_TIME_RANDOM_CONSTANTS) || defined(ROTATION_OVER_LIFETIME_RANDOM_CURVES)\n attribute vec4 a_Random0;\n//#endif\n\n#if defined(RENDERER_TSA_FRAME_RANDOM_CURVES) || defined(RENDERER_VOL_IS_RANDOM_TWO)\n attribute vec4 a_Random1; // x:texture sheet animation random\n#endif\n\nattribute vec3 a_SimulationWorldPosition;\nattribute vec4 a_SimulationWorldRotation;\n\nvarying vec4 v_Color;\n#ifdef MATERIAL_HAS_BASETEXTURE\n attribute vec4 a_SimulationUV;\n varying vec2 v_TextureCoordinate;\n#endif\n\nuniform float renderer_CurrentTime;\nuniform vec3 renderer_Gravity;\nuniform vec2 u_DragConstant;\nuniform vec3 renderer_WorldPosition;\nuniform vec4 renderer_WorldRotation;\nuniform bool renderer_ThreeDStartRotation;\nuniform int renderer_ScalingMode;\nuniform vec3 renderer_PositionScale;\nuniform vec3 renderer_SizeScale;\nuniform vec3 renderer_PivotOffset;\n\nuniform mat4 camera_ViewMat;\nuniform mat4 camera_ProjMat;\n\n#ifdef RENDERER_MODE_STRETCHED_BILLBOARD\n uniform vec3 camera_Position;\n#endif\nuniform vec3 camera_Forward; // TODO:只有几种广告牌模式需要用\nuniform vec3 camera_Up;\n\nuniform float renderer_StretchedBillboardLengthScale;\nuniform float renderer_StretchedBillboardSpeedScale;\nuniform int renderer_SimulationSpace;\n\n#include <particle_common>\n#include <velocity_over_lifetime_module>\n#include <force_over_lifetime_module>\n#include <color_over_lifetime_module>\n#include <size_over_lifetime_module>\n#include <rotation_over_lifetime_module>\n#include <texture_sheet_animation_module>\n\nvec3 getStartPosition(vec3 startVelocity, float age, vec3 dragData) {\n vec3 startPosition;\n float lastTime = min(startVelocity.x / dragData.x, age); // todo 0/0\n startPosition = lastTime * (startVelocity - 0.5 * dragData * lastTime);\n return startPosition;\n}\n\nvec3 computeParticlePosition(in vec3 startVelocity, in float age, in float normalizedAge, vec3 gravityVelocity, vec4 worldRotation, vec3 dragData, out vec3 localVelocity, out vec3 worldVelocity) {\n vec3 startPosition = getStartPosition(startVelocity, age, dragData);\n\n vec3 finalPosition;\n vec3 localPositionOffset = startPosition;\n vec3 worldPositionOffset;\n\n #ifdef _VOL_MODULE_ENABLED\n vec3 lifeVelocity; \n vec3 velocityPositionOffset = computeVelocityPositionOffset(normalizedAge, age, lifeVelocity);\n if (renderer_VOLSpace == 0) {\n localVelocity += lifeVelocity;\n localPositionOffset += velocityPositionOffset;\n } else {\n worldVelocity += lifeVelocity;\n worldPositionOffset += velocityPositionOffset;\n }\n #endif\n\n #ifdef _FOL_MODULE_ENABLED\n vec3 forceVelocity;\n vec3 forcePositionOffset = computeForcePositionOffset(normalizedAge, age, forceVelocity);\n if (renderer_FOLSpace == 0) {\n localVelocity += forceVelocity;\n localPositionOffset += forcePositionOffset;\n } else {\n worldVelocity += forceVelocity;\n worldPositionOffset += forcePositionOffset;\n }\n #endif\n\n finalPosition = rotationByQuaternions(a_ShapePositionStartLifeTime.xyz + localPositionOffset, worldRotation) + worldPositionOffset;\n\n if (renderer_SimulationSpace == 0) {\n finalPosition = finalPosition + renderer_WorldPosition;\n } else if (renderer_SimulationSpace == 1) {\n\t finalPosition = finalPosition + a_SimulationWorldPosition;\n\t}\n\n finalPosition += 0.5 * gravityVelocity * age;\n\n return finalPosition;\n}\n\nvoid main() {\n float age = renderer_CurrentTime - a_DirectionTime.w;\n float normalizedAge = age / a_ShapePositionStartLifeTime.w;\n if (normalizedAge < 1.0) {\n vec3 startVelocity = a_DirectionTime.xyz * a_StartSpeed;\n vec3 gravityVelocity = renderer_Gravity * a_Random0.x * age;\n\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = a_SimulationWorldRotation;\n }\n\n vec3 localVelocity = startVelocity;\n vec3 worldVelocity = gravityVelocity;\n\n //drag\n vec3 dragData = a_DirectionTime.xyz * mix(u_DragConstant.x, u_DragConstant.y, a_Random0.x);\n vec3 center = computeParticlePosition(startVelocity, age, normalizedAge, gravityVelocity, worldRotation, dragData, localVelocity, worldVelocity);\n\n #include <sphere_billboard>\n #include <stretched_billboard>\n #include <horizontal_billboard>\n #include <vertical_billboard>\n #include <particle_mesh>\n\n gl_Position = camera_ProjMat * camera_ViewMat * vec4(center, 1.0);\n v_Color = computeParticleColor(a_StartColor, normalizedAge);\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n vec2 simulateUV;\n #if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n simulateUV = a_CornerTextureCoordinate.zw * a_SimulationUV.xy + a_SimulationUV.zw;\n v_TextureCoordinate = computeParticleUV(simulateUV, normalizedAge);\n #endif\n #ifdef RENDERER_MODE_MESH\n simulateUV = a_SimulationUV.xy + a_MeshTextureCoordinate * a_SimulationUV.zw;\n v_TextureCoordinate = computeParticleUV(simulateUV, normalizedAge);\n #endif\n #endif\n } else {\n\t gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Discard use out of X(-1,1),Y(-1,1),Z(0,1)\n }\n}"; // eslint-disable-line
25795
+ var particleVs = "#if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n attribute vec4 a_CornerTextureCoordinate;\n#endif\n\n#ifdef RENDERER_MODE_MESH\n attribute vec3 POSITION;\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n attribute vec4 COLOR_0;\n #endif\n attribute vec2 TEXCOORD_0;\n varying vec4 v_MeshColor;\n#endif\n\nattribute vec4 a_ShapePositionStartLifeTime;\nattribute vec4 a_DirectionTime;\nattribute vec4 a_StartColor;\nattribute vec3 a_StartSize;\nattribute vec3 a_StartRotation0;\nattribute float a_StartSpeed;\n\n//#if defined(COLOR_OVER_LIFETIME) || defined(RENDERER_COL_RANDOM_GRADIENTS) || defined(RENDERER_SOL_RANDOM_CURVES) || defined(RENDERER_SOL_RANDOM_CURVES_SEPARATE) || defined(ROTATION_OVER_LIFE_TIME_RANDOM_CONSTANTS) || defined(ROTATION_OVER_LIFETIME_RANDOM_CURVES)\n attribute vec4 a_Random0;\n//#endif\n\n#if defined(RENDERER_TSA_FRAME_RANDOM_CURVES) || defined(RENDERER_VOL_IS_RANDOM_TWO)\n attribute vec4 a_Random1; // x:texture sheet animation random\n#endif\n\nattribute vec3 a_SimulationWorldPosition;\nattribute vec4 a_SimulationWorldRotation;\n\nvarying vec4 v_Color;\n#ifdef MATERIAL_HAS_BASETEXTURE\n attribute vec4 a_SimulationUV;\n varying vec2 v_TextureCoordinate;\n#endif\n\nuniform float renderer_CurrentTime;\nuniform vec3 renderer_Gravity;\nuniform vec2 u_DragConstant;\nuniform vec3 renderer_WorldPosition;\nuniform vec4 renderer_WorldRotation;\nuniform bool renderer_ThreeDStartRotation;\nuniform int renderer_ScalingMode;\nuniform vec3 renderer_PositionScale;\nuniform vec3 renderer_SizeScale;\nuniform vec3 renderer_PivotOffset;\n\nuniform mat4 camera_ViewMat;\nuniform mat4 camera_ProjMat;\n\n#ifdef RENDERER_MODE_STRETCHED_BILLBOARD\n uniform vec3 camera_Position;\n#endif\nuniform vec3 camera_Forward; // TODO:只有几种广告牌模式需要用\nuniform vec3 camera_Up;\n\nuniform float renderer_StretchedBillboardLengthScale;\nuniform float renderer_StretchedBillboardSpeedScale;\nuniform int renderer_SimulationSpace;\n\n#include <particle_common>\n#include <velocity_over_lifetime_module>\n#include <force_over_lifetime_module>\n#include <color_over_lifetime_module>\n#include <size_over_lifetime_module>\n#include <rotation_over_lifetime_module>\n#include <texture_sheet_animation_module>\n\nvec3 getStartPosition(vec3 startVelocity, float age, vec3 dragData) {\n vec3 startPosition;\n float lastTime = min(startVelocity.x / dragData.x, age); // todo 0/0\n startPosition = lastTime * (startVelocity - 0.5 * dragData * lastTime);\n return startPosition;\n}\n\nvec3 computeParticlePosition(in vec3 startVelocity, in float age, in float normalizedAge, vec3 gravityVelocity, vec4 worldRotation, vec3 dragData, inout vec3 localVelocity, inout vec3 worldVelocity) {\n vec3 startPosition = getStartPosition(startVelocity, age, dragData);\n\n vec3 finalPosition;\n vec3 localPositionOffset = startPosition;\n vec3 worldPositionOffset;\n\n #ifdef _VOL_MODULE_ENABLED\n vec3 lifeVelocity; \n vec3 velocityPositionOffset = computeVelocityPositionOffset(normalizedAge, age, lifeVelocity);\n if (renderer_VOLSpace == 0) {\n localVelocity += lifeVelocity;\n localPositionOffset += velocityPositionOffset;\n } else {\n worldVelocity += lifeVelocity;\n worldPositionOffset += velocityPositionOffset;\n }\n #endif\n\n #ifdef _FOL_MODULE_ENABLED\n vec3 forceVelocity;\n vec3 forcePositionOffset = computeForcePositionOffset(normalizedAge, age, forceVelocity);\n if (renderer_FOLSpace == 0) {\n localVelocity += forceVelocity;\n localPositionOffset += forcePositionOffset;\n } else {\n worldVelocity += forceVelocity;\n worldPositionOffset += forcePositionOffset;\n }\n #endif\n\n finalPosition = rotationByQuaternions(a_ShapePositionStartLifeTime.xyz + localPositionOffset, worldRotation) + worldPositionOffset;\n\n if (renderer_SimulationSpace == 0) {\n finalPosition = finalPosition + renderer_WorldPosition;\n } else if (renderer_SimulationSpace == 1) {\n\t finalPosition = finalPosition + a_SimulationWorldPosition;\n\t}\n\n finalPosition += 0.5 * gravityVelocity * age;\n\n return finalPosition;\n}\n\nvoid main() {\n float age = renderer_CurrentTime - a_DirectionTime.w;\n float normalizedAge = age / a_ShapePositionStartLifeTime.w;\n if (normalizedAge < 1.0) {\n vec3 startVelocity = a_DirectionTime.xyz * a_StartSpeed;\n vec3 gravityVelocity = renderer_Gravity * a_Random0.x * age;\n\n vec4 worldRotation;\n if (renderer_SimulationSpace == 0) {\n worldRotation = renderer_WorldRotation;\n } else {\n worldRotation = a_SimulationWorldRotation;\n }\n\n vec3 localVelocity = startVelocity;\n vec3 worldVelocity = gravityVelocity;\n\n //drag\n vec3 dragData = a_DirectionTime.xyz * mix(u_DragConstant.x, u_DragConstant.y, a_Random0.x);\n vec3 center = computeParticlePosition(startVelocity, age, normalizedAge, gravityVelocity, worldRotation, dragData, localVelocity, worldVelocity);\n\n #include <sphere_billboard>\n #include <stretched_billboard>\n #include <horizontal_billboard>\n #include <vertical_billboard>\n #include <particle_mesh>\n\n gl_Position = camera_ProjMat * camera_ViewMat * vec4(center, 1.0);\n v_Color = computeParticleColor(a_StartColor, normalizedAge);\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n vec2 simulateUV;\n #if defined(RENDERER_MODE_SPHERE_BILLBOARD) || defined(RENDERER_MODE_STRETCHED_BILLBOARD) || defined(RENDERER_MODE_HORIZONTAL_BILLBOARD) || defined(RENDERER_MODE_VERTICAL_BILLBOARD)\n simulateUV = a_CornerTextureCoordinate.zw * a_SimulationUV.xy + a_SimulationUV.zw;\n v_TextureCoordinate = computeParticleUV(simulateUV, normalizedAge);\n #endif\n #ifdef RENDERER_MODE_MESH\n simulateUV = a_SimulationUV.zw + TEXCOORD_0 * a_SimulationUV.xy;\n v_TextureCoordinate = computeParticleUV(simulateUV, normalizedAge);\n #endif\n #endif\n } else {\n\t gl_Position = vec4(2.0, 2.0, 2.0, 1.0); // Discard use out of X(-1,1),Y(-1,1),Z(0,1)\n }\n}"; // eslint-disable-line
25786
25796
 
25787
25797
  var pbrSpecularFs = "#include <common>\n#include <camera_declare>\n\n#include <FogFragmentDeclaration>\n\n#include <uv_share>\n#include <normal_share>\n#include <color_share>\n#include <worldpos_share>\n\n#include <light_frag_define>\n\n\n#include <pbr_frag_define>\n#include <pbr_helper>\n\nvoid main() {\n #include <pbr_frag>\n #include <FogFragment>\n}\n"; // eslint-disable-line
25788
25798
 
@@ -32472,7 +32482,7 @@ var ParticleStopMode = /*#__PURE__*/ function(ParticleStopMode) {
32472
32482
  }
32473
32483
  generator._primitive.instanceCount = aliveParticleCount;
32474
32484
  var material = this.getMaterial();
32475
- if (!material) {
32485
+ if (!material || this._renderMode === ParticleRenderMode.Mesh && !this._mesh) {
32476
32486
  return;
32477
32487
  }
32478
32488
  if (material.destroyed || material.shader.destroyed) {
@@ -32532,7 +32542,6 @@ var ParticleStopMode = /*#__PURE__*/ function(ParticleStopMode) {
32532
32542
  var lastRenderMode = this._renderMode;
32533
32543
  this._renderMode = value;
32534
32544
  var renderModeMacro = null;
32535
- var shaderData = this.shaderData;
32536
32545
  switch(value){
32537
32546
  case ParticleRenderMode.Billboard:
32538
32547
  renderModeMacro = ParticleRenderer._billboardModeMacro;
@@ -32545,16 +32554,21 @@ var ParticleStopMode = /*#__PURE__*/ function(ParticleStopMode) {
32545
32554
  case ParticleRenderMode.VerticalBillboard:
32546
32555
  throw "Not implemented";
32547
32556
  case ParticleRenderMode.Mesh:
32548
- throw "Not implemented";
32557
+ renderModeMacro = ParticleRenderer._meshModeMacro;
32558
+ break;
32549
32559
  }
32550
32560
  if (this._currentRenderModeMacro !== renderModeMacro) {
32561
+ var shaderData = this.shaderData;
32551
32562
  this._currentRenderModeMacro && shaderData.disableMacro(this._currentRenderModeMacro);
32552
32563
  renderModeMacro && shaderData.enableMacro(renderModeMacro);
32553
32564
  this._currentRenderModeMacro = renderModeMacro;
32554
32565
  }
32555
- // @ts-ignore
32556
- if (lastRenderMode !== ParticleRenderMode.Mesh !== (value === ParticleRenderMode.Mesh)) {
32557
- this.generator._reorganizeGeometryBuffers();
32566
+ var wasMeshMode = lastRenderMode === ParticleRenderMode.Mesh;
32567
+ var isMeshMode = value === ParticleRenderMode.Mesh;
32568
+ if (wasMeshMode !== isMeshMode) {
32569
+ if (!isMeshMode || this.mesh) {
32570
+ this.generator._reorganizeGeometryBuffers();
32571
+ }
32558
32572
  }
32559
32573
  }
32560
32574
  }
@@ -32562,8 +32576,8 @@ var ParticleStopMode = /*#__PURE__*/ function(ParticleStopMode) {
32562
32576
  {
32563
32577
  key: "mesh",
32564
32578
  get: /**
32565
- * The mesh of particle.
32566
- * @remarks Valid when `renderMode` is `Mesh`.
32579
+ * The mesh shape for rendering each emitted particle.
32580
+ * @remarks Only effective when `renderMode` is `ParticleRenderMode.Mesh`.
32567
32581
  */ function get() {
32568
32582
  return this._mesh;
32569
32583
  },
@@ -32572,9 +32586,14 @@ var ParticleStopMode = /*#__PURE__*/ function(ParticleStopMode) {
32572
32586
  if (lastMesh !== value) {
32573
32587
  this._mesh = value;
32574
32588
  lastMesh && this._addResourceReferCount(lastMesh, -1);
32575
- value && this._addResourceReferCount(value, 1);
32576
- if (this.renderMode === ParticleRenderMode.Mesh) {
32577
- this.generator._reorganizeGeometryBuffers();
32589
+ if (value) {
32590
+ if (value.subMeshes.length !== 1) {
32591
+ Logger.error("Particle emit mesh must have only one sub mesh.");
32592
+ }
32593
+ this._addResourceReferCount(value, 1);
32594
+ if (this.renderMode === ParticleRenderMode.Mesh) {
32595
+ this.generator._reorganizeGeometryBuffers();
32596
+ }
32578
32597
  }
32579
32598
  }
32580
32599
  }
@@ -32586,7 +32605,7 @@ ParticleRenderer._billboardModeMacro = ShaderMacro.getByName("RENDERER_MODE_SPHE
32586
32605
  ParticleRenderer._stretchedBillboardModeMacro = ShaderMacro.getByName("RENDERER_MODE_STRETCHED_BILLBOARD");
32587
32606
  ParticleRenderer._horizontalBillboardModeMacro = ShaderMacro.getByName("RENDERER_MODE_HORIZONTAL_BILLBOARD");
32588
32607
  ParticleRenderer._verticalBillboardModeMacro = ShaderMacro.getByName("RENDERER_MODE_VERTICAL_BILLBOARD");
32589
- ParticleRenderer._renderModeMeshMacro = ShaderMacro.getByName("RENDERER_MODE_MESH");
32608
+ ParticleRenderer._meshModeMacro = ShaderMacro.getByName("RENDERER_MODE_MESH");
32590
32609
  ParticleRenderer._pivotOffsetProperty = ShaderProperty.getByName("renderer_PivotOffset");
32591
32610
  ParticleRenderer._lengthScale = ShaderProperty.getByName("renderer_StretchedBillboardLengthScale");
32592
32611
  ParticleRenderer._speedScale = ShaderProperty.getByName("renderer_StretchedBillboardSpeedScale");
@@ -33477,6 +33496,24 @@ __decorate([
33477
33496
  this._currentBurstIndex = index;
33478
33497
  };
33479
33498
  _create_class(EmissionModule, [
33499
+ {
33500
+ key: "enabled",
33501
+ get: /**
33502
+ * @inheritdoc
33503
+ */ function get() {
33504
+ return this._enabled;
33505
+ },
33506
+ set: function set(value) {
33507
+ if (value !== this._enabled) {
33508
+ this._enabled = value;
33509
+ if (value && this._shape) {
33510
+ this._generator._renderer.shaderData.enableMacro(EmissionModule._emissionShapeMacro);
33511
+ } else {
33512
+ this._generator._renderer.shaderData.disableMacro(EmissionModule._emissionShapeMacro);
33513
+ }
33514
+ }
33515
+ }
33516
+ },
33480
33517
  {
33481
33518
  key: "shape",
33482
33519
  get: /**
@@ -33490,7 +33527,12 @@ __decorate([
33490
33527
  this._shape = value;
33491
33528
  var renderer = this._generator._renderer;
33492
33529
  lastShape == null ? void 0 : lastShape._unRegisterOnValueChanged(renderer._onGeneratorParamsChanged);
33493
- value == null ? void 0 : value._registerOnValueChanged(renderer._onGeneratorParamsChanged);
33530
+ if (value) {
33531
+ value._registerOnValueChanged(renderer._onGeneratorParamsChanged);
33532
+ this.enabled && renderer.shaderData.enableMacro(EmissionModule._emissionShapeMacro);
33533
+ } else {
33534
+ renderer.shaderData.disableMacro(EmissionModule._emissionShapeMacro);
33535
+ }
33494
33536
  renderer._onGeneratorParamsChanged();
33495
33537
  }
33496
33538
  }
@@ -33506,6 +33548,7 @@ __decorate([
33506
33548
  ]);
33507
33549
  return EmissionModule;
33508
33550
  }(ParticleGeneratorModule);
33551
+ /** @internal */ EmissionModule._emissionShapeMacro = ShaderMacro.getByName("RENDERER_EMISSION_SHAPE");
33509
33552
  __decorate([
33510
33553
  deepClone
33511
33554
  ], EmissionModule.prototype, "rateOverTime", void 0);
@@ -34037,7 +34080,7 @@ __decorate([
34037
34080
  * @internal
34038
34081
  */ _proto._updateShaderData = function _updateShaderData(shaderData) {
34039
34082
  var enableSeparateMacro = null;
34040
- var isCurveMacro = null;
34083
+ var modeMacro = null;
34041
34084
  var isRandomTwoMacro = null;
34042
34085
  if (this.enabled) {
34043
34086
  var rotationX = this.rotationX;
@@ -34060,7 +34103,7 @@ __decorate([
34060
34103
  }
34061
34104
  isRandomTwoMacro = RotationOverLifetimeModule._isRandomTwoMacro;
34062
34105
  }
34063
- isCurveMacro = RotationOverLifetimeModule._curveModeMacro;
34106
+ modeMacro = RotationOverLifetimeModule._curveModeMacro;
34064
34107
  } else {
34065
34108
  var constantMax = this._rotationMaxConstant;
34066
34109
  constantMax.set(MathUtil.degreeToRadian(rotationX.constantMax), MathUtil.degreeToRadian(rotationY.constantMax), MathUtil.degreeToRadian(rotationZ.constantMax));
@@ -34071,14 +34114,14 @@ __decorate([
34071
34114
  shaderData.setVector3(RotationOverLifetimeModule._minConstantProperty, constantMin);
34072
34115
  isRandomTwoMacro = RotationOverLifetimeModule._isRandomTwoMacro;
34073
34116
  }
34074
- isCurveMacro = RotationOverLifetimeModule._constantModeMacro;
34117
+ modeMacro = RotationOverLifetimeModule._constantModeMacro;
34075
34118
  }
34076
34119
  if (separateAxes) {
34077
34120
  enableSeparateMacro = RotationOverLifetimeModule._isSeparateMacro;
34078
34121
  }
34079
34122
  }
34080
34123
  this._enableSeparateMacro = this._enableMacro(shaderData, this._enableSeparateMacro, enableSeparateMacro);
34081
- this._isCurveMacro = this._enableMacro(shaderData, this._isCurveMacro, isCurveMacro);
34124
+ this._modeMacro = this._enableMacro(shaderData, this._modeMacro, modeMacro);
34082
34125
  this._isRandomTwoMacro = this._enableMacro(shaderData, this._isRandomTwoMacro, isRandomTwoMacro);
34083
34126
  };
34084
34127
  /**
@@ -34123,7 +34166,7 @@ __decorate([
34123
34166
  ], RotationOverLifetimeModule.prototype, "_enableSeparateMacro", void 0);
34124
34167
  __decorate([
34125
34168
  ignoreClone
34126
- ], RotationOverLifetimeModule.prototype, "_isCurveMacro", void 0);
34169
+ ], RotationOverLifetimeModule.prototype, "_modeMacro", void 0);
34127
34170
  __decorate([
34128
34171
  ignoreClone
34129
34172
  ], RotationOverLifetimeModule.prototype, "_isRandomTwoMacro", void 0);
@@ -34813,25 +34856,32 @@ __decorate([
34813
34856
  /**
34814
34857
  * @internal
34815
34858
  */ _proto._emit = function _emit(playTime, count) {
34816
- if (this.emission.enabled) {
34859
+ var emission = this.emission;
34860
+ if (emission.enabled) {
34861
+ var main = this.main;
34817
34862
  // Wait the existing particles to be retired
34818
34863
  var notRetireParticleCount = this._getNotRetiredParticleCount();
34819
- if (notRetireParticleCount >= this.main.maxParticles) {
34864
+ if (notRetireParticleCount >= main.maxParticles) {
34820
34865
  return;
34821
34866
  }
34822
34867
  var position = ParticleGenerator._tempVector30;
34823
34868
  var direction = ParticleGenerator._tempVector31;
34824
34869
  var transform = this._renderer.entity.transform;
34825
- var shape = this.emission.shape;
34870
+ var shape = emission.shape;
34871
+ var positionScale = main._getPositionScale();
34826
34872
  for(var i = 0; i < count; i++){
34827
34873
  if (shape == null ? void 0 : shape.enabled) {
34828
- shape._generatePositionAndDirection(this.emission._shapeRand, playTime, position, direction);
34829
- var positionScale = this.main._getPositionScale();
34874
+ shape._generatePositionAndDirection(emission._shapeRand, playTime, position, direction);
34830
34875
  position.multiply(positionScale);
34831
34876
  direction.normalize().multiply(positionScale);
34832
34877
  } else {
34833
34878
  position.set(0, 0, 0);
34834
34879
  direction.set(0, 0, -1);
34880
+ // Speed is scaled by shape scale in world simulation space
34881
+ // So if no shape and in world simulation space, we shouldn't scale the speed
34882
+ if (main.simulationSpace === ParticleSimulationSpace.Local) {
34883
+ direction.multiply(positionScale);
34884
+ }
34835
34885
  }
34836
34886
  this._addNewParticle(position, direction, transform, playTime);
34837
34887
  }
@@ -34898,17 +34948,12 @@ __decorate([
34898
34948
  /**
34899
34949
  * @internal
34900
34950
  */ _proto._reorganizeGeometryBuffers = function _reorganizeGeometryBuffers() {
34901
- var renderer = this._renderer;
34902
- var particleUtils = renderer.engine._particleBufferUtils;
34903
- var primitive = this._primitive;
34904
- var vertexBufferBindings = this._vertexBufferBindings;
34951
+ var _this = this, renderer = _this._renderer, primitive = _this._primitive, vertexBufferBindings = _this._vertexBufferBindings;
34952
+ var _renderer_engine = renderer.engine, particleUtils = _renderer_engine._particleBufferUtils;
34905
34953
  primitive.clearVertexElements();
34906
34954
  vertexBufferBindings.length = 0;
34907
34955
  if (renderer.renderMode === ParticleRenderMode.Mesh) {
34908
34956
  var mesh = renderer.mesh;
34909
- if (!mesh) {
34910
- return;
34911
- }
34912
34957
  var positionElement = mesh.getVertexElement(VertexAttribute.Position);
34913
34958
  var colorElement = mesh.getVertexElement(VertexAttribute.Color);
34914
34959
  var uvElement = mesh.getVertexElement(VertexAttribute.UV);
@@ -34922,28 +34967,38 @@ __decorate([
34922
34967
  if (colorBufferBinding) {
34923
34968
  var index1 = this._addVertexBufferBindingsFilterDuplicate(colorBufferBinding, vertexBufferBindings);
34924
34969
  primitive.addVertexElement(new VertexElement(VertexAttribute.Color, colorElement.offset, colorElement.format, index1));
34970
+ renderer.shaderData.enableMacro(MeshRenderer._enableVertexColorMacro);
34971
+ } else {
34972
+ renderer.shaderData.disableMacro(MeshRenderer._enableVertexColorMacro);
34925
34973
  }
34926
34974
  if (uvBufferBinding) {
34927
34975
  var index2 = this._addVertexBufferBindingsFilterDuplicate(uvBufferBinding, vertexBufferBindings);
34928
34976
  primitive.addVertexElement(new VertexElement(VertexAttribute.UV, uvElement.offset, uvElement.format, index2));
34929
34977
  }
34930
- // @todo: multi subMesh or not support
34931
- var indexBufferBinding = mesh._primitive.indexBufferBinding;
34932
- primitive.setIndexBufferBinding(indexBufferBinding);
34933
- this._subPrimitive.count = indexBufferBinding.buffer.byteLength / primitive._glIndexByteCount;
34978
+ primitive.setIndexBufferBinding(mesh._primitive.indexBufferBinding);
34979
+ var subMesh = mesh.subMesh;
34980
+ var _this1 = this, subPrimitive = _this1._subPrimitive;
34981
+ subPrimitive.start = subMesh.start;
34982
+ subPrimitive.topology = subMesh.topology;
34983
+ subPrimitive.count = subMesh.count;
34934
34984
  } else {
34985
+ renderer.shaderData.disableMacro(MeshRenderer._enableVertexColorMacro);
34935
34986
  primitive.addVertexElement(particleUtils.billboardVertexElement);
34936
34987
  vertexBufferBindings.push(particleUtils.billboardVertexBufferBinding);
34937
34988
  primitive.setIndexBufferBinding(particleUtils.billboardIndexBufferBinding);
34938
34989
  this._subPrimitive.count = ParticleBufferUtils.billboardIndexCount;
34939
34990
  }
34940
- primitive.setVertexBufferBindings(vertexBufferBindings);
34941
34991
  var instanceVertexElements = particleUtils.instanceVertexElements;
34942
34992
  var bindingIndex = vertexBufferBindings.length;
34943
34993
  for(var i = 0, n = instanceVertexElements.length; i < n; i++){
34944
34994
  var element = instanceVertexElements[i];
34945
34995
  primitive.addVertexElement(new VertexElement(element.attribute, element.offset, element.format, bindingIndex, element.instanceStepRate));
34946
34996
  }
34997
+ // If instance buffer already created
34998
+ if (this._instanceVertexBufferBinding) {
34999
+ vertexBufferBindings.push(this._instanceVertexBufferBinding);
35000
+ }
35001
+ primitive.setVertexBufferBindings(vertexBufferBindings);
34947
35002
  };
34948
35003
  /**
34949
35004
  * @internal
@@ -35207,16 +35262,20 @@ __decorate([
35207
35262
  }
35208
35263
  // Start rotation
35209
35264
  var startRotationRand = main._startRotationRand, flipRotation = main.flipRotation;
35210
- var isOpposite = flipRotation < startRotationRand.random();
35265
+ var isFlip = flipRotation > startRotationRand.random();
35266
+ // @todo:None-Mesh mode should inverse the rotation, maybe should unify it
35267
+ if (this._renderer.renderMode !== ParticleRenderMode.Mesh) {
35268
+ isFlip = !isFlip;
35269
+ }
35211
35270
  var rotationZ = MathUtil.degreeToRadian(main.startRotationZ.evaluate(undefined, startRotationRand.random()));
35212
35271
  if (main.startRotation3D) {
35213
35272
  var rotationX = MathUtil.degreeToRadian(main.startRotationX.evaluate(undefined, startRotationRand.random()));
35214
35273
  var rotationY = MathUtil.degreeToRadian(main.startRotationY.evaluate(undefined, startRotationRand.random()));
35215
- instanceVertices[offset + 15] = isOpposite ? -rotationX : rotationX;
35216
- instanceVertices[offset + 16] = isOpposite ? -rotationY : rotationY;
35217
- instanceVertices[offset + 17] = isOpposite ? -rotationZ : rotationZ;
35274
+ instanceVertices[offset + 15] = isFlip ? -rotationX : rotationX;
35275
+ instanceVertices[offset + 16] = isFlip ? -rotationY : rotationY;
35276
+ instanceVertices[offset + 17] = isFlip ? -rotationZ : rotationZ;
35218
35277
  } else {
35219
- instanceVertices[offset + 15] = isOpposite ? -rotationZ : rotationZ;
35278
+ instanceVertices[offset + 15] = isFlip ? -rotationZ : rotationZ;
35220
35279
  }
35221
35280
  // Start speed
35222
35281
  instanceVertices[offset + 18] = startSpeed;
@@ -36846,22 +36905,32 @@ var cacheDir = new Vector3();
36846
36905
  }(ReferResource);
36847
36906
 
36848
36907
  /**
36849
- * @internal
36850
- * Audio Manager.
36908
+ * Audio Manager for managing global audio context and settings.
36851
36909
  */ var AudioManager = /*#__PURE__*/ function() {
36852
36910
  function AudioManager() {}
36853
- AudioManager.getContext = function getContext() {
36911
+ /**
36912
+ * Resume the audio context.
36913
+ * @remarks On iOS Safari, calling this within a user gesture (e.g., click/touch event handler) can pre-unlock audio and reduce playback delay.
36914
+ * @returns A promise that resolves when the audio context is resumed
36915
+ */ AudioManager.resume = function resume() {
36916
+ var _AudioManager;
36917
+ var __resumePromise;
36918
+ return (__resumePromise = (_AudioManager = AudioManager)._resumePromise) != null ? __resumePromise : _AudioManager._resumePromise = AudioManager._context.resume().finally(function() {
36919
+ AudioManager._resumePromise = null;
36920
+ });
36921
+ };
36922
+ /**
36923
+ * @internal
36924
+ */ AudioManager.getContext = function getContext() {
36854
36925
  var context = AudioManager._context;
36855
36926
  if (!context) {
36856
36927
  AudioManager._context = context = new window.AudioContext();
36857
- // Safari can't resume audio context without element interaction
36858
- document.addEventListener("pointerdown", AudioManager._tryResume, true);
36859
- document.addEventListener("touchend", AudioManager._tryResume, true);
36860
- document.addEventListener("touchstart", AudioManager._tryResume, true);
36861
36928
  }
36862
36929
  return context;
36863
36930
  };
36864
- AudioManager.getGainNode = function getGainNode() {
36931
+ /**
36932
+ * @internal
36933
+ */ AudioManager.getGainNode = function getGainNode() {
36865
36934
  var gainNode = AudioManager._gainNode;
36866
36935
  if (!AudioManager._gainNode) {
36867
36936
  AudioManager._gainNode = gainNode = AudioManager.getContext().createGain();
@@ -36869,27 +36938,14 @@ var cacheDir = new Vector3();
36869
36938
  }
36870
36939
  return gainNode;
36871
36940
  };
36872
- AudioManager.isAudioContextRunning = function isAudioContextRunning() {
36873
- if (AudioManager.getContext().state !== "running") {
36874
- console.warn("The AudioContext is not running and requires user interaction, such as a click or touch.");
36875
- return false;
36876
- }
36877
- return true;
36878
- };
36879
- AudioManager._tryResume = function _tryResume() {
36880
- if (AudioManager._context.state !== "running") {
36881
- if (AudioManager._isResuming) {
36882
- return;
36883
- }
36884
- AudioManager._isResuming = true;
36885
- AudioManager._context.resume().then(function() {
36886
- AudioManager._isResuming = false;
36887
- });
36888
- }
36941
+ /**
36942
+ * @internal
36943
+ */ AudioManager.isAudioContextRunning = function isAudioContextRunning() {
36944
+ return AudioManager.getContext().state === "running";
36889
36945
  };
36890
36946
  return AudioManager;
36891
36947
  }();
36892
- AudioManager._isResuming = false;
36948
+ AudioManager._resumePromise = null;
36893
36949
 
36894
36950
  /**
36895
36951
  * Audio Source Component.
@@ -36897,7 +36953,7 @@ AudioManager._isResuming = false;
36897
36953
  _inherits(AudioSource, Component);
36898
36954
  function AudioSource(entity) {
36899
36955
  var _this;
36900
- _this = Component.call(this, entity) || this, /** If set to true, the audio component automatically begins to play on startup. */ _this.playOnEnabled = true, _this._isPlaying = false, _this._sourceNode = null, _this._pausedTime = -1, _this._playTime = -1, _this._volume = 1, _this._lastVolume = 1, _this._playbackRate = 1, _this._loop = false;
36956
+ _this = Component.call(this, entity) || this, /** If set to true, the audio component automatically begins to play on startup. */ _this.playOnEnabled = true, _this._isPlaying = false, _this._pendingPlay = false, _this._sourceNode = null, _this._pausedTime = -1, _this._playTime = -1, _this._volume = 1, _this._lastVolume = 1, _this._playbackRate = 1, _this._loop = false;
36901
36957
  _this._onPlayEnd = _this._onPlayEnd.bind(_this);
36902
36958
  _this._gainNode = AudioManager.getContext().createGain();
36903
36959
  _this._gainNode.connect(AudioManager.getGainNode());
@@ -36907,21 +36963,37 @@ AudioManager._isResuming = false;
36907
36963
  /**
36908
36964
  * Play the clip.
36909
36965
  */ _proto.play = function play() {
36910
- if (!this._canPlay()) {
36966
+ var _this = this;
36967
+ var _this__clip;
36968
+ if (!((_this__clip = this._clip) == null ? void 0 : _this__clip._getAudioSource())) {
36911
36969
  return;
36912
36970
  }
36913
- if (this._isPlaying) {
36971
+ if (this._isPlaying || this._pendingPlay) {
36914
36972
  return;
36915
36973
  }
36916
- var startTime = this._pausedTime > 0 ? this._pausedTime - this._playTime : 0;
36917
- this._initSourceNode(startTime);
36918
- this._playTime = AudioManager.getContext().currentTime - startTime;
36919
- this._pausedTime = -1;
36920
- this._isPlaying = true;
36974
+ if (AudioManager.isAudioContextRunning()) {
36975
+ this._startPlayback();
36976
+ } else {
36977
+ // iOS Safari requires resume() to be called within the same user gesture callback that triggers playback.
36978
+ // Document-level events won't work - must call resume() directly here in play().
36979
+ this._pendingPlay = true;
36980
+ AudioManager.resume().then(function() {
36981
+ _this._pendingPlay = false;
36982
+ // Check if still valid to play after async resume
36983
+ if (_this._destroyed || !_this.enabled || !_this._clip) {
36984
+ return;
36985
+ }
36986
+ _this._startPlayback();
36987
+ }, function(e) {
36988
+ _this._pendingPlay = false;
36989
+ console.warn("AudioContext resume failed:", e);
36990
+ });
36991
+ }
36921
36992
  };
36922
36993
  /**
36923
36994
  * Stops playing the clip.
36924
36995
  */ _proto.stop = function stop() {
36996
+ this._pendingPlay = false;
36925
36997
  if (this._isPlaying) {
36926
36998
  this._clearSourceNode();
36927
36999
  this._isPlaying = false;
@@ -36932,6 +37004,7 @@ AudioManager._isResuming = false;
36932
37004
  /**
36933
37005
  * Pauses playing the clip.
36934
37006
  */ _proto.pause = function pause() {
37007
+ this._pendingPlay = false;
36935
37008
  if (this._isPlaying) {
36936
37009
  this._clearSourceNode();
36937
37010
  this._pausedTime = AudioManager.getContext().currentTime;
@@ -36965,6 +37038,13 @@ AudioManager._isResuming = false;
36965
37038
  _proto._onPlayEnd = function _onPlayEnd() {
36966
37039
  this.stop();
36967
37040
  };
37041
+ _proto._startPlayback = function _startPlayback() {
37042
+ var startTime = this._pausedTime > 0 ? this._pausedTime - this._playTime : 0;
37043
+ this._initSourceNode(startTime);
37044
+ this._playTime = AudioManager.getContext().currentTime - startTime;
37045
+ this._pausedTime = -1;
37046
+ this._isPlaying = true;
37047
+ };
36968
37048
  _proto._initSourceNode = function _initSourceNode(startTime) {
36969
37049
  var context = AudioManager.getContext();
36970
37050
  var sourceNode = context.createBufferSource();
@@ -36982,11 +37062,6 @@ AudioManager._isResuming = false;
36982
37062
  this._sourceNode.onended = null;
36983
37063
  this._sourceNode = null;
36984
37064
  };
36985
- _proto._canPlay = function _canPlay() {
36986
- var _this__clip;
36987
- var isValidClip = ((_this__clip = this._clip) == null ? void 0 : _this__clip._getAudioSource()) ? true : false;
36988
- return isValidClip && AudioManager.isAudioContextRunning();
36989
- };
36990
37065
  _create_class(AudioSource, [
36991
37066
  {
36992
37067
  key: "clip",
@@ -37095,6 +37170,9 @@ AudioManager._isResuming = false;
37095
37170
  __decorate([
37096
37171
  ignoreClone
37097
37172
  ], AudioSource.prototype, "_isPlaying", void 0);
37173
+ __decorate([
37174
+ ignoreClone
37175
+ ], AudioSource.prototype, "_pendingPlay", void 0);
37098
37176
  __decorate([
37099
37177
  assignmentClone
37100
37178
  ], AudioSource.prototype, "_clip", void 0);