2021-07-21 23:11:13 +08:00

32167 lines
1.6 MiB
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function (exports, Laya) {
'use strict';
class MathUtils3D {
constructor() {
}
static isZero(v) {
return Math.abs(v) < MathUtils3D.zeroTolerance;
}
static nearEqual(n1, n2) {
if (MathUtils3D.isZero(n1 - n2))
return true;
return false;
}
static fastInvSqrt(value) {
if (MathUtils3D.isZero(value))
return value;
return 1.0 / Math.sqrt(value);
}
}
MathUtils3D.zeroTolerance = 1e-6;
MathUtils3D.MaxValue = 3.40282347e+38;
MathUtils3D.MinValue = -3.40282347e+38;
MathUtils3D.Deg2Rad = Math.PI / 180;
class Vector2 {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
setValue(x, y) {
this.x = x;
this.y = y;
}
static scale(a, b, out) {
out.x = a.x * b;
out.y = a.y * b;
}
fromArray(array, offset = 0) {
this.x = array[offset + 0];
this.y = array[offset + 1];
}
toArray(array, offset = 0) {
array[offset + 0] = this.x;
array[offset + 1] = this.y;
}
cloneTo(destObject) {
var destVector2 = destObject;
destVector2.x = this.x;
destVector2.y = this.y;
}
static dot(a, b) {
return (a.x * b.x) + (a.y * b.y);
}
static normalize(s, out) {
var x = s.x, y = s.y;
var len = x * x + y * y;
if (len > 0) {
len = 1 / Math.sqrt(len);
out.x = x * len;
out.y = y * len;
}
}
static scalarLength(a) {
var x = a.x, y = a.y;
return Math.sqrt(x * x + y * y);
}
clone() {
var destVector2 = new Vector2();
this.cloneTo(destVector2);
return destVector2;
}
forNativeElement(nativeElements = null) {
if (nativeElements) {
this.elements = nativeElements;
this.elements[0] = this.x;
this.elements[1] = this.y;
}
else {
this.elements = new Float32Array([this.x, this.y]);
}
Vector2.rewriteNumProperty(this, "x", 0);
Vector2.rewriteNumProperty(this, "y", 1);
}
static rewriteNumProperty(proto, name, index) {
Object["defineProperty"](proto, name, {
"get": function () {
return this.elements[index];
},
"set": function (v) {
this.elements[index] = v;
}
});
}
}
Vector2.ZERO = new Vector2(0.0, 0.0);
Vector2.ONE = new Vector2(1.0, 1.0);
class Vector4 {
constructor(x = 0, y = 0, z = 0, w = 0) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
setValue(x, y, z, w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
fromArray(array, offset = 0) {
this.x = array[offset + 0];
this.y = array[offset + 1];
this.z = array[offset + 2];
this.w = array[offset + 3];
}
toArray(array, offset = 0) {
array[offset + 0] = this.x;
array[offset + 1] = this.y;
array[offset + 2] = this.z;
array[offset + 3] = this.w;
}
cloneTo(destObject) {
var destVector4 = destObject;
destVector4.x = this.x;
destVector4.y = this.y;
destVector4.z = this.z;
destVector4.w = this.w;
}
clone() {
var destVector4 = new Vector4();
this.cloneTo(destVector4);
return destVector4;
}
static lerp(a, b, t, out) {
var ax = a.x, ay = a.y, az = a.z, aw = a.w;
out.x = ax + t * (b.x - ax);
out.y = ay + t * (b.y - ay);
out.z = az + t * (b.z - az);
out.w = aw + t * (b.w - aw);
}
static transformByM4x4(vector4, m4x4, out) {
var vx = vector4.x;
var vy = vector4.y;
var vz = vector4.z;
var vw = vector4.w;
var me = m4x4.elements;
out.x = vx * me[0] + vy * me[4] + vz * me[8] + vw * me[12];
out.y = vx * me[1] + vy * me[5] + vz * me[9] + vw * me[13];
out.z = vx * me[2] + vy * me[6] + vz * me[10] + vw * me[14];
out.w = vx * me[3] + vy * me[7] + vz * me[11] + vw * me[15];
}
static equals(a, b) {
return MathUtils3D.nearEqual(Math.abs(a.x), Math.abs(b.x)) && MathUtils3D.nearEqual(Math.abs(a.y), Math.abs(b.y)) && MathUtils3D.nearEqual(Math.abs(a.z), Math.abs(b.z)) && MathUtils3D.nearEqual(Math.abs(a.w), Math.abs(b.w));
}
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
}
lengthSquared() {
return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
}
static normalize(s, out) {
var len = s.length();
if (len > 0) {
var inverse = 1.0 / len;
out.x = s.x * inverse;
out.y = s.y * inverse;
out.z = s.z * inverse;
out.w = s.w * inverse;
}
}
static add(a, b, out) {
out.x = a.x + b.x;
out.y = a.y + b.y;
out.z = a.z + b.z;
out.w = a.w + b.w;
}
static subtract(a, b, out) {
out.x = a.x - b.x;
out.y = a.y - b.y;
out.z = a.z - b.z;
out.w = a.w - b.w;
}
static multiply(a, b, out) {
out.x = a.x * b.x;
out.y = a.y * b.y;
out.z = a.z * b.z;
out.w = a.w * b.w;
}
static scale(a, b, out) {
out.x = a.x * b;
out.y = a.y * b;
out.z = a.z * b;
out.w = a.w * b;
}
static Clamp(value, min, max, out) {
var x = value.x;
var y = value.y;
var z = value.z;
var w = value.w;
var mineX = min.x;
var mineY = min.y;
var mineZ = min.z;
var mineW = min.w;
var maxeX = max.x;
var maxeY = max.y;
var maxeZ = max.z;
var maxeW = max.w;
x = (x > maxeX) ? maxeX : x;
x = (x < mineX) ? mineX : x;
y = (y > maxeY) ? maxeY : y;
y = (y < mineY) ? mineY : y;
z = (z > maxeZ) ? maxeZ : z;
z = (z < mineZ) ? mineZ : z;
w = (w > maxeW) ? maxeW : w;
w = (w < mineW) ? mineW : w;
out.x = x;
out.y = y;
out.z = z;
out.w = w;
}
static distanceSquared(value1, value2) {
var x = value1.x - value2.x;
var y = value1.y - value2.y;
var z = value1.z - value2.z;
var w = value1.w - value2.w;
return (x * x) + (y * y) + (z * z) + (w * w);
}
static distance(value1, value2) {
var x = value1.x - value2.x;
var y = value1.y - value2.y;
var z = value1.z - value2.z;
var w = value1.w - value2.w;
return Math.sqrt((x * x) + (y * y) + (z * z) + (w * w));
}
static dot(a, b) {
return (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
}
static min(a, b, out) {
out.x = Math.min(a.x, b.x);
out.y = Math.min(a.y, b.y);
out.z = Math.min(a.z, b.z);
out.w = Math.min(a.w, b.w);
}
static max(a, b, out) {
out.x = Math.max(a.x, b.x);
out.y = Math.max(a.y, b.y);
out.z = Math.max(a.z, b.z);
out.w = Math.max(a.w, b.w);
}
forNativeElement(nativeElements = null) {
if (nativeElements) {
this.elements = nativeElements;
this.elements[0] = this.x;
this.elements[1] = this.y;
this.elements[2] = this.z;
this.elements[3] = this.w;
}
else {
this.elements = new Float32Array([this.x, this.y, this.z, this.w]);
}
Vector2.rewriteNumProperty(this, "x", 0);
Vector2.rewriteNumProperty(this, "y", 1);
Vector2.rewriteNumProperty(this, "z", 2);
Vector2.rewriteNumProperty(this, "w", 3);
}
}
Vector4.ZERO = new Vector4();
Vector4.ONE = new Vector4(1.0, 1.0, 1.0, 1.0);
Vector4.UnitX = new Vector4(1.0, 0.0, 0.0, 0.0);
Vector4.UnitY = new Vector4(0.0, 1.0, 0.0, 0.0);
Vector4.UnitZ = new Vector4(0.0, 0.0, 1.0, 0.0);
Vector4.UnitW = new Vector4(0.0, 0.0, 0.0, 1.0);
class Vector3 {
constructor(x = 0, y = 0, z = 0) {
this.x = x;
this.y = y;
this.z = z;
}
static distanceSquared(value1, value2) {
var x = value1.x - value2.x;
var y = value1.y - value2.y;
var z = value1.z - value2.z;
return (x * x) + (y * y) + (z * z);
}
static distance(value1, value2) {
var x = value1.x - value2.x;
var y = value1.y - value2.y;
var z = value1.z - value2.z;
return Math.sqrt((x * x) + (y * y) + (z * z));
}
static min(a, b, out) {
out.x = Math.min(a.x, b.x);
out.y = Math.min(a.y, b.y);
out.z = Math.min(a.z, b.z);
}
static max(a, b, out) {
out.x = Math.max(a.x, b.x);
out.y = Math.max(a.y, b.y);
out.z = Math.max(a.z, b.z);
}
static transformQuat(source, rotation, out) {
var x = source.x, y = source.y, z = source.z, qx = rotation.x, qy = rotation.y, qz = rotation.z, qw = rotation.w, ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z;
out.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
out.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
out.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
}
static scalarLength(a) {
var x = a.x, y = a.y, z = a.z;
return Math.sqrt(x * x + y * y + z * z);
}
static scalarLengthSquared(a) {
var x = a.x, y = a.y, z = a.z;
return x * x + y * y + z * z;
}
static normalize(s, out) {
var x = s.x, y = s.y, z = s.z;
var len = x * x + y * y + z * z;
if (len > 0) {
len = 1 / Math.sqrt(len);
out.x = x * len;
out.y = y * len;
out.z = z * len;
}
}
static multiply(a, b, out) {
out.x = a.x * b.x;
out.y = a.y * b.y;
out.z = a.z * b.z;
}
static scale(a, b, out) {
out.x = a.x * b;
out.y = a.y * b;
out.z = a.z * b;
}
static lerp(a, b, t, out) {
var ax = a.x, ay = a.y, az = a.z;
out.x = ax + t * (b.x - ax);
out.y = ay + t * (b.y - ay);
out.z = az + t * (b.z - az);
}
static transformV3ToV3(vector, transform, result) {
var intermediate = Vector3._tempVector4;
Vector3.transformV3ToV4(vector, transform, intermediate);
result.x = intermediate.x;
result.y = intermediate.y;
result.z = intermediate.z;
}
static transformV3ToV4(vector, transform, result) {
var vectorX = vector.x;
var vectorY = vector.y;
var vectorZ = vector.z;
var transformElem = transform.elements;
result.x = (vectorX * transformElem[0]) + (vectorY * transformElem[4]) + (vectorZ * transformElem[8]) + transformElem[12];
result.y = (vectorX * transformElem[1]) + (vectorY * transformElem[5]) + (vectorZ * transformElem[9]) + transformElem[13];
result.z = (vectorX * transformElem[2]) + (vectorY * transformElem[6]) + (vectorZ * transformElem[10]) + transformElem[14];
result.w = (vectorX * transformElem[3]) + (vectorY * transformElem[7]) + (vectorZ * transformElem[11]) + transformElem[15];
}
static TransformNormal(normal, transform, result) {
var normalX = normal.x;
var normalY = normal.y;
var normalZ = normal.z;
var transformElem = transform.elements;
result.x = (normalX * transformElem[0]) + (normalY * transformElem[4]) + (normalZ * transformElem[8]);
result.y = (normalX * transformElem[1]) + (normalY * transformElem[5]) + (normalZ * transformElem[9]);
result.z = (normalX * transformElem[2]) + (normalY * transformElem[6]) + (normalZ * transformElem[10]);
}
static transformCoordinate(coordinate, transform, result) {
var coordinateX = coordinate.x;
var coordinateY = coordinate.y;
var coordinateZ = coordinate.z;
var transformElem = transform.elements;
var w = coordinateX * transformElem[3] + coordinateY * transformElem[7] + coordinateZ * transformElem[11] + transformElem[15];
result.x = (coordinateX * transformElem[0] + coordinateY * transformElem[4] + coordinateZ * transformElem[8] + transformElem[12]) / w;
result.y = (coordinateX * transformElem[1] + coordinateY * transformElem[5] + coordinateZ * transformElem[9] + transformElem[13]) / w;
result.z = (coordinateX * transformElem[2] + coordinateY * transformElem[6] + coordinateZ * transformElem[10] + transformElem[14]) / w;
}
static Clamp(value, min, max, out) {
var x = value.x;
var y = value.y;
var z = value.z;
var mineX = min.x;
var mineY = min.y;
var mineZ = min.z;
var maxeX = max.x;
var maxeY = max.y;
var maxeZ = max.z;
x = (x > maxeX) ? maxeX : x;
x = (x < mineX) ? mineX : x;
y = (y > maxeY) ? maxeY : y;
y = (y < mineY) ? mineY : y;
z = (z > maxeZ) ? maxeZ : z;
z = (z < mineZ) ? mineZ : z;
out.x = x;
out.y = y;
out.z = z;
}
static add(a, b, out) {
out.x = a.x + b.x;
out.y = a.y + b.y;
out.z = a.z + b.z;
}
static subtract(a, b, o) {
o.x = a.x - b.x;
o.y = a.y - b.y;
o.z = a.z - b.z;
}
static cross(a, b, o) {
var ax = a.x, ay = a.y, az = a.z, bx = b.x, by = b.y, bz = b.z;
o.x = ay * bz - az * by;
o.y = az * bx - ax * bz;
o.z = ax * by - ay * bx;
}
static dot(a, b) {
return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
}
static equals(a, b) {
return MathUtils3D.nearEqual(a.x, b.x) && MathUtils3D.nearEqual(a.y, b.y) && MathUtils3D.nearEqual(a.z, b.z);
}
setValue(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
fromArray(array, offset = 0) {
this.x = array[offset + 0];
this.y = array[offset + 1];
this.z = array[offset + 2];
}
toArray(array, offset = 0) {
array[offset + 0] = this.x;
array[offset + 1] = this.y;
array[offset + 2] = this.z;
}
cloneTo(destObject) {
var destVector3 = destObject;
destVector3.x = this.x;
destVector3.y = this.y;
destVector3.z = this.z;
}
clone() {
var destVector3 = new Vector3();
this.cloneTo(destVector3);
return destVector3;
}
toDefault() {
this.x = 0;
this.y = 0;
this.z = 0;
}
forNativeElement(nativeElements = null) {
if (nativeElements) {
this.elements = nativeElements;
this.elements[0] = this.x;
this.elements[1] = this.y;
this.elements[2] = this.z;
}
else {
this.elements = new Float32Array([this.x, this.y, this.z]);
}
Vector2.rewriteNumProperty(this, "x", 0);
Vector2.rewriteNumProperty(this, "y", 1);
Vector2.rewriteNumProperty(this, "z", 2);
}
}
Vector3._tempVector4 = new Vector4();
Vector3._ZERO = new Vector3(0.0, 0.0, 0.0);
Vector3._ONE = new Vector3(1.0, 1.0, 1.0);
Vector3._NegativeUnitX = new Vector3(-1, 0, 0);
Vector3._UnitX = new Vector3(1, 0, 0);
Vector3._UnitY = new Vector3(0, 1, 0);
Vector3._UnitZ = new Vector3(0, 0, 1);
Vector3._ForwardRH = new Vector3(0, 0, -1);
Vector3._ForwardLH = new Vector3(0, 0, 1);
Vector3._Up = new Vector3(0, 1, 0);
(function (PBRRenderQuality) {
PBRRenderQuality[PBRRenderQuality["High"] = 0] = "High";
PBRRenderQuality[PBRRenderQuality["Low"] = 1] = "Low";
})(exports.PBRRenderQuality || (exports.PBRRenderQuality = {}));
class ILaya3D {
}
ILaya3D.Shader3D = null;
ILaya3D.Scene3D = null;
ILaya3D.MeshRenderStaticBatchManager = null;
ILaya3D.MeshRenderDynamicBatchManager = null;
ILaya3D.SubMeshDynamicBatch = null;
ILaya3D.Laya3D = null;
ILaya3D.Matrix4x4 = null;
ILaya3D.Physics3D = null;
ILaya3D.ShadowLightType = null;
ILaya3D.RenderElement = null;
ILaya3D.CommandBuffer = null;
ILaya3D.Camera = null;
ILaya3D.SubMeshRenderElement = null;
class Physics3D {
static __bulletinit__() {
this._bullet = window.Physics3D;
if (this._bullet) {
Laya.StaticPlaneColliderShape.__init__();
Laya.ColliderShape.__init__();
Laya.CompoundColliderShape.__init__();
Laya.PhysicsComponent.__init__();
Laya.PhysicsSimulation.__init__();
Laya.BoxColliderShape.__init__();
Laya.CylinderColliderShape.__init__();
Laya.CharacterController.__init__();
Laya.Rigidbody3D.__init__();
}
}
static __cannoninit__() {
this._cannon = window.CANNON;
if (!this._cannon)
return;
Laya.CannonColliderShape.__init__();
Laya.CannonPhysicsComponent.__init__();
Laya.CannonPhysicsSimulation.__init__();
Laya.CannonBoxColliderShape.__init__();
Laya.CannonRigidbody3D.__init__();
}
}
Physics3D._bullet = null;
Physics3D._cannon = null;
Physics3D._enablePhysics = false;
class Config3D {
constructor() {
this._defaultPhysicsMemory = 16;
this._maxLightCount = 32;
this._lightClusterCount = new Vector3(12, 12, 12);
this._editerEnvironment = false;
this.isAntialias = true;
this.isAlpha = false;
this.premultipliedAlpha = true;
this.isStencil = true;
this.enableMultiLight = true;
this.octreeCulling = false;
this.octreeInitialSize = 64.0;
this.octreeInitialCenter = new Vector3(0, 0, 0);
this.octreeMinNodeSize = 2.0;
this.octreeLooseness = 1.25;
this.debugFrustumCulling = false;
this.pbrRenderQuality = exports.PBRRenderQuality.High;
this.isUseCannonPhysicsEngine = false;
this._maxAreaLightCountPerClusterAverage = Math.min(Math.floor(2048 / this._lightClusterCount.z - 1) * 4, this._maxLightCount);
}
static get useCannonPhysics() {
return Config3D._config.isUseCannonPhysicsEngine;
}
static set useCannonPhysics(value) {
Config3D._config.isUseCannonPhysicsEngine = value;
if (value) {
Physics3D.__cannoninit__();
if (!ILaya3D.Scene3D.cannonPhysicsSettings)
ILaya3D.Scene3D.cannonPhysicsSettings = new Laya.CannonPhysicsSettings();
}
}
static set enableDynamicManager(value) {
ILaya3D.SubMeshRenderElement.enableDynamicBatch = value;
}
static get enableDynamicManager() {
return ILaya3D.SubMeshRenderElement.enableDynamicBatch;
}
static set enableStaticManager(value) {
ILaya3D.SubMeshRenderElement.enableStaticBatch = value;
}
static get enableStaticManager() {
return ILaya3D.SubMeshRenderElement.enableStaticBatch;
}
get defaultPhysicsMemory() {
return this._defaultPhysicsMemory;
}
set defaultPhysicsMemory(value) {
if (value < 16)
throw "defaultPhysicsMemory must large than 16M";
this._defaultPhysicsMemory = value;
}
get maxLightCount() {
return this._maxLightCount;
}
set maxLightCount(value) {
if (value > 2048) {
this._maxLightCount = 2048;
console.warn("Config3D: maxLightCount must less equal 2048.");
}
else {
this._maxLightCount = value;
}
}
get lightClusterCount() {
return this._lightClusterCount;
}
set lightClusterCount(value) {
if (value.x > 128 || value.y > 128 || value.z > 128) {
this._lightClusterCount.setValue(Math.min(value.x, 128), Math.min(value.y, 128), Math.min(value.z, 128));
console.warn("Config3D: lightClusterCount X and Y、Z must less equal 128.");
}
else {
value.cloneTo(this._lightClusterCount);
}
var maxAreaLightCountWithZ = Math.floor(2048 / this._lightClusterCount.z - 1) * 4;
if (maxAreaLightCountWithZ < this._maxLightCount)
console.warn("Config3D: if the area light(PointLight、SpotLight) count is large than " + maxAreaLightCountWithZ + ",maybe the far away culster will ingonre some light.");
this._maxAreaLightCountPerClusterAverage = Math.min(maxAreaLightCountWithZ, this._maxLightCount);
}
cloneTo(dest) {
var destConfig3D = dest;
destConfig3D._defaultPhysicsMemory = this._defaultPhysicsMemory;
destConfig3D._editerEnvironment = this._editerEnvironment;
destConfig3D.isAntialias = this.isAntialias;
destConfig3D.isAlpha = this.isAlpha;
destConfig3D.premultipliedAlpha = this.premultipliedAlpha;
destConfig3D.isStencil = this.isStencil;
destConfig3D.octreeCulling = this.octreeCulling;
this.octreeInitialCenter.cloneTo(destConfig3D.octreeInitialCenter);
destConfig3D.octreeInitialSize = this.octreeInitialSize;
destConfig3D.octreeMinNodeSize = this.octreeMinNodeSize;
destConfig3D.octreeLooseness = this.octreeLooseness;
destConfig3D.debugFrustumCulling = this.debugFrustumCulling;
destConfig3D.maxLightCount = this.maxLightCount;
destConfig3D.enableMultiLight = this.enableMultiLight;
var lightClusterCount = destConfig3D.lightClusterCount;
this.lightClusterCount.cloneTo(lightClusterCount);
destConfig3D.lightClusterCount = lightClusterCount;
destConfig3D.pbrRenderQuality = this.pbrRenderQuality;
}
clone() {
var dest = new Config3D();
this.cloneTo(dest);
return dest;
}
}
Config3D._config = new Config3D();
window.Config3D = Config3D;
class KeyframeNode {
constructor() {
this._ownerPath = [];
this._propertys = [];
this._keyFrames = [];
}
get ownerPathCount() {
return this._ownerPath.length;
}
get propertyCount() {
return this._propertys.length;
}
get keyFramesCount() {
return this._keyFrames.length;
}
_setOwnerPathCount(value) {
this._ownerPath.length = value;
}
_setOwnerPathByIndex(index, value) {
this._ownerPath[index] = value;
}
_joinOwnerPath(sep) {
return this._ownerPath.join(sep);
}
_setPropertyCount(value) {
this._propertys.length = value;
}
_setPropertyByIndex(index, value) {
this._propertys[index] = value;
}
_joinProperty(sep) {
return this._propertys.join(sep);
}
_setKeyframeCount(value) {
this._keyFrames.length = value;
}
_setKeyframeByIndex(index, value) {
this._keyFrames[index] = value;
}
getOwnerPathByIndex(index) {
return this._ownerPath[index];
}
getPropertyByIndex(index) {
return this._propertys[index];
}
getKeyframeByIndex(index) {
return this._keyFrames[index];
}
}
class AnimationEvent {
constructor() {
}
}
class Keyframe {
constructor() {
}
cloneTo(destObject) {
var destKeyFrame = destObject;
destKeyFrame.time = this.time;
}
clone() {
var dest = new Keyframe();
this.cloneTo(dest);
return dest;
}
}
class FloatKeyframe extends Keyframe {
constructor() {
super();
}
cloneTo(destObject) {
super.cloneTo(destObject);
var destKeyFrame = destObject;
destKeyFrame.inTangent = this.inTangent;
destKeyFrame.outTangent = this.outTangent;
destKeyFrame.value = this.value;
}
}
class Matrix3x3 {
constructor() {
var e = this.elements = new Float32Array(9);
e[0] = 1;
e[1] = 0;
e[2] = 0;
e[3] = 0;
e[4] = 1;
e[5] = 0;
e[6] = 0;
e[7] = 0;
e[8] = 1;
}
static createRotationQuaternion(rotation, out) {
var rotX = rotation.x;
var rotY = rotation.y;
var rotZ = rotation.z;
var rotW = rotation.w;
var xx = rotX * rotX;
var yy = rotY * rotY;
var zz = rotZ * rotZ;
var xy = rotX * rotY;
var zw = rotZ * rotW;
var zx = rotZ * rotX;
var yw = rotY * rotW;
var yz = rotY * rotZ;
var xw = rotX * rotW;
var resultE = out.elements;
resultE[0] = 1.0 - (2.0 * (yy + zz));
resultE[1] = 2.0 * (xy + zw);
resultE[2] = 2.0 * (zx - yw);
resultE[3] = 2.0 * (xy - zw);
resultE[4] = 1.0 - (2.0 * (zz + xx));
resultE[5] = 2.0 * (yz + xw);
resultE[6] = 2.0 * (zx + yw);
resultE[7] = 2.0 * (yz - xw);
resultE[8] = 1.0 - (2.0 * (yy + xx));
}
static createFromTranslation(trans, out) {
var e = out.elements;
e[0] = 1;
e[1] = 0;
e[2] = 0;
e[3] = 0;
e[4] = 1;
e[5] = 0;
e[6] = trans.x;
e[7] = trans.y;
e[8] = 1;
}
static createFromRotation(rad, out) {
var e = out.elements;
var s = Math.sin(rad), c = Math.cos(rad);
e[0] = c;
e[1] = s;
e[2] = 0;
e[3] = -s;
e[4] = c;
e[5] = 0;
e[6] = 0;
e[7] = 0;
e[8] = 1;
}
static createFromScaling(scale, out) {
var e = out.elements;
e[0] = scale.x;
e[1] = 0;
e[2] = 0;
e[3] = 0;
e[4] = scale.y;
e[5] = 0;
e[6] = 0;
e[7] = 0;
e[8] = scale.z;
}
static createFromMatrix4x4(sou, out) {
var souE = sou.elements;
var outE = out.elements;
outE[0] = souE[0];
outE[1] = souE[1];
outE[2] = souE[2];
outE[3] = souE[4];
outE[4] = souE[5];
outE[5] = souE[6];
outE[6] = souE[8];
outE[7] = souE[9];
outE[8] = souE[10];
}
static multiply(left, right, out) {
var l = left.elements;
var r = right.elements;
var e = out.elements;
var l11 = l[0], l12 = l[1], l13 = l[2];
var l21 = l[3], l22 = l[4], l23 = l[5];
var l31 = l[6], l32 = l[7], l33 = l[8];
var r11 = r[0], r12 = r[1], r13 = r[2];
var r21 = r[3], r22 = r[4], r23 = r[5];
var r31 = r[6], r32 = r[7], r33 = r[8];
e[0] = r11 * l11 + r12 * l21 + r13 * l31;
e[1] = r11 * l12 + r12 * l22 + r13 * r32;
e[2] = r11 * l13 + r12 * l23 + r13 * l33;
e[3] = r21 * l11 + r22 * l21 + r23 * l31;
e[4] = r21 * l12 + r22 * l22 + r23 * l32;
e[5] = r21 * l13 + r22 * l23 + r23 * l33;
e[6] = r31 * l11 + r32 * l21 + r33 * l31;
e[7] = r31 * l12 + r32 * l22 + r33 * l32;
e[8] = r31 * l13 + r32 * l23 + r33 * l33;
}
determinant() {
var f = this.elements;
var a00 = f[0], a01 = f[1], a02 = f[2];
var a10 = f[3], a11 = f[4], a12 = f[5];
var a20 = f[6], a21 = f[7], a22 = f[8];
return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
}
translate(trans, out) {
var e = out.elements;
var f = this.elements;
var a00 = f[0], a01 = f[1], a02 = f[2];
var a10 = f[3], a11 = f[4], a12 = f[5];
var a20 = f[6], a21 = f[7], a22 = f[8];
var x = trans.x, y = trans.y;
e[0] = a00;
e[1] = a01;
e[2] = a02;
e[3] = a10;
e[4] = a11;
e[5] = a12;
e[6] = x * a00 + y * a10 + a20;
e[7] = x * a01 + y * a11 + a21;
e[8] = x * a02 + y * a12 + a22;
}
rotate(rad, out) {
var e = out.elements;
var f = this.elements;
var a00 = f[0], a01 = f[1], a02 = f[2];
var a10 = f[3], a11 = f[4], a12 = f[5];
var a20 = f[6], a21 = f[7], a22 = f[8];
var s = Math.sin(rad);
var c = Math.cos(rad);
e[0] = c * a00 + s * a10;
e[1] = c * a01 + s * a11;
e[2] = c * a02 + s * a12;
e[3] = c * a10 - s * a00;
e[4] = c * a11 - s * a01;
e[5] = c * a12 - s * a02;
e[6] = a20;
e[7] = a21;
e[8] = a22;
}
scale(scale, out) {
var e = out.elements;
var f = this.elements;
var x = scale.x, y = scale.y;
e[0] = x * f[0];
e[1] = x * f[1];
e[2] = x * f[2];
e[3] = y * f[3];
e[4] = y * f[4];
e[5] = y * f[5];
e[6] = f[6];
e[7] = f[7];
e[8] = f[8];
}
invert(out) {
var e = out.elements;
var f = this.elements;
var a00 = f[0], a01 = f[1], a02 = f[2];
var a10 = f[3], a11 = f[4], a12 = f[5];
var a20 = f[6], a21 = f[7], a22 = f[8];
var b01 = a22 * a11 - a12 * a21;
var b11 = -a22 * a10 + a12 * a20;
var b21 = a21 * a10 - a11 * a20;
var det = a00 * b01 + a01 * b11 + a02 * b21;
if (!det) {
return;
}
det = 1.0 / det;
e[0] = b01 * det;
e[1] = (-a22 * a01 + a02 * a21) * det;
e[2] = (a12 * a01 - a02 * a11) * det;
e[3] = b11 * det;
e[4] = (a22 * a00 - a02 * a20) * det;
e[5] = (-a12 * a00 + a02 * a10) * det;
e[6] = b21 * det;
e[7] = (-a21 * a00 + a01 * a20) * det;
e[8] = (a11 * a00 - a01 * a10) * det;
}
transpose(out) {
var e = out.elements;
var f = this.elements;
if (out === this) {
var a01 = f[1], a02 = f[2], a12 = f[5];
e[1] = f[3];
e[2] = f[6];
e[3] = a01;
e[5] = f[7];
e[6] = a02;
e[7] = a12;
}
else {
e[0] = f[0];
e[1] = f[3];
e[2] = f[6];
e[3] = f[1];
e[4] = f[4];
e[5] = f[7];
e[6] = f[2];
e[7] = f[5];
e[8] = f[8];
}
}
identity() {
var e = this.elements;
e[0] = 1;
e[1] = 0;
e[2] = 0;
e[3] = 0;
e[4] = 1;
e[5] = 0;
e[6] = 0;
e[7] = 0;
e[8] = 1;
}
cloneTo(destObject) {
var i, s, d;
s = this.elements;
d = destObject.elements;
if (s === d) {
return;
}
for (i = 0; i < 9; ++i) {
d[i] = s[i];
}
}
clone() {
var dest = new Matrix3x3();
this.cloneTo(dest);
return dest;
}
static lookAt(eye, target, up, out) {
Vector3.subtract(eye, target, Matrix3x3._tempV30);
Vector3.normalize(Matrix3x3._tempV30, Matrix3x3._tempV30);
Vector3.cross(up, Matrix3x3._tempV30, Matrix3x3._tempV31);
Vector3.normalize(Matrix3x3._tempV31, Matrix3x3._tempV31);
Vector3.cross(Matrix3x3._tempV30, Matrix3x3._tempV31, Matrix3x3._tempV32);
var v0 = Matrix3x3._tempV30;
var v1 = Matrix3x3._tempV31;
var v2 = Matrix3x3._tempV32;
var me = out.elements;
me[0] = v1.x;
me[3] = v1.y;
me[6] = v1.z;
me[1] = v2.x;
me[4] = v2.y;
me[7] = v2.z;
me[2] = v0.x;
me[5] = v0.y;
me[8] = v0.z;
}
}
Matrix3x3.DEFAULT = new Matrix3x3();
Matrix3x3._tempV30 = new Vector3();
Matrix3x3._tempV31 = new Vector3();
Matrix3x3._tempV32 = new Vector3();
class Quaternion {
constructor(x = 0, y = 0, z = 0, w = 1) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
static createFromYawPitchRoll(yaw, pitch, roll, out) {
var halfRoll = roll * 0.5;
var halfPitch = pitch * 0.5;
var halfYaw = yaw * 0.5;
var sinRoll = Math.sin(halfRoll);
var cosRoll = Math.cos(halfRoll);
var sinPitch = Math.sin(halfPitch);
var cosPitch = Math.cos(halfPitch);
var sinYaw = Math.sin(halfYaw);
var cosYaw = Math.cos(halfYaw);
out.x = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);
out.y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);
out.z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);
out.w = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);
}
static multiply(left, right, out) {
var lx = left.x;
var ly = left.y;
var lz = left.z;
var lw = left.w;
var rx = right.x;
var ry = right.y;
var rz = right.z;
var rw = right.w;
var a = (ly * rz - lz * ry);
var b = (lz * rx - lx * rz);
var c = (lx * ry - ly * rx);
var d = (lx * rx + ly * ry + lz * rz);
out.x = (lx * rw + rx * lw) + a;
out.y = (ly * rw + ry * lw) + b;
out.z = (lz * rw + rz * lw) + c;
out.w = lw * rw - d;
}
static arcTanAngle(x, y) {
if (x == 0) {
if (y == 1)
return Math.PI / 2;
return -Math.PI / 2;
}
if (x > 0)
return Math.atan(y / x);
if (x < 0) {
if (y > 0)
return Math.atan(y / x) + Math.PI;
return Math.atan(y / x) - Math.PI;
}
return 0;
}
static angleTo(from, location, angle) {
Vector3.subtract(location, from, Quaternion.TEMPVector30);
Vector3.normalize(Quaternion.TEMPVector30, Quaternion.TEMPVector30);
angle.x = Math.asin(Quaternion.TEMPVector30.y);
angle.y = Quaternion.arcTanAngle(-Quaternion.TEMPVector30.z, -Quaternion.TEMPVector30.x);
}
static createFromAxisAngle(axis, rad, out) {
rad = rad * 0.5;
var s = Math.sin(rad);
out.x = s * axis.x;
out.y = s * axis.y;
out.z = s * axis.z;
out.w = Math.cos(rad);
}
static createFromMatrix4x4(mat, out) {
var me = mat.elements;
var sqrt;
var half;
var scale = me[0] + me[5] + me[10];
if (scale > 0.0) {
sqrt = Math.sqrt(scale + 1.0);
out.w = sqrt * 0.5;
sqrt = 0.5 / sqrt;
out.x = (me[6] - me[9]) * sqrt;
out.y = (me[8] - me[2]) * sqrt;
out.z = (me[1] - me[4]) * sqrt;
}
else if ((me[0] >= me[5]) && (me[0] >= me[10])) {
sqrt = Math.sqrt(1.0 + me[0] - me[5] - me[10]);
half = 0.5 / sqrt;
out.x = 0.5 * sqrt;
out.y = (me[1] + me[4]) * half;
out.z = (me[2] + me[8]) * half;
out.w = (me[6] - me[9]) * half;
}
else if (me[5] > me[10]) {
sqrt = Math.sqrt(1.0 + me[5] - me[0] - me[10]);
half = 0.5 / sqrt;
out.x = (me[4] + me[1]) * half;
out.y = 0.5 * sqrt;
out.z = (me[9] + me[6]) * half;
out.w = (me[8] - me[2]) * half;
}
else {
sqrt = Math.sqrt(1.0 + me[10] - me[0] - me[5]);
half = 0.5 / sqrt;
out.x = (me[8] + me[2]) * half;
out.y = (me[9] + me[6]) * half;
out.z = 0.5 * sqrt;
out.w = (me[1] - me[4]) * half;
}
}
static slerp(left, right, t, out) {
var ax = left.x, ay = left.y, az = left.z, aw = left.w, bx = right.x, by = right.y, bz = right.z, bw = right.w;
var omega, cosom, sinom, scale0, scale1;
cosom = ax * bx + ay * by + az * bz + aw * bw;
if (cosom < 0.0) {
cosom = -cosom;
bx = -bx;
by = -by;
bz = -bz;
bw = -bw;
}
if ((1.0 - cosom) > 0.000001) {
omega = Math.acos(cosom);
sinom = Math.sin(omega);
scale0 = Math.sin((1.0 - t) * omega) / sinom;
scale1 = Math.sin(t * omega) / sinom;
}
else {
scale0 = 1.0 - t;
scale1 = t;
}
out.x = scale0 * ax + scale1 * bx;
out.y = scale0 * ay + scale1 * by;
out.z = scale0 * az + scale1 * bz;
out.w = scale0 * aw + scale1 * bw;
return out;
}
static lerp(left, right, amount, out) {
var inverse = 1.0 - amount;
if (Quaternion.dot(left, right) >= 0) {
out.x = (inverse * left.x) + (amount * right.x);
out.y = (inverse * left.y) + (amount * right.y);
out.z = (inverse * left.z) + (amount * right.z);
out.w = (inverse * left.w) + (amount * right.w);
}
else {
out.x = (inverse * left.x) - (amount * right.x);
out.y = (inverse * left.y) - (amount * right.y);
out.z = (inverse * left.z) - (amount * right.z);
out.w = (inverse * left.w) - (amount * right.w);
}
out.normalize(out);
}
static add(left, right, out) {
out.x = left.x + right.x;
out.y = left.y + right.y;
out.z = left.z + right.z;
out.w = left.w + right.w;
}
static dot(left, right) {
return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w;
}
scaling(scaling, out) {
out.x = this.x * scaling;
out.y = this.y * scaling;
out.z = this.z * scaling;
out.w = this.w * scaling;
}
normalize(out) {
var len = this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
if (len > 0) {
len = 1 / Math.sqrt(len);
out.x = this.x * len;
out.y = this.y * len;
out.z = this.z * len;
out.w = this.w * len;
}
}
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
}
rotateX(rad, out) {
rad *= 0.5;
var bx = Math.sin(rad), bw = Math.cos(rad);
out.x = this.x * bw + this.w * bx;
out.y = this.y * bw + this.z * bx;
out.z = this.z * bw - this.y * bx;
out.w = this.w * bw - this.x * bx;
}
rotateY(rad, out) {
rad *= 0.5;
var by = Math.sin(rad), bw = Math.cos(rad);
out.x = this.x * bw - this.z * by;
out.y = this.y * bw + this.w * by;
out.z = this.z * bw + this.x * by;
out.w = this.w * bw - this.y * by;
}
rotateZ(rad, out) {
rad *= 0.5;
var bz = Math.sin(rad), bw = Math.cos(rad);
out.x = this.x * bw + this.y * bz;
out.y = this.y * bw - this.x * bz;
out.z = this.z * bw + this.w * bz;
out.w = this.w * bw - this.z * bz;
}
getYawPitchRoll(out) {
Vector3.transformQuat(Vector3._ForwardRH, this, Quaternion.TEMPVector31);
Vector3.transformQuat(Vector3._Up, this, Quaternion.TEMPVector32);
var upe = Quaternion.TEMPVector32;
Quaternion.angleTo(Vector3._ZERO, Quaternion.TEMPVector31, Quaternion.TEMPVector33);
var angle = Quaternion.TEMPVector33;
if (angle.x == Math.PI / 2) {
angle.y = Quaternion.arcTanAngle(upe.z, upe.x);
angle.z = 0;
}
else if (angle.x == -Math.PI / 2) {
angle.y = Quaternion.arcTanAngle(-upe.z, -upe.x);
angle.z = 0;
}
else {
ILaya3D.Matrix4x4.createRotationY(-angle.y, ILaya3D.Matrix4x4.TEMPMatrix0);
ILaya3D.Matrix4x4.createRotationX(-angle.x, ILaya3D.Matrix4x4.TEMPMatrix1);
Vector3.transformCoordinate(Quaternion.TEMPVector32, ILaya3D.Matrix4x4.TEMPMatrix0, Quaternion.TEMPVector32);
Vector3.transformCoordinate(Quaternion.TEMPVector32, ILaya3D.Matrix4x4.TEMPMatrix1, Quaternion.TEMPVector32);
angle.z = Quaternion.arcTanAngle(upe.y, -upe.x);
}
if (angle.y <= -Math.PI)
angle.y = Math.PI;
if (angle.z <= -Math.PI)
angle.z = Math.PI;
if (angle.y >= Math.PI && angle.z >= Math.PI) {
angle.y = 0;
angle.z = 0;
angle.x = Math.PI - angle.x;
}
var oe = out;
oe.x = angle.y;
oe.y = angle.x;
oe.z = angle.z;
}
invert(out) {
var a0 = this.x, a1 = this.y, a2 = this.z, a3 = this.w;
var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
var invDot = dot ? 1.0 / dot : 0;
out.x = -a0 * invDot;
out.y = -a1 * invDot;
out.z = -a2 * invDot;
out.w = a3 * invDot;
}
identity() {
this.x = 0;
this.y = 0;
this.z = 0;
this.w = 1;
}
fromArray(array, offset = 0) {
this.x = array[offset + 0];
this.y = array[offset + 1];
this.z = array[offset + 2];
this.w = array[offset + 3];
}
cloneTo(destObject) {
if (this === destObject) {
return;
}
destObject.x = this.x;
destObject.y = this.y;
destObject.z = this.z;
destObject.w = this.w;
}
clone() {
var dest = new Quaternion();
this.cloneTo(dest);
return dest;
}
equals(b) {
return MathUtils3D.nearEqual(this.x, b.x) && MathUtils3D.nearEqual(this.y, b.y) && MathUtils3D.nearEqual(this.z, b.z) && MathUtils3D.nearEqual(this.w, b.w);
}
static rotationLookAt(forward, up, out) {
Quaternion.lookAt(Vector3._ZERO, forward, up, out);
}
static lookAt(eye, target, up, out) {
Matrix3x3.lookAt(eye, target, up, Quaternion._tempMatrix3x3);
Quaternion.rotationMatrix(Quaternion._tempMatrix3x3, out);
}
lengthSquared() {
return (this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w);
}
static invert(value, out) {
var lengthSq = value.lengthSquared();
if (!MathUtils3D.isZero(lengthSq)) {
lengthSq = 1.0 / lengthSq;
out.x = -value.x * lengthSq;
out.y = -value.y * lengthSq;
out.z = -value.z * lengthSq;
out.w = value.w * lengthSq;
}
}
static rotationMatrix(matrix3x3, out) {
var me = matrix3x3.elements;
var m11 = me[0];
var m12 = me[1];
var m13 = me[2];
var m21 = me[3];
var m22 = me[4];
var m23 = me[5];
var m31 = me[6];
var m32 = me[7];
var m33 = me[8];
var sqrt, half;
var scale = m11 + m22 + m33;
if (scale > 0) {
sqrt = Math.sqrt(scale + 1);
out.w = sqrt * 0.5;
sqrt = 0.5 / sqrt;
out.x = (m23 - m32) * sqrt;
out.y = (m31 - m13) * sqrt;
out.z = (m12 - m21) * sqrt;
}
else if ((m11 >= m22) && (m11 >= m33)) {
sqrt = Math.sqrt(1 + m11 - m22 - m33);
half = 0.5 / sqrt;
out.x = 0.5 * sqrt;
out.y = (m12 + m21) * half;
out.z = (m13 + m31) * half;
out.w = (m23 - m32) * half;
}
else if (m22 > m33) {
sqrt = Math.sqrt(1 + m22 - m11 - m33);
half = 0.5 / sqrt;
out.x = (m21 + m12) * half;
out.y = 0.5 * sqrt;
out.z = (m32 + m23) * half;
out.w = (m31 - m13) * half;
}
else {
sqrt = Math.sqrt(1 + m33 - m11 - m22);
half = 0.5 / sqrt;
out.x = (m31 + m13) * half;
out.y = (m32 + m23) * half;
out.z = 0.5 * sqrt;
out.w = (m12 - m21) * half;
}
}
forNativeElement(nativeElements = null) {
if (nativeElements) {
this.elements = nativeElements;
this.elements[0] = this.x;
this.elements[1] = this.y;
this.elements[2] = this.z;
this.elements[3] = this.w;
}
else {
this.elements = new Float32Array([this.x, this.y, this.z, this.w]);
}
Vector2.rewriteNumProperty(this, "x", 0);
Vector2.rewriteNumProperty(this, "y", 1);
Vector2.rewriteNumProperty(this, "z", 2);
Vector2.rewriteNumProperty(this, "w", 3);
}
}
Quaternion.TEMPVector30 = new Vector3();
Quaternion.TEMPVector31 = new Vector3();
Quaternion.TEMPVector32 = new Vector3();
Quaternion.TEMPVector33 = new Vector3();
Quaternion._tempMatrix3x3 = new Matrix3x3();
Quaternion.DEFAULT = new Quaternion();
Quaternion.NAN = new Quaternion(NaN, NaN, NaN, NaN);
class QuaternionKeyframe extends Keyframe {
constructor() {
super();
this.inTangent = new Vector4();
this.outTangent = new Vector4();
this.value = new Quaternion();
}
cloneTo(dest) {
super.cloneTo(dest);
var destKeyFarme = dest;
this.inTangent.cloneTo(destKeyFarme.inTangent);
this.outTangent.cloneTo(destKeyFarme.outTangent);
this.value.cloneTo(destKeyFarme.value);
}
}
class Vector3Keyframe extends Keyframe {
constructor() {
super();
this.inTangent = new Vector3();
this.outTangent = new Vector3();
this.value = new Vector3();
}
cloneTo(dest) {
super.cloneTo(dest);
var destKeyFarme = dest;
this.inTangent.cloneTo(destKeyFarme.inTangent);
this.outTangent.cloneTo(destKeyFarme.outTangent);
this.value.cloneTo(destKeyFarme.value);
}
}
class AnimationClipParser03 {
static READ_DATA() {
AnimationClipParser03._DATA.offset = AnimationClipParser03._reader.getUint32();
AnimationClipParser03._DATA.size = AnimationClipParser03._reader.getUint32();
}
static READ_BLOCK() {
var count = AnimationClipParser03._BLOCK.count = AnimationClipParser03._reader.getUint16();
var blockStarts = AnimationClipParser03._BLOCK.blockStarts = [];
var blockLengths = AnimationClipParser03._BLOCK.blockLengths = [];
for (var i = 0; i < count; i++) {
blockStarts.push(AnimationClipParser03._reader.getUint32());
blockLengths.push(AnimationClipParser03._reader.getUint32());
}
}
static READ_STRINGS() {
var offset = AnimationClipParser03._reader.getUint32();
var count = AnimationClipParser03._reader.getUint16();
var prePos = AnimationClipParser03._reader.pos;
AnimationClipParser03._reader.pos = offset + AnimationClipParser03._DATA.offset;
for (var i = 0; i < count; i++)
AnimationClipParser03._strings[i] = AnimationClipParser03._reader.readUTFString();
AnimationClipParser03._reader.pos = prePos;
}
static parse(clip, reader) {
AnimationClipParser03._animationClip = clip;
AnimationClipParser03._reader = reader;
AnimationClipParser03.READ_DATA();
AnimationClipParser03.READ_BLOCK();
AnimationClipParser03.READ_STRINGS();
for (var i = 0, n = AnimationClipParser03._BLOCK.count; i < n; i++) {
var index = reader.getUint16();
var blockName = AnimationClipParser03._strings[index];
var fn = AnimationClipParser03["READ_" + blockName];
if (fn == null)
throw new Error("model file err,no this function:" + index + " " + blockName);
else
fn.call(null);
}
}
static READ_ANIMATIONS() {
var i, j;
var node;
var reader = AnimationClipParser03._reader;
var startTimeTypes = [];
var startTimeTypeCount = reader.getUint16();
startTimeTypes.length = startTimeTypeCount;
for (i = 0; i < startTimeTypeCount; i++)
startTimeTypes[i] = reader.getFloat32();
var clip = AnimationClipParser03._animationClip;
clip.name = AnimationClipParser03._strings[reader.getUint16()];
var clipDur = clip._duration = reader.getFloat32();
clip.islooping = !!reader.getByte();
clip._frameRate = reader.getInt16();
var nodeCount = reader.getInt16();
var nodes = clip._nodes;
nodes.count = nodeCount;
var nodesMap = clip._nodesMap = {};
var nodesDic = clip._nodesDic = {};
for (i = 0; i < nodeCount; i++) {
node = new KeyframeNode();
nodes.setNodeByIndex(i, node);
node._indexInList = i;
var type = node.type = reader.getUint8();
var pathLength = reader.getUint16();
node._setOwnerPathCount(pathLength);
for (j = 0; j < pathLength; j++)
node._setOwnerPathByIndex(j, AnimationClipParser03._strings[reader.getUint16()]);
var nodePath = node._joinOwnerPath("/");
var mapArray = nodesMap[nodePath];
(mapArray) || (nodesMap[nodePath] = mapArray = []);
mapArray.push(node);
node.propertyOwner = AnimationClipParser03._strings[reader.getUint16()];
var propertyLength = reader.getUint16();
node._setPropertyCount(propertyLength);
for (j = 0; j < propertyLength; j++)
node._setPropertyByIndex(j, AnimationClipParser03._strings[reader.getUint16()]);
var fullPath = nodePath + "." + node.propertyOwner + "." + node._joinProperty(".");
nodesDic[fullPath] = node;
node.fullPath = fullPath;
var keyframeCount = reader.getUint16();
node._setKeyframeCount(keyframeCount);
for (j = 0; j < keyframeCount; j++) {
switch (type) {
case 0:
var floatKeyframe = new FloatKeyframe();
node._setKeyframeByIndex(j, floatKeyframe);
floatKeyframe.time = startTimeTypes[reader.getUint16()];
floatKeyframe.inTangent = reader.getFloat32();
floatKeyframe.outTangent = reader.getFloat32();
floatKeyframe.value = reader.getFloat32();
break;
case 1:
case 3:
case 4:
var floatArrayKeyframe = new Vector3Keyframe();
node._setKeyframeByIndex(j, floatArrayKeyframe);
floatArrayKeyframe.time = startTimeTypes[reader.getUint16()];
var inTangent = floatArrayKeyframe.inTangent;
var outTangent = floatArrayKeyframe.outTangent;
var value = floatArrayKeyframe.value;
inTangent.x = reader.getFloat32();
inTangent.y = reader.getFloat32();
inTangent.z = reader.getFloat32();
outTangent.x = reader.getFloat32();
outTangent.y = reader.getFloat32();
outTangent.z = reader.getFloat32();
value.x = reader.getFloat32();
value.y = reader.getFloat32();
value.z = reader.getFloat32();
break;
case 2:
var quaArrayKeyframe = new QuaternionKeyframe();
node._setKeyframeByIndex(j, quaArrayKeyframe);
quaArrayKeyframe.time = startTimeTypes[reader.getUint16()];
var inTangentQua = quaArrayKeyframe.inTangent;
var outTangentQua = quaArrayKeyframe.outTangent;
var valueQua = quaArrayKeyframe.value;
inTangentQua.x = reader.getFloat32();
inTangentQua.y = reader.getFloat32();
inTangentQua.z = reader.getFloat32();
inTangentQua.w = reader.getFloat32();
outTangentQua.x = reader.getFloat32();
outTangentQua.y = reader.getFloat32();
outTangentQua.z = reader.getFloat32();
outTangentQua.w = reader.getFloat32();
valueQua.x = reader.getFloat32();
valueQua.y = reader.getFloat32();
valueQua.z = reader.getFloat32();
valueQua.w = reader.getFloat32();
break;
default:
throw "AnimationClipParser03:unknown type.";
}
}
}
var eventCount = reader.getUint16();
for (i = 0; i < eventCount; i++) {
var event = new AnimationEvent();
event.time = Math.min(clipDur, reader.getFloat32());
event.eventName = AnimationClipParser03._strings[reader.getUint16()];
var params = [];
var paramCount = reader.getUint16();
(paramCount > 0) && (event.params = params = []);
for (j = 0; j < paramCount; j++) {
var eventType = reader.getByte();
switch (eventType) {
case 0:
params.push(!!reader.getByte());
break;
case 1:
params.push(reader.getInt32());
break;
case 2:
params.push(reader.getFloat32());
break;
case 3:
params.push(AnimationClipParser03._strings[reader.getUint16()]);
break;
default:
throw new Error("unknown type.");
}
}
clip.addEvent(event);
}
}
}
AnimationClipParser03._strings = [];
AnimationClipParser03._BLOCK = { count: 0 };
AnimationClipParser03._DATA = { offset: 0, size: 0 };
class AnimationClipParser04 {
static READ_DATA() {
AnimationClipParser04._DATA.offset = AnimationClipParser04._reader.getUint32();
AnimationClipParser04._DATA.size = AnimationClipParser04._reader.getUint32();
}
static READ_BLOCK() {
var count = AnimationClipParser04._BLOCK.count = AnimationClipParser04._reader.getUint16();
var blockStarts = AnimationClipParser04._BLOCK.blockStarts = [];
var blockLengths = AnimationClipParser04._BLOCK.blockLengths = [];
for (var i = 0; i < count; i++) {
blockStarts.push(AnimationClipParser04._reader.getUint32());
blockLengths.push(AnimationClipParser04._reader.getUint32());
}
}
static READ_STRINGS() {
var offset = AnimationClipParser04._reader.getUint32();
var count = AnimationClipParser04._reader.getUint16();
var prePos = AnimationClipParser04._reader.pos;
AnimationClipParser04._reader.pos = offset + AnimationClipParser04._DATA.offset;
for (var i = 0; i < count; i++)
AnimationClipParser04._strings[i] = AnimationClipParser04._reader.readUTFString();
AnimationClipParser04._reader.pos = prePos;
}
static parse(clip, reader, version) {
AnimationClipParser04._animationClip = clip;
AnimationClipParser04._reader = reader;
AnimationClipParser04._version = version;
AnimationClipParser04.READ_DATA();
AnimationClipParser04.READ_BLOCK();
AnimationClipParser04.READ_STRINGS();
for (var i = 0, n = AnimationClipParser04._BLOCK.count; i < n; i++) {
var index = reader.getUint16();
var blockName = AnimationClipParser04._strings[index];
var fn = AnimationClipParser04["READ_" + blockName];
if (fn == null)
throw new Error("model file err,no this function:" + index + " " + blockName);
else
fn.call(null);
}
AnimationClipParser04._version = null;
AnimationClipParser04._reader = null;
AnimationClipParser04._animationClip = null;
}
static READ_ANIMATIONS() {
var i, j;
var node;
var reader = AnimationClipParser04._reader;
var startTimeTypes = [];
var startTimeTypeCount = reader.getUint16();
startTimeTypes.length = startTimeTypeCount;
for (i = 0; i < startTimeTypeCount; i++)
startTimeTypes[i] = reader.getFloat32();
var clip = AnimationClipParser04._animationClip;
clip.name = AnimationClipParser04._strings[reader.getUint16()];
var clipDur = clip._duration = reader.getFloat32();
clip.islooping = !!reader.getByte();
clip._frameRate = reader.getInt16();
var nodeCount = reader.getInt16();
var nodes = clip._nodes;
nodes.count = nodeCount;
var nodesMap = clip._nodesMap = {};
var nodesDic = clip._nodesDic = {};
for (i = 0; i < nodeCount; i++) {
node = new KeyframeNode();
nodes.setNodeByIndex(i, node);
node._indexInList = i;
var type = node.type = reader.getUint8();
var pathLength = reader.getUint16();
node._setOwnerPathCount(pathLength);
for (j = 0; j < pathLength; j++)
node._setOwnerPathByIndex(j, AnimationClipParser04._strings[reader.getUint16()]);
var nodePath = node._joinOwnerPath("/");
var mapArray = nodesMap[nodePath];
(mapArray) || (nodesMap[nodePath] = mapArray = []);
mapArray.push(node);
node.propertyOwner = AnimationClipParser04._strings[reader.getUint16()];
var propertyLength = reader.getUint16();
node._setPropertyCount(propertyLength);
for (j = 0; j < propertyLength; j++)
node._setPropertyByIndex(j, AnimationClipParser04._strings[reader.getUint16()]);
var fullPath = nodePath + "." + node.propertyOwner + "." + node._joinProperty(".");
nodesDic[fullPath] = node;
node.fullPath = fullPath;
node.nodePath = nodePath;
var keyframeCount = reader.getUint16();
node._setKeyframeCount(keyframeCount);
switch (AnimationClipParser04._version) {
case "LAYAANIMATION:04":
for (j = 0; j < keyframeCount; j++) {
switch (type) {
case 0:
var floatKeyframe = new FloatKeyframe();
node._setKeyframeByIndex(j, floatKeyframe);
floatKeyframe.time = startTimeTypes[reader.getUint16()];
floatKeyframe.inTangent = reader.getFloat32();
floatKeyframe.outTangent = reader.getFloat32();
floatKeyframe.value = reader.getFloat32();
break;
case 1:
case 3:
case 4:
var floatArrayKeyframe = new Vector3Keyframe();
node._setKeyframeByIndex(j, floatArrayKeyframe);
floatArrayKeyframe.time = startTimeTypes[reader.getUint16()];
var inTangent = floatArrayKeyframe.inTangent;
var outTangent = floatArrayKeyframe.outTangent;
var value = floatArrayKeyframe.value;
inTangent.x = reader.getFloat32();
inTangent.y = reader.getFloat32();
inTangent.z = reader.getFloat32();
outTangent.x = reader.getFloat32();
outTangent.y = reader.getFloat32();
outTangent.z = reader.getFloat32();
value.x = reader.getFloat32();
value.y = reader.getFloat32();
value.z = reader.getFloat32();
break;
case 2:
var quaternionKeyframe = new QuaternionKeyframe();
node._setKeyframeByIndex(j, quaternionKeyframe);
quaternionKeyframe.time = startTimeTypes[reader.getUint16()];
var inTangentQua = quaternionKeyframe.inTangent;
var outTangentQua = quaternionKeyframe.outTangent;
var valueQua = quaternionKeyframe.value;
inTangentQua.x = reader.getFloat32();
inTangentQua.y = reader.getFloat32();
inTangentQua.z = reader.getFloat32();
inTangentQua.w = reader.getFloat32();
outTangentQua.x = reader.getFloat32();
outTangentQua.y = reader.getFloat32();
outTangentQua.z = reader.getFloat32();
outTangentQua.w = reader.getFloat32();
valueQua.x = reader.getFloat32();
valueQua.y = reader.getFloat32();
valueQua.z = reader.getFloat32();
valueQua.w = reader.getFloat32();
break;
default:
throw "AnimationClipParser04:unknown type.";
}
}
break;
case "LAYAANIMATION:COMPRESSION_04":
for (j = 0; j < keyframeCount; j++) {
switch (type) {
case 0:
floatKeyframe = new FloatKeyframe();
node._setKeyframeByIndex(j, floatKeyframe);
floatKeyframe.time = startTimeTypes[reader.getUint16()];
floatKeyframe.inTangent = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
floatKeyframe.outTangent = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
floatKeyframe.value = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
break;
case 1:
case 3:
case 4:
floatArrayKeyframe = new Vector3Keyframe();
node._setKeyframeByIndex(j, floatArrayKeyframe);
floatArrayKeyframe.time = startTimeTypes[reader.getUint16()];
inTangent = floatArrayKeyframe.inTangent;
outTangent = floatArrayKeyframe.outTangent;
value = floatArrayKeyframe.value;
inTangent.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
inTangent.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
inTangent.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
outTangent.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
outTangent.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
outTangent.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
value.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
value.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
value.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
break;
case 2:
quaternionKeyframe = new QuaternionKeyframe();
node._setKeyframeByIndex(j, quaternionKeyframe);
quaternionKeyframe.time = startTimeTypes[reader.getUint16()];
inTangentQua = quaternionKeyframe.inTangent;
outTangentQua = quaternionKeyframe.outTangent;
valueQua = quaternionKeyframe.value;
inTangentQua.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
inTangentQua.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
inTangentQua.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
inTangentQua.w = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
outTangentQua.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
outTangentQua.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
outTangentQua.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
outTangentQua.w = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
valueQua.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
valueQua.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
valueQua.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
valueQua.w = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
break;
default:
throw "AnimationClipParser04:unknown type.";
}
}
break;
}
}
var eventCount = reader.getUint16();
for (i = 0; i < eventCount; i++) {
var event = new AnimationEvent();
event.time = Math.min(clipDur, reader.getFloat32());
event.eventName = AnimationClipParser04._strings[reader.getUint16()];
var params = [];
var paramCount = reader.getUint16();
(paramCount > 0) && (event.params = params = []);
for (j = 0; j < paramCount; j++) {
var eventType = reader.getByte();
switch (eventType) {
case 0:
params.push(!!reader.getByte());
break;
case 1:
params.push(reader.getInt32());
break;
case 2:
params.push(reader.getFloat32());
break;
case 3:
params.push(AnimationClipParser04._strings[reader.getUint16()]);
break;
default:
throw new Error("unknown type.");
}
}
clip.addEvent(event);
}
}
}
AnimationClipParser04._strings = [];
AnimationClipParser04._BLOCK = { count: 0 };
AnimationClipParser04._DATA = { offset: 0, size: 0 };
class KeyframeNodeList {
constructor() {
this._nodes = [];
}
get count() {
return this._nodes.length;
}
set count(value) {
this._nodes.length = value;
}
getNodeByIndex(index) {
return this._nodes[index];
}
setNodeByIndex(index, node) {
this._nodes[index] = node;
}
}
class TextureGenerator {
constructor() {
}
static lightAttenTexture(x, y, maxX, maxY, index, data) {
var sqrRange = x / maxX;
var atten = 1.0 / (1.0 + 25.0 * sqrRange);
if (sqrRange >= 0.64) {
if (sqrRange > 1.0) {
atten = 0;
}
else {
atten *= 1 - (sqrRange - 0.64) / (1 - 0.64);
}
}
data[index] = Math.floor(atten * 255.0 + 0.5);
}
static haloTexture(x, y, maxX, maxY, index, data) {
maxX >>= 1;
maxY >>= 1;
var xFac = (x - maxX) / maxX;
var yFac = (y - maxY) / maxY;
var sqrRange = xFac * xFac + yFac * yFac;
if (sqrRange > 1.0) {
sqrRange = 1.0;
}
data[index] = Math.floor((1.0 - sqrRange) * 255.0 + 0.5);
}
static _generateTexture2D(texture, textureWidth, textureHeight, func) {
var index = 0;
var size = 0;
switch (texture.format) {
case Laya.TextureFormat.R8G8B8:
size = 3;
break;
case Laya.TextureFormat.R8G8B8A8:
size = 4;
break;
case Laya.TextureFormat.Alpha8:
size = 1;
break;
default:
throw "GeneratedTexture._generateTexture: unkonw texture format.";
}
var data = new Uint8Array(textureWidth * textureHeight * size);
for (var y = 0; y < textureHeight; y++) {
for (var x = 0; x < textureWidth; x++) {
func(x, y, textureWidth, textureHeight, index, data);
index += size;
}
}
texture.setPixels(data);
}
}
class Utils3D {
static _createFloatTextureBuffer(width, height) {
var floatTex = new Laya.Texture2D(width, height, Laya.TextureFormat.R32G32B32A32, false, false);
floatTex.filterMode = Laya.FilterMode.Point;
floatTex.wrapModeU = Laya.WarpMode.Clamp;
floatTex.wrapModeV = Laya.WarpMode.Clamp;
floatTex.anisoLevel = 0;
return floatTex;
}
static _convertToLayaVec3(bVector, out, inverseX) {
var bullet = ILaya3D.Physics3D._bullet;
out.x = inverseX ? -bullet.btVector3_x(bVector) : bullet.btVector3_x(bVector);
out.y = bullet.btVector3_y(bVector);
out.z = bullet.btVector3_z(bVector);
}
static _convertToBulletVec3(lVector, out, inverseX) {
ILaya3D.Physics3D._bullet.btVector3_setValue(out, inverseX ? -lVector.x : lVector.x, lVector.y, lVector.z);
}
static _rotationTransformScaleSkinAnimation(tx, ty, tz, qx, qy, qz, qw, sx, sy, sz, outArray, outOffset) {
var re = Utils3D._tempArray16_0;
var se = Utils3D._tempArray16_1;
var tse = Utils3D._tempArray16_2;
var x2 = qx + qx;
var y2 = qy + qy;
var z2 = qz + qz;
var xx = qx * x2;
var yx = qy * x2;
var yy = qy * y2;
var zx = qz * x2;
var zy = qz * y2;
var zz = qz * z2;
var wx = qw * x2;
var wy = qw * y2;
var wz = qw * z2;
re[15] = 1;
re[0] = 1 - yy - zz;
re[1] = yx + wz;
re[2] = zx - wy;
re[4] = yx - wz;
re[5] = 1 - xx - zz;
re[6] = zy + wx;
re[8] = zx + wy;
re[9] = zy - wx;
re[10] = 1 - xx - yy;
se[15] = 1;
se[0] = sx;
se[5] = sy;
se[10] = sz;
var i, ai0, ai1, ai2, ai3;
for (i = 0; i < 4; i++) {
ai0 = re[i];
ai1 = re[i + 4];
ai2 = re[i + 8];
ai3 = re[i + 12];
tse[i] = ai0;
tse[i + 4] = ai1;
tse[i + 8] = ai2;
tse[i + 12] = ai0 * tx + ai1 * ty + ai2 * tz + ai3;
}
for (i = 0; i < 4; i++) {
ai0 = tse[i];
ai1 = tse[i + 4];
ai2 = tse[i + 8];
ai3 = tse[i + 12];
outArray[i + outOffset] = ai0 * se[0] + ai1 * se[1] + ai2 * se[2] + ai3 * se[3];
outArray[i + outOffset + 4] = ai0 * se[4] + ai1 * se[5] + ai2 * se[6] + ai3 * se[7];
outArray[i + outOffset + 8] = ai0 * se[8] + ai1 * se[9] + ai2 * se[10] + ai3 * se[11];
outArray[i + outOffset + 12] = ai0 * se[12] + ai1 * se[13] + ai2 * se[14] + ai3 * se[15];
}
}
static _computeBoneAndAnimationDatasByBindPoseMatrxix(bones, curData, inverGlobalBindPose, outBonesDatas, outAnimationDatas, boneIndexToMesh) {
var offset = 0;
var matOffset = 0;
var i;
var parentOffset;
var boneLength = bones.length;
for (i = 0; i < boneLength; offset += bones[i].keyframeWidth, matOffset += 16, i++) {
Utils3D._rotationTransformScaleSkinAnimation(curData[offset + 0], curData[offset + 1], curData[offset + 2], curData[offset + 3], curData[offset + 4], curData[offset + 5], curData[offset + 6], curData[offset + 7], curData[offset + 8], curData[offset + 9], outBonesDatas, matOffset);
if (i != 0) {
parentOffset = bones[i].parentIndex * 16;
Utils3D.mulMatrixByArray(outBonesDatas, parentOffset, outBonesDatas, matOffset, outBonesDatas, matOffset);
}
}
var n = inverGlobalBindPose.length;
for (i = 0; i < n; i++) {
Utils3D.mulMatrixByArrayAndMatrixFast(outBonesDatas, boneIndexToMesh[i] * 16, inverGlobalBindPose[i], outAnimationDatas, i * 16);
}
}
static _computeAnimationDatasByArrayAndMatrixFast(inverGlobalBindPose, bonesDatas, outAnimationDatas, boneIndexToMesh) {
for (var i = 0, n = inverGlobalBindPose.length; i < n; i++)
Utils3D.mulMatrixByArrayAndMatrixFast(bonesDatas, boneIndexToMesh[i] * 16, inverGlobalBindPose[i], outAnimationDatas, i * 16);
}
static _computeBoneAndAnimationDatasByBindPoseMatrxixOld(bones, curData, inverGlobalBindPose, outBonesDatas, outAnimationDatas) {
var offset = 0;
var matOffset = 0;
var i;
var parentOffset;
var boneLength = bones.length;
for (i = 0; i < boneLength; offset += bones[i].keyframeWidth, matOffset += 16, i++) {
Utils3D._rotationTransformScaleSkinAnimation(curData[offset + 7], curData[offset + 8], curData[offset + 9], curData[offset + 3], curData[offset + 4], curData[offset + 5], curData[offset + 6], curData[offset + 0], curData[offset + 1], curData[offset + 2], outBonesDatas, matOffset);
if (i != 0) {
parentOffset = bones[i].parentIndex * 16;
Utils3D.mulMatrixByArray(outBonesDatas, parentOffset, outBonesDatas, matOffset, outBonesDatas, matOffset);
}
}
var n = inverGlobalBindPose.length;
for (i = 0; i < n; i++) {
var arrayOffset = i * 16;
Utils3D.mulMatrixByArrayAndMatrixFast(outBonesDatas, arrayOffset, inverGlobalBindPose[i], outAnimationDatas, arrayOffset);
}
}
static _computeAnimationDatasByArrayAndMatrixFastOld(inverGlobalBindPose, bonesDatas, outAnimationDatas) {
var n = inverGlobalBindPose.length;
for (var i = 0; i < n; i++) {
var arrayOffset = i * 16;
Utils3D.mulMatrixByArrayAndMatrixFast(bonesDatas, arrayOffset, inverGlobalBindPose[i], outAnimationDatas, arrayOffset);
}
}
static _computeRootAnimationData(bones, curData, animationDatas) {
for (var i = 0, offset = 0, matOffset = 0, boneLength = bones.length; i < boneLength; offset += bones[i].keyframeWidth, matOffset += 16, i++)
Utils3D.createAffineTransformationArray(curData[offset + 0], curData[offset + 1], curData[offset + 2], curData[offset + 3], curData[offset + 4], curData[offset + 5], curData[offset + 6], curData[offset + 7], curData[offset + 8], curData[offset + 9], animationDatas, matOffset);
}
static transformVector3ArrayByQuat(sourceArray, sourceOffset, rotation, outArray, outOffset) {
var x = sourceArray[sourceOffset], y = sourceArray[sourceOffset + 1], z = sourceArray[sourceOffset + 2], qx = rotation.x, qy = rotation.y, qz = rotation.z, qw = rotation.w, ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z;
outArray[outOffset] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
outArray[outOffset + 1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
outArray[outOffset + 2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
}
static mulMatrixByArray(leftArray, leftOffset, rightArray, rightOffset, outArray, outOffset) {
var i, ai0, ai1, ai2, ai3;
if (outArray === rightArray) {
rightArray = Utils3D._tempArray16_3;
for (i = 0; i < 16; ++i) {
rightArray[i] = outArray[outOffset + i];
}
rightOffset = 0;
}
for (i = 0; i < 4; i++) {
ai0 = leftArray[leftOffset + i];
ai1 = leftArray[leftOffset + i + 4];
ai2 = leftArray[leftOffset + i + 8];
ai3 = leftArray[leftOffset + i + 12];
outArray[outOffset + i] = ai0 * rightArray[rightOffset + 0] + ai1 * rightArray[rightOffset + 1] + ai2 * rightArray[rightOffset + 2] + ai3 * rightArray[rightOffset + 3];
outArray[outOffset + i + 4] = ai0 * rightArray[rightOffset + 4] + ai1 * rightArray[rightOffset + 5] + ai2 * rightArray[rightOffset + 6] + ai3 * rightArray[rightOffset + 7];
outArray[outOffset + i + 8] = ai0 * rightArray[rightOffset + 8] + ai1 * rightArray[rightOffset + 9] + ai2 * rightArray[rightOffset + 10] + ai3 * rightArray[rightOffset + 11];
outArray[outOffset + i + 12] = ai0 * rightArray[rightOffset + 12] + ai1 * rightArray[rightOffset + 13] + ai2 * rightArray[rightOffset + 14] + ai3 * rightArray[rightOffset + 15];
}
}
static mulMatrixByArrayFast(leftArray, leftOffset, rightArray, rightOffset, outArray, outOffset) {
var i, ai0, ai1, ai2, ai3;
for (i = 0; i < 4; i++) {
ai0 = leftArray[leftOffset + i];
ai1 = leftArray[leftOffset + i + 4];
ai2 = leftArray[leftOffset + i + 8];
ai3 = leftArray[leftOffset + i + 12];
outArray[outOffset + i] = ai0 * rightArray[rightOffset + 0] + ai1 * rightArray[rightOffset + 1] + ai2 * rightArray[rightOffset + 2] + ai3 * rightArray[rightOffset + 3];
outArray[outOffset + i + 4] = ai0 * rightArray[rightOffset + 4] + ai1 * rightArray[rightOffset + 5] + ai2 * rightArray[rightOffset + 6] + ai3 * rightArray[rightOffset + 7];
outArray[outOffset + i + 8] = ai0 * rightArray[rightOffset + 8] + ai1 * rightArray[rightOffset + 9] + ai2 * rightArray[rightOffset + 10] + ai3 * rightArray[rightOffset + 11];
outArray[outOffset + i + 12] = ai0 * rightArray[rightOffset + 12] + ai1 * rightArray[rightOffset + 13] + ai2 * rightArray[rightOffset + 14] + ai3 * rightArray[rightOffset + 15];
}
}
static mulMatrixByArrayAndMatrixFast(leftArray, leftOffset, rightMatrix, outArray, outOffset) {
var i, ai0, ai1, ai2, ai3;
var rightMatrixE = rightMatrix.elements;
var m11 = rightMatrixE[0], m12 = rightMatrixE[1], m13 = rightMatrixE[2], m14 = rightMatrixE[3];
var m21 = rightMatrixE[4], m22 = rightMatrixE[5], m23 = rightMatrixE[6], m24 = rightMatrixE[7];
var m31 = rightMatrixE[8], m32 = rightMatrixE[9], m33 = rightMatrixE[10], m34 = rightMatrixE[11];
var m41 = rightMatrixE[12], m42 = rightMatrixE[13], m43 = rightMatrixE[14], m44 = rightMatrixE[15];
var ai0LeftOffset = leftOffset;
var ai1LeftOffset = leftOffset + 4;
var ai2LeftOffset = leftOffset + 8;
var ai3LeftOffset = leftOffset + 12;
var ai0OutOffset = outOffset;
var ai1OutOffset = outOffset + 4;
var ai2OutOffset = outOffset + 8;
var ai3OutOffset = outOffset + 12;
for (i = 0; i < 4; i++) {
ai0 = leftArray[ai0LeftOffset + i];
ai1 = leftArray[ai1LeftOffset + i];
ai2 = leftArray[ai2LeftOffset + i];
ai3 = leftArray[ai3LeftOffset + i];
outArray[ai0OutOffset + i] = ai0 * m11 + ai1 * m12 + ai2 * m13 + ai3 * m14;
outArray[ai1OutOffset + i] = ai0 * m21 + ai1 * m22 + ai2 * m23 + ai3 * m24;
outArray[ai2OutOffset + i] = ai0 * m31 + ai1 * m32 + ai2 * m33 + ai3 * m34;
outArray[ai3OutOffset + i] = ai0 * m41 + ai1 * m42 + ai2 * m43 + ai3 * m44;
}
}
static createAffineTransformationArray(tX, tY, tZ, rX, rY, rZ, rW, sX, sY, sZ, outArray, outOffset) {
var x2 = rX + rX, y2 = rY + rY, z2 = rZ + rZ;
var xx = rX * x2, xy = rX * y2, xz = rX * z2, yy = rY * y2, yz = rY * z2, zz = rZ * z2;
var wx = rW * x2, wy = rW * y2, wz = rW * z2;
outArray[outOffset + 0] = (1 - (yy + zz)) * sX;
outArray[outOffset + 1] = (xy + wz) * sX;
outArray[outOffset + 2] = (xz - wy) * sX;
outArray[outOffset + 3] = 0;
outArray[outOffset + 4] = (xy - wz) * sY;
outArray[outOffset + 5] = (1 - (xx + zz)) * sY;
outArray[outOffset + 6] = (yz + wx) * sY;
outArray[outOffset + 7] = 0;
outArray[outOffset + 8] = (xz + wy) * sZ;
outArray[outOffset + 9] = (yz - wx) * sZ;
outArray[outOffset + 10] = (1 - (xx + yy)) * sZ;
outArray[outOffset + 11] = 0;
outArray[outOffset + 12] = tX;
outArray[outOffset + 13] = tY;
outArray[outOffset + 14] = tZ;
outArray[outOffset + 15] = 1;
}
static transformVector3ArrayToVector3ArrayCoordinate(source, sourceOffset, transform, result, resultOffset) {
var coordinateX = source[sourceOffset + 0];
var coordinateY = source[sourceOffset + 1];
var coordinateZ = source[sourceOffset + 2];
var transformElem = transform.elements;
var w = ((coordinateX * transformElem[3]) + (coordinateY * transformElem[7]) + (coordinateZ * transformElem[11]) + transformElem[15]);
result[resultOffset] = (coordinateX * transformElem[0]) + (coordinateY * transformElem[4]) + (coordinateZ * transformElem[8]) + transformElem[12] / w;
result[resultOffset + 1] = (coordinateX * transformElem[1]) + (coordinateY * transformElem[5]) + (coordinateZ * transformElem[9]) + transformElem[13] / w;
result[resultOffset + 2] = (coordinateX * transformElem[2]) + (coordinateY * transformElem[6]) + (coordinateZ * transformElem[10]) + transformElem[14] / w;
}
static transformVector3ArrayToVector3ArrayNormal(source, sourceOffset, transform, result, resultOffset) {
var coordinateX = source[sourceOffset + 0];
var coordinateY = source[sourceOffset + 1];
var coordinateZ = source[sourceOffset + 2];
var transformElem = transform.elements;
result[resultOffset] = coordinateX * transformElem[0] + coordinateY * transformElem[4] + coordinateZ * transformElem[8];
result[resultOffset + 1] = coordinateX * transformElem[1] + coordinateY * transformElem[5] + coordinateZ * transformElem[9];
result[resultOffset + 2] = coordinateX * transformElem[2] + coordinateY * transformElem[6] + coordinateZ * transformElem[10];
}
static transformLightingMapTexcoordArray(source, sourceOffset, lightingMapScaleOffset, result, resultOffset) {
result[resultOffset + 0] = source[sourceOffset + 0] * lightingMapScaleOffset.x + lightingMapScaleOffset.z;
result[resultOffset + 1] = 1.0 - ((1.0 - source[sourceOffset + 1]) * lightingMapScaleOffset.y + lightingMapScaleOffset.w);
}
static getURLVerion(url) {
var index = url.indexOf("?");
return index >= 0 ? url.substr(index) : null;
}
static _createAffineTransformationArray(trans, rot, scale, outE) {
var x = rot.x, y = rot.y, z = rot.z, w = rot.w, x2 = x + x, y2 = y + y, z2 = z + z;
var xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2;
var wx = w * x2, wy = w * y2, wz = w * z2, sx = scale.x, sy = scale.y, sz = scale.z;
outE[0] = (1 - (yy + zz)) * sx;
outE[1] = (xy + wz) * sx;
outE[2] = (xz - wy) * sx;
outE[3] = 0;
outE[4] = (xy - wz) * sy;
outE[5] = (1 - (xx + zz)) * sy;
outE[6] = (yz + wx) * sy;
outE[7] = 0;
outE[8] = (xz + wy) * sz;
outE[9] = (yz - wx) * sz;
outE[10] = (1 - (xx + yy)) * sz;
outE[11] = 0;
outE[12] = trans.x;
outE[13] = trans.y;
outE[14] = trans.z;
outE[15] = 1;
}
static _mulMatrixArray(left, right, rightOffset, outArray, outOffset) {
var l = right;
var r = left;
var e = outArray;
var l11 = l[rightOffset], l12 = l[rightOffset + 1], l13 = l[rightOffset + 2], l14 = l[rightOffset + 3];
var l21 = l[rightOffset + 4], l22 = l[rightOffset + 5], l23 = l[rightOffset + 6], l24 = l[rightOffset + 7];
var l31 = l[rightOffset + 8], l32 = l[rightOffset + 9], l33 = l[rightOffset + 10], l34 = l[rightOffset + 11];
var l41 = l[rightOffset + 12], l42 = l[rightOffset + 13], l43 = l[rightOffset + 14], l44 = l[rightOffset + 15];
var r11 = r[0], r12 = r[1], r13 = r[2], r14 = r[3];
var r21 = r[4], r22 = r[5], r23 = r[6], r24 = r[7];
var r31 = r[8], r32 = r[9], r33 = r[10], r34 = r[11];
var r41 = r[12], r42 = r[13], r43 = r[14], r44 = r[15];
e[outOffset] = (l11 * r11) + (l12 * r21) + (l13 * r31) + (l14 * r41);
e[outOffset + 1] = (l11 * r12) + (l12 * r22) + (l13 * r32) + (l14 * r42);
e[outOffset + 2] = (l11 * r13) + (l12 * r23) + (l13 * r33) + (l14 * r43);
e[outOffset + 3] = (l11 * r14) + (l12 * r24) + (l13 * r34) + (l14 * r44);
e[outOffset + 4] = (l21 * r11) + (l22 * r21) + (l23 * r31) + (l24 * r41);
e[outOffset + 5] = (l21 * r12) + (l22 * r22) + (l23 * r32) + (l24 * r42);
e[outOffset + 6] = (l21 * r13) + (l22 * r23) + (l23 * r33) + (l24 * r43);
e[outOffset + 7] = (l21 * r14) + (l22 * r24) + (l23 * r34) + (l24 * r44);
e[outOffset + 8] = (l31 * r11) + (l32 * r21) + (l33 * r31) + (l34 * r41);
e[outOffset + 9] = (l31 * r12) + (l32 * r22) + (l33 * r32) + (l34 * r42);
e[outOffset + 10] = (l31 * r13) + (l32 * r23) + (l33 * r33) + (l34 * r43);
e[outOffset + 11] = (l31 * r14) + (l32 * r24) + (l33 * r34) + (l34 * r44);
e[outOffset + 12] = (l41 * r11) + (l42 * r21) + (l43 * r31) + (l44 * r41);
e[outOffset + 13] = (l41 * r12) + (l42 * r22) + (l43 * r32) + (l44 * r42);
e[outOffset + 14] = (l41 * r13) + (l42 * r23) + (l43 * r33) + (l44 * r43);
e[outOffset + 15] = (l41 * r14) + (l42 * r24) + (l43 * r34) + (l44 * r44);
}
static arcTanAngle(x, y) {
if (x == 0) {
if (y == 1)
return Math.PI / 2;
return -Math.PI / 2;
}
if (x > 0)
return Math.atan(y / x);
if (x < 0) {
if (y > 0)
return Math.atan(y / x) + Math.PI;
return Math.atan(y / x) - Math.PI;
}
return 0;
}
static angleTo(from, location, angle) {
Vector3.subtract(location, from, Quaternion.TEMPVector30);
Vector3.normalize(Quaternion.TEMPVector30, Quaternion.TEMPVector30);
angle.x = Math.asin(Quaternion.TEMPVector30.y);
angle.y = Utils3D.arcTanAngle(-Quaternion.TEMPVector30.z, -Quaternion.TEMPVector30.x);
}
static transformQuat(source, rotation, out) {
var re = rotation;
var x = source.x, y = source.y, z = source.z, qx = re[0], qy = re[1], qz = re[2], qw = re[3], ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z;
out.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
out.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
out.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
}
static quaternionWeight(f, weight, e) {
e.x = f.x * weight;
e.y = f.y * weight;
e.z = f.z * weight;
e.w = f.w;
}
static quaternionConjugate(value, result) {
result.x = -value.x;
result.y = -value.y;
result.z = -value.z;
result.w = value.w;
}
static scaleWeight(s, w, out) {
var sX = s.x, sY = s.y, sZ = s.z;
out.x = sX > 0 ? Math.pow(Math.abs(sX), w) : -Math.pow(Math.abs(sX), w);
out.y = sY > 0 ? Math.pow(Math.abs(sY), w) : -Math.pow(Math.abs(sY), w);
out.z = sZ > 0 ? Math.pow(Math.abs(sZ), w) : -Math.pow(Math.abs(sZ), w);
}
static scaleBlend(sa, sb, w, out) {
var saw = Utils3D._tempVector3_0;
var sbw = Utils3D._tempVector3_1;
Utils3D.scaleWeight(sa, 1.0 - w, saw);
Utils3D.scaleWeight(sb, w, sbw);
var sng = w > 0.5 ? sb : sa;
out.x = sng.x > 0 ? Math.abs(saw.x * sbw.x) : -Math.abs(saw.x * sbw.x);
out.y = sng.y > 0 ? Math.abs(saw.y * sbw.y) : -Math.abs(saw.y * sbw.y);
out.z = sng.z > 0 ? Math.abs(saw.z * sbw.z) : -Math.abs(saw.z * sbw.z);
}
static matrix4x4MultiplyFFF(a, b, e) {
var i, ai0, ai1, ai2, ai3;
if (e === b) {
b = new Float32Array(16);
for (i = 0; i < 16; ++i) {
b[i] = e[i];
}
}
var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
var b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7];
var b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11];
var b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
for (i = 0; i < 4; i++) {
ai0 = a[i];
ai1 = a[i + 4];
ai2 = a[i + 8];
ai3 = a[i + 12];
e[i] = ai0 * b0 + ai1 * b1 + ai2 * b2 + ai3 * b3;
e[i + 4] = ai0 * b4 + ai1 * b5 + ai2 * b6 + ai3 * b7;
e[i + 8] = ai0 * b8 + ai1 * b9 + ai2 * b10 + ai3 * b11;
e[i + 12] = ai0 * b12 + ai1 * b13 + ai2 * b14 + ai3 * b15;
}
}
static matrix4x4MultiplyFFFForNative(a, b, e) {
Laya.LayaGL.instance.matrix4x4Multiply(a, b, e);
}
static matrix4x4MultiplyMFM(left, right, out) {
Utils3D.matrix4x4MultiplyFFF(left.elements, right, out.elements);
}
static _buildTexture2D(width, height, format, colorFunc, mipmaps = false) {
var texture = new Laya.Texture2D(width, height, format, mipmaps, true);
texture.anisoLevel = 1;
texture.filterMode = Laya.FilterMode.Point;
TextureGenerator._generateTexture2D(texture, width, height, colorFunc);
return texture;
}
static _drawBound(debugLine, boundBox, color) {
if (debugLine.lineCount + 12 > debugLine.maxLineCount)
debugLine.maxLineCount += 12;
var start = Utils3D._tempVector3_0;
var end = Utils3D._tempVector3_1;
var min = boundBox.min;
var max = boundBox.max;
start.setValue(min.x, min.y, min.z);
end.setValue(max.x, min.y, min.z);
debugLine.addLine(start, end, color, color);
start.setValue(min.x, min.y, min.z);
end.setValue(min.x, min.y, max.z);
debugLine.addLine(start, end, color, color);
start.setValue(max.x, min.y, min.z);
end.setValue(max.x, min.y, max.z);
debugLine.addLine(start, end, color, color);
start.setValue(min.x, min.y, max.z);
end.setValue(max.x, min.y, max.z);
debugLine.addLine(start, end, color, color);
start.setValue(min.x, min.y, min.z);
end.setValue(min.x, max.y, min.z);
debugLine.addLine(start, end, color, color);
start.setValue(min.x, min.y, max.z);
end.setValue(min.x, max.y, max.z);
debugLine.addLine(start, end, color, color);
start.setValue(max.x, min.y, min.z);
end.setValue(max.x, max.y, min.z);
debugLine.addLine(start, end, color, color);
start.setValue(max.x, min.y, max.z);
end.setValue(max.x, max.y, max.z);
debugLine.addLine(start, end, color, color);
start.setValue(min.x, max.y, min.z);
end.setValue(max.x, max.y, min.z);
debugLine.addLine(start, end, color, color);
start.setValue(min.x, max.y, min.z);
end.setValue(min.x, max.y, max.z);
debugLine.addLine(start, end, color, color);
start.setValue(max.x, max.y, min.z);
end.setValue(max.x, max.y, max.z);
debugLine.addLine(start, end, color, color);
start.setValue(min.x, max.y, max.z);
end.setValue(max.x, max.y, max.z);
debugLine.addLine(start, end, color, color);
}
static _getHierarchyPath(rootSprite, checkSprite, path) {
path.length = 0;
var sprite = checkSprite;
while (sprite !== rootSprite) {
var parent = sprite._parent;
if (parent)
path.push(parent.getChildIndex(sprite));
else
return null;
sprite = parent;
}
return path;
}
static _getNodeByHierarchyPath(rootSprite, invPath) {
var sprite = rootSprite;
for (var i = invPath.length - 1; i >= 0; i--) {
sprite = sprite.getChildAt(invPath[i]);
}
return sprite;
}
static uint8ArrayToArrayBuffer(rendertexture) {
let pixelArray;
let width = rendertexture.width;
let height = rendertexture.height;
switch (rendertexture.format) {
case Laya.RenderTextureFormat.R8G8B8:
pixelArray = new Uint8Array(width * height * 4);
break;
case Laya.RenderTextureFormat.R8G8B8A8:
pixelArray = new Uint8Array(width * height * 4);
break;
case Laya.RenderTextureFormat.R16G16B16A16:
pixelArray = new Float32Array(width * height * 4);
break;
default:
throw "this function is not surpprt " + rendertexture.format.toString() + "format Material";
}
rendertexture.getData(0, 0, rendertexture.width, rendertexture.height, pixelArray);
switch (rendertexture.format) {
case Laya.RenderTextureFormat.R16G16B16A16:
let ori = pixelArray;
let trans = new Uint8Array(width * height * 4);
for (let i = 0, n = ori.length; i < n; i++) {
trans[i] = Math.min(Math.floor(ori[i] * 255), 255);
}
pixelArray = trans;
break;
}
let pixels = pixelArray;
var bs;
if (Laya.Render.isConchApp) ;
else {
var canv = new Laya.HTMLCanvas(true);
canv.lock = true;
canv.size(width, height);
var ctx2d = canv.getContext('2d');
var imgdata = ctx2d.createImageData(width, height);
imgdata.data.set(new Uint8ClampedArray(pixels));
ctx2d.putImageData(imgdata, 0, 0);
bs = canv.source.toDataURL();
canv.destroy();
}
return bs;
}
}
Utils3D._tempVector3_0 = new Vector3();
Utils3D._tempVector3_1 = new Vector3();
Utils3D._tempArray16_0 = new Float32Array(16);
Utils3D._tempArray16_1 = new Float32Array(16);
Utils3D._tempArray16_2 = new Float32Array(16);
Utils3D._tempArray16_3 = new Float32Array(16);
Utils3D._compIdToNode = new Object();
class AnimationClip extends Laya.Resource {
constructor() {
super();
this._duration = 0;
this._frameRate = 0;
this._nodes = new KeyframeNodeList();
this.islooping = false;
this._animationEvents = [];
}
static _parse(data) {
var clip = new AnimationClip();
var reader = new Laya.Byte(data);
var version = reader.readUTFString();
switch (version) {
case "LAYAANIMATION:03":
AnimationClipParser03.parse(clip, reader);
break;
case "LAYAANIMATION:04":
case "LAYAANIMATION:COMPRESSION_04":
AnimationClipParser04.parse(clip, reader, version);
break;
default:
throw "unknown animationClip version.";
}
return clip;
}
static load(url, complete) {
Laya.ILaya.loader.create(url, complete, null, AnimationClip.ANIMATIONCLIP);
}
duration() {
return this._duration;
}
_hermiteInterpolate(frame, nextFrame, t, dur) {
var t0 = frame.outTangent, t1 = nextFrame.inTangent;
if (Number.isFinite(t0) && Number.isFinite(t1)) {
var t2 = t * t;
var t3 = t2 * t;
var a = 2.0 * t3 - 3.0 * t2 + 1.0;
var b = t3 - 2.0 * t2 + t;
var c = t3 - t2;
var d = -2.0 * t3 + 3.0 * t2;
return a * frame.value + b * t0 * dur + c * t1 * dur + d * nextFrame.value;
}
else
return frame.value;
}
_hermiteInterpolateVector3(frame, nextFrame, t, dur, out) {
var p0 = frame.value;
var tan0 = frame.outTangent;
var p1 = nextFrame.value;
var tan1 = nextFrame.inTangent;
var t2 = t * t;
var t3 = t2 * t;
var a = 2.0 * t3 - 3.0 * t2 + 1.0;
var b = t3 - 2.0 * t2 + t;
var c = t3 - t2;
var d = -2.0 * t3 + 3.0 * t2;
var t0 = tan0.x, t1 = tan1.x;
if (Number.isFinite(t0) && Number.isFinite(t1))
out.x = a * p0.x + b * t0 * dur + c * t1 * dur + d * p1.x;
else
out.x = p0.x;
t0 = tan0.y, t1 = tan1.y;
if (Number.isFinite(t0) && Number.isFinite(t1))
out.y = a * p0.y + b * t0 * dur + c * t1 * dur + d * p1.y;
else
out.y = p0.y;
t0 = tan0.z, t1 = tan1.z;
if (Number.isFinite(t0) && Number.isFinite(t1))
out.z = a * p0.z + b * t0 * dur + c * t1 * dur + d * p1.z;
else
out.z = p0.z;
}
_hermiteInterpolateQuaternion(frame, nextFrame, t, dur, out) {
var p0 = frame.value;
var tan0 = frame.outTangent;
var p1 = nextFrame.value;
var tan1 = nextFrame.inTangent;
var t2 = t * t;
var t3 = t2 * t;
var a = 2.0 * t3 - 3.0 * t2 + 1.0;
var b = t3 - 2.0 * t2 + t;
var c = t3 - t2;
var d = -2.0 * t3 + 3.0 * t2;
var t0 = tan0.x, t1 = tan1.x;
if (Number.isFinite(t0) && Number.isFinite(t1))
out.x = a * p0.x + b * t0 * dur + c * t1 * dur + d * p1.x;
else
out.x = p0.x;
t0 = tan0.y, t1 = tan1.y;
if (Number.isFinite(t0) && Number.isFinite(t1))
out.y = a * p0.y + b * t0 * dur + c * t1 * dur + d * p1.y;
else
out.y = p0.y;
t0 = tan0.z, t1 = tan1.z;
if (Number.isFinite(t0) && Number.isFinite(t1))
out.z = a * p0.z + b * t0 * dur + c * t1 * dur + d * p1.z;
else
out.z = p0.z;
t0 = tan0.w, t1 = tan1.w;
if (Number.isFinite(t0) && Number.isFinite(t1))
out.w = a * p0.w + b * t0 * dur + c * t1 * dur + d * p1.w;
else
out.w = p0.w;
}
_evaluateClipDatasRealTime(nodes, playCurTime, realTimeCurrentFrameIndexes, addtive, frontPlay, outDatas, avatarMask) {
for (var i = 0, n = nodes.count; i < n; i++) {
var node = nodes.getNodeByIndex(i);
var type = node.type;
var nextFrameIndex;
var keyFrames = node._keyFrames;
var keyFramesCount = keyFrames.length;
var frameIndex = realTimeCurrentFrameIndexes[i];
if (avatarMask && (!avatarMask.getTransformActive(node.nodePath))) {
continue;
}
if (frontPlay) {
if ((frameIndex !== -1) && (playCurTime < keyFrames[frameIndex].time)) {
frameIndex = -1;
realTimeCurrentFrameIndexes[i] = frameIndex;
}
nextFrameIndex = frameIndex + 1;
while (nextFrameIndex < keyFramesCount) {
if (keyFrames[nextFrameIndex].time > playCurTime)
break;
frameIndex++;
nextFrameIndex++;
realTimeCurrentFrameIndexes[i] = frameIndex;
}
}
else {
nextFrameIndex = frameIndex + 1;
if ((nextFrameIndex !== keyFramesCount) && (playCurTime > keyFrames[nextFrameIndex].time)) {
frameIndex = keyFramesCount - 1;
realTimeCurrentFrameIndexes[i] = frameIndex;
}
nextFrameIndex = frameIndex + 1;
while (frameIndex > -1) {
if (keyFrames[frameIndex].time < playCurTime)
break;
frameIndex--;
nextFrameIndex--;
realTimeCurrentFrameIndexes[i] = frameIndex;
}
}
var isEnd = nextFrameIndex === keyFramesCount;
switch (type) {
case 0:
if (frameIndex !== -1) {
var frame = keyFrames[frameIndex];
if (isEnd) {
outDatas[i] = frame.value;
}
else {
var nextFarme = keyFrames[nextFrameIndex];
var d = nextFarme.time - frame.time;
var t;
if (d !== 0)
t = (playCurTime - frame.time) / d;
else
t = 0;
outDatas[i] = this._hermiteInterpolate(frame, nextFarme, t, d);
}
}
else {
outDatas[i] = keyFrames[0].value;
}
if (addtive)
outDatas[i] = outDatas[i] - keyFrames[0].value;
break;
case 1:
case 4:
var clipData = outDatas[i];
this._evaluateFrameNodeVector3DatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, clipData);
if (addtive) {
var firstFrameValue = keyFrames[0].value;
clipData.x -= firstFrameValue.x;
clipData.y -= firstFrameValue.y;
clipData.z -= firstFrameValue.z;
}
break;
case 2:
var clipQuat = outDatas[i];
this._evaluateFrameNodeQuaternionDatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, clipQuat);
if (addtive) {
var tempQuat = AnimationClip._tempQuaternion0;
var firstFrameValueQua = keyFrames[0].value;
Utils3D.quaternionConjugate(firstFrameValueQua, tempQuat);
Quaternion.multiply(tempQuat, clipQuat, clipQuat);
}
break;
case 3:
clipData = outDatas[i];
this._evaluateFrameNodeVector3DatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, clipData);
if (addtive) {
firstFrameValue = keyFrames[0].value;
clipData.x /= firstFrameValue.x;
clipData.y /= firstFrameValue.y;
clipData.z /= firstFrameValue.z;
}
break;
default:
throw "AnimationClip:unknown node type.";
}
}
}
_evaluateClipDatasRealTimeForNative(nodes, playCurTime, realTimeCurrentFrameIndexes, addtive) {
Laya.LayaGL.instance.evaluateClipDatasRealTime(nodes._nativeObj, playCurTime, realTimeCurrentFrameIndexes, addtive);
}
_evaluateFrameNodeVector3DatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, outDatas) {
if (frameIndex !== -1) {
var frame = keyFrames[frameIndex];
if (isEnd) {
var frameData = frame.value;
outDatas.x = frameData.x;
outDatas.y = frameData.y;
outDatas.z = frameData.z;
}
else {
var nextKeyFrame = keyFrames[frameIndex + 1];
var t;
var startTime = frame.time;
var d = nextKeyFrame.time - startTime;
if (d !== 0)
t = (playCurTime - startTime) / d;
else
t = 0;
this._hermiteInterpolateVector3(frame, nextKeyFrame, t, d, outDatas);
}
}
else {
var firstFrameDatas = keyFrames[0].value;
outDatas.x = firstFrameDatas.x;
outDatas.y = firstFrameDatas.y;
outDatas.z = firstFrameDatas.z;
}
}
_evaluateFrameNodeQuaternionDatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, outDatas) {
if (frameIndex !== -1) {
var frame = keyFrames[frameIndex];
if (isEnd) {
var frameData = frame.value;
outDatas.x = frameData.x;
outDatas.y = frameData.y;
outDatas.z = frameData.z;
outDatas.w = frameData.w;
}
else {
var nextKeyFrame = keyFrames[frameIndex + 1];
var t;
var startTime = frame.time;
var d = nextKeyFrame.time - startTime;
if (d !== 0)
t = (playCurTime - startTime) / d;
else
t = 0;
this._hermiteInterpolateQuaternion(frame, nextKeyFrame, t, d, outDatas);
}
}
else {
var firstFrameDatas = keyFrames[0].value;
outDatas.x = firstFrameDatas.x;
outDatas.y = firstFrameDatas.y;
outDatas.z = firstFrameDatas.z;
outDatas.w = firstFrameDatas.w;
}
}
_binarySearchEventIndex(time) {
var start = 0;
var end = this._animationEvents.length - 1;
var mid;
while (start <= end) {
mid = Math.floor((start + end) / 2);
var midValue = this._animationEvents[mid].time;
if (midValue == time)
return mid;
else if (midValue > time)
end = mid - 1;
else
start = mid + 1;
}
return start;
}
addEvent(event) {
var index = this._binarySearchEventIndex(event.time);
this._animationEvents.splice(index, 0, event);
}
_disposeResource() {
this._nodes = null;
this._nodesMap = null;
}
}
AnimationClip.ANIMATIONCLIP = "ANIMATIONCLIP";
AnimationClip._tempQuaternion0 = new Quaternion();
class AnimatorPlayState {
constructor() {
this._currentState = null;
}
get normalizedTime() {
return this._normalizedTime;
}
get duration() {
return this._duration;
}
get animatorState() {
return this._currentState;
}
_resetPlayState(startTime, clipDuration) {
this._finish = false;
this._startPlayTime = startTime;
this._elapsedTime = startTime;
this._playEventIndex = 0;
this._lastIsFront = true;
this._normalizedTime = this._elapsedTime / clipDuration;
var playTime = this._normalizedTime % 1.0;
this._normalizedPlayTime = playTime < 0 ? playTime + 1.0 : playTime;
}
_cloneTo(dest) {
dest._finish = this._finish;
dest._startPlayTime = this._startPlayTime;
dest._elapsedTime = this._elapsedTime;
dest._normalizedTime = this._normalizedTime;
dest._normalizedPlayTime = this._normalizedPlayTime;
dest._playEventIndex = this._playEventIndex;
dest._lastIsFront = this._lastIsFront;
}
}
class AnimatorControllerLayer {
constructor(name) {
this._referenceCount = 0;
this._playType = -1;
this._crossDuration = -1;
this._crossMark = 0;
this._crossNodesOwnersCount = 0;
this._crossNodesOwners = [];
this._crossNodesOwnersIndicesMap = {};
this._srcCrossClipNodeIndices = [];
this._destCrossClipNodeIndices = [];
this._statesMap = {};
this._states = [];
this._playStateInfo = new AnimatorPlayState();
this._crossPlayStateInfo = new AnimatorPlayState();
this.blendingMode = AnimatorControllerLayer.BLENDINGMODE_OVERRIDE;
this.defaultWeight = 1.0;
this.playOnWake = true;
this.name = name;
}
get defaultState() {
return this._defaultState;
}
set defaultState(value) {
this._defaultState = value;
this._statesMap[value.name] = value;
}
get avatarMask() {
return this._avatarMask;
}
set avatarMask(value) {
this._avatarMask = value;
}
_removeClip(clipStateInfos, statesMap, index, state) {
var clip = state._clip;
var clipStateInfo = clipStateInfos[index];
clipStateInfos.splice(index, 1);
delete statesMap[state.name];
if (this._animator) {
var frameNodes = clip._nodes;
var nodeOwners = clipStateInfo._nodeOwners;
clip._removeReference();
for (var i = 0, n = frameNodes.count; i < n; i++)
this._animator._removeKeyframeNodeOwner(nodeOwners, frameNodes.getNodeByIndex(i));
}
}
_getReferenceCount() {
return this._referenceCount;
}
_addReference(count = 1) {
for (var i = 0, n = this._states.length; i < n; i++)
this._states[i]._addReference(count);
this._referenceCount += count;
}
_removeReference(count = 1) {
for (var i = 0, n = this._states.length; i < n; i++)
this._states[i]._removeReference(count);
this._referenceCount -= count;
}
_clearReference() {
this._removeReference(-this._referenceCount);
}
getCurrentPlayState() {
return this._playStateInfo;
}
getAnimatorState(name) {
var state = this._statesMap[name];
return state ? state : null;
}
addState(state) {
var stateName = state.name;
if (this._statesMap[stateName]) {
throw "AnimatorControllerLayer:this stat's name has exist.";
}
else {
this._statesMap[stateName] = state;
this._states.push(state);
if (this._animator) {
state._clip._addReference();
this._animator._getOwnersByClip(state);
}
}
}
removeState(state) {
var states = this._states;
var index = -1;
for (var i = 0, n = states.length; i < n; i++) {
if (states[i] === state) {
index = i;
break;
}
}
if (index !== -1)
this._removeClip(states, this._statesMap, index, state);
}
destroy() {
this._clearReference();
this._statesMap = null;
this._states = [];
this._playStateInfo = null;
this._crossPlayStateInfo = null;
this._defaultState = null;
}
cloneTo(destObject) {
var dest = destObject;
dest.name = this.name;
dest.blendingMode = this.blendingMode;
dest.defaultWeight = this.defaultWeight;
dest.playOnWake = this.playOnWake;
}
clone() {
var dest = new AnimatorControllerLayer(this.name);
this.cloneTo(dest);
return dest;
}
}
AnimatorControllerLayer.BLENDINGMODE_OVERRIDE = 0;
AnimatorControllerLayer.BLENDINGMODE_ADDTIVE = 1;
class AnimatorState {
constructor() {
this._referenceCount = 0;
this._clip = null;
this._nodeOwners = [];
this._currentFrameIndices = null;
this._realtimeDatas = [];
this._scripts = null;
this.speed = 1.0;
this.clipStart = 0.0;
this.clipEnd = 1.0;
}
get clip() {
return this._clip;
}
set clip(value) {
if (this._clip !== value) {
if (this._clip)
(this._referenceCount > 0) && (this._clip._removeReference(this._referenceCount));
if (value) {
var realtimeDatas = this._realtimeDatas;
var clipNodes = value._nodes;
var count = clipNodes.count;
this._currentFrameIndices = new Int16Array(count);
this._resetFrameIndices();
(this._referenceCount > 0) && (value._addReference(this._referenceCount));
this._realtimeDatas.length = count;
for (var i = 0; i < count; i++) {
switch (clipNodes.getNodeByIndex(i).type) {
case 0:
break;
case 1:
case 3:
case 4:
realtimeDatas[i] = new Vector3();
break;
case 2:
realtimeDatas[i] = new Quaternion();
break;
default:
throw "AnimationClipParser04:unknown type.";
}
}
}
this._clip = value;
}
}
_getReferenceCount() {
return this._referenceCount;
}
_addReference(count = 1) {
(this._clip) && (this._clip._addReference(count));
this._referenceCount += count;
}
_removeReference(count = 1) {
(this._clip) && (this._clip._removeReference(count));
this._referenceCount -= count;
}
_clearReference() {
this._removeReference(-this._referenceCount);
}
_resetFrameIndices() {
for (var i = 0, n = this._currentFrameIndices.length; i < n; i++)
this._currentFrameIndices[i] = -1;
}
addScript(type) {
var script = new type();
this._scripts = this._scripts || [];
this._scripts.push(script);
return script;
}
getScript(type) {
if (this._scripts) {
for (var i = 0, n = this._scripts.length; i < n; i++) {
var script = this._scripts[i];
if (script instanceof type)
return script;
}
}
return null;
}
getScripts(type) {
var coms = null;
if (this._scripts) {
for (var i = 0, n = this._scripts.length; i < n; i++) {
var script = this._scripts[i];
if (script instanceof type) {
coms = coms || [];
coms.push(script);
}
}
}
return coms;
}
cloneTo(destObject) {
var dest = destObject;
dest.name = this.name;
dest.speed = this.speed;
dest.clipStart = this.clipStart;
dest.clipEnd = this.clipEnd;
dest.clip = this._clip;
}
clone() {
var dest = new AnimatorState();
this.cloneTo(dest);
return dest;
}
}
class AvatarMask {
constructor(animator) {
this._avatarPathMap = {};
this._catchAnimator = animator;
}
get getCatchAnimator() {
return this._catchAnimator;
}
getTransformActive(path) {
return this._avatarPathMap[path];
}
setTransformActive(path, value) {
this._avatarPathMap[path] = value;
}
getAllTranfromPath() {
return this._avatarPathMap;
}
}
class KeyframeNodeOwner {
constructor() {
this.indexInList = -1;
this.referenceCount = 0;
this.updateMark = -1;
this.type = -1;
this.fullPath = null;
this.propertyOwner = null;
this.property = null;
this.defaultValue = null;
this.value = null;
this.crossFixedValue = null;
}
saveCrossFixedValue() {
var pro = this.propertyOwner;
if (pro) {
switch (this.type) {
case 0:
this.crossFixedValue = this.value;
break;
case 1:
case 3:
case 4:
this.value.cloneTo(this.crossFixedValue);
break;
case 2:
this.value.cloneTo(this.crossFixedValue);
break;
default:
throw "Animator:unknown type.";
}
}
}
}
class Animator extends Laya.Component {
constructor() {
super();
this._keyframeNodeOwners = [];
this._linkAvatarSpritesData = {};
this._linkAvatarSprites = [];
this._renderableSprites = [];
this.cullingMode = Animator.CULLINGMODE_CULLCOMPLETELY;
this._controllerLayers = [];
this._linkSprites = {};
this._speed = 1.0;
this._keyframeNodeOwnerMap = {};
this._updateMark = 0;
}
static _update(scene) {
var pool = scene._animatorPool;
var elements = pool.elements;
for (var i = 0, n = pool.length; i < n; i++) {
var animator = elements[i];
(animator && animator.enabled) && (animator._update());
}
}
get speed() {
return this._speed;
}
set speed(value) {
this._speed = value;
}
get controllerLayerCount() {
return this._controllerLayers.length;
}
_linkToSprites(linkSprites) {
for (var k in linkSprites) {
var nodeOwner = this.owner;
var path = linkSprites[k];
for (var j = 0, m = path.length; j < m; j++) {
var p = path[j];
if (p === "") {
break;
}
else {
nodeOwner = nodeOwner.getChildByName(p);
if (!nodeOwner)
break;
}
}
(nodeOwner) && (this.linkSprite3DToAvatarNode(k, nodeOwner));
}
}
_addKeyframeNodeOwner(clipOwners, node, propertyOwner) {
var nodeIndex = node._indexInList;
var fullPath = node.fullPath;
var keyframeNodeOwner = this._keyframeNodeOwnerMap[fullPath];
if (keyframeNodeOwner) {
keyframeNodeOwner.referenceCount++;
clipOwners[nodeIndex] = keyframeNodeOwner;
}
else {
var property = propertyOwner;
for (var i = 0, n = node.propertyCount; i < n; i++) {
property = property[node.getPropertyByIndex(i)];
if (!property)
break;
}
keyframeNodeOwner = this._keyframeNodeOwnerMap[fullPath] = new KeyframeNodeOwner();
keyframeNodeOwner.fullPath = fullPath;
keyframeNodeOwner.indexInList = this._keyframeNodeOwners.length;
keyframeNodeOwner.referenceCount = 1;
keyframeNodeOwner.propertyOwner = propertyOwner;
var propertyCount = node.propertyCount;
var propertys = [];
for (i = 0; i < propertyCount; i++)
propertys[i] = node.getPropertyByIndex(i);
keyframeNodeOwner.property = propertys;
keyframeNodeOwner.type = node.type;
if (property) {
if (node.type === 0) {
keyframeNodeOwner.defaultValue = property;
}
else {
var defaultValue = new property.constructor();
property.cloneTo(defaultValue);
keyframeNodeOwner.defaultValue = defaultValue;
keyframeNodeOwner.value = new property.constructor();
keyframeNodeOwner.crossFixedValue = new property.constructor();
}
}
this._keyframeNodeOwners.push(keyframeNodeOwner);
clipOwners[nodeIndex] = keyframeNodeOwner;
}
}
_removeKeyframeNodeOwner(nodeOwners, node) {
var fullPath = node.fullPath;
var keyframeNodeOwner = this._keyframeNodeOwnerMap[fullPath];
if (keyframeNodeOwner) {
keyframeNodeOwner.referenceCount--;
if (keyframeNodeOwner.referenceCount === 0) {
delete this._keyframeNodeOwnerMap[fullPath];
this._keyframeNodeOwners.splice(this._keyframeNodeOwners.indexOf(keyframeNodeOwner), 1);
}
nodeOwners[node._indexInList] = null;
}
}
_getOwnersByClip(clipStateInfo) {
var frameNodes = clipStateInfo._clip._nodes;
var frameNodesCount = frameNodes.count;
var nodeOwners = clipStateInfo._nodeOwners;
nodeOwners.length = frameNodesCount;
for (var i = 0; i < frameNodesCount; i++) {
var node = frameNodes.getNodeByIndex(i);
var property = this._avatar ? this._avatarNodeMap[this._avatar._rootNode.name] : this.owner;
for (var j = 0, m = node.ownerPathCount; j < m; j++) {
var ownPat = node.getOwnerPathByIndex(j);
if (ownPat === "") {
break;
}
else {
property = property.getChildByName(ownPat);
if (!property)
break;
}
}
if (property) {
var propertyOwner = node.propertyOwner;
(propertyOwner) && (property = property[propertyOwner]);
property && this._addKeyframeNodeOwner(nodeOwners, node, property);
}
}
}
_updatePlayer(animatorState, playState, elapsedTime, islooping) {
var clipDuration = animatorState._clip._duration * (animatorState.clipEnd - animatorState.clipStart);
var lastElapsedTime = playState._elapsedTime;
var elapsedPlaybackTime = lastElapsedTime + elapsedTime;
playState._lastElapsedTime = lastElapsedTime;
playState._elapsedTime = elapsedPlaybackTime;
var normalizedTime = elapsedPlaybackTime / clipDuration;
playState._normalizedTime = normalizedTime;
var playTime = normalizedTime % 1.0;
playState._normalizedPlayTime = playTime < 0 ? playTime + 1.0 : playTime;
playState._duration = clipDuration;
var scripts = animatorState._scripts;
if ((!islooping && elapsedPlaybackTime >= clipDuration)) {
playState._finish = true;
playState._elapsedTime = clipDuration;
playState._normalizedPlayTime = 1.0;
return;
}
if (scripts) {
for (var i = 0, n = scripts.length; i < n; i++)
scripts[i].onStateUpdate();
}
}
_updateStateFinish(animatorState, playState) {
if (playState._finish) {
var scripts = animatorState._scripts;
if (scripts) {
for (var i = 0, n = scripts.length; i < n; i++) {
scripts[i].onStateExit();
}
}
}
}
_eventScript(scripts, events, eventIndex, endTime, front) {
if (front) {
for (var n = events.length; eventIndex < n; eventIndex++) {
var event = events[eventIndex];
if (event.time <= endTime) {
for (var j = 0, m = scripts.length; j < m; j++) {
var script = scripts[j];
var fun = script[event.eventName];
(fun) && (fun.apply(script, event.params));
}
}
else {
break;
}
}
}
else {
for (; eventIndex >= 0; eventIndex--) {
event = events[eventIndex];
if (event.time >= endTime) {
for (j = 0, m = scripts.length; j < m; j++) {
script = scripts[j];
fun = script[event.eventName];
(fun) && (fun.apply(script, event.params));
}
}
else {
break;
}
}
}
return eventIndex;
}
_updateEventScript(stateInfo, playStateInfo) {
var scripts = this.owner._scripts;
if (scripts) {
var clip = stateInfo._clip;
var events = clip._animationEvents;
var clipDuration = clip._duration;
var elapsedTime = playStateInfo._elapsedTime;
var time = elapsedTime % clipDuration;
var loopCount = Math.abs(Math.floor(elapsedTime / clipDuration) - Math.floor(playStateInfo._lastElapsedTime / clipDuration));
var frontPlay = playStateInfo._elapsedTime >= playStateInfo._lastElapsedTime;
if (playStateInfo._lastIsFront !== frontPlay) {
if (frontPlay)
playStateInfo._playEventIndex++;
else
playStateInfo._playEventIndex--;
playStateInfo._lastIsFront = frontPlay;
}
var preEventIndex = playStateInfo._playEventIndex;
if (frontPlay) {
var newEventIndex = this._eventScript(scripts, events, playStateInfo._playEventIndex, loopCount > 0 ? clipDuration : time, true);
(preEventIndex === playStateInfo._playEventIndex) && (playStateInfo._playEventIndex = newEventIndex);
for (var i = 0, n = loopCount - 1; i < n; i++)
this._eventScript(scripts, events, 0, clipDuration, true);
(loopCount > 0 && time > 0) && (playStateInfo._playEventIndex = this._eventScript(scripts, events, 0, time, true));
}
else {
var newEventIndex = this._eventScript(scripts, events, playStateInfo._playEventIndex, loopCount > 0 ? 0 : time, false);
(preEventIndex === playStateInfo._playEventIndex) && (playStateInfo._playEventIndex = newEventIndex);
var eventIndex = events.length - 1;
for (i = 0, n = loopCount - 1; i < n; i++)
this._eventScript(scripts, events, eventIndex, 0, false);
(loopCount > 0 && time > 0) && (playStateInfo._playEventIndex = this._eventScript(scripts, events, eventIndex, time, false));
}
}
}
_updateClipDatas(animatorState, addtive, playStateInfo, animatorMask = null) {
var clip = animatorState._clip;
var clipDuration = clip._duration;
var curPlayTime = animatorState.clipStart * clipDuration + playStateInfo._normalizedPlayTime * playStateInfo._duration;
var currentFrameIndices = animatorState._currentFrameIndices;
var frontPlay = playStateInfo._elapsedTime > playStateInfo._lastElapsedTime;
clip._evaluateClipDatasRealTime(clip._nodes, curPlayTime, currentFrameIndices, addtive, frontPlay, animatorState._realtimeDatas, animatorMask);
}
_applyFloat(pro, proName, nodeOwner, additive, weight, isFirstLayer, data) {
if (nodeOwner.updateMark === this._updateMark) {
if (additive) {
pro[proName] += weight * data;
}
else {
var oriValue = pro[proName];
pro[proName] = oriValue + weight * (data - oriValue);
}
}
else {
if (isFirstLayer) {
if (additive)
pro[proName] = nodeOwner.defaultValue + data;
else
pro[proName] = data;
}
else {
if (additive) {
pro[proName] = nodeOwner.defaultValue + weight * (data);
}
else {
var defValue = nodeOwner.defaultValue;
pro[proName] = defValue + weight * (data - defValue);
}
}
}
}
_applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, data, out) {
if (nodeOwner.updateMark === this._updateMark) {
if (additive) {
out.x += weight * data.x;
out.y += weight * data.y;
out.z += weight * data.z;
}
else {
var oriX = out.x;
var oriY = out.y;
var oriZ = out.z;
out.x = oriX + weight * (data.x - oriX);
out.y = oriY + weight * (data.y - oriY);
out.z = oriZ + weight * (data.z - oriZ);
}
}
else {
if (isFirstLayer) {
if (additive) {
var defValue = nodeOwner.defaultValue;
out.x = defValue.x + data.x;
out.y = defValue.y + data.y;
out.z = defValue.z + data.z;
}
else {
out.x = data.x;
out.y = data.y;
out.z = data.z;
}
}
else {
defValue = nodeOwner.defaultValue;
if (additive) {
out.x = defValue.x + weight * data.x;
out.y = defValue.y + weight * data.y;
out.z = defValue.z + weight * data.z;
}
else {
var defX = defValue.x;
var defY = defValue.y;
var defZ = defValue.z;
out.x = defX + weight * (data.x - defX);
out.y = defY + weight * (data.y - defY);
out.z = defZ + weight * (data.z - defZ);
}
}
}
}
_applyRotation(nodeOwner, additive, weight, isFirstLayer, clipRot, localRotation) {
if (nodeOwner.updateMark === this._updateMark) {
if (additive) {
var tempQuat = Animator._tempQuaternion1;
Utils3D.quaternionWeight(clipRot, weight, tempQuat);
tempQuat.normalize(tempQuat);
Quaternion.multiply(localRotation, tempQuat, localRotation);
}
else {
Quaternion.lerp(localRotation, clipRot, weight, localRotation);
}
}
else {
if (isFirstLayer) {
if (additive) {
var defaultRot = nodeOwner.defaultValue;
Quaternion.multiply(defaultRot, clipRot, localRotation);
}
else {
localRotation.x = clipRot.x;
localRotation.y = clipRot.y;
localRotation.z = clipRot.z;
localRotation.w = clipRot.w;
}
}
else {
defaultRot = nodeOwner.defaultValue;
if (additive) {
tempQuat = Animator._tempQuaternion1;
Utils3D.quaternionWeight(clipRot, weight, tempQuat);
tempQuat.normalize(tempQuat);
Quaternion.multiply(defaultRot, tempQuat, localRotation);
}
else {
Quaternion.lerp(defaultRot, clipRot, weight, localRotation);
}
}
}
}
_applyScale(nodeOwner, additive, weight, isFirstLayer, clipSca, localScale) {
if (nodeOwner.updateMark === this._updateMark) {
if (additive) {
var scale = Animator._tempVector31;
Utils3D.scaleWeight(clipSca, weight, scale);
localScale.x = localScale.x * scale.x;
localScale.y = localScale.y * scale.y;
localScale.z = localScale.z * scale.z;
}
else {
Utils3D.scaleBlend(localScale, clipSca, weight, localScale);
}
}
else {
if (isFirstLayer) {
if (additive) {
var defaultSca = nodeOwner.defaultValue;
localScale.x = defaultSca.x * clipSca.x;
localScale.y = defaultSca.y * clipSca.y;
localScale.z = defaultSca.z * clipSca.z;
}
else {
localScale.x = clipSca.x;
localScale.y = clipSca.y;
localScale.z = clipSca.z;
}
}
else {
defaultSca = nodeOwner.defaultValue;
if (additive) {
scale = Animator._tempVector31;
Utils3D.scaleWeight(clipSca, weight, scale);
localScale.x = defaultSca.x * scale.x;
localScale.y = defaultSca.y * scale.y;
localScale.z = defaultSca.z * scale.z;
}
else {
Utils3D.scaleBlend(defaultSca, clipSca, weight, localScale);
}
}
}
}
_applyCrossData(nodeOwner, additive, weight, isFirstLayer, srcValue, desValue, crossWeight) {
var pro = nodeOwner.propertyOwner;
if (pro) {
switch (nodeOwner.type) {
case 0:
var proPat = nodeOwner.property;
var m = proPat.length - 1;
for (var j = 0; j < m; j++) {
pro = pro[proPat[j]];
if (!pro)
break;
}
var crossValue = srcValue + crossWeight * (desValue - srcValue);
nodeOwner.value = crossValue;
pro && this._applyFloat(pro, proPat[m], nodeOwner, additive, weight, isFirstLayer, crossValue);
break;
case 1:
var localPos = pro.localPosition;
var position = nodeOwner.value;
var srcX = srcValue.x, srcY = srcValue.y, srcZ = srcValue.z;
position.x = srcX + crossWeight * (desValue.x - srcX);
position.y = srcY + crossWeight * (desValue.y - srcY);
position.z = srcZ + crossWeight * (desValue.z - srcZ);
this._applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, position, localPos);
pro.localPosition = localPos;
break;
case 2:
var localRot = pro.localRotation;
var rotation = nodeOwner.value;
Quaternion.lerp(srcValue, desValue, crossWeight, rotation);
this._applyRotation(nodeOwner, additive, weight, isFirstLayer, rotation, localRot);
pro.localRotation = localRot;
break;
case 3:
var localSca = pro.localScale;
var scale = nodeOwner.value;
Utils3D.scaleBlend(srcValue, desValue, crossWeight, scale);
this._applyScale(nodeOwner, additive, weight, isFirstLayer, scale, localSca);
pro.localScale = localSca;
break;
case 4:
var localEuler = pro.localRotationEuler;
var rotationEuler = nodeOwner.value;
srcX = srcValue.x, srcY = srcValue.y, srcZ = srcValue.z;
rotationEuler.x = srcX + crossWeight * (desValue.x - srcX);
rotationEuler.y = srcY + crossWeight * (desValue.y - srcY);
rotationEuler.z = srcZ + crossWeight * (desValue.z - srcZ);
this._applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, rotationEuler, localEuler);
pro.localRotationEuler = localEuler;
break;
}
nodeOwner.updateMark = this._updateMark;
}
}
_setClipDatasToNode(stateInfo, additive, weight, isFirstLayer, controllerLayer = null) {
var realtimeDatas = stateInfo._realtimeDatas;
var nodes = stateInfo._clip._nodes;
var nodeOwners = stateInfo._nodeOwners;
for (var i = 0, n = nodes.count; i < n; i++) {
var nodeOwner = nodeOwners[i];
if (nodeOwner) {
var node = nodes.getNodeByIndex(i);
if (controllerLayer.avatarMask && (!controllerLayer.avatarMask.getTransformActive(node.nodePath)))
continue;
var pro = nodeOwner.propertyOwner;
if (pro) {
switch (nodeOwner.type) {
case 0:
var proPat = nodeOwner.property;
var m = proPat.length - 1;
for (var j = 0; j < m; j++) {
pro = pro[proPat[j]];
if (!pro)
break;
}
pro && this._applyFloat(pro, proPat[m], nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i]);
break;
case 1:
var localPos = pro.localPosition;
this._applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i], localPos);
pro.localPosition = localPos;
break;
case 2:
var localRot = pro.localRotation;
this._applyRotation(nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i], localRot);
pro.localRotation = localRot;
break;
case 3:
var localSca = pro.localScale;
this._applyScale(nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i], localSca);
pro.localScale = localSca;
break;
case 4:
var localEuler = pro.localRotationEuler;
this._applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i], localEuler);
pro.localRotationEuler = localEuler;
break;
}
nodeOwner.updateMark = this._updateMark;
}
}
}
}
_setCrossClipDatasToNode(controllerLayer, srcState, destState, crossWeight, isFirstLayer) {
var nodeOwners = controllerLayer._crossNodesOwners;
var ownerCount = controllerLayer._crossNodesOwnersCount;
var additive = controllerLayer.blendingMode !== AnimatorControllerLayer.BLENDINGMODE_OVERRIDE;
var weight = controllerLayer.defaultWeight;
var destRealtimeDatas = destState._realtimeDatas;
var destDataIndices = controllerLayer._destCrossClipNodeIndices;
var destNodeOwners = destState._nodeOwners;
var srcRealtimeDatas = srcState._realtimeDatas;
var srcDataIndices = controllerLayer._srcCrossClipNodeIndices;
var srcNodeOwners = srcState._nodeOwners;
for (var i = 0; i < ownerCount; i++) {
var nodeOwner = nodeOwners[i];
if (nodeOwner) {
var srcIndex = srcDataIndices[i];
var destIndex = destDataIndices[i];
var srcValue = srcIndex !== -1 ? srcRealtimeDatas[srcIndex] : destNodeOwners[destIndex].defaultValue;
var desValue = destIndex !== -1 ? destRealtimeDatas[destIndex] : srcNodeOwners[srcIndex].defaultValue;
this._applyCrossData(nodeOwner, additive, weight, isFirstLayer, srcValue, desValue, crossWeight);
}
}
}
_setFixedCrossClipDatasToNode(controllerLayer, destState, crossWeight, isFirstLayer) {
var nodeOwners = controllerLayer._crossNodesOwners;
var ownerCount = controllerLayer._crossNodesOwnersCount;
var additive = controllerLayer.blendingMode !== AnimatorControllerLayer.BLENDINGMODE_OVERRIDE;
var weight = controllerLayer.defaultWeight;
var destRealtimeDatas = destState._realtimeDatas;
var destDataIndices = controllerLayer._destCrossClipNodeIndices;
for (var i = 0; i < ownerCount; i++) {
var nodeOwner = nodeOwners[i];
if (nodeOwner) {
var destIndex = destDataIndices[i];
var srcValue = nodeOwner.crossFixedValue;
var desValue = destIndex !== -1 ? destRealtimeDatas[destIndex] : nodeOwner.defaultValue;
this._applyCrossData(nodeOwner, additive, weight, isFirstLayer, srcValue, desValue, crossWeight);
}
}
}
_revertDefaultKeyframeNodes(clipStateInfo) {
var nodeOwners = clipStateInfo._nodeOwners;
for (var i = 0, n = nodeOwners.length; i < n; i++) {
var nodeOwner = nodeOwners[i];
if (nodeOwner) {
var pro = nodeOwner.propertyOwner;
if (pro) {
switch (nodeOwner.type) {
case 0:
var proPat = nodeOwner.property;
var m = proPat.length - 1;
for (var j = 0; j < m; j++) {
pro = pro[proPat[j]];
if (!pro)
break;
}
pro[proPat[m]] = nodeOwner.defaultValue;
break;
case 1:
var locPos = pro.localPosition;
var def = nodeOwner.defaultValue;
locPos.x = def.x;
locPos.y = def.y;
locPos.z = def.z;
pro.localPosition = locPos;
break;
case 2:
var locRot = pro.localRotation;
var defQua = nodeOwner.defaultValue;
locRot.x = defQua.x;
locRot.y = defQua.y;
locRot.z = defQua.z;
locRot.w = defQua.w;
pro.localRotation = locRot;
break;
case 3:
var locSca = pro.localScale;
def = nodeOwner.defaultValue;
locSca.x = def.x;
locSca.y = def.y;
locSca.z = def.z;
pro.localScale = locSca;
break;
case 4:
var locEul = pro.localRotationEuler;
def = nodeOwner.defaultValue;
locEul.x = def.x;
locEul.y = def.y;
locEul.z = def.z;
pro.localRotationEuler = locEul;
break;
default:
throw "Animator:unknown type.";
}
}
}
}
}
_onAdded() {
var parent = this.owner._parent;
this.owner._setHierarchyAnimator(this, parent ? parent._hierarchyAnimator : null);
this.owner._changeAnimatorToLinkSprite3DNoAvatar(this, true, []);
}
_onDestroy() {
for (var i = 0, n = this._controllerLayers.length; i < n; i++)
this._controllerLayers[i]._removeReference();
var parent = this.owner._parent;
this.owner._clearHierarchyAnimator(this, parent ? parent._hierarchyAnimator : null);
}
_onEnable() {
this.owner._scene._animatorPool.add(this);
for (var i = 0, n = this._controllerLayers.length; i < n; i++) {
if (this._controllerLayers[i].playOnWake) {
var defaultClip = this.getDefaultState(i);
(defaultClip) && (this.play(null, i, 0));
}
}
}
_onDisable() {
this.owner._scene._animatorPool.remove(this);
}
_handleSpriteOwnersBySprite(isLink, path, sprite) {
for (var i = 0, n = this._controllerLayers.length; i < n; i++) {
var clipStateInfos = this._controllerLayers[i]._states;
for (var j = 0, m = clipStateInfos.length; j < m; j++) {
var clipStateInfo = clipStateInfos[j];
var clip = clipStateInfo._clip;
var nodePath = path.join("/");
var ownersNodes = clip._nodesMap[nodePath];
if (ownersNodes) {
var nodeOwners = clipStateInfo._nodeOwners;
for (var k = 0, p = ownersNodes.length; k < p; k++) {
if (isLink)
this._addKeyframeNodeOwner(nodeOwners, ownersNodes[k], sprite);
else
this._removeKeyframeNodeOwner(nodeOwners, ownersNodes[k]);
}
}
}
}
}
_parse(data) {
var avatarData = data.avatar;
if (avatarData) {
this.avatar = Laya.Loader.getRes(avatarData.path);
var linkSprites = avatarData.linkSprites;
this._linkSprites = linkSprites;
this._linkToSprites(linkSprites);
}
var play = data.playOnWake;
var layersData = data.layers;
for (var i = 0; i < layersData.length; i++) {
var layerData = layersData[i];
var animatorLayer = new AnimatorControllerLayer(layerData.name);
if (i === 0)
animatorLayer.defaultWeight = 1.0;
else
animatorLayer.defaultWeight = layerData.weight;
var blendingModeData = layerData.blendingMode;
(blendingModeData) && (animatorLayer.blendingMode = blendingModeData);
this.addControllerLayer(animatorLayer);
var states = layerData.states;
for (var j = 0, m = states.length; j < m; j++) {
var state = states[j];
var clipPath = state.clipPath;
if (clipPath) {
var name = state.name;
var motion;
motion = Laya.Loader.getRes(clipPath);
if (motion) {
var animatorState = new AnimatorState();
animatorState.name = name;
animatorState.clip = motion;
animatorLayer.addState(animatorState);
(j === 0) && (this.getControllerLayer(i).defaultState = animatorState);
}
}
}
(play !== undefined) && (animatorLayer.playOnWake = play);
let layerMaskData = layerData.avatarMask;
if (layerMaskData) {
let avaMask = new AvatarMask(this);
animatorLayer.avatarMask = avaMask;
for (var bips in layerMaskData) {
avaMask.setTransformActive(bips, layerMaskData[bips]);
}
}
}
var cullingModeData = data.cullingMode;
(cullingModeData !== undefined) && (this.cullingMode = cullingModeData);
}
_update() {
var timer = this.owner._scene.timer;
var delta = timer._delta / 1000.0;
if (this._speed === 0 || delta === 0)
return;
var needRender;
if (this.cullingMode === Animator.CULLINGMODE_CULLCOMPLETELY) {
needRender = false;
for (var i = 0, n = this._renderableSprites.length; i < n; i++) {
if (this._renderableSprites[i]._render.isRender) {
needRender = true;
break;
}
}
}
else {
needRender = true;
}
this._updateMark++;
for (i = 0, n = this._controllerLayers.length; i < n; i++) {
var controllerLayer = this._controllerLayers[i];
var playStateInfo = controllerLayer._playStateInfo;
var crossPlayStateInfo = controllerLayer._crossPlayStateInfo;
addtive = controllerLayer.blendingMode !== AnimatorControllerLayer.BLENDINGMODE_OVERRIDE;
switch (controllerLayer._playType) {
case 0:
var animatorState = playStateInfo._currentState;
var clip = animatorState._clip;
var speed = this._speed * animatorState.speed;
var finish = playStateInfo._finish;
finish || this._updatePlayer(animatorState, playStateInfo, delta * speed, clip.islooping);
if (needRender) {
var addtive = controllerLayer.blendingMode !== AnimatorControllerLayer.BLENDINGMODE_OVERRIDE;
this._updateClipDatas(animatorState, addtive, playStateInfo, controllerLayer.avatarMask);
this._setClipDatasToNode(animatorState, addtive, controllerLayer.defaultWeight, i === 0, controllerLayer);
finish || this._updateEventScript(animatorState, playStateInfo);
}
playStateInfo._finish && this._updateStateFinish(animatorState, playStateInfo);
break;
case 1:
animatorState = playStateInfo._currentState;
clip = animatorState._clip;
var crossState = controllerLayer._crossPlayState;
var crossClip = crossState._clip;
var crossDuratuion = controllerLayer._crossDuration;
var startPlayTime = crossPlayStateInfo._startPlayTime;
var crossClipDuration = crossClip._duration - startPlayTime;
var crossScale = crossDuratuion > crossClipDuration ? crossClipDuration / crossDuratuion : 1.0;
var crossSpeed = this._speed * crossState.speed;
this._updatePlayer(crossState, crossPlayStateInfo, delta * crossScale * crossSpeed, crossClip.islooping);
var crossWeight = ((crossPlayStateInfo._elapsedTime - startPlayTime) / crossScale) / crossDuratuion;
var needUpdateFinishcurrentState = false;
if (crossWeight >= 1.0) {
if (needRender) {
this._updateClipDatas(crossState, addtive, crossPlayStateInfo, controllerLayer.avatarMask);
this._setClipDatasToNode(crossState, addtive, controllerLayer.defaultWeight, i === 0, controllerLayer);
controllerLayer._playType = 0;
playStateInfo._currentState = crossState;
crossPlayStateInfo._cloneTo(playStateInfo);
}
}
else {
if (!playStateInfo._finish) {
speed = this._speed * animatorState.speed;
needUpdateFinishcurrentState = true;
this._updatePlayer(animatorState, playStateInfo, delta * speed, clip.islooping);
if (needRender)
this._updateClipDatas(animatorState, addtive, playStateInfo, controllerLayer.avatarMask);
}
if (needRender) {
this._updateClipDatas(crossState, addtive, crossPlayStateInfo, controllerLayer.avatarMask);
this._setCrossClipDatasToNode(controllerLayer, animatorState, crossState, crossWeight, i === 0);
}
}
if (needRender) {
this._updateEventScript(animatorState, playStateInfo);
this._updateEventScript(crossState, crossPlayStateInfo);
}
this._updateStateFinish(crossState, crossPlayStateInfo);
needUpdateFinishcurrentState && this._updateStateFinish(playStateInfo._currentState, playStateInfo);
break;
case 2:
crossState = controllerLayer._crossPlayState;
crossClip = crossState._clip;
crossDuratuion = controllerLayer._crossDuration;
startPlayTime = crossPlayStateInfo._startPlayTime;
crossClipDuration = crossClip._duration - startPlayTime;
crossScale = crossDuratuion > crossClipDuration ? crossClipDuration / crossDuratuion : 1.0;
crossSpeed = this._speed * crossState.speed;
this._updatePlayer(crossState, crossPlayStateInfo, delta * crossScale * crossSpeed, crossClip.islooping);
if (needRender) {
crossWeight = ((crossPlayStateInfo._elapsedTime - startPlayTime) / crossScale) / crossDuratuion;
if (crossWeight >= 1.0) {
this._updateClipDatas(crossState, addtive, crossPlayStateInfo, controllerLayer.avatarMask);
this._setClipDatasToNode(crossState, addtive, 1.0, i === 0, controllerLayer);
controllerLayer._playType = 0;
playStateInfo._currentState = crossState;
crossPlayStateInfo._cloneTo(playStateInfo);
}
else {
this._updateClipDatas(crossState, addtive, crossPlayStateInfo, controllerLayer.avatarMask);
this._setFixedCrossClipDatasToNode(controllerLayer, crossState, crossWeight, i === 0);
}
this._updateEventScript(crossState, crossPlayStateInfo);
}
this._updateStateFinish(crossState, crossPlayStateInfo);
break;
}
}
if (needRender) {
if (this._avatar) {
this._updateAvatarNodesToSprite();
}
}
}
_cloneTo(dest) {
var animator = dest;
animator.avatar = this.avatar;
animator.cullingMode = this.cullingMode;
for (var i = 0, n = this._controllerLayers.length; i < n; i++) {
var controllLayer = this._controllerLayers[i];
animator.addControllerLayer(controllLayer.clone());
var animatorStates = controllLayer._states;
for (var j = 0, m = animatorStates.length; j < m; j++) {
var state = animatorStates[j].clone();
var cloneLayer = animator.getControllerLayer(i);
cloneLayer.addState(state);
(j == 0) && (cloneLayer.defaultState = state);
}
}
animator._linkSprites = this._linkSprites;
animator._linkToSprites(this._linkSprites);
}
getDefaultState(layerIndex = 0) {
var controllerLayer = this._controllerLayers[layerIndex];
return controllerLayer.defaultState;
}
addState(state, layerIndex = 0) {
var controllerLayer = this._controllerLayers[layerIndex];
controllerLayer.addState(state);
console.warn("Animator:this function is discard,please use animatorControllerLayer.addState() instead.");
}
removeState(state, layerIndex = 0) {
var controllerLayer = this._controllerLayers[layerIndex];
controllerLayer.removeState(state);
console.warn("Animator:this function is discard,please use animatorControllerLayer.removeState() instead.");
}
addControllerLayer(controllderLayer) {
this._controllerLayers.push(controllderLayer);
controllderLayer._animator = this;
controllderLayer._addReference();
var states = controllderLayer._states;
for (var i = 0, n = states.length; i < n; i++)
this._getOwnersByClip(states[i]);
}
getControllerLayer(layerInex = 0) {
return this._controllerLayers[layerInex];
}
play(name = null, layerIndex = 0, normalizedTime = Number.NEGATIVE_INFINITY) {
var controllerLayer = this._controllerLayers[layerIndex];
if (controllerLayer) {
var defaultState = controllerLayer.defaultState;
if (!name && !defaultState)
throw new Error("Animator:must have default clip value,please set clip property.");
var playStateInfo = controllerLayer._playStateInfo;
var curPlayState = playStateInfo._currentState;
var animatorState = name ? controllerLayer._statesMap[name] : defaultState;
var clipDuration = animatorState._clip._duration;
var calclipduration = animatorState._clip._duration * (animatorState.clipEnd - animatorState.clipStart);
if (curPlayState !== animatorState) {
if (normalizedTime !== Number.NEGATIVE_INFINITY)
playStateInfo._resetPlayState(clipDuration * normalizedTime, calclipduration);
else
playStateInfo._resetPlayState(0.0, calclipduration);
(curPlayState !== null && curPlayState !== animatorState) && (this._revertDefaultKeyframeNodes(curPlayState));
controllerLayer._playType = 0;
playStateInfo._currentState = animatorState;
}
else {
if (normalizedTime !== Number.NEGATIVE_INFINITY) {
playStateInfo._resetPlayState(clipDuration * normalizedTime, calclipduration);
controllerLayer._playType = 0;
}
}
var scripts = animatorState._scripts;
if (scripts) {
for (var i = 0, n = scripts.length; i < n; i++)
scripts[i].onStateEnter();
}
}
else {
console.warn("Invalid layerIndex " + layerIndex + ".");
}
if (this.owner._scene) {
this._update();
}
}
crossFade(name, transitionDuration, layerIndex = 0, normalizedTime = Number.NEGATIVE_INFINITY) {
var controllerLayer = this._controllerLayers[layerIndex];
if (controllerLayer) {
var destAnimatorState = controllerLayer._statesMap[name];
if (destAnimatorState) {
var playType = controllerLayer._playType;
if (playType === -1) {
this.play(name, layerIndex, normalizedTime);
return;
}
var crossPlayStateInfo = controllerLayer._crossPlayStateInfo;
var crossNodeOwners = controllerLayer._crossNodesOwners;
var crossNodeOwnerIndicesMap = controllerLayer._crossNodesOwnersIndicesMap;
var srcAnimatorState = controllerLayer._playStateInfo._currentState;
var destNodeOwners = destAnimatorState._nodeOwners;
var destCrossClipNodeIndices = controllerLayer._destCrossClipNodeIndices;
var destClip = destAnimatorState._clip;
var destNodes = destClip._nodes;
var destNodesMap = destClip._nodesDic;
var crossCount = 0;
switch (playType) {
case 0:
var srcNodeOwners = srcAnimatorState._nodeOwners;
var scrCrossClipNodeIndices = controllerLayer._srcCrossClipNodeIndices;
var srcClip = srcAnimatorState._clip;
var srcNodes = srcClip._nodes;
var srcNodesMap = srcClip._nodesDic;
controllerLayer._playType = 1;
var crossMark = ++controllerLayer._crossMark;
crossCount = controllerLayer._crossNodesOwnersCount = 0;
for (var i = 0, n = srcNodes.count; i < n; i++) {
var srcNode = srcNodes.getNodeByIndex(i);
var srcIndex = srcNode._indexInList;
var srcNodeOwner = srcNodeOwners[srcIndex];
if (srcNodeOwner) {
var srcFullPath = srcNode.fullPath;
scrCrossClipNodeIndices[crossCount] = srcIndex;
var destNode = destNodesMap[srcFullPath];
if (destNode)
destCrossClipNodeIndices[crossCount] = destNode._indexInList;
else
destCrossClipNodeIndices[crossCount] = -1;
crossNodeOwnerIndicesMap[srcFullPath] = crossMark;
crossNodeOwners[crossCount] = srcNodeOwner;
crossCount++;
}
}
for (i = 0, n = destNodes.count; i < n; i++) {
destNode = destNodes.getNodeByIndex(i);
var destIndex = destNode._indexInList;
var destNodeOwner = destNodeOwners[destIndex];
if (destNodeOwner) {
var destFullPath = destNode.fullPath;
if (!srcNodesMap[destFullPath]) {
scrCrossClipNodeIndices[crossCount] = -1;
destCrossClipNodeIndices[crossCount] = destIndex;
crossNodeOwnerIndicesMap[destFullPath] = crossMark;
crossNodeOwners[crossCount] = destNodeOwner;
crossCount++;
}
}
}
break;
case 1:
case 2:
controllerLayer._playType = 2;
for (i = 0, n = crossNodeOwners.length; i < n; i++) {
var nodeOwner = crossNodeOwners[i];
nodeOwner.saveCrossFixedValue();
destNode = destNodesMap[nodeOwner.fullPath];
if (destNode)
destCrossClipNodeIndices[i] = destNode._indexInList;
else
destCrossClipNodeIndices[i] = -1;
}
crossCount = controllerLayer._crossNodesOwnersCount;
crossMark = controllerLayer._crossMark;
for (i = 0, n = destNodes.count; i < n; i++) {
destNode = destNodes.getNodeByIndex(i);
destIndex = destNode._indexInList;
destNodeOwner = destNodeOwners[destIndex];
if (destNodeOwner) {
destFullPath = destNode.fullPath;
if (crossNodeOwnerIndicesMap[destFullPath] !== crossMark) {
destCrossClipNodeIndices[crossCount] = destIndex;
crossNodeOwnerIndicesMap[destFullPath] = crossMark;
nodeOwner = destNodeOwners[destIndex];
crossNodeOwners[crossCount] = nodeOwner;
nodeOwner.saveCrossFixedValue();
crossCount++;
}
}
}
break;
}
controllerLayer._crossNodesOwnersCount = crossCount;
controllerLayer._crossPlayState = destAnimatorState;
controllerLayer._crossDuration = srcAnimatorState._clip._duration * transitionDuration;
if (normalizedTime !== Number.NEGATIVE_INFINITY)
crossPlayStateInfo._resetPlayState(destClip._duration * normalizedTime, controllerLayer._crossDuration);
else
crossPlayStateInfo._resetPlayState(0.0, controllerLayer._crossDuration);
var scripts = destAnimatorState._scripts;
if (scripts) {
for (i = 0, n = scripts.length; i < n; i++)
scripts[i].onStateEnter();
}
}
else {
console.warn("Invalid name " + layerIndex + ".");
}
}
else {
console.warn("Invalid layerIndex " + layerIndex + ".");
}
}
getCurrentAnimatorPlayState(layerInex = 0) {
return this._controllerLayers[layerInex]._playStateInfo;
}
get avatar() {
return this._avatar;
}
set avatar(value) {
if (this._avatar !== value) {
this._avatar = value;
if (value) {
this._getAvatarOwnersAndInitDatasAsync();
this.owner._changeHierarchyAnimatorAvatar(this, value);
}
else {
var parent = this.owner._parent;
this.owner._changeHierarchyAnimatorAvatar(this, parent ? parent._hierarchyAnimator._avatar : null);
}
}
}
_isLinkSpriteToAnimationNodeData(sprite, nodeName, isLink) {
var linkSprites = this._linkAvatarSpritesData[nodeName];
if (isLink) {
linkSprites || (this._linkAvatarSpritesData[nodeName] = linkSprites = []);
linkSprites.push(sprite);
}
else {
var index = linkSprites.indexOf(sprite);
linkSprites.splice(index, 1);
}
}
_getAvatarOwnersAndInitDatasAsync() {
for (var i = 0, n = this._controllerLayers.length; i < n; i++) {
var clipStateInfos = this._controllerLayers[i]._states;
for (var j = 0, m = clipStateInfos.length; j < m; j++)
this._getOwnersByClip(clipStateInfos[j]);
}
this._avatar._cloneDatasToAnimator(this);
for (var k in this._linkAvatarSpritesData) {
var sprites = this._linkAvatarSpritesData[k];
if (sprites) {
for (var c = 0, p = sprites.length; c < p; c++)
this._isLinkSpriteToAnimationNode(sprites[c], k, true);
}
}
}
_isLinkSpriteToAnimationNode(sprite, nodeName, isLink) {
if (this._avatar) {
var node = this._avatarNodeMap[nodeName];
if (node) {
if (isLink) {
sprite._transform._dummy = node.transform;
this._linkAvatarSprites.push(sprite);
var nodeTransform = node.transform;
var spriteTransform = sprite.transform;
if (!spriteTransform.owner.isStatic && nodeTransform) {
var spriteWorldMatrix = spriteTransform.worldMatrix;
var ownParTra = this.owner._transform._parent;
if (ownParTra) {
Utils3D.matrix4x4MultiplyMFM(ownParTra.worldMatrix, nodeTransform.getWorldMatrix(), spriteWorldMatrix);
}
else {
var sprWorE = spriteWorldMatrix.elements;
var nodWorE = nodeTransform.getWorldMatrix();
for (var i = 0; i < 16; i++)
sprWorE[i] = nodWorE[i];
}
spriteTransform.worldMatrix = spriteWorldMatrix;
}
}
else {
sprite._transform._dummy = null;
this._linkAvatarSprites.splice(this._linkAvatarSprites.indexOf(sprite), 1);
}
}
}
}
_updateAvatarNodesToSprite() {
for (var i = 0, n = this._linkAvatarSprites.length; i < n; i++) {
var sprite = this._linkAvatarSprites[i];
var nodeTransform = sprite.transform._dummy;
var spriteTransform = sprite.transform;
if (!spriteTransform.owner.isStatic && nodeTransform) {
var spriteWorldMatrix = spriteTransform.worldMatrix;
var ownTra = this.owner._transform;
Utils3D.matrix4x4MultiplyMFM(ownTra.worldMatrix, nodeTransform.getWorldMatrix(), spriteWorldMatrix);
spriteTransform.worldMatrix = spriteWorldMatrix;
}
}
}
linkSprite3DToAvatarNode(nodeName, sprite3D) {
this._isLinkSpriteToAnimationNodeData(sprite3D, nodeName, true);
this._isLinkSpriteToAnimationNode(sprite3D, nodeName, true);
return true;
}
unLinkSprite3DToAvatarNode(sprite3D) {
var dummy = sprite3D.transform._dummy;
if (dummy) {
var nodeName = dummy._owner.name;
this._isLinkSpriteToAnimationNodeData(sprite3D, nodeName, false);
this._isLinkSpriteToAnimationNode(sprite3D, nodeName, false);
return true;
}
else {
return false;
}
}
_updateAnimationNodeWorldMatix(localPositions, localRotations, localScales, worldMatrixs, parentIndices) {
Laya.LayaGL.instance.updateAnimationNodeWorldMatix(localPositions, localRotations, localScales, parentIndices, worldMatrixs);
}
}
Animator._tempVector31 = new Vector3();
Animator._tempQuaternion1 = new Quaternion();
Animator.CULLINGMODE_ALWAYSANIMATE = 0;
Animator.CULLINGMODE_CULLCOMPLETELY = 2;
class RenderContext3D {
constructor() {
this.invertY = false;
this.configPipeLineMode = "Forward";
}
}
RenderContext3D._instance = new RenderContext3D();
class RenderTexture extends Laya.BaseTexture {
constructor(width, height, format = Laya.RenderTextureFormat.R8G8B8, depthStencilFormat = Laya.RenderTextureDepthFormat.DEPTH_16, mulSampler = 1) {
super(format, false);
this._inPool = false;
this._mulSampler = 1;
this._mulSamplerRT = false;
this._isCameraTarget = false;
this._glTextureType = Laya.LayaGL.instance.TEXTURE_2D;
this._width = width;
this._height = height;
this._depthStencilFormat = depthStencilFormat;
this._mipmapCount = 1;
this._mulSampler = mulSampler;
this._create(width, height);
}
static get currentActive() {
return RenderTexture._currentActive;
}
static createFromPool(width, height, format = Laya.RenderTextureFormat.R8G8B8, depthStencilFormat = Laya.RenderTextureDepthFormat.DEPTH_16, mulSamples = 1) {
var tex;
for (var i = 0, n = RenderTexture._pool.length; i < n; i++) {
tex = RenderTexture._pool[i];
if (tex._width == width && tex._height == height && tex._format == format && tex._depthStencilFormat == depthStencilFormat && tex._mulSampler == mulSamples) {
tex._inPool = false;
var end = RenderTexture._pool[n - 1];
RenderTexture._pool[i] = end;
RenderTexture._pool.length -= 1;
return tex;
}
}
tex = new RenderTexture(width, height, format, depthStencilFormat, mulSamples);
tex.lock = true;
return tex;
}
static recoverToPool(renderTexture) {
if (renderTexture._inPool)
return;
RenderTexture._pool.push(renderTexture);
renderTexture._inPool = true;
}
get depthStencilFormat() {
return this._depthStencilFormat;
}
get defaulteTexture() {
return Laya.Texture2D.grayTexture;
}
get mulSampler() {
return this._mulSampler;
}
_create(width, height) {
var gl = Laya.LayaGL.instance;
var gl2 = gl;
var glTextureType = this._glTextureType;
var layaGPU = Laya.LayaGL.layaGPUInstance;
var isWebGL2 = layaGPU._isWebGL2;
var format = this._format;
this._frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
this._mulSamplerRT = isWebGL2 && (this._mulSampler > 1);
if (format !== Laya.RenderTextureFormat.Depth && format !== Laya.RenderTextureFormat.ShadowMap) {
if (this._mulSamplerRT) {
this._mulRenderBuffer = gl2.createRenderbuffer();
gl2.bindRenderbuffer(gl2.RENDERBUFFER, this._mulRenderBuffer);
switch (format) {
case Laya.RenderTextureFormat.R8G8B8:
gl2.renderbufferStorageMultisample(gl2.RENDERBUFFER, this._mulSampler, gl2.RGB8, width, height);
break;
case Laya.RenderTextureFormat.R8G8B8A8:
gl2.renderbufferStorageMultisample(gl2.RENDERBUFFER, this._mulSampler, gl2.RGBA8, width, height);
break;
case Laya.RenderTextureFormat.Alpha8:
gl2.renderbufferStorageMultisample(gl2.RENDERBUFFER, this._mulSampler, gl2.ALPHA, width, height);
break;
case Laya.RenderTextureFormat.R16G16B16A16:
gl2.renderbufferStorageMultisample(gl2.RENDERBUFFER, this._mulSampler, gl2.RGBA16F, width, height);
break;
}
gl2.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._mulRenderBuffer);
}
Laya.WebGLContext.bindTexture(gl, glTextureType, this._glTexture);
switch (format) {
case Laya.RenderTextureFormat.R8G8B8:
if (isWebGL2)
gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.RGB8, width, height);
else
gl.texImage2D(glTextureType, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
break;
case Laya.RenderTextureFormat.R8G8B8A8:
if (isWebGL2)
gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.RGBA8, width, height);
else
gl.texImage2D(glTextureType, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
break;
case Laya.RenderTextureFormat.Alpha8:
if (isWebGL2)
gl2.texStorage2D(glTextureType, this.mipmapCount, gl2.R8, width, height);
else
gl.texImage2D(glTextureType, 0, gl.ALPHA, width, height, 0, gl.ALPHA, gl.UNSIGNED_BYTE, null);
break;
case Laya.RenderTextureFormat.R16G16B16A16:
if (isWebGL2)
gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.RGBA16F, width, height);
else
gl.texImage2D(glTextureType, 0, gl.RGBA, width, height, 0, gl.RGBA, layaGPU._oesTextureHalfFloat.HALF_FLOAT_OES, null);
break;
}
if (this._mulSamplerRT) {
this._mulFrameBuffer = gl2.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this._mulFrameBuffer);
gl.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, this._glTexture, 0);
}
else
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._glTexture, 0);
}
if (format == Laya.RenderTextureFormat.Depth || format == Laya.RenderTextureFormat.ShadowMap) {
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
Laya.WebGLContext.bindTexture(gl, glTextureType, this._glTexture);
this.filterMode = Laya.FilterMode.Point;
switch (this._depthStencilFormat) {
case Laya.RenderTextureDepthFormat.DEPTH_16:
if (isWebGL2) {
gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.DEPTH_COMPONENT16, width, height);
}
else
gl.texImage2D(glTextureType, 0, gl.DEPTH_COMPONENT, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, this._glTexture, 0);
break;
case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8:
if (isWebGL2)
gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.DEPTH24_STENCIL8, width, height);
else
gl.texImage2D(glTextureType, 0, gl.DEPTH_STENCIL, width, height, 0, gl.DEPTH_STENCIL, layaGPU._webgl_depth_texture.UNSIGNED_INT_24_8_WEBGL, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, this._glTexture, 0);
break;
default:
throw "RenderTexture: depth format RenderTexture must use depthFormat with DEPTH_16 and DEPTHSTENCIL_16_8.";
}
if (isWebGL2 && format == Laya.RenderTextureFormat.ShadowMap)
gl2.texParameteri(glTextureType, gl2.TEXTURE_COMPARE_MODE, gl2.COMPARE_REF_TO_TEXTURE);
}
else {
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
if (this._depthStencilFormat !== Laya.RenderTextureDepthFormat.DEPTHSTENCIL_NONE) {
this._depthStencilBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthStencilBuffer);
if (this._mulSamplerRT) {
switch (this._depthStencilFormat) {
case Laya.RenderTextureDepthFormat.DEPTH_16:
gl2.renderbufferStorageMultisample(gl.RENDERBUFFER, this._mulSampler, gl2.DEPTH_COMPONENT16, width, height);
gl2.framebufferRenderbuffer(gl.FRAMEBUFFER, gl2.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer);
break;
case Laya.RenderTextureDepthFormat.STENCIL_8:
gl2.renderbufferStorageMultisample(gl.RENDERBUFFER, this._mulSampler, gl2.STENCIL_INDEX8, width, height);
gl2.framebufferRenderbuffer(gl.FRAMEBUFFER, gl2.STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer);
break;
case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8:
gl2.renderbufferStorageMultisample(gl.RENDERBUFFER, this._mulSampler, gl2.DEPTH_STENCIL, width, height);
gl2.framebufferRenderbuffer(gl.FRAMEBUFFER, gl2.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer);
break;
default:
throw "RenderTexture: unkonw depth format.";
}
}
else {
switch (this._depthStencilFormat) {
case Laya.RenderTextureDepthFormat.DEPTH_16:
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl2.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer);
break;
case Laya.RenderTextureDepthFormat.STENCIL_8:
gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer);
break;
case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8:
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer);
break;
default:
throw "RenderTexture: unkonw depth format.";
}
}
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
}
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU);
this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV);
this._setFilterMode(this._filterMode);
this._setAnisotropy(this._anisoLevel);
this._readyed = true;
this._activeResource();
this._setGPUMemory(width * height * 4);
}
_start() {
var gl = Laya.LayaGL.instance;
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
RenderTexture._currentActive = this;
(this._isCameraTarget) && (RenderContext3D._instance.invertY = true);
this._readyed = false;
}
_end() {
var gl = Laya.LayaGL.instance;
var gl2 = gl;
if (this._mulSamplerRT) {
gl2.bindFramebuffer(gl2.READ_FRAMEBUFFER, this._frameBuffer);
gl2.bindFramebuffer(gl2.DRAW_FRAMEBUFFER, this._mulFrameBuffer);
gl2.clearBufferfv(gl2.COLOR, 0, [0.0, 0.0, 0.0, 0.0]);
gl2.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this._width, this._height, gl2.COLOR_BUFFER_BIT, gl.NEAREST);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
RenderTexture._currentActive = null;
(this._isCameraTarget) && (RenderContext3D._instance.invertY = false);
this._readyed = true;
}
getData(x, y, width, height, out) {
if (Laya.Render.isConchApp && window.conchConfig.threadMode == 2) {
throw "native 2 thread mode use getDataAsync";
}
var gl = Laya.LayaGL.instance;
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
var canRead = (gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE);
if (!canRead) {
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
return null;
}
switch (this.format) {
case Laya.RenderTextureFormat.R8G8B8:
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, out);
break;
case Laya.RenderTextureFormat.R8G8B8A8:
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, out);
break;
case Laya.RenderTextureFormat.R16G16B16A16:
gl.readPixels(x, y, width, height, gl.RGBA, gl.FLOAT, out);
debugger;
break;
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
return out;
}
_disposeResource() {
if (this._frameBuffer) {
var gl = Laya.LayaGL.instance;
gl.deleteTexture(this._glTexture);
gl.deleteFramebuffer(this._frameBuffer);
gl.deleteRenderbuffer(this._depthStencilBuffer);
this._glTexture = null;
this._frameBuffer = null;
this._depthStencilBuffer = null;
this._setGPUMemory(0);
}
}
getDataAsync(x, y, width, height, callBack) {
var gl = Laya.LayaGL.instance;
gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer);
gl.readPixelsAsync(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, function (data) {
callBack(new Uint8Array(data));
});
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
}
RenderTexture._pool = [];
class DefineDatas {
constructor() {
this._mask = [];
this._length = 0;
}
_intersectionDefineDatas(define) {
var unionMask = define._mask;
var mask = this._mask;
for (var i = this._length - 1; i >= 0; i--) {
var value = mask[i] & unionMask[i];
if (value == 0 && i == this._length - 1)
this._length--;
else
mask[i] = value;
}
}
add(define) {
var index = define._index;
var size = index + 1;
var mask = this._mask;
var maskStart = this._length;
if (maskStart < size) {
(mask.length < size) && (mask.length = size);
for (; maskStart < index; maskStart++)
mask[maskStart] = 0;
mask[index] = define._value;
this._length = size;
}
else {
mask[index] |= define._value;
}
}
remove(define) {
var index = define._index;
var mask = this._mask;
var endIndex = this._length - 1;
if (index > endIndex)
return;
var newValue = mask[index] & ~define._value;
if (index == endIndex && newValue === 0)
this._length--;
else
mask[index] = newValue;
}
addDefineDatas(define) {
var addMask = define._mask;
var size = define._length;
var mask = this._mask;
var maskStart = this._length;
if (maskStart < size) {
mask.length = size;
for (var i = 0; i < maskStart; i++)
mask[i] |= addMask[i];
for (; i < size; i++)
mask[i] = addMask[i];
this._length = size;
}
else {
for (var i = 0; i < size; i++) {
mask[i] |= addMask[i];
}
}
}
removeDefineDatas(define) {
var removeMask = define._mask;
var mask = this._mask;
var endIndex = this._length - 1;
var i = Math.min(define._length, endIndex);
for (; i >= 0; i--) {
var newValue = mask[i] & ~removeMask[i];
if (i == endIndex && newValue === 0) {
endIndex--;
this._length--;
}
else {
mask[i] = newValue;
}
}
}
has(define) {
var index = define._index;
if (index >= this._length)
return false;
return (this._mask[index] & define._value) !== 0;
}
clear() {
this._length = 0;
}
cloneTo(destObject) {
var destDefineData = destObject;
var destMask = destDefineData._mask;
var mask = this._mask;
var count = this._length;
destMask.length = count;
for (var i = 0; i < count; i++)
destMask[i] = mask[i];
destDefineData._length = count;
}
clone() {
var dest = new DefineDatas();
this.cloneTo(dest);
return dest;
}
}
class VertexBuffer3D extends Laya.Buffer {
constructor(byteLength, bufferUsage, canRead = false) {
super();
this._vertexDeclaration = null;
this._float32Reader = null;
var gl = Laya.LayaGL.instance;
this._bufferUsage = bufferUsage;
this._bufferType = gl.ARRAY_BUFFER;
this._canRead = canRead;
this._byteLength = byteLength;
this.bind();
gl.bufferData(this._bufferType, this._byteLength, this._bufferUsage);
if (canRead) {
this._buffer = new Uint8Array(byteLength);
this._float32Reader = new Float32Array(this._buffer.buffer);
}
}
get vertexDeclaration() {
return this._vertexDeclaration;
}
set vertexDeclaration(value) {
this._vertexDeclaration = value;
}
get canRead() {
return this._canRead;
}
bind() {
if (Laya.Buffer._bindedVertexBuffer !== this._glBuffer) {
var gl = Laya.LayaGL.instance;
gl.bindBuffer(gl.ARRAY_BUFFER, this._glBuffer);
Laya.Buffer._bindedVertexBuffer = this._glBuffer;
return true;
}
else {
return false;
}
}
orphanStorage() {
this.bind();
Laya.LayaGL.instance.bufferData(this._bufferType, this._byteLength, this._bufferUsage);
}
setData(buffer, bufferOffset = 0, dataStartIndex = 0, dataCount = Number.MAX_SAFE_INTEGER) {
this.bind();
var needSubData = dataStartIndex !== 0 || dataCount !== Number.MAX_SAFE_INTEGER;
if (needSubData) {
var subData = new Uint8Array(buffer, dataStartIndex, dataCount);
Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset, subData);
if (this._canRead)
this._buffer.set(subData, bufferOffset);
}
else {
Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset, buffer);
if (this._canRead)
this._buffer.set(new Uint8Array(buffer), bufferOffset);
}
}
getUint8Data() {
if (this._canRead)
return this._buffer;
else
throw new Error("Can't read data from VertexBuffer with only write flag!");
}
getFloat32Data() {
if (this._canRead)
return this._float32Reader;
else
throw new Error("Can't read data from VertexBuffer with only write flag!");
}
markAsUnreadbale() {
this._canRead = false;
this._buffer = null;
this._float32Reader = null;
}
destroy() {
super.destroy();
this._buffer = null;
this._float32Reader = null;
this._vertexDeclaration = null;
this._byteLength = 0;
}
}
VertexBuffer3D.DATATYPE_FLOAT32ARRAY = 0;
VertexBuffer3D.DATATYPE_UINT8ARRAY = 1;
class VertexElementFormat {
static __init__() {
var gl = Laya.LayaGL.instance;
VertexElementFormat._elementInfos = {
"single": [1, gl.FLOAT, 0],
"vector2": [2, gl.FLOAT, 0],
"vector3": [3, gl.FLOAT, 0],
"vector4": [4, gl.FLOAT, 0],
"color": [4, gl.FLOAT, 0],
"byte4": [4, gl.UNSIGNED_BYTE, 0],
"byte3": [3, gl.UNSIGNED_BYTE, 0],
"byte2": [2, gl.UNSIGNED_BYTE, 0],
"byte": [1, gl.UNSIGNED_BYTE, 0],
"short2": [2, gl.FLOAT, 0],
"short4": [4, gl.FLOAT, 0],
"normalizedshort2": [2, gl.FLOAT, 0],
"normalizedshort4": [4, gl.FLOAT, 0],
"halfvector2": [2, gl.FLOAT, 0],
"halfvector4": [4, gl.FLOAT, 0]
};
}
static getElementInfos(element) {
var info = VertexElementFormat._elementInfos[element];
if (info)
return info;
else
throw "VertexElementFormat: this vertexElementFormat is not implement.";
}
}
VertexElementFormat.Single = "single";
VertexElementFormat.Vector2 = "vector2";
VertexElementFormat.Vector3 = "vector3";
VertexElementFormat.Vector4 = "vector4";
VertexElementFormat.Color = "color";
VertexElementFormat.Byte4 = "byte4";
VertexElementFormat.Byte3 = "byte3";
VertexElementFormat.Byte2 = "byte2";
VertexElementFormat.ByteOne = "byte";
VertexElementFormat.Short2 = "short2";
VertexElementFormat.Short4 = "short4";
VertexElementFormat.NormalizedShort2 = "normalizedshort2";
VertexElementFormat.NormalizedShort4 = "normalizedshort4";
VertexElementFormat.HalfVector2 = "halfvector2";
VertexElementFormat.HalfVector4 = "halfvector4";
class Matrix4x4 {
constructor(m11 = 1, m12 = 0, m13 = 0, m14 = 0, m21 = 0, m22 = 1, m23 = 0, m24 = 0, m31 = 0, m32 = 0, m33 = 1, m34 = 0, m41 = 0, m42 = 0, m43 = 0, m44 = 1, elements = null) {
var e = elements ? this.elements = elements : this.elements = new Float32Array(16);
e[0] = m11;
e[1] = m12;
e[2] = m13;
e[3] = m14;
e[4] = m21;
e[5] = m22;
e[6] = m23;
e[7] = m24;
e[8] = m31;
e[9] = m32;
e[10] = m33;
e[11] = m34;
e[12] = m41;
e[13] = m42;
e[14] = m43;
e[15] = m44;
}
static createRotationX(rad, out) {
var oe = out.elements;
var s = Math.sin(rad), c = Math.cos(rad);
oe[1] = oe[2] = oe[3] = oe[4] = oe[7] = oe[8] = oe[11] = oe[12] = oe[13] = oe[14] = 0;
oe[0] = oe[15] = 1;
oe[5] = oe[10] = c;
oe[6] = s;
oe[9] = -s;
}
static createRotationY(rad, out) {
var oe = out.elements;
var s = Math.sin(rad), c = Math.cos(rad);
oe[1] = oe[3] = oe[4] = oe[6] = oe[7] = oe[9] = oe[11] = oe[12] = oe[13] = oe[14] = 0;
oe[5] = oe[15] = 1;
oe[0] = oe[10] = c;
oe[2] = -s;
oe[8] = s;
}
static createRotationZ(rad, out) {
var oe = out.elements;
var s = Math.sin(rad), c = Math.cos(rad);
oe[2] = oe[3] = oe[6] = oe[7] = oe[8] = oe[9] = oe[11] = oe[12] = oe[13] = oe[14] = 0;
oe[10] = oe[15] = 1;
oe[0] = oe[5] = c;
oe[1] = s;
oe[4] = -s;
}
static createRotationYawPitchRoll(yaw, pitch, roll, result) {
Quaternion.createFromYawPitchRoll(yaw, pitch, roll, Matrix4x4._tempQuaternion);
Matrix4x4.createRotationQuaternion(Matrix4x4._tempQuaternion, result);
}
static createRotationAxis(axis, angle, result) {
var x = axis.x;
var y = axis.y;
var z = axis.z;
var cos = Math.cos(angle);
var sin = Math.sin(angle);
var xx = x * x;
var yy = y * y;
var zz = z * z;
var xy = x * y;
var xz = x * z;
var yz = y * z;
var resultE = result.elements;
resultE[3] = resultE[7] = resultE[11] = resultE[12] = resultE[13] = resultE[14] = 0;
resultE[15] = 1.0;
resultE[0] = xx + (cos * (1.0 - xx));
resultE[1] = (xy - (cos * xy)) + (sin * z);
resultE[2] = (xz - (cos * xz)) - (sin * y);
resultE[4] = (xy - (cos * xy)) - (sin * z);
resultE[5] = yy + (cos * (1.0 - yy));
resultE[6] = (yz - (cos * yz)) + (sin * x);
resultE[8] = (xz - (cos * xz)) + (sin * y);
resultE[9] = (yz - (cos * yz)) - (sin * x);
resultE[10] = zz + (cos * (1.0 - zz));
}
setRotation(rotation) {
var rotationX = rotation.x;
var rotationY = rotation.y;
var rotationZ = rotation.z;
var rotationW = rotation.w;
var xx = rotationX * rotationX;
var yy = rotationY * rotationY;
var zz = rotationZ * rotationZ;
var xy = rotationX * rotationY;
var zw = rotationZ * rotationW;
var zx = rotationZ * rotationX;
var yw = rotationY * rotationW;
var yz = rotationY * rotationZ;
var xw = rotationX * rotationW;
var e = this.elements;
e[0] = 1.0 - (2.0 * (yy + zz));
e[1] = 2.0 * (xy + zw);
e[2] = 2.0 * (zx - yw);
e[4] = 2.0 * (xy - zw);
e[5] = 1.0 - (2.0 * (zz + xx));
e[6] = 2.0 * (yz + xw);
e[8] = 2.0 * (zx + yw);
e[9] = 2.0 * (yz - xw);
e[10] = 1.0 - (2.0 * (yy + xx));
}
setPosition(position) {
var e = this.elements;
e[12] = position.x;
e[13] = position.y;
e[14] = position.z;
}
static createRotationQuaternion(rotation, result) {
var resultE = result.elements;
var rotationX = rotation.x;
var rotationY = rotation.y;
var rotationZ = rotation.z;
var rotationW = rotation.w;
var xx = rotationX * rotationX;
var yy = rotationY * rotationY;
var zz = rotationZ * rotationZ;
var xy = rotationX * rotationY;
var zw = rotationZ * rotationW;
var zx = rotationZ * rotationX;
var yw = rotationY * rotationW;
var yz = rotationY * rotationZ;
var xw = rotationX * rotationW;
resultE[3] = resultE[7] = resultE[11] = resultE[12] = resultE[13] = resultE[14] = 0;
resultE[15] = 1.0;
resultE[0] = 1.0 - (2.0 * (yy + zz));
resultE[1] = 2.0 * (xy + zw);
resultE[2] = 2.0 * (zx - yw);
resultE[4] = 2.0 * (xy - zw);
resultE[5] = 1.0 - (2.0 * (zz + xx));
resultE[6] = 2.0 * (yz + xw);
resultE[8] = 2.0 * (zx + yw);
resultE[9] = 2.0 * (yz - xw);
resultE[10] = 1.0 - (2.0 * (yy + xx));
}
static createTranslate(trans, out) {
var oe = out.elements;
oe[4] = oe[8] = oe[1] = oe[9] = oe[2] = oe[6] = oe[3] = oe[7] = oe[11] = 0;
oe[0] = oe[5] = oe[10] = oe[15] = 1;
oe[12] = trans.x;
oe[13] = trans.y;
oe[14] = trans.z;
}
static createScaling(scale, out) {
var oe = out.elements;
oe[0] = scale.x;
oe[5] = scale.y;
oe[10] = scale.z;
oe[1] = oe[4] = oe[8] = oe[12] = oe[9] = oe[13] = oe[2] = oe[6] = oe[14] = oe[3] = oe[7] = oe[11] = 0;
oe[15] = 1;
}
static multiply(left, right, out) {
var l = right.elements;
var r = left.elements;
var e = out.elements;
var l11 = l[0], l12 = l[1], l13 = l[2], l14 = l[3];
var l21 = l[4], l22 = l[5], l23 = l[6], l24 = l[7];
var l31 = l[8], l32 = l[9], l33 = l[10], l34 = l[11];
var l41 = l[12], l42 = l[13], l43 = l[14], l44 = l[15];
var r11 = r[0], r12 = r[1], r13 = r[2], r14 = r[3];
var r21 = r[4], r22 = r[5], r23 = r[6], r24 = r[7];
var r31 = r[8], r32 = r[9], r33 = r[10], r34 = r[11];
var r41 = r[12], r42 = r[13], r43 = r[14], r44 = r[15];
e[0] = (l11 * r11) + (l12 * r21) + (l13 * r31) + (l14 * r41);
e[1] = (l11 * r12) + (l12 * r22) + (l13 * r32) + (l14 * r42);
e[2] = (l11 * r13) + (l12 * r23) + (l13 * r33) + (l14 * r43);
e[3] = (l11 * r14) + (l12 * r24) + (l13 * r34) + (l14 * r44);
e[4] = (l21 * r11) + (l22 * r21) + (l23 * r31) + (l24 * r41);
e[5] = (l21 * r12) + (l22 * r22) + (l23 * r32) + (l24 * r42);
e[6] = (l21 * r13) + (l22 * r23) + (l23 * r33) + (l24 * r43);
e[7] = (l21 * r14) + (l22 * r24) + (l23 * r34) + (l24 * r44);
e[8] = (l31 * r11) + (l32 * r21) + (l33 * r31) + (l34 * r41);
e[9] = (l31 * r12) + (l32 * r22) + (l33 * r32) + (l34 * r42);
e[10] = (l31 * r13) + (l32 * r23) + (l33 * r33) + (l34 * r43);
e[11] = (l31 * r14) + (l32 * r24) + (l33 * r34) + (l34 * r44);
e[12] = (l41 * r11) + (l42 * r21) + (l43 * r31) + (l44 * r41);
e[13] = (l41 * r12) + (l42 * r22) + (l43 * r32) + (l44 * r42);
e[14] = (l41 * r13) + (l42 * r23) + (l43 * r33) + (l44 * r43);
e[15] = (l41 * r14) + (l42 * r24) + (l43 * r34) + (l44 * r44);
}
static multiplyForNative(left, right, out) {
Laya.LayaGL.instance.matrix4x4Multiply(left.elements, right.elements, out.elements);
}
static createFromQuaternion(rotation, out) {
var e = out.elements;
var x = rotation.x, y = rotation.y, z = rotation.z, w = rotation.w;
var x2 = x + x;
var y2 = y + y;
var z2 = z + z;
var xx = x * x2;
var yx = y * x2;
var yy = y * y2;
var zx = z * x2;
var zy = z * y2;
var zz = z * z2;
var wx = w * x2;
var wy = w * y2;
var wz = w * z2;
e[0] = 1 - yy - zz;
e[1] = yx + wz;
e[2] = zx - wy;
e[3] = 0;
e[4] = yx - wz;
e[5] = 1 - xx - zz;
e[6] = zy + wx;
e[7] = 0;
e[8] = zx + wy;
e[9] = zy - wx;
e[10] = 1 - xx - yy;
e[11] = 0;
e[12] = 0;
e[13] = 0;
e[14] = 0;
e[15] = 1;
}
static createAffineTransformation(trans, rot, scale, out) {
var oe = out.elements;
var x = rot.x, y = rot.y, z = rot.z, w = rot.w, x2 = x + x, y2 = y + y, z2 = z + z;
var xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2;
var wx = w * x2, wy = w * y2, wz = w * z2, sx = scale.x, sy = scale.y, sz = scale.z;
oe[0] = (1 - (yy + zz)) * sx;
oe[1] = (xy + wz) * sx;
oe[2] = (xz - wy) * sx;
oe[3] = 0;
oe[4] = (xy - wz) * sy;
oe[5] = (1 - (xx + zz)) * sy;
oe[6] = (yz + wx) * sy;
oe[7] = 0;
oe[8] = (xz + wy) * sz;
oe[9] = (yz - wx) * sz;
oe[10] = (1 - (xx + yy)) * sz;
oe[11] = 0;
oe[12] = trans.x;
oe[13] = trans.y;
oe[14] = trans.z;
oe[15] = 1;
}
static createLookAt(eye, target, up, out) {
var oE = out.elements;
var xaxis = Matrix4x4._tempVector0;
var yaxis = Matrix4x4._tempVector1;
var zaxis = Matrix4x4._tempVector2;
Vector3.subtract(eye, target, zaxis);
Vector3.normalize(zaxis, zaxis);
Vector3.cross(up, zaxis, xaxis);
Vector3.normalize(xaxis, xaxis);
Vector3.cross(zaxis, xaxis, yaxis);
oE[3] = oE[7] = oE[11] = 0;
oE[15] = 1;
oE[0] = xaxis.x;
oE[4] = xaxis.y;
oE[8] = xaxis.z;
oE[1] = yaxis.x;
oE[5] = yaxis.y;
oE[9] = yaxis.z;
oE[2] = zaxis.x;
oE[6] = zaxis.y;
oE[10] = zaxis.z;
oE[12] = -Vector3.dot(xaxis, eye);
oE[13] = -Vector3.dot(yaxis, eye);
oE[14] = -Vector3.dot(zaxis, eye);
}
static createPerspective(fov, aspect, znear, zfar, out) {
var yScale = 1.0 / Math.tan(fov * 0.5);
var xScale = yScale / aspect;
var halfWidth = znear / xScale;
var halfHeight = znear / yScale;
Matrix4x4.createPerspectiveOffCenter(-halfWidth, halfWidth, -halfHeight, halfHeight, znear, zfar, out);
}
static createPerspectiveOffCenter(left, right, bottom, top, znear, zfar, out) {
var oe = out.elements;
var zRange = zfar / (zfar - znear);
oe[1] = oe[2] = oe[3] = oe[4] = oe[6] = oe[7] = oe[12] = oe[13] = oe[15] = 0;
oe[0] = 2.0 * znear / (right - left);
oe[5] = 2.0 * znear / (top - bottom);
oe[8] = (left + right) / (right - left);
oe[9] = (top + bottom) / (top - bottom);
oe[10] = -zRange;
oe[11] = -1.0;
oe[14] = -znear * zRange;
}
static createOrthoOffCenter(left, right, bottom, top, znear, zfar, out) {
var oe = out.elements;
var zRange = 1.0 / (zfar - znear);
oe[1] = oe[2] = oe[3] = oe[4] = oe[6] = oe[8] = oe[7] = oe[9] = oe[11] = 0;
oe[15] = 1;
oe[0] = 2.0 / (right - left);
oe[5] = 2.0 / (top - bottom);
oe[10] = -zRange;
oe[12] = (left + right) / (left - right);
oe[13] = (top + bottom) / (bottom - top);
oe[14] = -znear * zRange;
}
getElementByRowColumn(row, column) {
if (row < 0 || row > 3)
throw new Error("row Rows and columns for matrices run from 0 to 3, inclusive.");
if (column < 0 || column > 3)
throw new Error("column Rows and columns for matrices run from 0 to 3, inclusive.");
return this.elements[(row * 4) + column];
}
setElementByRowColumn(row, column, value) {
if (row < 0 || row > 3)
throw new Error("row Rows and columns for matrices run from 0 to 3, inclusive.");
if (column < 0 || column > 3)
throw new Error("column Rows and columns for matrices run from 0 to 3, inclusive.");
this.elements[(row * 4) + column] = value;
}
equalsOtherMatrix(other) {
var e = this.elements;
var oe = other.elements;
return (MathUtils3D.nearEqual(e[0], oe[0]) && MathUtils3D.nearEqual(e[1], oe[1]) && MathUtils3D.nearEqual(e[2], oe[2]) && MathUtils3D.nearEqual(e[3], oe[3]) && MathUtils3D.nearEqual(e[4], oe[4]) && MathUtils3D.nearEqual(e[5], oe[5]) && MathUtils3D.nearEqual(e[6], oe[6]) && MathUtils3D.nearEqual(e[7], oe[7]) && MathUtils3D.nearEqual(e[8], oe[8]) && MathUtils3D.nearEqual(e[9], oe[9]) && MathUtils3D.nearEqual(e[10], oe[10]) && MathUtils3D.nearEqual(e[11], oe[11]) && MathUtils3D.nearEqual(e[12], oe[12]) && MathUtils3D.nearEqual(e[13], oe[13]) && MathUtils3D.nearEqual(e[14], oe[14]) && MathUtils3D.nearEqual(e[15], oe[15]));
}
decomposeTransRotScale(translation, rotation, scale) {
var rotationMatrix = Matrix4x4._tempMatrix4x4;
if (this.decomposeTransRotMatScale(translation, rotationMatrix, scale)) {
Quaternion.createFromMatrix4x4(rotationMatrix, rotation);
return true;
}
else {
rotation.identity();
return false;
}
}
decomposeTransRotMatScale(translation, rotationMatrix, scale) {
var e = this.elements;
var te = translation;
var re = rotationMatrix.elements;
var se = scale;
te.x = e[12];
te.y = e[13];
te.z = e[14];
var m11 = e[0], m12 = e[1], m13 = e[2];
var m21 = e[4], m22 = e[5], m23 = e[6];
var m31 = e[8], m32 = e[9], m33 = e[10];
var sX = se.x = Math.sqrt((m11 * m11) + (m12 * m12) + (m13 * m13));
var sY = se.y = Math.sqrt((m21 * m21) + (m22 * m22) + (m23 * m23));
var sZ = se.z = Math.sqrt((m31 * m31) + (m32 * m32) + (m33 * m33));
if (MathUtils3D.isZero(sX) || MathUtils3D.isZero(sY) || MathUtils3D.isZero(sZ)) {
re[1] = re[2] = re[3] = re[4] = re[6] = re[7] = re[8] = re[9] = re[11] = re[12] = re[13] = re[14] = 0;
re[0] = re[5] = re[10] = re[15] = 1;
return false;
}
var at = Matrix4x4._tempVector0;
at.x = m31 / sZ;
at.y = m32 / sZ;
at.z = m33 / sZ;
var tempRight = Matrix4x4._tempVector1;
tempRight.x = m11 / sX;
tempRight.y = m12 / sX;
tempRight.z = m13 / sX;
var up = Matrix4x4._tempVector2;
Vector3.cross(at, tempRight, up);
var right = Matrix4x4._tempVector1;
Vector3.cross(up, at, right);
re[3] = re[7] = re[11] = re[12] = re[13] = re[14] = 0;
re[15] = 1;
re[0] = right.x;
re[1] = right.y;
re[2] = right.z;
re[4] = up.x;
re[5] = up.y;
re[6] = up.z;
re[8] = at.x;
re[9] = at.y;
re[10] = at.z;
((re[0] * m11 + re[1] * m12 + re[2] * m13) < 0.0) && (se.x = -sX);
((re[4] * m21 + re[5] * m22 + re[6] * m23) < 0.0) && (se.y = -sY);
((re[8] * m31 + re[9] * m32 + re[10] * m33) < 0.0) && (se.z = -sZ);
return true;
}
decomposeYawPitchRoll(yawPitchRoll) {
var pitch = Math.asin(-this.elements[9]);
yawPitchRoll.y = pitch;
var test = Math.cos(pitch);
if (test > MathUtils3D.zeroTolerance) {
yawPitchRoll.z = Math.atan2(this.elements[1], this.elements[5]);
yawPitchRoll.x = Math.atan2(this.elements[8], this.elements[10]);
}
else {
yawPitchRoll.z = Math.atan2(-this.elements[4], this.elements[0]);
yawPitchRoll.x = 0.0;
}
}
normalize() {
var v = this.elements;
var c = v[0], d = v[1], e = v[2], g = Math.sqrt(c * c + d * d + e * e);
if (g) {
if (g == 1)
return;
}
else {
v[0] = 0;
v[1] = 0;
v[2] = 0;
return;
}
g = 1 / g;
v[0] = c * g;
v[1] = d * g;
v[2] = e * g;
}
transpose() {
var e, t;
e = this.elements;
t = e[1];
e[1] = e[4];
e[4] = t;
t = e[2];
e[2] = e[8];
e[8] = t;
t = e[3];
e[3] = e[12];
e[12] = t;
t = e[6];
e[6] = e[9];
e[9] = t;
t = e[7];
e[7] = e[13];
e[13] = t;
t = e[11];
e[11] = e[14];
e[14] = t;
return this;
}
invert(out) {
var ae = this.elements;
var oe = out.elements;
var a00 = ae[0], a01 = ae[1], a02 = ae[2], a03 = ae[3], a10 = ae[4], a11 = ae[5], a12 = ae[6], a13 = ae[7], a20 = ae[8], a21 = ae[9], a22 = ae[10], a23 = ae[11], a30 = ae[12], a31 = ae[13], a32 = ae[14], a33 = ae[15], b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10, b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11, b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12, b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30, b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31, b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32, det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (Math.abs(det) === 0.0) {
return;
}
det = 1.0 / det;
oe[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
oe[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
oe[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
oe[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
oe[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
oe[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
oe[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
oe[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
oe[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
oe[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
oe[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
oe[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
oe[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
oe[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
oe[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
oe[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
}
static billboard(objectPosition, cameraPosition, cameraUp, cameraForward, mat) {
Vector3.subtract(objectPosition, cameraPosition, Matrix4x4._tempVector0);
var lengthSq = Vector3.scalarLengthSquared(Matrix4x4._tempVector0);
if (MathUtils3D.isZero(lengthSq)) {
Vector3.scale(cameraForward, -1, Matrix4x4._tempVector1);
Matrix4x4._tempVector1.cloneTo(Matrix4x4._tempVector0);
}
else {
Vector3.scale(Matrix4x4._tempVector0, 1 / Math.sqrt(lengthSq), Matrix4x4._tempVector0);
}
Vector3.cross(cameraUp, Matrix4x4._tempVector0, Matrix4x4._tempVector2);
Vector3.normalize(Matrix4x4._tempVector2, Matrix4x4._tempVector2);
Vector3.cross(Matrix4x4._tempVector0, Matrix4x4._tempVector2, Matrix4x4._tempVector3);
var crosse = Matrix4x4._tempVector2;
var finale = Matrix4x4._tempVector3;
var diffee = Matrix4x4._tempVector0;
var obpose = objectPosition;
var mate = mat.elements;
mate[0] = crosse.x;
mate[1] = crosse.y;
mate[2] = crosse.z;
mate[3] = 0.0;
mate[4] = finale.x;
mate[5] = finale.y;
mate[6] = finale.z;
mate[7] = 0.0;
mate[8] = diffee.x;
mate[9] = diffee.y;
mate[10] = diffee.z;
mate[11] = 0.0;
mate[12] = obpose.x;
mate[13] = obpose.y;
mate[14] = obpose.z;
mate[15] = 1.0;
}
identity() {
var e = this.elements;
e[1] = e[2] = e[3] = e[4] = e[6] = e[7] = e[8] = e[9] = e[11] = e[12] = e[13] = e[14] = 0;
e[0] = e[5] = e[10] = e[15] = 1;
}
cloneTo(destObject) {
var i, s, d;
s = this.elements;
d = destObject.elements;
if (s === d) {
return;
}
for (i = 0; i < 16; ++i) {
d[i] = s[i];
}
}
clone() {
var dest = new Matrix4x4();
this.cloneTo(dest);
return dest;
}
static translation(v3, out) {
var oe = out.elements;
oe[0] = oe[5] = oe[10] = oe[15] = 1;
oe[12] = v3.x;
oe[13] = v3.y;
oe[14] = v3.z;
}
getTranslationVector(out) {
var me = this.elements;
out.x = me[12];
out.y = me[13];
out.z = me[14];
}
setTranslationVector(translate) {
var me = this.elements;
var ve = translate;
me[12] = ve.x;
me[13] = ve.y;
me[14] = ve.z;
}
getForward(out) {
var me = this.elements;
out.x = -me[8];
out.y = -me[9];
out.z = -me[10];
}
setForward(forward) {
var me = this.elements;
me[8] = -forward.x;
me[9] = -forward.y;
me[10] = -forward.z;
}
getInvertFront() {
this.decomposeTransRotScale(Matrix4x4._tempVector0, Matrix4x4._tempQuaternion, Matrix4x4._tempVector1);
var scale = Matrix4x4._tempVector1;
var isInvert = scale.x < 0;
(scale.y < 0) && (isInvert = !isInvert);
(scale.z < 0) && (isInvert = !isInvert);
return isInvert;
}
}
Matrix4x4._tempMatrix4x4 = new Matrix4x4();
Matrix4x4.TEMPMatrix0 = new Matrix4x4();
Matrix4x4.TEMPMatrix1 = new Matrix4x4();
Matrix4x4._tempVector0 = new Vector3();
Matrix4x4._tempVector1 = new Vector3();
Matrix4x4._tempVector2 = new Vector3();
Matrix4x4._tempVector3 = new Vector3();
Matrix4x4._tempQuaternion = new Quaternion();
Matrix4x4.DEFAULT = new Matrix4x4();
Matrix4x4.ZERO = new Matrix4x4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
class ShaderData {
constructor(ownerResource = null) {
this._ownerResource = null;
this._data = null;
this._defineDatas = new DefineDatas();
this._runtimeCopyValues = [];
this._ownerResource = ownerResource;
this._initData();
}
_initData() {
this._data = {};
}
getData() {
return this._data;
}
addDefine(define) {
this._defineDatas.add(define);
}
removeDefine(define) {
this._defineDatas.remove(define);
}
hasDefine(define) {
return this._defineDatas.has(define);
}
clearDefine() {
this._defineDatas.clear();
}
getBool(index) {
return this._data[index];
}
setBool(index, value) {
this._data[index] = value;
}
getInt(index) {
return this._data[index];
}
setInt(index, value) {
this._data[index] = value;
}
getNumber(index) {
return this._data[index];
}
setNumber(index, value) {
this._data[index] = value;
}
getVector2(index) {
return this._data[index];
}
setVector2(index, value) {
this._data[index] = value;
}
getVector3(index) {
return this._data[index];
}
setVector3(index, value) {
this._data[index] = value;
}
getVector(index) {
return this._data[index];
}
setVector(index, value) {
this._data[index] = value;
}
getQuaternion(index) {
return this._data[index];
}
setQuaternion(index, value) {
this._data[index] = value;
}
getMatrix4x4(index) {
return this._data[index];
}
setMatrix4x4(index, value) {
this._data[index] = value;
}
getBuffer(shaderIndex) {
return this._data[shaderIndex];
}
setBuffer(index, value) {
this._data[index] = value;
}
setTexture(index, value) {
var lastValue = this._data[index];
this._data[index] = value ? value : Laya.Texture2D.erroTextur;
if (this._ownerResource && this._ownerResource.referenceCount > 0) {
(lastValue) && (lastValue._removeReference());
(value) && (value._addReference());
}
}
getTexture(index) {
return this._data[index];
}
setValueData(index, value) {
this._data[index] = value;
}
getValueData(index) {
return this._data[index];
}
setAttribute(index, value) {
this._data[index] = value;
}
getAttribute(index) {
return this._data[index];
}
getLength() {
return this._data.length;
}
setLength(value) {
this._data.length = value;
}
cloneTo(destObject) {
var dest = destObject;
var destData = dest._data;
for (var k in this._data) {
var value = this._data[k];
if (value != null) {
if (typeof (value) == 'number') {
destData[k] = value;
}
else if (typeof (value) == 'number') {
destData[k] = value;
}
else if (typeof (value) == "boolean") {
destData[k] = value;
}
else if (value instanceof Vector2) {
var v2 = (destData[k]) || (destData[k] = new Vector2());
value.cloneTo(v2);
destData[k] = v2;
}
else if (value instanceof Vector3) {
var v3 = (destData[k]) || (destData[k] = new Vector3());
value.cloneTo(v3);
destData[k] = v3;
}
else if (value instanceof Vector4) {
var v4 = (destData[k]) || (destData[k] = new Vector4());
value.cloneTo(v4);
destData[k] = v4;
}
else if (value instanceof Matrix4x4) {
var mat = (destData[k]) || (destData[k] = new Matrix4x4());
value.cloneTo(mat);
destData[k] = mat;
}
else if (value instanceof Laya.BaseTexture) {
destData[k] = value;
}
}
}
this._defineDatas.cloneTo(dest._defineDatas);
}
clone() {
var dest = new ShaderData();
this.cloneTo(dest);
return dest;
}
cloneToForNative(destObject) {
var dest = destObject;
var diffSize = this._int32Data.length - dest._int32Data.length;
if (diffSize > 0) {
dest.needRenewArrayBufferForNative(this._int32Data.length);
}
dest._int32Data.set(this._int32Data, 0);
var destData = dest._nativeArray;
var dataCount = this._nativeArray.length;
destData.length = dataCount;
for (var i = 0; i < dataCount; i++) {
var value = this._nativeArray[i];
if (value) {
if (typeof (value) == 'number') {
destData[i] = value;
dest.setNumber(i, value);
}
else if (typeof (value) == 'number') {
destData[i] = value;
dest.setInt(i, value);
}
else if (typeof (value) == "boolean") {
destData[i] = value;
dest.setBool(i, value);
}
else if (value instanceof Vector2) {
var v2 = (destData[i]) || (destData[i] = new Vector2());
value.cloneTo(v2);
destData[i] = v2;
dest.setVector2(i, v2);
}
else if (value instanceof Vector3) {
var v3 = (destData[i]) || (destData[i] = new Vector3());
value.cloneTo(v3);
destData[i] = v3;
dest.setVector3(i, v3);
}
else if (value instanceof Vector4) {
var v4 = (destData[i]) || (destData[i] = new Vector4());
value.cloneTo(v4);
destData[i] = v4;
dest.setVector(i, v4);
}
else if (value instanceof Matrix4x4) {
var mat = (destData[i]) || (destData[i] = new Matrix4x4());
value.cloneTo(mat);
destData[i] = mat;
dest.setMatrix4x4(i, mat);
}
else if (value instanceof Laya.BaseTexture) {
destData[i] = value;
dest.setTexture(i, value);
}
}
}
this._defineDatas.cloneTo(dest._defineDatas);
}
_initDataForNative() {
var length = 8;
this._frameCount = -1;
this._runtimeCopyValues.length = 0;
this._nativeArray = [];
this._data = new ArrayBuffer(length * 4);
this._int32Data = new Int32Array(this._data);
this._float32Data = new Float32Array(this._data);
Laya.LayaGL.instance.createArrayBufferRef(this._data, Laya.LayaGL.ARRAY_BUFFER_TYPE_DATA, true);
}
needRenewArrayBufferForNative(index) {
if (index >= this._int32Data.length) {
var nByteLen = (index + 1) * 4;
var pre = this._int32Data;
var preConchRef = this._data["conchRef"];
var prePtrID = this._data["_ptrID"];
this._data = new ArrayBuffer(nByteLen);
this._int32Data = new Int32Array(this._data);
this._float32Data = new Float32Array(this._data);
this._data["conchRef"] = preConchRef;
this._data["_ptrID"] = prePtrID;
pre && this._int32Data.set(pre, 0);
var layagl = Laya.LayaGL.instance;
if (layagl.updateArrayBufferRef) {
layagl.updateArrayBufferRef(this._data['_ptrID'], preConchRef.isSyncToRender(), this._data);
}
else {
window.conch.updateArrayBufferRef(this._data['_ptrID'], preConchRef.isSyncToRender(), this._data);
}
}
}
getDataForNative() {
return this._nativeArray;
}
getIntForNative(index) {
return this._int32Data[index];
}
setIntForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._int32Data[index] = value;
this._nativeArray[index] = value;
}
getBoolForNative(index) {
return this._int32Data[index] == 1;
}
setBoolForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._int32Data[index] = value ? 1 : 0;
this._nativeArray[index] = value;
}
getNumberForNative(index) {
return this._float32Data[index];
}
setNumberForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._float32Data[index] = value;
this._nativeArray[index] = value;
}
getMatrix4x4ForNative(index) {
return this._nativeArray[index];
}
setMatrix4x4ForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._nativeArray[index] = value;
var nPtrID = this.setReferenceForNative(value.elements);
this._int32Data[index] = nPtrID;
}
getVectorForNative(index) {
return this._nativeArray[index];
}
setVectorForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._nativeArray[index] = value;
if (!value.elements) {
value.forNativeElement();
}
var nPtrID = this.setReferenceForNative(value.elements);
this._int32Data[index] = nPtrID;
}
getVector2ForNative(index) {
return this._nativeArray[index];
}
setVector2ForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._nativeArray[index] = value;
if (!value.elements) {
value.forNativeElement();
}
var nPtrID = this.setReferenceForNative(value.elements);
this._int32Data[index] = nPtrID;
}
getVector3ForNative(index) {
return this._nativeArray[index];
}
setVector3ForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._nativeArray[index] = value;
if (!value.elements) {
value.forNativeElement();
}
var nPtrID = this.setReferenceForNative(value.elements);
this._int32Data[index] = nPtrID;
}
getQuaternionForNative(index) {
return this._nativeArray[index];
}
setQuaternionForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._nativeArray[index] = value;
if (!value.elements) {
value.forNativeElement();
}
var nPtrID = this.setReferenceForNative(value.elements);
this._int32Data[index] = nPtrID;
}
getBufferForNative(shaderIndex) {
return this._nativeArray[shaderIndex];
}
setBufferForNative(index, value) {
this.needRenewArrayBufferForNative(index);
this._nativeArray[index] = value;
var nPtrID = this.setReferenceForNative(value);
this._int32Data[index] = nPtrID;
}
getAttributeForNative(index) {
return this._nativeArray[index];
}
setAttributeForNative(index, value) {
this._nativeArray[index] = value;
if (!value["_ptrID"]) {
Laya.LayaGL.instance.createArrayBufferRef(value, Laya.LayaGL.ARRAY_BUFFER_TYPE_DATA, true);
}
Laya.LayaGL.instance.syncBufferToRenderThread(value);
this._int32Data[index] = value["_ptrID"];
}
getTextureForNative(index) {
return this._nativeArray[index];
}
setTextureForNative(index, value) {
if (!value)
return;
this.needRenewArrayBufferForNative(index);
var lastValue = this._nativeArray[index];
this._nativeArray[index] = value;
var glTexture = value._getSource() || value.defaulteTexture._getSource();
this._int32Data[index] = glTexture.id;
if (this._ownerResource && this._ownerResource.referenceCount > 0) {
(lastValue) && (lastValue._removeReference());
(value) && (value._addReference());
}
}
setReferenceForNative(value) {
this.clearRuntimeCopyArray();
var nRefID = 0;
var nPtrID = 0;
if (ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_) {
Laya.LayaGL.instance.createArrayBufferRefs(value, Laya.LayaGL.ARRAY_BUFFER_TYPE_DATA, true, Laya.LayaGL.ARRAY_BUFFER_REF_REFERENCE);
nRefID = 0;
nPtrID = value.getPtrID(nRefID);
}
else {
Laya.LayaGL.instance.createArrayBufferRefs(value, Laya.LayaGL.ARRAY_BUFFER_TYPE_DATA, true, Laya.LayaGL.ARRAY_BUFFER_REF_COPY);
nRefID = value.getRefNum() - 1;
nPtrID = value.getPtrID(nRefID);
this._runtimeCopyValues.push({ "obj": value, "refID": nRefID, "ptrID": nPtrID });
}
Laya.LayaGL.instance.syncBufferToRenderThread(value, nRefID);
return nPtrID;
}
static setRuntimeValueMode(bReference) {
ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_ = bReference;
}
clearRuntimeCopyArray() {
var currentFrame = Laya.Stat.loopCount;
if (this._frameCount != currentFrame) {
this._frameCount = currentFrame;
for (var i = 0, n = this._runtimeCopyValues.length; i < n; i++) {
var obj = this._runtimeCopyValues[i];
obj.obj.clearRefNum();
}
this._runtimeCopyValues.length = 0;
}
}
}
ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_ = true;
class VertexDeclaration {
constructor(vertexStride, vertexElements) {
this._id = ++VertexDeclaration._uniqueIDCounter;
this._vertexElementsDic = {};
this._vertexStride = vertexStride;
this._vertexElements = vertexElements;
var count = vertexElements.length;
this._shaderValues = new ShaderData(null);
for (var j = 0; j < count; j++) {
var vertexElement = vertexElements[j];
var name = vertexElement._elementUsage;
this._vertexElementsDic[name] = vertexElement;
var value = new Int32Array(5);
var elmentInfo = VertexElementFormat.getElementInfos(vertexElement._elementFormat);
value[0] = elmentInfo[0];
value[1] = elmentInfo[1];
value[2] = elmentInfo[2];
value[3] = this._vertexStride;
value[4] = vertexElement._offset;
this._shaderValues.setAttribute(name, value);
}
}
get id() {
return this._id;
}
get vertexStride() {
return this._vertexStride;
}
get vertexElementCount() {
return this._vertexElements.length;
}
getVertexElementByIndex(index) {
return this._vertexElements[index];
}
getVertexElementByUsage(usage) {
return this._vertexElementsDic[usage];
}
}
VertexDeclaration._uniqueIDCounter = 1;
class VertexElement {
constructor(offset, elementFormat, elementUsage) {
this._offset = offset;
this._elementFormat = elementFormat;
this._elementUsage = elementUsage;
}
get offset() {
return this._offset;
}
get elementFormat() {
return this._elementFormat;
}
get elementUsage() {
return this._elementUsage;
}
}
class BufferState extends Laya.BufferStateBase {
constructor() {
super();
}
applyVertexBuffer(vertexBuffer) {
if (Laya.BufferStateBase._curBindedBufferState === this) {
var gl = Laya.LayaGL.instance;
var verDec = vertexBuffer.vertexDeclaration;
var valueData = verDec._shaderValues.getData();
this.vertexDeclaration = verDec;
vertexBuffer.bind();
for (var k in valueData) {
var loc = parseInt(k);
var attribute = valueData[k];
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, attribute[0], attribute[1], !!attribute[2], attribute[3], attribute[4]);
}
}
else {
throw "BufferState: must call bind() function first.";
}
}
applyVertexBuffers(vertexBuffers) {
if (Laya.BufferStateBase._curBindedBufferState === this) {
var gl = Laya.LayaGL.instance;
for (var i = 0, n = vertexBuffers.length; i < n; i++) {
var verBuf = vertexBuffers[i];
var verDec = verBuf.vertexDeclaration;
var valueData = verDec._shaderValues.getData();
verBuf.bind();
for (var k in valueData) {
var loc = parseInt(k);
var attribute = valueData[k];
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, attribute[0], attribute[1], !!attribute[2], attribute[3], attribute[4]);
}
}
}
else {
throw "BufferState: must call bind() function first.";
}
}
applyInstanceVertexBuffer(vertexBuffer) {
if (Laya.LayaGL.layaGPUInstance.supportInstance()) {
if (Laya.BufferStateBase._curBindedBufferState === this) {
var gl = Laya.LayaGL.instance;
var verDec = vertexBuffer.vertexDeclaration;
var valueData = verDec._shaderValues.getData();
vertexBuffer.bind();
for (var k in valueData) {
var loc = parseInt(k);
var attribute = valueData[k];
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, attribute[0], attribute[1], !!attribute[2], attribute[3], attribute[4]);
Laya.LayaGL.layaGPUInstance.vertexAttribDivisor(loc, 1);
}
}
else {
throw "BufferState: must call bind() function first.";
}
}
}
applyIndexBuffer(indexBuffer) {
if (Laya.BufferStateBase._curBindedBufferState === this) {
if (this._bindedIndexBuffer !== indexBuffer) {
indexBuffer._bindForVAO();
this._bindedIndexBuffer = indexBuffer;
}
}
else {
throw "BufferState: must call bind() function first.";
}
}
}
class ScreenQuad extends Laya.Resource {
constructor() {
super();
this._bufferState = new BufferState();
this._bufferStateInvertUV = new BufferState();
var gl = Laya.LayaGL.instance;
this._vertexBuffer = new VertexBuffer3D(16 * 4, gl.STATIC_DRAW, false);
this._vertexBuffer.vertexDeclaration = ScreenQuad._vertexDeclaration;
this._vertexBuffer.setData(ScreenQuad._vertices.buffer);
this._bufferState.bind();
this._bufferState.applyVertexBuffer(this._vertexBuffer);
this._bufferState.unBind();
this._vertexBufferInvertUV = new VertexBuffer3D(16 * 4, gl.STATIC_DRAW, false);
this._vertexBufferInvertUV.vertexDeclaration = ScreenQuad._vertexDeclaration;
this._vertexBufferInvertUV.setData(ScreenQuad._verticesInvertUV.buffer);
this._bufferStateInvertUV.bind();
this._bufferStateInvertUV.applyVertexBuffer(this._vertexBufferInvertUV);
this._bufferStateInvertUV.unBind();
this._setGPUMemory(this._vertexBuffer._byteLength + this._vertexBufferInvertUV._byteLength);
}
static __init__() {
ScreenQuad._vertexDeclaration = new VertexDeclaration(16, [new VertexElement(0, VertexElementFormat.Vector4, ScreenQuad.SCREENQUAD_POSITION_UV)]);
ScreenQuad.instance = new ScreenQuad();
ScreenQuad.instance.lock = true;
}
render() {
var gl = Laya.LayaGL.instance;
this._bufferState.bind();
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
Laya.Stat.renderBatches++;
}
renderInvertUV() {
var gl = Laya.LayaGL.instance;
this._bufferStateInvertUV.bind();
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
Laya.Stat.renderBatches++;
}
destroy() {
super.destroy();
this._bufferState.destroy();
this._vertexBuffer.destroy();
this._bufferStateInvertUV.destroy();
this._vertexBufferInvertUV.destroy();
this._setGPUMemory(0);
}
}
ScreenQuad.SCREENQUAD_POSITION_UV = 0;
ScreenQuad._vertices = new Float32Array([1, 1, 1, 1, 1, -1, 1, 0, -1, 1, 0, 1, -1, -1, 0, 0]);
ScreenQuad._verticesInvertUV = new Float32Array([1, 1, 1, 0, 1, -1, 1, 1, -1, 1, 0, 0, -1, -1, 0, 1]);
class ScreenTriangle extends Laya.Resource {
constructor() {
super();
this._bufferState = new BufferState();
this._bufferStateInvertUV = new BufferState();
var gl = Laya.LayaGL.instance;
this._vertexBuffer = new VertexBuffer3D(12 * 4, gl.STATIC_DRAW, false);
this._vertexBuffer.vertexDeclaration = ScreenTriangle._vertexDeclaration;
this._vertexBuffer.setData(ScreenTriangle._vertices.buffer);
this._bufferState.bind();
this._bufferState.applyVertexBuffer(this._vertexBuffer);
this._bufferState.unBind();
this._vertexBufferInvertUV = new VertexBuffer3D(12 * 4, gl.STATIC_DRAW, false);
this._vertexBufferInvertUV.vertexDeclaration = ScreenTriangle._vertexDeclaration;
this._vertexBufferInvertUV.setData(ScreenTriangle._verticesInvertUV.buffer);
this._bufferStateInvertUV.bind();
this._bufferStateInvertUV.applyVertexBuffer(this._vertexBufferInvertUV);
this._bufferStateInvertUV.unBind();
this._setGPUMemory(this._vertexBuffer._byteLength + this._vertexBufferInvertUV._byteLength);
}
static __init__() {
ScreenTriangle._vertexDeclaration = new VertexDeclaration(16, [new VertexElement(0, VertexElementFormat.Vector4, ScreenTriangle.SCREENTRIANGLE_POSITION_UV)]);
ScreenTriangle.instance = new ScreenTriangle();
ScreenTriangle.instance.lock = true;
}
render() {
var gl = Laya.LayaGL.instance;
this._bufferState.bind();
gl.drawArrays(gl.TRIANGLES, 0, 3);
Laya.Stat.renderBatches++;
}
renderInvertUV() {
var gl = Laya.LayaGL.instance;
this._bufferStateInvertUV.bind();
gl.drawArrays(gl.TRIANGLES, 0, 3);
Laya.Stat.renderBatches++;
}
destroy() {
super.destroy();
this._bufferState.destroy();
this._vertexBuffer.destroy();
this._bufferStateInvertUV.destroy();
this._vertexBufferInvertUV.destroy();
this._setGPUMemory(0);
}
}
ScreenTriangle.SCREENTRIANGLE_POSITION_UV = 0;
ScreenTriangle._vertices = new Float32Array([-1, -1, 0, 0, -1, 3, 0, 2, 3, -1, 2, 0]);
ScreenTriangle._verticesInvertUV = new Float32Array([-1, -1, 0, 1, -1, 3, 0, -1, 3, -1, 2, 1]);
class ShaderDefine {
constructor(index, value) {
this._index = index;
this._value = value;
}
}
class ShaderVariant {
constructor(shader, subShaderIndex, passIndex, defines) {
this._subShaderIndex = 0;
this._passIndex = 0;
this.setValue(shader, subShaderIndex, passIndex, defines);
}
get shader() {
return this._shader;
}
get subShaderIndex() {
return this._subShaderIndex;
}
get passIndex() {
return this._passIndex;
}
get defineNames() {
return this._defineNames;
}
setValue(shader, subShaderIndex, passIndex, defineNames) {
if (shader) {
var subShader = shader.getSubShaderAt(subShaderIndex);
if (subShader) {
var pass = subShader._passes[passIndex];
if (pass) {
var validDefine = pass._validDefine;
for (var i = 0, n = defineNames.length; i < n; i++) {
var defname = defineNames[i];
if (!validDefine.has(ILaya3D.Shader3D.getDefineByName(defname)))
throw `ShaderVariantInfo:Invalid defineName ${defname} in ${shader._name} subShaderIndex of ${subShaderIndex} passIndex of ${passIndex}.`;
}
}
else {
throw `ShaderVariantInfo:Shader don't have passIndex of ${passIndex}.`;
}
}
else {
throw `ShaderVariantInfo:Shader don't have subShaderIndex of ${subShaderIndex}.`;
}
}
else {
throw `ShaderVariantInfo:Shader can't be null.`;
}
this._shader = shader;
this._subShaderIndex = subShaderIndex;
this._passIndex = passIndex;
this._defineNames = defineNames;
}
equal(other) {
if (this._shader !== other._shader || this._subShaderIndex !== other._subShaderIndex || this._passIndex !== other._passIndex)
return false;
var defines = this._defineNames;
var otherDefines = other._defineNames;
if (defines.length !== otherDefines.length)
return false;
for (var i = 0, n = this._defineNames.length; i < n; i++) {
if (defines[i] !== otherDefines[i])
return false;
}
return true;
}
clone() {
var dest = new ShaderVariant(this._shader, this._subShaderIndex, this._passIndex, this._defineNames.slice());
return dest;
}
}
class ShaderVariantCollection {
constructor() {
this._allCompiled = false;
this._variants = [];
}
get allCompiled() {
return this._allCompiled;
}
get variantCount() {
return this._variants.length;
}
add(variant) {
for (var i = 0, n = this._variants.length; i < n; i++) {
if (this._variants[i].equal(variant))
return false;
}
this._variants.push(variant.clone());
this._allCompiled = false;
return true;
}
remove(variant) {
for (var i = 0, n = this._variants.length; i < n; i++) {
if (this._variants[i].equal(variant)) {
this._variants.splice(i, 1);
return true;
}
}
return false;
}
contatins(variant) {
for (var i = 0, n = this._variants.length; i < n; i++) {
if (this._variants[i].equal(variant))
return true;
}
return false;
}
getByIndex(index) {
return this._variants[index];
}
clear() {
this._variants.length = 0;
}
compile() {
if (!this._allCompiled) {
var variants = this._variants;
for (var i = 0, n = variants.length; i < n; i++) {
var variant = variants[i];
ILaya3D.Shader3D.compileShaderByDefineNames(variant._shader._name, variant._subShaderIndex, variant._passIndex, variant._defineNames);
}
this._allCompiled = true;
}
}
}
class Shader3D {
constructor(name, attributeMap, uniformMap, enableInstancing, supportReflectionProbe) {
this._attributeMap = null;
this._uniformMap = null;
this._enableInstancing = false;
this._supportReflectionProbe = false;
this._subShaders = [];
this._name = name;
this._attributeMap = attributeMap;
this._uniformMap = uniformMap;
this._enableInstancing = enableInstancing;
this._supportReflectionProbe = supportReflectionProbe;
}
static _getNamesByDefineData(defineData, out) {
var maskMap = Shader3D._maskMap;
var mask = defineData._mask;
out.length = 0;
for (var i = 0, n = defineData._length; i < n; i++) {
var subMaskMap = maskMap[i];
var subMask = mask[i];
for (var j = 0; j < 32; j++) {
var d = 1 << j;
if (subMask > 0 && d > subMask)
break;
if (subMask & d)
out.push(subMaskMap[d]);
}
}
}
static getDefineByName(name) {
var define = Shader3D._defineMap[name];
if (!define) {
var maskMap = Shader3D._maskMap;
var counter = Shader3D._defineCounter;
var index = Math.floor(counter / 32);
var value = 1 << counter % 32;
define = new ShaderDefine(index, value);
Shader3D._defineMap[name] = define;
if (index == maskMap.length) {
maskMap.length++;
maskMap[index] = {};
}
maskMap[index][value] = name;
Shader3D._defineCounter++;
}
return define;
}
static propertyNameToID(name) {
if (Shader3D._propertyNameMap[name] != null) {
return Shader3D._propertyNameMap[name];
}
else {
var id = Shader3D._propertyNameCounter++;
Shader3D._propertyNameMap[name] = id;
Shader3D._propertyNameMap[id] = name;
return id;
}
}
static addInclude(fileName, txt) {
txt = txt.replace(Laya.ShaderCompile._clearCR, "");
Laya.ShaderCompile.addInclude(fileName, txt);
}
static compileShaderByDefineNames(shaderName, subShaderIndex, passIndex, defineNames) {
var shader = Shader3D.find(shaderName);
if (shader) {
var subShader = shader.getSubShaderAt(subShaderIndex);
if (subShader) {
var pass = subShader._passes[passIndex];
if (pass) {
var compileDefineDatas = Shader3D._compileDefineDatas;
compileDefineDatas.clear();
for (var i = 0, n = defineNames.length; i < n; i++)
compileDefineDatas.add(Shader3D.getDefineByName(defineNames[i]));
pass.withCompile(compileDefineDatas);
}
else {
console.warn("Shader3D: unknown passIndex.");
}
}
else {
console.warn("Shader3D: unknown subShaderIndex.");
}
}
else {
console.warn("Shader3D: unknown shader name.");
}
}
static add(name, attributeMap = null, uniformMap = null, enableInstancing = false, supportReflectionProbe = false) {
return Shader3D._preCompileShader[name] = new Shader3D(name, attributeMap, uniformMap, enableInstancing, supportReflectionProbe);
}
static find(name) {
return Shader3D._preCompileShader[name];
}
get name() {
return this._name;
}
addSubShader(subShader) {
this._subShaders.push(subShader);
subShader._owner = this;
}
getSubShaderAt(index) {
return this._subShaders[index];
}
static compileShader(shaderName, subShaderIndex, passIndex, ...defineMask) {
var shader = Shader3D.find(shaderName);
if (shader) {
var subShader = shader.getSubShaderAt(subShaderIndex);
if (subShader) {
var pass = subShader._passes[passIndex];
if (pass) {
var compileDefineDatas = Shader3D._compileDefineDatas;
var mask = compileDefineDatas._mask;
mask.length = 0;
for (var i = 0, n = defineMask.length; i < n; i++)
mask.push(defineMask[i]);
compileDefineDatas._length = defineMask.length;
pass.withCompile(compileDefineDatas);
}
else {
console.warn("Shader3D: unknown passIndex.");
}
}
else {
console.warn("Shader3D: unknown subShaderIndex.");
}
}
else {
console.warn("Shader3D: unknown shader name.");
}
}
}
Shader3D._compileDefineDatas = new DefineDatas();
Shader3D.RENDER_STATE_CULL = 0;
Shader3D.RENDER_STATE_BLEND = 1;
Shader3D.RENDER_STATE_BLEND_SRC = 2;
Shader3D.RENDER_STATE_BLEND_DST = 3;
Shader3D.RENDER_STATE_BLEND_SRC_RGB = 4;
Shader3D.RENDER_STATE_BLEND_DST_RGB = 5;
Shader3D.RENDER_STATE_BLEND_SRC_ALPHA = 6;
Shader3D.RENDER_STATE_BLEND_DST_ALPHA = 7;
Shader3D.RENDER_STATE_BLEND_CONST_COLOR = 8;
Shader3D.RENDER_STATE_BLEND_EQUATION = 9;
Shader3D.RENDER_STATE_BLEND_EQUATION_RGB = 10;
Shader3D.RENDER_STATE_BLEND_EQUATION_ALPHA = 11;
Shader3D.RENDER_STATE_DEPTH_TEST = 12;
Shader3D.RENDER_STATE_DEPTH_WRITE = 13;
Shader3D.PERIOD_CUSTOM = 0;
Shader3D.PERIOD_MATERIAL = 1;
Shader3D.PERIOD_SPRITE = 2;
Shader3D.PERIOD_CAMERA = 3;
Shader3D.PERIOD_SCENE = 4;
Shader3D._propertyNameMap = {};
Shader3D._propertyNameCounter = 0;
Shader3D._defineCounter = 0;
Shader3D._defineMap = {};
Shader3D._preCompileShader = {};
Shader3D._maskMap = [];
Shader3D.debugMode = false;
Shader3D.debugShaderVariantCollection = new ShaderVariantCollection();
class Command {
constructor() {
this._commandBuffer = null;
}
static __init__() {
Command._screenShaderData = new ShaderData();
Command._screenShader = Shader3D.find("BlitScreen");
}
run() {
}
recover() {
this._commandBuffer = null;
}
setContext(context) {
this._context = context;
}
}
Command.SCREENTEXTURE_NAME = "u_MainTex";
Command.SCREENTEXTUREOFFSETSCALE_NAME = "u_OffsetScale";
Command.MAINTEXTURE_TEXELSIZE_NAME = "u_MainTex_TexelSize";
Command.SCREENTEXTURE_ID = Shader3D.propertyNameToID(Command.SCREENTEXTURE_NAME);
Command.SCREENTEXTUREOFFSETSCALE_ID = Shader3D.propertyNameToID(Command.SCREENTEXTUREOFFSETSCALE_NAME);
Command.MAINTEXTURE_TEXELSIZE_ID = Shader3D.propertyNameToID(Command.MAINTEXTURE_TEXELSIZE_NAME);
class BlitScreenQuadCMD extends Command {
constructor() {
super(...arguments);
this._source = null;
this._dest = null;
this._offsetScale = null;
this._shader = null;
this._shaderData = null;
this._subShader = 0;
this._sourceTexelSize = new Vector4();
this._screenType = 0;
this._drawDefineCavans = false;
}
static create(source, dest, offsetScale = null, shader = null, shaderData = null, subShader = 0, screenType = BlitScreenQuadCMD._SCREENTYPE_QUAD, commandbuffer = null, definedCanvas = false) {
var cmd;
cmd = BlitScreenQuadCMD._pool.length > 0 ? BlitScreenQuadCMD._pool.pop() : new BlitScreenQuadCMD();
cmd._source = source;
cmd._dest = dest;
cmd._offsetScale = offsetScale;
cmd._shader = shader;
cmd._shaderData = shaderData;
cmd._subShader = subShader;
cmd._screenType = screenType;
cmd._commandBuffer = commandbuffer;
cmd._drawDefineCavans = definedCanvas;
return cmd;
}
run() {
var source;
if (!this._source) {
if (!this._commandBuffer._camera._internalRenderTexture)
throw "camera internalRenderTexture is null,please set camera enableBuiltInRenderTexture";
source = this._commandBuffer._camera._internalRenderTexture;
}
else
source = this._source;
var shader = this._shader || Command._screenShader;
var shaderData = this._shaderData || Command._screenShaderData;
var dest = this._dest ? this._dest : (this._drawDefineCavans ? this._dest : this._commandBuffer._camera._internalRenderTexture);
if (dest) {
Laya.LayaGL.instance.viewport(0, 0, dest.width, dest.height);
}
else {
let camera = this._commandBuffer._camera;
let viewport = camera.viewport;
let vpH = viewport.height;
let vpY = RenderContext3D.clientHeight - viewport.y - vpH;
Laya.LayaGL.instance.viewport(viewport.x, vpY, viewport.width, vpH);
}
shaderData.setTexture(Command.SCREENTEXTURE_ID, source);
shaderData.setVector(Command.SCREENTEXTUREOFFSETSCALE_ID, this._offsetScale || BlitScreenQuadCMD._defaultOffsetScale);
this._sourceTexelSize.setValue(1.0 / source.width, 1.0 / source.height, source.width, source.height);
shaderData.setVector(Command.MAINTEXTURE_TEXELSIZE_ID, this._sourceTexelSize);
(RenderTexture.currentActive) && (RenderTexture.currentActive._end());
(dest) && (dest._start());
var subShader = shader.getSubShaderAt(this._subShader);
var passes = subShader._passes;
for (var i = 0, n = passes.length; i < n; i++) {
var comDef = BlitScreenQuadCMD._compileDefine;
shaderData._defineDatas.cloneTo(comDef);
var shaderPass = passes[i].withCompile(comDef);
shaderPass.bind();
shaderPass.uploadUniforms(shaderPass._materialUniformParamsMap, shaderData, true);
shaderPass.uploadRenderStateBlendDepth(shaderData);
shaderPass.uploadRenderStateFrontFace(shaderData, false, null);
switch (this._screenType) {
case BlitScreenQuadCMD._SCREENTYPE_QUAD:
RenderContext3D._instance.invertY ? ScreenQuad.instance.renderInvertUV() : ScreenQuad.instance.render();
break;
case BlitScreenQuadCMD._SCREENTYPE_TRIANGLE:
RenderContext3D._instance.invertY ? ScreenTriangle.instance.renderInvertUV() : ScreenTriangle.instance.render();
break;
default:
throw "BlitScreenQuadCMD:unknown screen Type.";
}
}
(dest) && (dest._end());
}
recover() {
BlitScreenQuadCMD._pool.push(this);
this._source = null;
this._dest = null;
this._offsetScale = null;
this._shader = null;
this._shaderData = null;
this._drawDefineCavans = false;
super.recover();
}
}
BlitScreenQuadCMD._SCREENTYPE_QUAD = 0;
BlitScreenQuadCMD._SCREENTYPE_TRIANGLE = 1;
BlitScreenQuadCMD._compileDefine = new DefineDatas();
BlitScreenQuadCMD._pool = [];
BlitScreenQuadCMD._defaultOffsetScale = new Vector4(0, 0, 1, 1);
class SetRenderTargetCMD extends Command {
constructor() {
super(...arguments);
this._renderTexture = null;
}
static create(renderTexture) {
var cmd;
cmd = SetRenderTargetCMD._pool.length > 0 ? SetRenderTargetCMD._pool.pop() : new SetRenderTargetCMD();
cmd._renderTexture = renderTexture;
return cmd;
}
run() {
(RenderTexture.currentActive) && (RenderTexture.currentActive._end());
Laya.LayaGL.instance.viewport(0, 0, this._renderTexture.width, this._renderTexture.height);
this._renderTexture._start();
}
recover() {
SetRenderTargetCMD._pool.push(this);
this._renderTexture = null;
}
}
SetRenderTargetCMD._pool = [];
(function (ShaderDataType) {
ShaderDataType[ShaderDataType["Int"] = 0] = "Int";
ShaderDataType[ShaderDataType["Bool"] = 1] = "Bool";
ShaderDataType[ShaderDataType["Number"] = 2] = "Number";
ShaderDataType[ShaderDataType["Vector2"] = 3] = "Vector2";
ShaderDataType[ShaderDataType["Vector3"] = 4] = "Vector3";
ShaderDataType[ShaderDataType["Vector4"] = 5] = "Vector4";
ShaderDataType[ShaderDataType["Quaternion"] = 6] = "Quaternion";
ShaderDataType[ShaderDataType["Matrix4x4"] = 7] = "Matrix4x4";
ShaderDataType[ShaderDataType["Buffer"] = 8] = "Buffer";
ShaderDataType[ShaderDataType["Texture"] = 9] = "Texture";
})(exports.ShaderDataType || (exports.ShaderDataType = {}));
class SetShaderDataCMD extends Command {
constructor() {
super(...arguments);
this._shaderData = null;
this._nameID = 0;
this._value = null;
this._dataType = -1;
}
static create(shaderData, nameID, value, shaderDataType, commandBuffer) {
var cmd;
cmd = SetShaderDataCMD._pool.length > 0 ? SetShaderDataCMD._pool.pop() : new SetShaderDataCMD();
cmd._shaderData = shaderData;
cmd._nameID = nameID;
cmd._value = value;
cmd._dataType = shaderDataType;
cmd._commandBuffer = commandBuffer;
return cmd;
}
run() {
switch (this._dataType) {
case exports.ShaderDataType.Int:
this._shaderData.setInt(this._nameID, this._value);
break;
case exports.ShaderDataType.Number:
this._shaderData.setNumber(this._nameID, this._value);
break;
case exports.ShaderDataType.Bool:
this._shaderData.setBool(this._nameID, this._value);
break;
case exports.ShaderDataType.Matrix4x4:
this._shaderData.setMatrix4x4(this._nameID, this._value);
break;
case exports.ShaderDataType.Quaternion:
this._shaderData.setQuaternion(this._nameID, this._value);
break;
case exports.ShaderDataType.Texture:
this._shaderData.setTexture(this._nameID, this._value);
break;
case exports.ShaderDataType.Vector4:
this._shaderData.setVector(this._nameID, this._value);
break;
case exports.ShaderDataType.Vector2:
this._shaderData.setVector2(this._nameID, this._value);
break;
case exports.ShaderDataType.Vector3:
this._shaderData.setVector3(this._nameID, this._value);
break;
case exports.ShaderDataType.Buffer:
this._shaderData.setBuffer(this._nameID, this._value);
break;
default:
throw "no type shaderValue on this CommendBuffer";
}
}
recover() {
SetShaderDataCMD._pool.push(this);
this._shaderData = null;
this._nameID = 0;
this._value = null;
this._dataType = -1;
}
}
SetShaderDataCMD._pool = [];
class Transform3D extends Laya.EventDispatcher {
constructor(owner) {
super();
this._localPosition = new Vector3(0, 0, 0);
this._localRotation = new Quaternion(0, 0, 0, 1);
this._localScale = new Vector3(1, 1, 1);
this._localRotationEuler = new Vector3(0, 0, 0);
this._localMatrix = new Matrix4x4();
this._position = new Vector3(0, 0, 0);
this._rotation = new Quaternion(0, 0, 0, 1);
this._scale = new Vector3(1, 1, 1);
this._rotationEuler = new Vector3(0, 0, 0);
this._worldMatrix = new Matrix4x4();
this._children = null;
this._parent = null;
this._dummy = null;
this._transformFlag = 0;
this._owner = owner;
this._children = [];
this._setTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION | Transform3D.TRANSFORM_LOCALEULER | Transform3D.TRANSFORM_LOCALMATRIX, false);
this._setTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDEULER | Transform3D.TRANSFORM_WORLDSCALE | Transform3D.TRANSFORM_WORLDMATRIX, true);
}
get _isFrontFaceInvert() {
var scale = this.getWorldLossyScale();
var isInvert = scale.x < 0;
(scale.y < 0) && (isInvert = !isInvert);
(scale.z < 0) && (isInvert = !isInvert);
return isInvert;
}
get owner() {
return this._owner;
}
get worldNeedUpdate() {
return this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX);
}
get localPositionX() {
return this._localPosition.x;
}
set localPositionX(x) {
this._localPosition.x = x;
this.localPosition = this._localPosition;
}
get localPositionY() {
return this._localPosition.y;
}
set localPositionY(y) {
this._localPosition.y = y;
this.localPosition = this._localPosition;
}
get localPositionZ() {
return this._localPosition.z;
}
set localPositionZ(z) {
this._localPosition.z = z;
this.localPosition = this._localPosition;
}
get localPosition() {
return this._localPosition;
}
set localPosition(value) {
if (this._localPosition !== value)
value.cloneTo(this._localPosition);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX, true);
this._onWorldPositionTransform();
}
get localRotationX() {
return this.localRotation.x;
}
set localRotationX(x) {
this._localRotation.x = x;
this.localRotation = this._localRotation;
}
get localRotationY() {
return this.localRotation.y;
}
set localRotationY(y) {
this._localRotation.y = y;
this.localRotation = this._localRotation;
}
get localRotationZ() {
return this.localRotation.z;
}
set localRotationZ(z) {
this._localRotation.z = z;
this.localRotation = this._localRotation;
}
get localRotationW() {
return this.localRotation.w;
}
set localRotationW(w) {
this._localRotation.w = w;
this.localRotation = this._localRotation;
}
get localRotation() {
if (this._getTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION)) {
var eulerE = this._localRotationEuler;
Quaternion.createFromYawPitchRoll(eulerE.y / Transform3D._angleToRandin, eulerE.x / Transform3D._angleToRandin, eulerE.z / Transform3D._angleToRandin, this._localRotation);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION, false);
}
return this._localRotation;
}
set localRotation(value) {
if (this._localRotation !== value)
value.cloneTo(this._localRotation);
this._localRotation.normalize(this._localRotation);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALEULER | Transform3D.TRANSFORM_LOCALMATRIX, true);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION, false);
this._onWorldRotationTransform();
}
get localScaleX() {
return this._localScale.x;
}
set localScaleX(value) {
this._localScale.x = value;
this.localScale = this._localScale;
}
get localScaleY() {
return this._localScale.y;
}
set localScaleY(value) {
this._localScale.y = value;
this.localScale = this._localScale;
}
get localScaleZ() {
return this._localScale.z;
}
set localScaleZ(value) {
this._localScale.z = value;
this.localScale = this._localScale;
}
get localScale() {
return this._localScale;
}
set localScale(value) {
if (this._localScale !== value)
value.cloneTo(this._localScale);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX, true);
this._onWorldScaleTransform();
}
get localRotationEulerX() {
return this.localRotationEuler.x;
}
set localRotationEulerX(value) {
this._localRotationEuler.x = value;
this.localRotationEuler = this._localRotationEuler;
}
get localRotationEulerY() {
return this.localRotationEuler.y;
}
set localRotationEulerY(value) {
this._localRotationEuler.y = value;
this.localRotationEuler = this._localRotationEuler;
}
get localRotationEulerZ() {
return this.localRotationEuler.z;
}
set localRotationEulerZ(value) {
this._localRotationEuler.z = value;
this.localRotationEuler = this._localRotationEuler;
}
get localRotationEuler() {
if (this._getTransformFlag(Transform3D.TRANSFORM_LOCALEULER)) {
this._localRotation.getYawPitchRoll(Transform3D._tempVector30);
var euler = Transform3D._tempVector30;
var localRotationEuler = this._localRotationEuler;
localRotationEuler.x = euler.y * Transform3D._angleToRandin;
localRotationEuler.y = euler.x * Transform3D._angleToRandin;
localRotationEuler.z = euler.z * Transform3D._angleToRandin;
this._setTransformFlag(Transform3D.TRANSFORM_LOCALEULER, false);
}
return this._localRotationEuler;
}
set localRotationEuler(value) {
if (this._localRotationEuler !== value)
value.cloneTo(this._localRotationEuler);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALEULER, false);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION | Transform3D.TRANSFORM_LOCALMATRIX, true);
this._onWorldRotationTransform();
}
get localMatrix() {
if (this._getTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX)) {
Matrix4x4.createAffineTransformation(this._localPosition, this.localRotation, this._localScale, this._localMatrix);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX, false);
}
return this._localMatrix;
}
set localMatrix(value) {
if (this._localMatrix !== value)
value.cloneTo(this._localMatrix);
this._localMatrix.decomposeTransRotScale(this._localPosition, this._localRotation, this._localScale);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALEULER, true);
this._setTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX, false);
this._onWorldTransform();
}
get position() {
if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION)) {
if (this._parent != null) {
var worldMatE = this.worldMatrix.elements;
this._position.x = worldMatE[12];
this._position.y = worldMatE[13];
this._position.z = worldMatE[14];
}
else {
this._localPosition.cloneTo(this._position);
}
this._setTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION, false);
}
return this._position;
}
set position(value) {
if (this._parent != null) {
var parentInvMat = Transform3D._tempMatrix0;
this._parent.worldMatrix.invert(parentInvMat);
Vector3.transformCoordinate(value, parentInvMat, this._localPosition);
}
else {
value.cloneTo(this._localPosition);
}
this.localPosition = this._localPosition;
if (this._position !== value)
value.cloneTo(this._position);
this._setTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION, false);
}
get rotation() {
if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION)) {
if (this._parent != null)
Quaternion.multiply(this._parent.rotation, this.localRotation, this._rotation);
else
this.localRotation.cloneTo(this._rotation);
this._setTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION, false);
}
return this._rotation;
}
set rotation(value) {
if (this._parent != null) {
this._parent.rotation.invert(Transform3D._tempQuaternion0);
Quaternion.multiply(Transform3D._tempQuaternion0, value, this._localRotation);
}
else {
value.cloneTo(this._localRotation);
}
this.localRotation = this._localRotation;
if (value !== this._rotation)
value.cloneTo(this._rotation);
this._setTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION, false);
}
get rotationEuler() {
if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDEULER)) {
this.rotation.getYawPitchRoll(Transform3D._tempVector30);
var eulerE = Transform3D._tempVector30;
var rotationEulerE = this._rotationEuler;
rotationEulerE.x = eulerE.y * Transform3D._angleToRandin;
rotationEulerE.y = eulerE.x * Transform3D._angleToRandin;
rotationEulerE.z = eulerE.z * Transform3D._angleToRandin;
this._setTransformFlag(Transform3D.TRANSFORM_WORLDEULER, false);
}
return this._rotationEuler;
}
set rotationEuler(value) {
Quaternion.createFromYawPitchRoll(value.y / Transform3D._angleToRandin, value.x / Transform3D._angleToRandin, value.z / Transform3D._angleToRandin, this._rotation);
this.rotation = this._rotation;
if (this._rotationEuler !== value)
value.cloneTo(this._rotationEuler);
this._setTransformFlag(Transform3D.TRANSFORM_WORLDEULER, false);
}
get worldMatrix() {
if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX)) {
if (this._parent != null)
Matrix4x4.multiply(this._parent.worldMatrix, this.localMatrix, this._worldMatrix);
else
this.localMatrix.cloneTo(this._worldMatrix);
this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX, false);
}
return this._worldMatrix;
}
set worldMatrix(value) {
if (this._parent === null) {
value.cloneTo(this._localMatrix);
}
else {
this._parent.worldMatrix.invert(this._localMatrix);
Matrix4x4.multiply(this._localMatrix, value, this._localMatrix);
}
this.localMatrix = this._localMatrix;
if (this._worldMatrix !== value)
value.cloneTo(this._worldMatrix);
this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX, false);
}
_getScaleMatrix() {
var invRotation = Transform3D._tempQuaternion0;
var invRotationMat = Transform3D._tempMatrix3x30;
var worldRotScaMat = Transform3D._tempMatrix3x31;
var scaMat = Transform3D._tempMatrix3x32;
Matrix3x3.createFromMatrix4x4(this.worldMatrix, worldRotScaMat);
this.rotation.invert(invRotation);
Matrix3x3.createRotationQuaternion(invRotation, invRotationMat);
Matrix3x3.multiply(invRotationMat, worldRotScaMat, scaMat);
return scaMat;
}
_setTransformFlag(type, value) {
if (value)
this._transformFlag |= type;
else
this._transformFlag &= ~type;
}
_getTransformFlag(type) {
return (this._transformFlag & type) != 0;
}
_setParent(value) {
if (this._parent !== value) {
if (this._parent) {
var parentChilds = this._parent._children;
var index = parentChilds.indexOf(this);
parentChilds.splice(index, 1);
}
if (value) {
value._children.push(this);
(value) && (this._onWorldTransform());
}
this._parent = value;
}
}
_onWorldPositionRotationTransform() {
if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDEULER)) {
this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDEULER, true);
this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag);
}
for (var i = 0, n = this._children.length; i < n; i++)
this._children[i]._onWorldPositionRotationTransform();
}
_onWorldPositionScaleTransform() {
if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDSCALE)) {
this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDSCALE, true);
this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag);
}
for (var i = 0, n = this._children.length; i < n; i++)
this._children[i]._onWorldPositionScaleTransform();
}
_onWorldPositionTransform() {
if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION)) {
this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDPOSITION, true);
this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag);
}
for (var i = 0, n = this._children.length; i < n; i++)
this._children[i]._onWorldPositionTransform();
}
_onWorldRotationTransform() {
if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDEULER)) {
this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDEULER, true);
this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag);
}
for (var i = 0, n = this._children.length; i < n; i++)
this._children[i]._onWorldPositionRotationTransform();
}
_onWorldScaleTransform() {
if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDSCALE)) {
this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDSCALE, true);
this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag);
}
for (var i = 0, n = this._children.length; i < n; i++)
this._children[i]._onWorldPositionScaleTransform();
}
_onWorldTransform() {
if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDEULER) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDSCALE)) {
this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDEULER | Transform3D.TRANSFORM_WORLDSCALE, true);
this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag);
}
for (var i = 0, n = this._children.length; i < n; i++)
this._children[i]._onWorldTransform();
}
translate(translation, isLocal = true) {
if (isLocal) {
Matrix4x4.createFromQuaternion(this.localRotation, Transform3D._tempMatrix0);
Vector3.transformCoordinate(translation, Transform3D._tempMatrix0, Transform3D._tempVector30);
Vector3.add(this.localPosition, Transform3D._tempVector30, this._localPosition);
this.localPosition = this._localPosition;
}
else {
Vector3.add(this.position, translation, this._position);
this.position = this._position;
}
}
rotate(rotation, isLocal = true, isRadian = true) {
var rot;
if (isRadian) {
rot = rotation;
}
else {
Vector3.scale(rotation, Math.PI / 180.0, Transform3D._tempVector30);
rot = Transform3D._tempVector30;
}
Quaternion.createFromYawPitchRoll(rot.y, rot.x, rot.z, Transform3D._tempQuaternion0);
if (isLocal) {
Quaternion.multiply(this._localRotation, Transform3D._tempQuaternion0, this._localRotation);
this.localRotation = this._localRotation;
}
else {
Quaternion.multiply(Transform3D._tempQuaternion0, this.rotation, this._rotation);
this.rotation = this._rotation;
}
}
getForward(forward) {
var worldMatElem = this.worldMatrix.elements;
forward.x = -worldMatElem[8];
forward.y = -worldMatElem[9];
forward.z = -worldMatElem[10];
}
getUp(up) {
var worldMatElem = this.worldMatrix.elements;
up.x = worldMatElem[4];
up.y = worldMatElem[5];
up.z = worldMatElem[6];
}
getRight(right) {
var worldMatElem = this.worldMatrix.elements;
right.x = worldMatElem[0];
right.y = worldMatElem[1];
right.z = worldMatElem[2];
}
lookAt(target, up, isLocal = false) {
var eye;
if (isLocal) {
eye = this._localPosition;
if (Math.abs(eye.x - target.x) < MathUtils3D.zeroTolerance && Math.abs(eye.y - target.y) < MathUtils3D.zeroTolerance && Math.abs(eye.z - target.z) < MathUtils3D.zeroTolerance)
return;
Quaternion.lookAt(this._localPosition, target, up, this._localRotation);
this._localRotation.invert(this._localRotation);
this.localRotation = this._localRotation;
}
else {
var worldPosition = this.position;
eye = worldPosition;
if (Math.abs(eye.x - target.x) < MathUtils3D.zeroTolerance && Math.abs(eye.y - target.y) < MathUtils3D.zeroTolerance && Math.abs(eye.z - target.z) < MathUtils3D.zeroTolerance)
return;
Quaternion.lookAt(worldPosition, target, up, this._rotation);
this._rotation.invert(this._rotation);
this.rotation = this._rotation;
}
}
getWorldLossyScale() {
if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDSCALE)) {
if (this._parent !== null) {
var scaMatE = this._getScaleMatrix().elements;
this._scale.x = scaMatE[0];
this._scale.y = scaMatE[4];
this._scale.z = scaMatE[8];
}
else {
this._localScale.cloneTo(this._scale);
}
this._setTransformFlag(Transform3D.TRANSFORM_WORLDSCALE, false);
}
return this._scale;
}
setWorldLossyScale(value) {
if (this._parent !== null) {
var scaleMat = Transform3D._tempMatrix3x33;
var localScaleMat = Transform3D._tempMatrix3x33;
var localScaleMatE = localScaleMat.elements;
var parInvScaleMat = this._parent._getScaleMatrix();
parInvScaleMat.invert(parInvScaleMat);
Matrix3x3.createFromScaling(value, scaleMat);
Matrix3x3.multiply(parInvScaleMat, scaleMat, localScaleMat);
this._localScale.x = localScaleMatE[0];
this._localScale.y = localScaleMatE[4];
this._localScale.z = localScaleMatE[8];
}
else {
value.cloneTo(this._localScale);
}
this.localScale = this._localScale;
if (this._scale !== value)
value.cloneTo(this._scale);
this._setTransformFlag(Transform3D.TRANSFORM_WORLDSCALE, false);
}
get scale() {
console.warn("Transfrm3D: discard function,please use getWorldLossyScale instead.");
return this.getWorldLossyScale();
}
set scale(value) {
console.warn("Transfrm3D: discard function,please use setWorldLossyScale instead.");
this.setWorldLossyScale(value);
}
}
Transform3D._tempVector30 = new Vector3();
Transform3D._tempQuaternion0 = new Quaternion();
Transform3D._tempMatrix0 = new Matrix4x4();
Transform3D._tempMatrix3x30 = new Matrix3x3();
Transform3D._tempMatrix3x31 = new Matrix3x3();
Transform3D._tempMatrix3x32 = new Matrix3x3();
Transform3D._tempMatrix3x33 = new Matrix3x3();
Transform3D.TRANSFORM_LOCALQUATERNION = 0x01;
Transform3D.TRANSFORM_LOCALEULER = 0x02;
Transform3D.TRANSFORM_LOCALMATRIX = 0x04;
Transform3D.TRANSFORM_WORLDPOSITION = 0x08;
Transform3D.TRANSFORM_WORLDQUATERNION = 0x10;
Transform3D.TRANSFORM_WORLDSCALE = 0x20;
Transform3D.TRANSFORM_WORLDMATRIX = 0x40;
Transform3D.TRANSFORM_WORLDEULER = 0x80;
Transform3D._angleToRandin = 180 / Math.PI;
class Sprite3D extends Laya.Node {
constructor(name = null, isStatic = false) {
super();
this._needProcessCollisions = false;
this._needProcessTriggers = false;
this._id = ++Sprite3D._uniqueIDCounter;
this._transform = new Transform3D(this);
this._isStatic = isStatic;
this.layer = 0;
this.name = name ? name : "New Sprite3D";
}
static __init__() {
}
static instantiate(original, parent = null, worldPositionStays = true, position = null, rotation = null) {
var destSprite3D = original.clone();
(parent) && (parent.addChild(destSprite3D));
var transform = destSprite3D.transform;
if (worldPositionStays) {
var worldMatrix = transform.worldMatrix;
original.transform.worldMatrix.cloneTo(worldMatrix);
transform.worldMatrix = worldMatrix;
}
else {
(position) && (transform.position = position);
(rotation) && (transform.rotation = rotation);
}
return destSprite3D;
}
static load(url, complete) {
Laya.Laya.loader.create(url, complete, null, Sprite3D.HIERARCHY);
}
get id() {
return this._id;
}
get layer() {
return this._layer;
}
set layer(value) {
if (this._layer !== value) {
if (value >= 0 && value <= 30) {
this._layer = value;
}
else {
throw new Error("Layer value must be 0-30.");
}
}
}
get url() {
return this._url;
}
get isStatic() {
return this._isStatic;
}
get transform() {
return this._transform;
}
_setCreateURL(url) {
this._url = Laya.URL.formatURL(url);
}
_changeAnimatorsToLinkSprite3D(sprite3D, isLink, path) {
var animator = this.getComponent(Animator);
if (animator) {
if (!animator.avatar)
sprite3D._changeAnimatorToLinkSprite3DNoAvatar(animator, isLink, path);
}
if (this._parent && this._parent instanceof Sprite3D) {
path.unshift(this._parent.name);
var p = this._parent;
(p._hierarchyAnimator) && (p._changeAnimatorsToLinkSprite3D(sprite3D, isLink, path));
}
}
_setHierarchyAnimator(animator, parentAnimator) {
this._changeHierarchyAnimator(animator);
this._changeAnimatorAvatar(animator.avatar);
for (var i = 0, n = this._children.length; i < n; i++) {
var child = this._children[i];
(child._hierarchyAnimator == parentAnimator) && (child._setHierarchyAnimator(animator, parentAnimator));
}
}
_clearHierarchyAnimator(animator, parentAnimator) {
this._changeHierarchyAnimator(parentAnimator);
this._changeAnimatorAvatar(parentAnimator ? parentAnimator.avatar : null);
for (var i = 0, n = this._children.length; i < n; i++) {
var child = this._children[i];
(child._hierarchyAnimator == animator) && (child._clearHierarchyAnimator(animator, parentAnimator));
}
}
_changeHierarchyAnimatorAvatar(animator, avatar) {
this._changeAnimatorAvatar(avatar);
for (var i = 0, n = this._children.length; i < n; i++) {
var child = this._children[i];
(child._hierarchyAnimator == animator) && (child._changeHierarchyAnimatorAvatar(animator, avatar));
}
}
_changeAnimatorToLinkSprite3DNoAvatar(animator, isLink, path) {
animator._handleSpriteOwnersBySprite(isLink, path, this);
for (var i = 0, n = this._children.length; i < n; i++) {
var child = this._children[i];
var index = path.length;
path.push(child.name);
child._changeAnimatorToLinkSprite3DNoAvatar(animator, isLink, path);
path.splice(index, 1);
}
}
_changeHierarchyAnimator(animator) {
this._hierarchyAnimator = animator;
}
_changeAnimatorAvatar(avatar) {
}
_onInActiveInScene() {
super._onInActiveInScene();
if (!this._scripts)
return;
for (let i = 0, n = this._scripts.length; i < n; i++)
this.scene._removeScript(this._scripts[i]);
}
_onAdded() {
if (this._parent instanceof Sprite3D) {
var parent3D = this._parent;
this.transform._setParent(parent3D.transform);
if (parent3D._hierarchyAnimator) {
(!this._hierarchyAnimator) && (this._setHierarchyAnimator(parent3D._hierarchyAnimator, null));
parent3D._changeAnimatorsToLinkSprite3D(this, true, [this.name]);
}
}
super._onAdded();
}
_onRemoved() {
super._onRemoved();
if (this._parent instanceof Sprite3D) {
var parent3D = this._parent;
this.transform._setParent(null);
if (parent3D._hierarchyAnimator) {
(this._hierarchyAnimator == parent3D._hierarchyAnimator) && (this._clearHierarchyAnimator(parent3D._hierarchyAnimator, null));
parent3D._changeAnimatorsToLinkSprite3D(this, false, [this.name]);
}
}
}
_parse(data, spriteMap) {
(data.isStatic !== undefined) && (this._isStatic = data.isStatic);
(data.active !== undefined) && (this.active = data.active);
(data.name != undefined) && (this.name = data.name);
if (data.position !== undefined) {
var loccalPosition = this.transform.localPosition;
loccalPosition.fromArray(data.position);
this.transform.localPosition = loccalPosition;
}
if (data.rotationEuler !== undefined) {
var localRotationEuler = this.transform.localRotationEuler;
localRotationEuler.fromArray(data.rotationEuler);
this.transform.localRotationEuler = localRotationEuler;
}
if (data.rotation !== undefined) {
var localRotation = this.transform.localRotation;
localRotation.fromArray(data.rotation);
this.transform.localRotation = localRotation;
}
if (data.scale !== undefined) {
var localScale = this.transform.localScale;
localScale.fromArray(data.scale);
this.transform.localScale = localScale;
}
(data.layer != undefined) && (this.layer = data.layer);
}
_cloneTo(destObject, srcRoot, dstRoot) {
if (this.destroyed)
throw new Error("Sprite3D: Can't be cloned if the Sprite3D has destroyed.");
var destSprite3D = destObject;
var trans = this._transform;
var destTrans = destSprite3D._transform;
destSprite3D.name = this.name;
destSprite3D.destroyed = this.destroyed;
destSprite3D.active = this.active;
destTrans.localPosition = trans.localPosition;
destTrans.localRotation = trans.localRotation;
destTrans.localScale = trans.localScale;
destSprite3D._isStatic = this._isStatic;
destSprite3D.layer = this.layer;
super._cloneTo(destSprite3D, srcRoot, dstRoot);
}
static _createSprite3DInstance(scrSprite) {
var node = scrSprite._create();
var children = scrSprite._children;
for (var i = 0, n = children.length; i < n; i++) {
var child = Sprite3D._createSprite3DInstance(children[i]);
node.addChild(child);
}
return node;
}
static _parseSprite3DInstance(srcRoot, dstRoot, scrSprite, dstSprite) {
var srcChildren = scrSprite._children;
var dstChildren = dstSprite._children;
for (var i = 0, n = srcChildren.length; i < n; i++)
Sprite3D._parseSprite3DInstance(srcRoot, dstRoot, srcChildren[i], dstChildren[i]);
scrSprite._cloneTo(dstSprite, srcRoot, dstRoot);
}
clone() {
var dstSprite3D = Sprite3D._createSprite3DInstance(this);
Sprite3D._parseSprite3DInstance(this, dstSprite3D, this, dstSprite3D);
return dstSprite3D;
}
destroy(destroyChild = true) {
if (this.destroyed)
return;
super.destroy(destroyChild);
this._transform = null;
this._scripts = null;
this._url && Laya.Loader.clearRes(this._url);
}
_create() {
return new Sprite3D();
}
}
Sprite3D.HIERARCHY = "HIERARCHY";
Sprite3D.WORLDMATRIX = Shader3D.propertyNameToID("u_WorldMat");
Sprite3D.MVPMATRIX = Shader3D.propertyNameToID("u_MvpMatrix");
Sprite3D._uniqueIDCounter = 0;
class DrawMeshCMD extends Command {
constructor() {
super();
this._projectionViewWorldMatrix = new Matrix4x4();
this._renderShaderValue = new ShaderData();
this._renderShaderValue = new ShaderData(null);
}
static create(mesh, matrix, material, subMeshIndex, subShaderIndex, commandBuffer) {
var cmd;
cmd = DrawMeshCMD._pool.length > 0 ? DrawMeshCMD._pool.pop() : new DrawMeshCMD();
cmd._mesh = mesh;
cmd._matrix = matrix;
cmd._material = material;
cmd._subMeshIndex = subMeshIndex;
cmd._subShaderIndex = subShaderIndex;
cmd._commandBuffer = commandBuffer;
return cmd;
}
run() {
var renderSubShader = this._material._shader.getSubShaderAt(this._subShaderIndex);
this.setContext(this._commandBuffer._context);
var context = this._context;
var forceInvertFace = context.invertY;
var scene = context.scene;
var cameraShaderValue = context.cameraShaderValue;
var projectionView = context.projectionViewMatrix;
Matrix4x4.multiply(projectionView, this._matrix, this._projectionViewWorldMatrix);
this._renderShaderValue.setMatrix4x4(Sprite3D.WORLDMATRIX, this._matrix);
this._renderShaderValue.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix);
var currentPipelineMode = context.pipelineMode;
var passes = renderSubShader._passes;
for (var j = 0, m = passes.length; j < m; j++) {
var pass = passes[j];
if (pass._pipelineMode !== currentPipelineMode)
continue;
var comDef = DrawMeshCMD._compileDefine;
scene._shaderValues._defineDatas.cloneTo(comDef);
comDef.addDefineDatas(this._renderShaderValue._defineDatas);
comDef.addDefineDatas(this._material._shaderValues._defineDatas);
var shaderIns = context.shader = pass.withCompile(comDef);
shaderIns.bind();
shaderIns.uploadUniforms(shaderIns._sceneUniformParamsMap, scene._shaderValues, true);
shaderIns.uploadUniforms(shaderIns._spriteUniformParamsMap, this._renderShaderValue, true);
shaderIns.uploadUniforms(shaderIns._cameraUniformParamsMap, cameraShaderValue, true);
var matValues = this._material._shaderValues;
shaderIns.uploadUniforms(shaderIns._materialUniformParamsMap, matValues, true);
shaderIns.uploadRenderStateBlendDepth(matValues);
shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, this._matrix.getInvertFront());
}
var subGeometryElement = this._mesh._subMeshes;
var subMeshRender;
if (this._subMeshIndex == -1) {
for (var i = 0, n = subGeometryElement.length; i < n; i++) {
subMeshRender = subGeometryElement[i];
if (subMeshRender._prepareRender(context)) {
subMeshRender._render(context);
}
}
}
else {
var subGeometryElement = this._mesh._subMeshes;
subMeshRender = subGeometryElement[this._subMeshIndex];
if (subMeshRender._prepareRender(context)) {
subMeshRender._render(context);
}
}
}
recover() {
DrawMeshCMD._pool.push(this);
this._renderShaderValue.clearDefine();
this._renderShaderValue._initData();
}
}
DrawMeshCMD._pool = [];
DrawMeshCMD._compileDefine = new DefineDatas();
class ClearRenderTextureCMD extends Command {
constructor() {
super(...arguments);
this._clearColor = false;
this._clearDepth = false;
this._backgroundColor = new Vector4();
this._depth = 1;
}
static create(clearColor, clearDepth, backgroundColor, depth = 1, commandBuffer) {
var cmd;
cmd = ClearRenderTextureCMD._pool.length > 0 ? ClearRenderTextureCMD._pool.pop() : new ClearRenderTextureCMD();
cmd._clearColor = clearColor;
cmd._clearDepth = clearDepth;
backgroundColor.cloneTo(cmd._backgroundColor);
cmd._depth = depth;
cmd._commandBuffer = commandBuffer;
return cmd;
}
run() {
var gl = Laya.LayaGL.instance;
var flag;
var backgroundColor = this._backgroundColor;
if (this._clearColor) {
gl.clearColor(backgroundColor.x, backgroundColor.y, backgroundColor.z, backgroundColor.w);
flag |= gl.COLOR_BUFFER_BIT;
}
if (this._clearDepth) {
gl.clearDepth(this._depth);
flag |= gl.DEPTH_BUFFER_BIT;
}
if (this._clearColor || this._clearDepth) {
gl.clear(flag);
}
}
recover() {
}
}
ClearRenderTextureCMD._pool = [];
class DrawRenderCMD extends Command {
static create(render, material, subShaderIndex, commandBuffer) {
var cmd;
cmd = DrawRenderCMD._pool.length > 0 ? DrawRenderCMD._pool.pop() : new DrawRenderCMD();
cmd._render = render;
cmd._material = material;
cmd._subShaderIndex = subShaderIndex;
cmd._commandBuffer = commandBuffer;
return cmd;
}
_elementRender(renderElement, context) {
var forceInvertFace = context.invertY;
var lastStateMaterial, lastStateShaderInstance, lastStateRender;
var updateMark = ILaya3D.Camera._updateMark;
var scene = context.scene;
this._render._scene = context.scene;
var cameraShaderValue = context.cameraShaderValue;
var transform = renderElement._transform;
var geometry = renderElement._geometry;
context.renderElement = renderElement;
var updateRender = updateMark !== renderElement.render._updateMark || renderElement.renderType !== renderElement.render._updateRenderType;
if (updateRender) {
renderElement.render._renderUpdate(context, transform);
renderElement.render._renderUpdateWithCamera(context, transform);
renderElement.render._updateMark = updateMark;
renderElement.render._updateRenderType = renderElement.renderType;
}
else {
if (renderElement.renderType == ILaya3D.RenderElement.RENDERTYPE_INSTANCEBATCH) {
renderElement.render._renderUpdate(context, transform);
renderElement.render._renderUpdateWithCamera(context, transform);
}
}
var currentPipelineMode = context.pipelineMode;
if (geometry._prepareRender(context)) {
var passes = renderElement.renderSubShader._passes;
for (var j = 0, m = passes.length; j < m; j++) {
var pass = passes[j];
if (pass._pipelineMode !== currentPipelineMode)
continue;
var comDef = DrawRenderCMD._compileDefine;
scene._shaderValues._defineDatas.cloneTo(comDef);
comDef.addDefineDatas(renderElement.render._shaderValues._defineDatas);
comDef.addDefineDatas(this._material._shaderValues._defineDatas);
var shaderIns = context.shader = pass.withCompile(comDef);
var switchShader = shaderIns.bind();
var switchUpdateMark = (updateMark !== shaderIns._uploadMark);
var uploadScene = (shaderIns._uploadScene !== scene) || switchUpdateMark;
if (uploadScene || switchShader) {
shaderIns.uploadUniforms(shaderIns._sceneUniformParamsMap, scene._shaderValues, uploadScene);
shaderIns._uploadScene = scene;
}
var uploadSprite3D = (shaderIns._uploadRender !== renderElement.render || shaderIns._uploadRenderType !== renderElement.renderType) || switchUpdateMark;
if (uploadSprite3D || switchShader) {
shaderIns.uploadUniforms(shaderIns._spriteUniformParamsMap, renderElement.render._shaderValues, uploadSprite3D);
shaderIns._uploadRender = renderElement.render;
shaderIns._uploadRenderType = renderElement.renderType;
}
var uploadCamera = shaderIns._uploadCameraShaderValue !== cameraShaderValue || switchUpdateMark;
if (uploadCamera || switchShader) {
shaderIns.uploadUniforms(shaderIns._cameraUniformParamsMap, cameraShaderValue, uploadCamera);
shaderIns._uploadCameraShaderValue = cameraShaderValue;
}
var uploadMaterial = (shaderIns._uploadMaterial !== this._material) || switchUpdateMark;
if (uploadMaterial || switchShader) {
shaderIns.uploadUniforms(shaderIns._materialUniformParamsMap, this._material._shaderValues, uploadMaterial);
shaderIns._uploadMaterial = this._material;
}
var matValues = this._material._shaderValues;
if (lastStateMaterial !== this._material || lastStateShaderInstance !== shaderIns) {
shaderIns.uploadRenderStateBlendDepth(matValues);
shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, renderElement.getInvertFront());
lastStateMaterial = this._material;
lastStateShaderInstance = shaderIns;
lastStateRender = renderElement.render;
}
else {
if (lastStateRender !== renderElement.render) {
shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, renderElement.getInvertFront());
lastStateRender = renderElement.render;
}
}
geometry._render(context);
shaderIns._uploadMark = updateMark;
}
}
if (renderElement.renderType !== ILaya3D.RenderElement.RENDERTYPE_NORMAL)
renderElement.render._revertBatchRenderUpdate(context);
}
run() {
if (!this._material)
throw "This render command material cannot be empty";
this.setContext(this._commandBuffer._context);
var context = this._context;
var scene = context.scene;
var renderElements = this._render._renderElements;
for (var i = 0, n = renderElements.length; i < n; i++) {
var renderelement = renderElements[i];
this._renderElementUpdate(renderelement);
this._elementRender(renderelement, context);
}
}
_renderElementUpdate(renderelement) {
if (this._material) {
renderelement.renderSubShader = this._material._shader.getSubShaderAt(this._subShaderIndex);
}
}
recover() {
DrawRenderCMD._pool.push(this);
}
}
DrawRenderCMD._pool = [];
DrawRenderCMD._compileDefine = new DefineDatas();
class SetGlobalShaderDataCMD extends Command {
constructor() {
super(...arguments);
this._nameID = 0;
this._value = null;
this._dataType = -1;
}
static create(nameID, value, shaderDataType, commandBuffer) {
var cmd;
cmd = SetGlobalShaderDataCMD._pool.length > 0 ? SetGlobalShaderDataCMD._pool.pop() : new SetGlobalShaderDataCMD();
cmd._nameID = nameID;
cmd._value = value;
cmd._dataType = shaderDataType;
cmd._commandBuffer = commandBuffer;
return cmd;
}
run() {
var shaderData = this._commandBuffer._camera.scene._shaderValues;
switch (this._dataType) {
case exports.ShaderDataType.Int:
shaderData.setInt(this._nameID, this._value);
break;
case exports.ShaderDataType.Number:
shaderData.setNumber(this._nameID, this._value);
break;
case exports.ShaderDataType.Bool:
shaderData.setBool(this._nameID, this._value);
break;
case exports.ShaderDataType.Matrix4x4:
shaderData.setMatrix4x4(this._nameID, this._value);
break;
case exports.ShaderDataType.Quaternion:
shaderData.setQuaternion(this._nameID, this._value);
break;
case exports.ShaderDataType.Texture:
shaderData.setTexture(this._nameID, this._value);
break;
case exports.ShaderDataType.Vector4:
shaderData.setVector(this._nameID, this._value);
break;
case exports.ShaderDataType.Vector2:
shaderData.setVector2(this._nameID, this._value);
break;
case exports.ShaderDataType.Vector3:
shaderData.setVector3(this._nameID, this._value);
break;
case exports.ShaderDataType.Buffer:
shaderData.setBuffer(this._nameID, this._value);
break;
default:
throw "no type shaderValue on this CommendBuffer";
}
}
recover() {
SetGlobalShaderDataCMD._pool.push(this);
this._nameID = 0;
this._value = null;
this._dataType = -1;
}
}
SetGlobalShaderDataCMD._pool = [];
class MeshSprite3DShaderDeclaration {
}
class VertexMesh {
static __init__() {
VertexMesh.instanceWorldMatrixDeclaration = new VertexDeclaration(64, [new VertexElement(0, VertexElementFormat.Vector4, VertexMesh.MESH_WORLDMATRIX_ROW0),
new VertexElement(16, VertexElementFormat.Vector4, VertexMesh.MESH_WORLDMATRIX_ROW1),
new VertexElement(32, VertexElementFormat.Vector4, VertexMesh.MESH_WORLDMATRIX_ROW2),
new VertexElement(48, VertexElementFormat.Vector4, VertexMesh.MESH_WORLDMATRIX_ROW3)]);
VertexMesh.instanceSimpleAnimatorDeclaration = new VertexDeclaration(16, [new VertexElement(0, VertexElementFormat.Vector4, VertexMesh.MESH_SIMPLEANIMATOR)]);
}
static getVertexDeclaration(vertexFlag, compatible = true) {
var verDec = VertexMesh._vertexDeclarationMap[vertexFlag + (compatible ? "_0" : "_1")];
if (!verDec) {
var subFlags = vertexFlag.split(",");
var offset = 0;
var elements = [];
for (var i = 0, n = subFlags.length; i < n; i++) {
var element;
switch (subFlags[i]) {
case "POSITION":
element = new VertexElement(offset, VertexElementFormat.Vector3, VertexMesh.MESH_POSITION0);
offset += 12;
break;
case "NORMAL":
element = new VertexElement(offset, VertexElementFormat.Vector3, VertexMesh.MESH_NORMAL0);
offset += 12;
break;
case "COLOR":
element = new VertexElement(offset, VertexElementFormat.Vector4, VertexMesh.MESH_COLOR0);
offset += 16;
break;
case "UV":
element = new VertexElement(offset, VertexElementFormat.Vector2, VertexMesh.MESH_TEXTURECOORDINATE0);
offset += 8;
break;
case "UV1":
element = new VertexElement(offset, VertexElementFormat.Vector2, VertexMesh.MESH_TEXTURECOORDINATE1);
offset += 8;
break;
case "BLENDWEIGHT":
element = new VertexElement(offset, VertexElementFormat.Vector4, VertexMesh.MESH_BLENDWEIGHT0);
offset += 16;
break;
case "BLENDINDICES":
if (compatible) {
element = new VertexElement(offset, VertexElementFormat.Vector4, VertexMesh.MESH_BLENDINDICES0);
offset += 16;
}
else {
element = new VertexElement(offset, VertexElementFormat.Byte4, VertexMesh.MESH_BLENDINDICES0);
offset += 4;
}
break;
case "TANGENT":
element = new VertexElement(offset, VertexElementFormat.Vector4, VertexMesh.MESH_TANGENT0);
offset += 16;
break;
default:
throw "VertexMesh: unknown vertex flag.";
}
elements.push(element);
}
verDec = new VertexDeclaration(offset, elements);
VertexMesh._vertexDeclarationMap[vertexFlag + (compatible ? "_0" : "_1")] = verDec;
}
return verDec;
}
}
VertexMesh.MESH_POSITION0 = 0;
VertexMesh.MESH_COLOR0 = 1;
VertexMesh.MESH_TEXTURECOORDINATE0 = 2;
VertexMesh.MESH_NORMAL0 = 3;
VertexMesh.MESH_TANGENT0 = 4;
VertexMesh.MESH_BLENDINDICES0 = 5;
VertexMesh.MESH_BLENDWEIGHT0 = 6;
VertexMesh.MESH_TEXTURECOORDINATE1 = 7;
VertexMesh.MESH_WORLDMATRIX_ROW0 = 8;
VertexMesh.MESH_WORLDMATRIX_ROW1 = 9;
VertexMesh.MESH_WORLDMATRIX_ROW2 = 10;
VertexMesh.MESH_WORLDMATRIX_ROW3 = 11;
VertexMesh.MESH_SIMPLEANIMATOR = 12;
VertexMesh.MESH_CUSTOME0 = 12;
VertexMesh.MESH_CUSTOME1 = 13;
VertexMesh.MESH_CUSTOME2 = 14;
VertexMesh.MESH_CUSTOME3 = 15;
VertexMesh._vertexDeclarationMap = {};
class DrawMeshInstancedCMD extends Command {
constructor() {
super();
this._renderShaderValue = new ShaderData(null);
let gl = Laya.LayaGL.instance;
this._instanceWorldMatrixData = new Float32Array(DrawMeshInstancedCMD.maxInstanceCount * 16);
this._instanceWorldMatrixBuffer = new VertexBuffer3D(this._instanceWorldMatrixData.length * 4, gl.DYNAMIC_DRAW);
this._instanceWorldMatrixBuffer.vertexDeclaration = VertexMesh.instanceWorldMatrixDeclaration;
}
static create(mesh, subMeshIndex, matrixs, material, subShaderIndex, instanceProperty, drawnums, commandBuffer) {
var cmd;
if ((matrixs && matrixs.length > 1024) || drawnums > DrawMeshInstancedCMD.maxInstanceCount) {
throw "the number of renderings exceeds the maximum number of merges";
}
cmd = DrawMeshInstancedCMD._pool.length > 0 ? DrawMeshInstancedCMD._pool.pop() : new DrawMeshInstancedCMD();
cmd._mesh = mesh;
cmd._matrixs = matrixs;
cmd._material = material;
cmd._subMeshIndex = subMeshIndex;
cmd._subShaderIndex = subShaderIndex;
cmd._commandBuffer = commandBuffer;
cmd._instanceProperty = instanceProperty;
cmd._drawnums = drawnums;
matrixs || cmd._updateWorldMatrixBuffer();
cmd._setInstanceBuffer();
return cmd;
}
_setInstanceBuffer() {
let instanceBufferState = this._instanceBufferState = new BufferState();
instanceBufferState.bind();
instanceBufferState.applyVertexBuffer(this._mesh._vertexBuffer);
instanceBufferState.applyInstanceVertexBuffer(this._instanceWorldMatrixBuffer);
let propertyMap = this._instanceProperty._propertyMap;
for (let i in propertyMap) {
instanceBufferState.applyInstanceVertexBuffer(propertyMap[i]._vertexBuffer);
}
instanceBufferState.applyIndexBuffer(this._mesh._indexBuffer);
instanceBufferState.unBind();
}
_updateWorldMatrixBuffer() {
let worldMatrixData = this._instanceWorldMatrixData;
let count = this._drawnums;
for (let i = 0; i < count; i++) {
worldMatrixData.set(this._matrixs[i].elements, i * 16);
}
let worldBuffer = this._instanceWorldMatrixBuffer;
worldBuffer.orphanStorage();
worldBuffer.setData(worldMatrixData.buffer, 0, 0, count * 64);
}
_render(subMesh) {
let gl = Laya.LayaGL.instance;
var count = this._drawnums;
var indexCount = subMesh._indexCount;
this._instanceBufferState.bind();
Laya.LayaGL.layaGPUInstance.drawElementsInstanced(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, subMesh._indexStart * 2, count);
Laya.Stat.renderBatches++;
Laya.Stat.trianglesFaces += indexCount * count / 3;
}
run() {
let renderSubShader = this._material._shader.getSubShaderAt(this._subShaderIndex);
this.setContext(this._commandBuffer._context);
let context = this._context;
let forceInvertFace = context.invertY;
let scene = context.scene;
let cameraShaderValue = context.cameraShaderValue;
let currentPipelineMode = context.pipelineMode;
this._renderShaderValue.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE);
let passes = renderSubShader._passes;
for (let j = 0, m = passes.length; j < m; j++) {
let pass = passes[j];
if (pass._pipelineMode !== currentPipelineMode)
continue;
let comDef = DrawMeshInstancedCMD._compileDefine;
scene._shaderValues._defineDatas.cloneTo(comDef);
comDef.addDefineDatas(this._renderShaderValue._defineDatas);
comDef.addDefineDatas(this._material._shaderValues._defineDatas);
let shaderIns = context.shader = pass.withCompile(comDef);
shaderIns.bind();
shaderIns.uploadUniforms(shaderIns._sceneUniformParamsMap, scene._shaderValues, true);
shaderIns.uploadUniforms(shaderIns._spriteUniformParamsMap, this._renderShaderValue, true);
shaderIns.uploadUniforms(shaderIns._cameraUniformParamsMap, cameraShaderValue, true);
let matValues = this._material._shaderValues;
shaderIns.uploadUniforms(shaderIns._materialUniformParamsMap, matValues, true);
shaderIns.uploadRenderStateBlendDepth(matValues);
shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, false);
}
let propertyMap = this._instanceProperty._propertyMap;
for (let i in propertyMap) {
propertyMap[i].updateVertexBufferData(this._drawnums);
}
let subGeometryElement = this._mesh._subMeshes;
let subMeshRender;
if (this._subMeshIndex == -1) {
for (let i = 0, n = subGeometryElement.length; i < n; i++) {
subMeshRender = subGeometryElement[i];
if (subMeshRender._prepareRender(context)) {
this._render(subMeshRender);
}
}
}
else {
let subGeometryElement = this._mesh._subMeshes;
subMeshRender = subGeometryElement[this._subMeshIndex];
if (subMeshRender._prepareRender(context)) {
this._render(subMeshRender);
}
}
}
setWorldMatrix(worldMatrixArray) {
if (worldMatrixArray.length < this._drawnums)
throw "worldMatrixArray length is less then drawnums";
this._matrixs = worldMatrixArray;
this._matrixs && this._updateWorldMatrixBuffer();
}
setDrawNums(drawNums) {
if (this._matrixs && this._matrixs.length < drawNums)
throw "worldMatrixArray length is less then drawnums";
this._drawnums = drawNums;
this._matrixs && this._updateWorldMatrixBuffer();
}
recover() {
DrawMeshInstancedCMD._pool.push(this);
this._renderShaderValue.clearDefine();
this._renderShaderValue._initData();
this._instanceBufferState.destroy();
this._instanceBufferState = null;
}
}
DrawMeshInstancedCMD._pool = [];
DrawMeshInstancedCMD._compileDefine = new DefineDatas();
DrawMeshInstancedCMD.maxInstanceCount = 1024;
class CommandBuffer {
constructor() {
this._camera = null;
this._commands = [];
}
_apply() {
for (var i = 0, n = this._commands.length; i < n; i++)
this._commands[i].run();
}
setShaderDataTexture(shaderData, nameID, source) {
this._commands.push(SetShaderDataCMD.create(shaderData, nameID, source, exports.ShaderDataType.Texture, this));
}
setGlobalTexture(nameID, source) {
this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Texture, this));
}
setShaderDataVector(shaderData, nameID, value) {
this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Vector4, this));
}
setGlobalVector(nameID, source) {
this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Vector4, this));
}
setShaderDataVector3(shaderData, nameID, value) {
this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Vector3, this));
}
setGlobalVector3(nameID, source) {
this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Vector3, this));
}
setShaderDataVector2(shaderData, nameID, value) {
this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Vector2, this));
}
setGlobalVector2(nameID, source) {
this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Vector2, this));
}
setShaderDataNumber(shaderData, nameID, value) {
this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Number, this));
}
setGlobalNumber(nameID, source) {
this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Number, this));
}
setShaderDataInt(shaderData, nameID, value) {
this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Int, this));
}
setGlobalInt(nameID, source) {
this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Int, this));
}
setShaderDataMatrix(shaderData, nameID, value) {
this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Matrix4x4, this));
}
setGlobalMatrix(nameID, source) {
this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Matrix4x4, this));
}
blitScreenQuad(source, dest, offsetScale = null, shader = null, shaderData = null, subShader = 0, definedCanvas = false) {
this._commands.push(BlitScreenQuadCMD.create(source, dest, offsetScale, shader, shaderData, subShader, BlitScreenQuadCMD._SCREENTYPE_QUAD, this, definedCanvas));
}
blitScreenQuadByMaterial(source, dest, offsetScale = null, material = null, subShader = 0) {
var shader;
var shaderData;
if (material) {
shader = material._shader;
shaderData = material.shaderData;
}
this._commands.push(BlitScreenQuadCMD.create(source, dest, offsetScale, shader, shaderData, subShader, BlitScreenQuadCMD._SCREENTYPE_QUAD, this));
}
blitScreenTriangle(source, dest, offsetScale = null, shader = null, shaderData = null, subShader = 0, defineCanvas = false) {
this._commands.push(BlitScreenQuadCMD.create(source, dest, offsetScale, shader, shaderData, subShader, BlitScreenQuadCMD._SCREENTYPE_TRIANGLE, this, defineCanvas));
}
setRenderTarget(renderTexture) {
this._commands.push(SetRenderTargetCMD.create(renderTexture));
}
clearRenderTarget(clearColor, clearDepth, backgroundColor, depth = 1) {
this._commands.push(ClearRenderTextureCMD.create(clearColor, clearDepth, backgroundColor, depth, this));
}
drawMesh(mesh, matrix, material, submeshIndex, subShaderIndex) {
this._commands.push(DrawMeshCMD.create(mesh, matrix, material, submeshIndex, subShaderIndex, this));
}
drawRender(render, material, subShaderIndex) {
this._commands.push(DrawRenderCMD.create(render, material, subShaderIndex, this));
}
drawMeshInstance(mesh, subMeshIndex, matrixs, material, subShaderIndex, instanceProperty, drawnums) {
if (!Laya.LayaGL.layaGPUInstance.supportInstance())
return null;
var drawMeshInstancedCMD = DrawMeshInstancedCMD.create(mesh, subMeshIndex, matrixs, material, subShaderIndex, instanceProperty, drawnums, this);
this._commands.push(drawMeshInstancedCMD);
return drawMeshInstancedCMD;
}
clear() {
for (var i = 0, n = this._commands.length; i < n; i++)
this._commands[i].recover();
this._commands.length = 0;
}
}
class PostProcessRenderContext {
constructor() {
this.source = null;
this.destination = null;
this.camera = null;
this.compositeShaderData = null;
this.command = null;
this.deferredReleaseTextures = [];
}
}
class PostProcess {
constructor() {
this._compositeShader = Shader3D.find("PostProcessComposite");
this._compositeShaderData = new ShaderData();
this._effects = [];
this._enable = true;
this._context = null;
this._context = new PostProcessRenderContext();
this._context.compositeShaderData = this._compositeShaderData;
this._context.command = new CommandBuffer();
}
static __init__() {
PostProcess.SHADERDEFINE_BLOOM_LOW = Shader3D.getDefineByName("BLOOM_LOW");
PostProcess.SHADERDEFINE_BLOOM = Shader3D.getDefineByName("BLOOM");
PostProcess.SHADERDEFINE_FINALPASS = Shader3D.getDefineByName("FINALPASS");
}
get enable() {
return this._enable;
}
set enable(value) {
this._enable = value;
}
_init(camera) {
this._context.camera = camera;
this._context.command._camera = camera;
}
_render() {
var noteValue = ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_;
Laya.ILaya.Render.supportWebGLPlusRendering && ShaderData.setRuntimeValueMode(false);
var camera = this._context.camera;
var viewport = camera.viewport;
var cameraTarget = camera._internalRenderTexture;
var screenTexture = cameraTarget;
this._context.command.clear();
this._context.source = screenTexture;
this._context.destination = cameraTarget;
this._context.compositeShaderData.clearDefine();
this._context.compositeShaderData.setTexture(PostProcess.SHADERVALUE_AUTOEXPOSURETEX, Laya.Texture2D.whiteTexture);
for (var i = 0, n = this._effects.length; i < n; i++)
this._effects[i].render(this._context);
this._compositeShaderData.addDefine(PostProcess.SHADERDEFINE_FINALPASS);
var offScreenTex = camera._offScreenRenderTexture;
var dest = offScreenTex ? offScreenTex : null;
this._context.destination = dest;
var canvasWidth = camera._getCanvasWidth(), canvasHeight = camera._getCanvasHeight();
camera._screenOffsetScale.setValue(viewport.x / canvasWidth, viewport.y / canvasHeight, viewport.width / canvasWidth, viewport.height / canvasHeight);
this._context.command.blitScreenTriangle(this._context.source, dest, camera._screenOffsetScale, this._compositeShader, this._compositeShaderData, 0, true);
RenderTexture.recoverToPool(screenTexture);
var tempRenderTextures = this._context.deferredReleaseTextures;
for (i = 0, n = tempRenderTextures.length; i < n; i++)
RenderTexture.recoverToPool(tempRenderTextures[i]);
tempRenderTextures.length = 0;
Laya.ILaya.Render.supportWebGLPlusRendering && ShaderData.setRuntimeValueMode(noteValue);
}
addEffect(effect) {
this._effects.push(effect);
}
removeEffect(effect) {
var index = this._effects.indexOf(effect);
if (index !== -1)
this._effects.splice(index, 1);
}
_applyPostProcessCommandBuffers() {
this._context.command._apply();
}
}
PostProcess.SHADERVALUE_MAINTEX = Shader3D.propertyNameToID("u_MainTex");
PostProcess.SHADERVALUE_BLOOMTEX = Shader3D.propertyNameToID("u_BloomTex");
PostProcess.SHADERVALUE_AUTOEXPOSURETEX = Shader3D.propertyNameToID("u_AutoExposureTex");
PostProcess.SHADERVALUE_BLOOM_DIRTTEX = Shader3D.propertyNameToID("u_Bloom_DirtTex");
PostProcess.SHADERVALUE_BLOOMTEX_TEXELSIZE = Shader3D.propertyNameToID("u_BloomTex_TexelSize");
PostProcess.SHADERVALUE_BLOOM_DIRTTILEOFFSET = Shader3D.propertyNameToID("u_Bloom_DirtTileOffset");
PostProcess.SHADERVALUE_BLOOM_SETTINGS = Shader3D.propertyNameToID("u_Bloom_Settings");
PostProcess.SHADERVALUE_BLOOM_COLOR = Shader3D.propertyNameToID("u_Bloom_Color");
class AnimationTransform3D extends Laya.EventDispatcher {
constructor(owner) {
super();
this._owner = owner;
this._children = [];
this._localMatrix = new Float32Array(16);
this._localPosition = new Vector3();
this._localRotation = new Quaternion();
this._localScale = new Vector3();
this._worldMatrix = new Float32Array(16);
this._localQuaternionUpdate = false;
this._locaEulerlUpdate = false;
this._localUpdate = false;
this._worldUpdate = true;
}
_getlocalMatrix() {
if (this._localUpdate) {
Utils3D._createAffineTransformationArray(this._localPosition, this._localRotation, this._localScale, this._localMatrix);
this._localUpdate = false;
}
return this._localMatrix;
}
_onWorldTransform() {
if (!this._worldUpdate) {
this._worldUpdate = true;
this.event(Laya.Event.TRANSFORM_CHANGED);
for (var i = 0, n = this._children.length; i < n; i++)
this._children[i]._onWorldTransform();
}
}
get localPosition() {
return this._localPosition;
}
set localPosition(value) {
this._localPosition = value;
this._localUpdate = true;
this._onWorldTransform();
}
get localRotation() {
if (this._localQuaternionUpdate) {
var euler = this._localRotationEuler;
Quaternion.createFromYawPitchRoll(euler.y / AnimationTransform3D._angleToRandin, euler.x / AnimationTransform3D._angleToRandin, euler.z / AnimationTransform3D._angleToRandin, this._localRotation);
this._localQuaternionUpdate = false;
}
return this._localRotation;
}
set localRotation(value) {
this._localRotation = value;
this._locaEulerlUpdate = true;
this._localQuaternionUpdate = false;
this._localUpdate = true;
this._onWorldTransform();
}
get localScale() {
return this._localScale;
}
set localScale(value) {
this._localScale = value;
this._localUpdate = true;
this._onWorldTransform();
}
get localRotationEuler() {
if (this._locaEulerlUpdate) {
this._localRotation.getYawPitchRoll(AnimationTransform3D._tempVector3);
var euler = AnimationTransform3D._tempVector3;
var localRotationEuler = this._localRotationEuler;
localRotationEuler.x = euler.y * AnimationTransform3D._angleToRandin;
localRotationEuler.y = euler.x * AnimationTransform3D._angleToRandin;
localRotationEuler.z = euler.z * AnimationTransform3D._angleToRandin;
this._locaEulerlUpdate = false;
}
return this._localRotationEuler;
}
set localRotationEuler(value) {
this._localRotationEuler = value;
this._locaEulerlUpdate = false;
this._localQuaternionUpdate = true;
this._localUpdate = true;
this._onWorldTransform();
}
getWorldMatrix() {
if (this._worldUpdate) {
if (this._parent != null) {
Utils3D.matrix4x4MultiplyFFF(this._parent.getWorldMatrix(), this._getlocalMatrix(), this._worldMatrix);
}
else {
var e = this._worldMatrix;
e[1] = e[2] = e[3] = e[4] = e[6] = e[7] = e[8] = e[9] = e[11] = e[12] = e[13] = e[14] = 0;
e[0] = e[5] = e[10] = e[15] = 1;
}
this._worldUpdate = false;
}
return this._worldMatrix;
}
setParent(value) {
if (this._parent !== value) {
if (this._parent) {
var parentChilds = this._parent._children;
var index = parentChilds.indexOf(this);
parentChilds.splice(index, 1);
}
if (value) {
value._children.push(this);
(value) && (this._onWorldTransform());
}
this._parent = value;
}
}
}
AnimationTransform3D._tempVector3 = new Vector3();
AnimationTransform3D._angleToRandin = 180 / Math.PI;
class AnimationNode {
constructor() {
this._parent = null;
this.name = null;
this._worldMatrixIndex = 0;
this._children = [];
this.transform = new AnimationTransform3D(this);
}
addChild(child) {
child._parent = this;
child.transform.setParent(this.transform);
this._children.push(child);
}
removeChild(child) {
var index = this._children.indexOf(child);
(index !== -1) && (this._children.splice(index, 1));
}
getChildByName(name) {
for (var i = 0, n = this._children.length; i < n; i++) {
var child = this._children[i];
if (child.name === name)
return child;
}
return null;
}
getChildByIndex(index) {
return this._children[index];
}
getChildCount() {
return this._children.length;
}
cloneTo(destObject) {
var destNode = destObject;
destNode.name = this.name;
for (var i = 0, n = this._children.length; i < n; i++) {
var child = this._children[i];
var destChild = child.clone();
destNode.addChild(destChild);
var transform = child.transform;
var destTransform = destChild.transform;
var destLocalPosition = destTransform.localPosition;
var destLocalRotation = destTransform.localRotation;
var destLocalScale = destTransform.localScale;
transform.localPosition.cloneTo(destLocalPosition);
transform.localRotation.cloneTo(destLocalRotation);
transform.localScale.cloneTo(destLocalScale);
destTransform.localPosition = destLocalPosition;
destTransform.localRotation = destLocalRotation;
destTransform.localScale = destLocalScale;
}
}
clone() {
var dest = new AnimationNode();
this.cloneTo(dest);
return dest;
}
_cloneNative(localPositions, localRotations, localScales, animationNodeWorldMatrixs, animationNodeParentIndices, parentIndex, avatar) {
var curID = avatar._nativeCurCloneCount;
animationNodeParentIndices[curID] = parentIndex;
var dest = new AnimationNode();
dest._worldMatrixIndex = curID;
this._cloneToNative(dest, localPositions, localRotations, localScales, animationNodeWorldMatrixs, animationNodeParentIndices, curID, avatar);
return dest;
}
_cloneToNative(destObject, localPositions, localRotations, localScales, animationNodeWorldMatrixs, animationNodeParentIndices, parentIndex, avatar) {
var destNode = destObject;
destNode.name = this.name;
for (var i = 0, n = this._children.length; i < n; i++) {
var child = this._children[i];
avatar._nativeCurCloneCount++;
var destChild = child._cloneNative(localPositions, localRotations, localScales, animationNodeWorldMatrixs, animationNodeParentIndices, parentIndex, avatar);
destNode.addChild(destChild);
var transform = child.transform;
var destTransform = destChild.transform;
var destLocalPosition = destTransform.localPosition;
var destLocalRotation = destTransform.localRotation;
var destLocalScale = destTransform.localScale;
transform.localPosition.cloneTo(destLocalPosition);
transform.localRotation.cloneTo(destLocalRotation);
transform.localScale.cloneTo(destLocalScale);
destTransform.localPosition = destLocalPosition;
destTransform.localRotation = destLocalRotation;
destTransform.localScale = destLocalScale;
}
}
}
class Avatar extends Laya.Resource {
constructor() {
super();
this._nativeNodeCount = 0;
this._nativeCurCloneCount = 0;
}
static _parse(data, propertyParams = null, constructParams = null) {
var avatar = new Avatar();
avatar._rootNode = new AnimationNode();
if (data.version) {
var rootNode = data.rootNode;
(rootNode) && (avatar._parseNode(rootNode, avatar._rootNode));
}
return avatar;
}
static load(url, complete) {
Laya.ILaya.loader.create(url, complete, null, Avatar.AVATAR);
}
_initCloneToAnimator(destNode, destAnimator) {
destAnimator._avatarNodeMap[destNode.name] = destNode;
for (var i = 0, n = destNode.getChildCount(); i < n; i++)
this._initCloneToAnimator(destNode.getChildByIndex(i), destAnimator);
}
_parseNode(nodaData, node) {
var name = nodaData.props.name;
node.name = name;
var props = nodaData.props;
var transform = node.transform;
var pos = transform.localPosition;
var rot = transform.localRotation;
var sca = transform.localScale;
pos.fromArray(props.translate);
rot.fromArray(props.rotation);
sca.fromArray(props.scale);
transform.localPosition = pos;
transform.localRotation = rot;
transform.localScale = sca;
var childrenData = nodaData.child;
for (var j = 0, n = childrenData.length; j < n; j++) {
var childData = childrenData[j];
var childBone = new AnimationNode();
node.addChild(childBone);
this._parseNode(childData, childBone);
}
}
_cloneDatasToAnimator(destAnimator) {
var destRoot;
destRoot = this._rootNode.clone();
var transform = this._rootNode.transform;
var destTransform = destRoot.transform;
var destPosition = destTransform.localPosition;
var destRotation = destTransform.localRotation;
var destScale = destTransform.localScale;
transform.localPosition.cloneTo(destPosition);
transform.localRotation.cloneTo(destRotation);
transform.localScale.cloneTo(destScale);
destTransform.localPosition = destPosition;
destTransform.localRotation = destRotation;
destTransform.localScale = destScale;
destAnimator._avatarNodeMap = {};
this._initCloneToAnimator(destRoot, destAnimator);
}
cloneTo(destObject) {
var destAvatar = destObject;
var destRoot = this._rootNode.clone();
destAvatar._rootNode = destRoot;
}
clone() {
var dest = new Avatar();
this.cloneTo(dest);
return dest;
}
_cloneDatasToAnimatorNative(destAnimator) {
var animationNodeLocalPositions = new Float32Array(this._nativeNodeCount * 3);
var animationNodeLocalRotations = new Float32Array(this._nativeNodeCount * 4);
var animationNodeLocalScales = new Float32Array(this._nativeNodeCount * 3);
var animationNodeWorldMatrixs = new Float32Array(this._nativeNodeCount * 16);
var animationNodeParentIndices = new Int16Array(this._nativeNodeCount);
destAnimator._animationNodeLocalPositions = animationNodeLocalPositions;
destAnimator._animationNodeLocalRotations = animationNodeLocalRotations;
destAnimator._animationNodeLocalScales = animationNodeLocalScales;
destAnimator._animationNodeWorldMatrixs = animationNodeWorldMatrixs;
destAnimator._animationNodeParentIndices = animationNodeParentIndices;
this._nativeCurCloneCount = 0;
var destRoot = this._rootNode._cloneNative(animationNodeLocalPositions, animationNodeLocalRotations, animationNodeLocalScales, animationNodeWorldMatrixs, animationNodeParentIndices, -1, this);
var transform = this._rootNode.transform;
var destTransform = destRoot.transform;
var destPosition = destTransform.localPosition;
var destRotation = destTransform.localRotation;
var destScale = destTransform.localScale;
transform.localPosition.cloneTo(destPosition);
transform.localRotation.cloneTo(destRotation);
transform.localScale.cloneTo(destScale);
destTransform.localPosition = destPosition;
destTransform.localRotation = destRotation;
destTransform.localScale = destScale;
destAnimator._avatarNodeMap = {};
this._initCloneToAnimator(destRoot, destAnimator);
}
}
Avatar.AVATAR = "AVATAR";
class Material extends Laya.Resource {
constructor() {
super();
this._shaderValues = new ShaderData(this);
this.renderQueue = Material.RENDERQUEUE_OPAQUE;
this.alphaTest = false;
}
static load(url, complete) {
Laya.Laya.loader.create(url, complete, null, Material.MATERIAL);
}
static __initDefine__() {
Material.SHADERDEFINE_ALPHATEST = Shader3D.getDefineByName("ALPHATEST");
}
static _parse(data, propertyParams = null, constructParams = null) {
var jsonData = data;
var props = jsonData.props;
var material;
var classType = props.type;
var clas = Laya.ClassUtils.getRegClass(classType);
if (clas)
material = new clas();
else {
material = new Material();
material.setShaderName(classType);
}
switch (jsonData.version) {
case "LAYAMATERIAL:01":
case "LAYAMATERIAL:02":
var i, n;
for (var key in props) {
switch (key) {
case "type":
break;
case "vectors":
var vectors = props[key];
for (i = 0, n = vectors.length; i < n; i++) {
var vector = vectors[i];
var vectorValue = vector.value;
switch (vectorValue.length) {
case 2:
material[vector.name] = new Vector2(vectorValue[0], vectorValue[1]);
break;
case 3:
material[vector.name] = new Vector3(vectorValue[0], vectorValue[1], vectorValue[2]);
break;
case 4:
material[vector.name] = new Vector4(vectorValue[0], vectorValue[1], vectorValue[2], vectorValue[3]);
break;
default:
throw new Error("BaseMaterial:unkonwn color length.");
}
}
break;
case "textures":
var textures = props[key];
for (i = 0, n = textures.length; i < n; i++) {
var texture = textures[i];
var path = texture.path;
(path) && (material[texture.name] = Laya.Loader.getRes(path));
}
break;
case "defines":
var defineNames = props[key];
for (i = 0, n = defineNames.length; i < n; i++) {
var define = Shader3D.getDefineByName(defineNames[i]);
material._shaderValues.addDefine(define);
}
break;
case "renderStates":
var renderStatesData = props[key];
var renderStateData = renderStatesData[0];
var mat = material;
mat.blend = renderStateData.blend;
mat.cull = renderStateData.cull;
mat.depthTest = renderStateData.depthTest;
mat.depthWrite = renderStateData.depthWrite;
mat.blendSrc = renderStateData.srcBlend;
mat.blendDst = renderStateData.dstBlend;
break;
case "cull":
material.cull = props[key];
break;
case "blend":
material.blend = props[key];
break;
case "depthWrite":
material.depthWrite = props[key];
break;
case "srcBlend":
material.blendSrc = props[key];
break;
case "dstBlend":
material.blendDst = props[key];
break;
default:
material[key] = props[key];
}
}
break;
case "LAYAMATERIAL:03":
var i, n;
for (var key in props) {
switch (key) {
case "type":
case "name":
break;
case "defines":
var defineNames = props[key];
for (i = 0, n = defineNames.length; i < n; i++) {
var define = Shader3D.getDefineByName(defineNames[i]);
material._shaderValues.addDefine(define);
}
break;
case "textures":
var textures = props[key];
for (i = 0, n = textures.length; i < n; i++) {
var texture = textures[i];
var path = texture.path;
(path) && (material._shaderValues.setTexture(Shader3D.propertyNameToID(texture.name), Laya.Loader.getRes(path)));
}
break;
default:
var property = props[key];
var uniName = Shader3D.propertyNameToID(key);
if (!property.length) {
material._shaderValues.setNumber(uniName, props[key]);
}
else {
var vectorValue = property;
switch (vectorValue.length) {
case 2:
material._shaderValues.setVector2(uniName, new Vector2(vectorValue[0], vectorValue[1]));
break;
case 3:
material._shaderValues.setVector3(uniName, new Vector3(vectorValue[0], vectorValue[1], vectorValue[2]));
break;
case 4:
material._shaderValues.setVector(uniName, new Vector4(vectorValue[0], vectorValue[1], vectorValue[2], vectorValue[3]));
break;
default:
throw new Error("BaseMaterial:unkonwn color length.");
}
}
}
}
break;
default:
throw new Error("BaseMaterial:unkonwn version.");
}
return material;
}
get shaderData() {
return this._shaderValues;
}
get alphaTestValue() {
return this._shaderValues.getNumber(Material.ALPHATESTVALUE);
}
set alphaTestValue(value) {
this._shaderValues.setNumber(Material.ALPHATESTVALUE, value);
}
get alphaTest() {
return this.shaderData.hasDefine(Material.SHADERDEFINE_ALPHATEST);
}
set alphaTest(value) {
if (value)
this._shaderValues.addDefine(Material.SHADERDEFINE_ALPHATEST);
else
this._shaderValues.removeDefine(Material.SHADERDEFINE_ALPHATEST);
}
get depthWrite() {
return this._shaderValues.getBool(Material.DEPTH_WRITE);
}
set depthWrite(value) {
this._shaderValues.setBool(Material.DEPTH_WRITE, value);
}
get cull() {
return this._shaderValues.getInt(Material.CULL);
}
set cull(value) {
this._shaderValues.setInt(Material.CULL, value);
}
get blend() {
return this._shaderValues.getInt(Material.BLEND);
}
set blend(value) {
this._shaderValues.setInt(Material.BLEND, value);
}
get blendSrc() {
return this._shaderValues.getInt(Material.BLEND_SRC);
}
set blendSrc(value) {
this._shaderValues.setInt(Material.BLEND_SRC, value);
}
get blendDst() {
return this._shaderValues.getInt(Material.BLEND_DST);
}
set blendDst(value) {
this._shaderValues.setInt(Material.BLEND_DST, value);
}
get depthTest() {
return this._shaderValues.getInt(Material.DEPTH_TEST);
}
set depthTest(value) {
this._shaderValues.setInt(Material.DEPTH_TEST, value);
}
get MaterialProperty() {
let propertyMap = {};
var shaderValues = this._shaderValues.getData();
for (let key in shaderValues) {
propertyMap[Shader3D._propertyNameMap[parseInt(key)]] = shaderValues[key];
}
return propertyMap;
}
get MaterialDefine() {
let shaderDefineArray = new Array();
let defineData = this._shaderValues._defineDatas;
Shader3D._getNamesByDefineData(defineData, shaderDefineArray);
return shaderDefineArray;
}
_removeTetxureReference() {
var data = this._shaderValues.getData();
for (var k in data) {
var value = data[k];
if (value && value instanceof Laya.BaseTexture)
value._removeReference();
}
}
_disposeResource() {
if (this._referenceCount > 0)
this._removeTetxureReference();
this._shaderValues = null;
}
_addReference(count = 1) {
super._addReference(count);
var data = this._shaderValues.getData();
for (var k in data) {
var value = data[k];
if (value && value instanceof Laya.BaseTexture)
value._addReference();
}
}
_removeReference(count = 1) {
super._removeReference(count);
this._removeTetxureReference();
}
setShaderName(name) {
this._shader = Shader3D.find(name);
if (!this._shader)
throw new Error("BaseMaterial: unknown shader name.");
}
setShaderPropertyValue(name, value) {
this.shaderData.setValueData(Shader3D.propertyNameToID(name), value);
}
getShaderPropertyValue(name) {
return this.shaderData.getValueData(Shader3D.propertyNameToID(name));
}
cloneTo(destObject) {
var destBaseMaterial = destObject;
destBaseMaterial.name = this.name;
destBaseMaterial.renderQueue = this.renderQueue;
this._shaderValues.cloneTo(destBaseMaterial._shaderValues);
}
clone() {
var dest = new Material();
this.cloneTo(dest);
return dest;
}
get _defineDatas() {
return this._shaderValues._defineDatas;
}
}
Material.MATERIAL = "MATERIAL";
Material.RENDERQUEUE_OPAQUE = 2000;
Material.RENDERQUEUE_ALPHATEST = 2450;
Material.RENDERQUEUE_TRANSPARENT = 3000;
Material.ALPHATESTVALUE = Shader3D.propertyNameToID("u_AlphaTestValue");
Material.CULL = Shader3D.propertyNameToID("s_Cull");
Material.BLEND = Shader3D.propertyNameToID("s_Blend");
Material.BLEND_SRC = Shader3D.propertyNameToID("s_BlendSrc");
Material.BLEND_DST = Shader3D.propertyNameToID("s_BlendDst");
Material.DEPTH_TEST = Shader3D.propertyNameToID("s_DepthTest");
Material.DEPTH_WRITE = Shader3D.propertyNameToID("s_DepthWrite");
class BaseMaterial {
static load(url, complete) {
Laya.Laya.loader.create(url, complete, null, Material.MATERIAL);
}
static __initDefine__() {
BaseMaterial.SHADERDEFINE_ALPHATEST = Material.SHADERDEFINE_ALPHATEST;
}
}
BaseMaterial.MATERIAL = "MATERIAL";
BaseMaterial.RENDERQUEUE_OPAQUE = 2000;
BaseMaterial.RENDERQUEUE_ALPHATEST = 2450;
BaseMaterial.RENDERQUEUE_TRANSPARENT = 3000;
BaseMaterial.ALPHATESTVALUE = Shader3D.propertyNameToID("u_AlphaTestValue");
class RenderState {
constructor() {
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_DISABLE;
this.srcBlend = RenderState.BLENDPARAM_ONE;
this.dstBlend = RenderState.BLENDPARAM_ZERO;
this.srcBlendRGB = RenderState.BLENDPARAM_ONE;
this.dstBlendRGB = RenderState.BLENDPARAM_ZERO;
this.srcBlendAlpha = RenderState.BLENDPARAM_ONE;
this.dstBlendAlpha = RenderState.BLENDPARAM_ZERO;
this.blendConstColor = new Vector4(1, 1, 1, 1);
this.blendEquation = RenderState.BLENDEQUATION_ADD;
this.blendEquationRGB = RenderState.BLENDEQUATION_ADD;
this.blendEquationAlpha = RenderState.BLENDEQUATION_ADD;
this.depthTest = RenderState.DEPTHTEST_LEQUAL;
this.depthWrite = true;
}
cloneTo(dest) {
var destState = dest;
destState.cull = this.cull;
destState.blend = this.blend;
destState.srcBlend = this.srcBlend;
destState.dstBlend = this.dstBlend;
destState.srcBlendRGB = this.srcBlendRGB;
destState.dstBlendRGB = this.dstBlendRGB;
destState.srcBlendAlpha = this.srcBlendAlpha;
destState.dstBlendAlpha = this.dstBlendAlpha;
this.blendConstColor.cloneTo(destState.blendConstColor);
destState.blendEquation = this.blendEquation;
destState.blendEquationRGB = this.blendEquationRGB;
destState.blendEquationAlpha = this.blendEquationAlpha;
destState.depthTest = this.depthTest;
destState.depthWrite = this.depthWrite;
}
clone() {
var dest = new RenderState();
this.cloneTo(dest);
return dest;
}
}
RenderState.CULL_NONE = 0;
RenderState.CULL_FRONT = 1;
RenderState.CULL_BACK = 2;
RenderState.BLEND_DISABLE = 0;
RenderState.BLEND_ENABLE_ALL = 1;
RenderState.BLEND_ENABLE_SEPERATE = 2;
RenderState.BLENDPARAM_ZERO = 0;
RenderState.BLENDPARAM_ONE = 1;
RenderState.BLENDPARAM_SRC_COLOR = 0x0300;
RenderState.BLENDPARAM_ONE_MINUS_SRC_COLOR = 0x0301;
RenderState.BLENDPARAM_DST_COLOR = 0x0306;
RenderState.BLENDPARAM_ONE_MINUS_DST_COLOR = 0x0307;
RenderState.BLENDPARAM_SRC_ALPHA = 0x0302;
RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA = 0x0303;
RenderState.BLENDPARAM_DST_ALPHA = 0x0304;
RenderState.BLENDPARAM_ONE_MINUS_DST_ALPHA = 0x0305;
RenderState.BLENDPARAM_SRC_ALPHA_SATURATE = 0x0308;
RenderState.BLENDEQUATION_ADD = 0x8006;
RenderState.BLENDEQUATION_SUBTRACT = 0x800A;
RenderState.BLENDEQUATION_REVERSE_SUBTRACT = 0x800B;
RenderState.DEPTHTEST_OFF = 0;
RenderState.DEPTHTEST_NEVER = 0x0200;
RenderState.DEPTHTEST_LESS = 0x0201;
RenderState.DEPTHTEST_EQUAL = 0x0202;
RenderState.DEPTHTEST_LEQUAL = 0x0203;
RenderState.DEPTHTEST_GREATER = 0x0204;
RenderState.DEPTHTEST_NOTEQUAL = 0x0205;
RenderState.DEPTHTEST_GEQUAL = 0x0206;
RenderState.DEPTHTEST_ALWAYS = 0x0207;
class BlinnPhongMaterial extends Material {
constructor() {
super();
this.setShaderName("BLINNPHONG");
this.albedoIntensity = 1.0;
var sv = this._shaderValues;
sv.setVector(BlinnPhongMaterial.ALBEDOCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0));
sv.setVector(BlinnPhongMaterial.MATERIALSPECULAR, new Vector4(1.0, 1.0, 1.0, 1.0));
sv.setNumber(BlinnPhongMaterial.SHININESS, 0.078125);
sv.setNumber(Material.ALPHATESTVALUE, 0.5);
sv.setVector(BlinnPhongMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0));
this.albedoIntensity = 1.0;
this.renderMode = BlinnPhongMaterial.RENDERMODE_OPAQUE;
}
static __initDefine__() {
BlinnPhongMaterial.SHADERDEFINE_DIFFUSEMAP = Shader3D.getDefineByName("DIFFUSEMAP");
BlinnPhongMaterial.SHADERDEFINE_NORMALMAP = Shader3D.getDefineByName("NORMALMAP");
BlinnPhongMaterial.SHADERDEFINE_SPECULARMAP = Shader3D.getDefineByName("SPECULARMAP");
BlinnPhongMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR = Shader3D.getDefineByName("ENABLEVERTEXCOLOR");
BlinnPhongMaterial.SHADERDEFINE_ENABLETRANSMISSION = Shader3D.getDefineByName("ENABLETRANSMISSION");
BlinnPhongMaterial.SHADERDEFINE_THICKNESSMAP = Shader3D.getDefineByName("THICKNESSMAP");
}
get _ColorR() {
return this.albedoColor.x;
}
set _ColorR(value) {
let albedoColor = this.albedoColor;
albedoColor.x = value;
this.albedoColor = albedoColor;
}
get _ColorG() {
return this.albedoColor.y;
}
set _ColorG(value) {
let albedoColor = this.albedoColor;
albedoColor.y = value;
this.albedoColor = albedoColor;
}
get _ColorB() {
return this.albedoColor.z;
}
set _ColorB(value) {
let albedoColor = this.albedoColor;
albedoColor.z = value;
this.albedoColor = albedoColor;
}
get _ColorA() {
return this.albedoColor.w;
}
set _ColorA(value) {
let albedoColor = this.albedoColor;
albedoColor.w = value;
this.albedoColor = albedoColor;
}
get _Color() {
return this._shaderValues.getVector(BlinnPhongMaterial.ALBEDOCOLOR);
}
set _Color(value) {
this.albedoColor = value;
}
get _SpecColorR() {
return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).x;
}
set _SpecColorR(value) {
this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).x = value;
}
get _SpecColorG() {
return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).y;
}
set _SpecColorG(value) {
this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).y = value;
}
get _SpecColorB() {
return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).z;
}
set _SpecColorB(value) {
this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).z = value;
}
get _SpecColorA() {
return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).w;
}
set _SpecColorA(value) {
this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).w = value;
}
get _SpecColor() {
return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR);
}
set _SpecColor(value) {
this.specularColor = value;
}
get _Shininess() {
return this._shaderValues.getNumber(BlinnPhongMaterial.SHININESS);
}
set _Shininess(value) {
value = Math.max(0.0, Math.min(1.0, value));
this._shaderValues.setNumber(BlinnPhongMaterial.SHININESS, value);
}
get _MainTex_STX() {
return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).x;
}
set _MainTex_STX(x) {
var tilOff = this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET);
tilOff.x = x;
this.tilingOffset = tilOff;
}
get _MainTex_STY() {
return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).y;
}
set _MainTex_STY(y) {
var tilOff = this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET);
tilOff.y = y;
this.tilingOffset = tilOff;
}
get _MainTex_STZ() {
return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).z;
}
set _MainTex_STZ(z) {
var tilOff = this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET);
tilOff.z = z;
this.tilingOffset = tilOff;
}
get _MainTex_STW() {
return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).w;
}
set _MainTex_STW(w) {
var tilOff = this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET);
tilOff.w = w;
this.tilingOffset = tilOff;
}
get _MainTex_ST() {
return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET);
}
set _MainTex_ST(value) {
this.tilingOffset = value;
}
get _Cutoff() {
return this.alphaTestValue;
}
set _Cutoff(value) {
this.alphaTestValue = value;
}
set renderMode(value) {
switch (value) {
case BlinnPhongMaterial.RENDERMODE_OPAQUE:
this.alphaTest = false;
this.renderQueue = Material.RENDERQUEUE_OPAQUE;
this.depthWrite = true;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_DISABLE;
this.depthTest = RenderState.DEPTHTEST_LESS;
break;
case BlinnPhongMaterial.RENDERMODE_CUTOUT:
this.renderQueue = Material.RENDERQUEUE_ALPHATEST;
this.alphaTest = true;
this.depthWrite = true;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_DISABLE;
this.depthTest = RenderState.DEPTHTEST_LESS;
break;
case BlinnPhongMaterial.RENDERMODE_TRANSPARENT:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.alphaTest = false;
this.depthWrite = false;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
this.depthTest = RenderState.DEPTHTEST_LESS;
break;
default:
throw new Error("Material:renderMode value error.");
}
}
get enableVertexColor() {
return this._shaderValues.hasDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR);
}
set enableVertexColor(value) {
if (value)
this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR);
else
this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR);
}
get tilingOffsetX() {
return this._MainTex_STX;
}
set tilingOffsetX(x) {
this._MainTex_STX = x;
}
get tilingOffsetY() {
return this._MainTex_STY;
}
set tilingOffsetY(y) {
this._MainTex_STY = y;
}
get tilingOffsetZ() {
return this._MainTex_STZ;
}
set tilingOffsetZ(z) {
this._MainTex_STZ = z;
}
get tilingOffsetW() {
return this._MainTex_STW;
}
set tilingOffsetW(w) {
this._MainTex_STW = w;
}
get tilingOffset() {
return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET);
}
set tilingOffset(value) {
if (value) {
this._shaderValues.setVector(BlinnPhongMaterial.TILINGOFFSET, value);
}
else {
this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0);
}
}
get albedoColorR() {
return this._ColorR;
}
set albedoColorR(value) {
this._ColorR = value;
}
get albedoColorG() {
return this._ColorG;
}
set albedoColorG(value) {
this._ColorG = value;
}
get albedoColorB() {
return this._ColorB;
}
set albedoColorB(value) {
this._ColorB = value;
}
get albedoColorA() {
return this._ColorA;
}
set albedoColorA(value) {
this._ColorA = value;
}
get albedoColor() {
return this._shaderValues.getVector(BlinnPhongMaterial.ALBEDOCOLOR);
}
set albedoColor(value) {
this._shaderValues.setVector(BlinnPhongMaterial.ALBEDOCOLOR, value);
}
get albedoIntensity() {
return this._shaderValues.getNumber(BlinnPhongMaterial.AlbedoIntensity);
}
set albedoIntensity(value) {
this._shaderValues.setNumber(BlinnPhongMaterial.AlbedoIntensity, value);
}
get specularColorR() {
return this._SpecColorR;
}
set specularColorR(value) {
this._SpecColorR = value;
}
get specularColorG() {
return this._SpecColorG;
}
set specularColorG(value) {
this._SpecColorG = value;
}
get specularColorB() {
return this._SpecColorB;
}
set specularColorB(value) {
this._SpecColorB = value;
}
get specularColorA() {
return this._SpecColorA;
}
set specularColorA(value) {
this._SpecColorA = value;
}
get specularColor() {
return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR);
}
set specularColor(value) {
this._shaderValues.setVector(BlinnPhongMaterial.MATERIALSPECULAR, value);
}
get shininess() {
return this._Shininess;
}
set shininess(value) {
this._Shininess = value;
}
get albedoTexture() {
return this._shaderValues.getTexture(BlinnPhongMaterial.ALBEDOTEXTURE);
}
set albedoTexture(value) {
if (value)
this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_DIFFUSEMAP);
else
this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_DIFFUSEMAP);
this._shaderValues.setTexture(BlinnPhongMaterial.ALBEDOTEXTURE, value);
}
get normalTexture() {
return this._shaderValues.getTexture(BlinnPhongMaterial.NORMALTEXTURE);
}
set normalTexture(value) {
if (value)
this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_NORMALMAP);
else
this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_NORMALMAP);
this._shaderValues.setTexture(BlinnPhongMaterial.NORMALTEXTURE, value);
}
get specularTexture() {
return this._shaderValues.getTexture(BlinnPhongMaterial.SPECULARTEXTURE);
}
set specularTexture(value) {
if (value)
this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_SPECULARMAP);
else
this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_SPECULARMAP);
this._shaderValues.setTexture(BlinnPhongMaterial.SPECULARTEXTURE, value);
}
get enableTransmission() {
return this._shaderValues.hasDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLETRANSMISSION);
}
set enableTransmission(value) {
if (value)
this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLETRANSMISSION);
else
this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLETRANSMISSION);
}
get transmissionRate() {
return this._shaderValues.getNumber(BlinnPhongMaterial.TRANSMISSIONRATE);
}
set transmissionRata(value) {
this._shaderValues.setNumber(BlinnPhongMaterial.TRANSMISSIONRATE, value);
}
get backDiffuse() {
return this._shaderValues.getNumber(BlinnPhongMaterial.IBACKDIFFUSE);
}
set backDiffuse(value) {
this._shaderValues.setNumber(BlinnPhongMaterial.IBACKDIFFUSE, Math.max(value, 1.0));
}
get backScale() {
return this._shaderValues.getNumber(BlinnPhongMaterial.IBACKSCALE);
}
set backScale(value) {
this._shaderValues.setNumber(BlinnPhongMaterial.IBACKSCALE, value);
}
get thinknessTexture() {
return this._shaderValues.getTexture(BlinnPhongMaterial.THINKNESSTEXTURE);
}
set thinknessTexture(value) {
if (value)
this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_THICKNESSMAP);
else
this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_THICKNESSMAP);
this._shaderValues.setTexture(BlinnPhongMaterial.THINKNESSTEXTURE, value);
}
get transmissionColor() {
return this._shaderValues.getVector(BlinnPhongMaterial.TRANSMISSIONCOLOR);
}
set transmissionColor(value) {
this._shaderValues.setVector(BlinnPhongMaterial.TRANSMISSIONCOLOR, value);
}
clone() {
var dest = new BlinnPhongMaterial();
this.cloneTo(dest);
return dest;
}
cloneTo(destObject) {
super.cloneTo(destObject);
var destMaterial = destObject;
destMaterial.albedoIntensity = this.albedoIntensity;
destMaterial.enableVertexColor = this.enableVertexColor;
this.albedoColor.cloneTo(destMaterial.albedoColor);
}
}
BlinnPhongMaterial.RENDERMODE_OPAQUE = 0;
BlinnPhongMaterial.RENDERMODE_CUTOUT = 1;
BlinnPhongMaterial.RENDERMODE_TRANSPARENT = 2;
BlinnPhongMaterial.ALBEDOTEXTURE = Shader3D.propertyNameToID("u_DiffuseTexture");
BlinnPhongMaterial.NORMALTEXTURE = Shader3D.propertyNameToID("u_NormalTexture");
BlinnPhongMaterial.SPECULARTEXTURE = Shader3D.propertyNameToID("u_SpecularTexture");
BlinnPhongMaterial.ALBEDOCOLOR = Shader3D.propertyNameToID("u_DiffuseColor");
BlinnPhongMaterial.MATERIALSPECULAR = Shader3D.propertyNameToID("u_MaterialSpecular");
BlinnPhongMaterial.SHININESS = Shader3D.propertyNameToID("u_Shininess");
BlinnPhongMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset");
BlinnPhongMaterial.TRANSMISSIONRATE = Shader3D.propertyNameToID("u_TransmissionRate");
BlinnPhongMaterial.IBACKDIFFUSE = Shader3D.propertyNameToID("u_BackDiffuse");
BlinnPhongMaterial.IBACKSCALE = Shader3D.propertyNameToID("u_BackScale");
BlinnPhongMaterial.THINKNESSTEXTURE = Shader3D.propertyNameToID("u_ThinknessTexture");
BlinnPhongMaterial.TRANSMISSIONCOLOR = Shader3D.propertyNameToID("u_TransmissionColor");
BlinnPhongMaterial.AlbedoIntensity = Shader3D.propertyNameToID("u_AlbedoIntensity");
class EffectMaterial extends Material {
constructor() {
super();
this.setShaderName("Effect");
this._shaderValues.setVector(EffectMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0));
this._shaderValues.setVector(EffectMaterial.TINTCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0));
this.renderMode = EffectMaterial.RENDERMODE_ADDTIVE;
}
static __initDefine__() {
EffectMaterial.SHADERDEFINE_MAINTEXTURE = Shader3D.getDefineByName("MAINTEXTURE");
EffectMaterial.SHADERDEFINE_ADDTIVEFOG = Shader3D.getDefineByName("ADDTIVEFOG");
}
get _TintColorR() {
return this.color.x;
}
set _TintColorR(value) {
let co = this.color;
co.x = value;
this.color = co;
}
get _TintColorG() {
return this.color.y;
}
set _TintColorG(value) {
let co = this.color;
co.y = value;
this.color = co;
}
get _TintColorB() {
return this.color.z;
}
set _TintColorB(value) {
let co = this.color;
co.z = value;
this.color = co;
}
get _TintColorA() {
return this.color.w;
}
set _TintColorA(value) {
let co = this.color;
co.w = value;
this.color = co;
}
get _TintColor() {
return this._shaderValues.getVector(EffectMaterial.TINTCOLOR);
}
set _TintColor(value) {
this.color = value;
}
get _MainTex_STX() {
return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).x;
}
set _MainTex_STX(x) {
var tilOff = this._shaderValues.getVector(EffectMaterial.TILINGOFFSET);
tilOff.x = x;
this.tilingOffset = tilOff;
}
get _MainTex_STY() {
return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).y;
}
set _MainTex_STY(y) {
var tilOff = this._shaderValues.getVector(EffectMaterial.TILINGOFFSET);
tilOff.y = y;
this.tilingOffset = tilOff;
}
get _MainTex_STZ() {
return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).z;
}
set _MainTex_STZ(z) {
var tilOff = this._shaderValues.getVector(EffectMaterial.TILINGOFFSET);
tilOff.z = z;
this.tilingOffset = tilOff;
}
get _MainTex_STW() {
return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).w;
}
set _MainTex_STW(w) {
var tilOff = this._shaderValues.getVector(EffectMaterial.TILINGOFFSET);
tilOff.w = w;
this.tilingOffset = tilOff;
}
get _MainTex_ST() {
return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET);
}
set _MainTex_ST(value) {
this.tilingOffset = value;
}
set renderMode(value) {
switch (value) {
case EffectMaterial.RENDERMODE_ADDTIVE:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.alphaTest = false;
this.depthWrite = false;
this.cull = RenderState.CULL_NONE;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE;
this.depthTest = RenderState.DEPTHTEST_LESS;
this._shaderValues.addDefine(EffectMaterial.SHADERDEFINE_ADDTIVEFOG);
break;
case EffectMaterial.RENDERMODE_ALPHABLENDED:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.alphaTest = false;
this.depthWrite = false;
this.cull = RenderState.CULL_NONE;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
this.depthTest = RenderState.DEPTHTEST_LESS;
this._shaderValues.removeDefine(EffectMaterial.SHADERDEFINE_ADDTIVEFOG);
break;
default:
throw new Error("MeshEffectMaterial : renderMode value error.");
}
}
get colorR() {
return this._TintColorR;
}
set colorR(value) {
this._TintColorR = value;
}
get colorG() {
return this._TintColorG;
}
set colorG(value) {
this._TintColorG = value;
}
get colorB() {
return this._TintColorB;
}
set colorB(value) {
this._TintColorB = value;
}
get colorA() {
return this._TintColorA;
}
set colorA(value) {
this._TintColorA = value;
}
get color() {
return this._shaderValues.getVector(EffectMaterial.TINTCOLOR);
}
set color(value) {
this._shaderValues.setVector(EffectMaterial.TINTCOLOR, value);
}
get texture() {
return this._shaderValues.getTexture(EffectMaterial.MAINTEXTURE);
}
set texture(value) {
if (value)
this._shaderValues.addDefine(EffectMaterial.SHADERDEFINE_MAINTEXTURE);
else
this._shaderValues.removeDefine(EffectMaterial.SHADERDEFINE_MAINTEXTURE);
this._shaderValues.setTexture(EffectMaterial.MAINTEXTURE, value);
}
get tilingOffsetX() {
return this._MainTex_STX;
}
set tilingOffsetX(x) {
this._MainTex_STX = x;
}
get tilingOffsetY() {
return this._MainTex_STY;
}
set tilingOffsetY(y) {
this._MainTex_STY = y;
}
get tilingOffsetZ() {
return this._MainTex_STZ;
}
set tilingOffsetZ(z) {
this._MainTex_STZ = z;
}
get tilingOffsetW() {
return this._MainTex_STW;
}
set tilingOffsetW(w) {
this._MainTex_STW = w;
}
get tilingOffset() {
return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET);
}
set tilingOffset(value) {
if (value) {
this._shaderValues.setVector(EffectMaterial.TILINGOFFSET, value);
}
else {
this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0);
}
}
clone() {
var dest = new EffectMaterial();
this.cloneTo(dest);
return dest;
}
}
EffectMaterial.RENDERMODE_ADDTIVE = 0;
EffectMaterial.RENDERMODE_ALPHABLENDED = 1;
EffectMaterial.MAINTEXTURE = Shader3D.propertyNameToID("u_AlbedoTexture");
EffectMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_AlbedoColor");
EffectMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset");
class ExtendTerrainMaterial extends Material {
constructor() {
super();
this.setShaderName("ExtendTerrain");
this.renderMode = ExtendTerrainMaterial.RENDERMODE_OPAQUE;
}
static __initDefine__() {
ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM1");
ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM2");
ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM3");
ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM4");
ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM5");
}
get splatAlphaTexture() {
return this._shaderValues.getTexture(ExtendTerrainMaterial.SPLATALPHATEXTURE);
}
set splatAlphaTexture(value) {
this._shaderValues.setTexture(ExtendTerrainMaterial.SPLATALPHATEXTURE, value);
}
get diffuseTexture1() {
return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE1);
}
set diffuseTexture1(value) {
this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE1, value);
this._setDetailNum(1);
}
get diffuseTexture2() {
return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE2);
}
set diffuseTexture2(value) {
this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE2, value);
this._setDetailNum(2);
}
get diffuseTexture3() {
return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE3);
}
set diffuseTexture3(value) {
this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE3, value);
this._setDetailNum(3);
}
get diffuseTexture4() {
return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE4);
}
set diffuseTexture4(value) {
this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE4, value);
this._setDetailNum(4);
}
get diffuseTexture5() {
return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE5);
}
set diffuseTexture5(value) {
this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE5, value);
this._setDetailNum(5);
}
set diffuseScaleOffset1(scaleOffset1) {
this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET1, scaleOffset1);
}
set diffuseScaleOffset2(scaleOffset2) {
this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET2, scaleOffset2);
}
set diffuseScaleOffset3(scaleOffset3) {
this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET3, scaleOffset3);
}
set diffuseScaleOffset4(scaleOffset4) {
this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET4, scaleOffset4);
}
set diffuseScaleOffset5(scaleOffset5) {
this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET5, scaleOffset5);
}
set renderMode(value) {
switch (value) {
case ExtendTerrainMaterial.RENDERMODE_OPAQUE:
this.renderQueue = Material.RENDERQUEUE_OPAQUE;
this.depthWrite = true;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_DISABLE;
this.depthTest = RenderState.DEPTHTEST_LESS;
break;
case ExtendTerrainMaterial.RENDERMODE_TRANSPARENT:
this.renderQueue = Material.RENDERQUEUE_OPAQUE;
this.depthWrite = false;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
this.depthTest = RenderState.DEPTHTEST_LEQUAL;
break;
default:
throw new Error("ExtendTerrainMaterial:renderMode value error.");
}
}
_setDetailNum(value) {
switch (value) {
case 1:
this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5);
break;
case 2:
this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5);
break;
case 3:
this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5);
break;
case 4:
this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5);
break;
case 5:
this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3);
this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4);
break;
}
}
clone() {
var dest = new ExtendTerrainMaterial();
this.cloneTo(dest);
return dest;
}
}
ExtendTerrainMaterial.RENDERMODE_OPAQUE = 1;
ExtendTerrainMaterial.RENDERMODE_TRANSPARENT = 2;
ExtendTerrainMaterial.SPLATALPHATEXTURE = Shader3D.propertyNameToID("u_SplatAlphaTexture");
ExtendTerrainMaterial.DIFFUSETEXTURE1 = Shader3D.propertyNameToID("u_DiffuseTexture1");
ExtendTerrainMaterial.DIFFUSETEXTURE2 = Shader3D.propertyNameToID("u_DiffuseTexture2");
ExtendTerrainMaterial.DIFFUSETEXTURE3 = Shader3D.propertyNameToID("u_DiffuseTexture3");
ExtendTerrainMaterial.DIFFUSETEXTURE4 = Shader3D.propertyNameToID("u_DiffuseTexture4");
ExtendTerrainMaterial.DIFFUSETEXTURE5 = Shader3D.propertyNameToID("u_DiffuseTexture5");
ExtendTerrainMaterial.DIFFUSESCALEOFFSET1 = Shader3D.propertyNameToID("u_DiffuseScaleOffset1");
ExtendTerrainMaterial.DIFFUSESCALEOFFSET2 = Shader3D.propertyNameToID("u_DiffuseScaleOffset2");
ExtendTerrainMaterial.DIFFUSESCALEOFFSET3 = Shader3D.propertyNameToID("u_DiffuseScaleOffset3");
ExtendTerrainMaterial.DIFFUSESCALEOFFSET4 = Shader3D.propertyNameToID("u_DiffuseScaleOffset4");
ExtendTerrainMaterial.DIFFUSESCALEOFFSET5 = Shader3D.propertyNameToID("u_DiffuseScaleOffset5");
(function (PBRRenderMode) {
PBRRenderMode[PBRRenderMode["Opaque"] = 0] = "Opaque";
PBRRenderMode[PBRRenderMode["Cutout"] = 1] = "Cutout";
PBRRenderMode[PBRRenderMode["Fade"] = 2] = "Fade";
PBRRenderMode[PBRRenderMode["Transparent"] = 3] = "Transparent";
})(exports.PBRRenderMode || (exports.PBRRenderMode = {}));
class PBRMaterial extends Material {
constructor() {
super();
this._shaderValues.setVector(PBRMaterial.ALBEDOCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0));
this._shaderValues.setVector(PBRMaterial.EMISSIONCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0));
this._shaderValues.setVector(PBRMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0));
this._shaderValues.setNumber(PBRMaterial.SMOOTHNESS, 0.5);
this._shaderValues.setNumber(PBRMaterial.SMOOTHNESSSCALE, 1.0);
this._shaderValues.setNumber(PBRMaterial.OCCLUSIONSTRENGTH, 1.0);
this._shaderValues.setNumber(PBRMaterial.NORMALSCALE, 1.0);
this._shaderValues.setNumber(PBRMaterial.PARALLAXSCALE, 0.001);
this._shaderValues.setNumber(Material.ALPHATESTVALUE, 0.5);
this.renderMode = exports.PBRRenderMode.Opaque;
}
static __init__() {
PBRMaterial.SHADERDEFINE_ALBEDOTEXTURE = Shader3D.getDefineByName("ALBEDOTEXTURE");
PBRMaterial.SHADERDEFINE_NORMALTEXTURE = Shader3D.getDefineByName("NORMALTEXTURE");
PBRMaterial.SHADERDEFINE_PARALLAXTEXTURE = Shader3D.getDefineByName("PARALLAXTEXTURE");
PBRMaterial.SHADERDEFINE_OCCLUSIONTEXTURE = Shader3D.getDefineByName("OCCLUSIONTEXTURE");
PBRMaterial.SHADERDEFINE_EMISSION = Shader3D.getDefineByName("EMISSION");
PBRMaterial.SHADERDEFINE_EMISSIONTEXTURE = Shader3D.getDefineByName("EMISSIONTEXTURE");
PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND = Shader3D.getDefineByName("TRANSPARENTBLEND");
PBRMaterial.SHADERDEFINE_LAYA_PBR_BRDF_HIGH = Shader3D.getDefineByName("LAYA_PBR_BRDF_HIGH");
PBRMaterial.SHADERDEFINE_LAYA_PBR_BRDF_LOW = Shader3D.getDefineByName("LAYA_PBR_BRDF_LOW");
}
get albedoColor() {
return this._shaderValues.getVector(PBRMaterial.ALBEDOCOLOR);
}
set albedoColor(value) {
this._shaderValues.setVector(PBRMaterial.ALBEDOCOLOR, value);
}
get albedoTexture() {
return this._shaderValues.getTexture(PBRMaterial.ALBEDOTEXTURE);
}
set albedoTexture(value) {
if (value)
this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_ALBEDOTEXTURE);
else
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_ALBEDOTEXTURE);
this._shaderValues.setTexture(PBRMaterial.ALBEDOTEXTURE, value);
}
get normalTexture() {
return this._shaderValues.getTexture(PBRMaterial.NORMALTEXTURE);
}
set normalTexture(value) {
if (value) {
this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_NORMALTEXTURE);
}
else {
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_NORMALTEXTURE);
}
this._shaderValues.setTexture(PBRMaterial.NORMALTEXTURE, value);
}
get normalTextureScale() {
return this._shaderValues.getNumber(PBRMaterial.NORMALSCALE);
}
set normalTextureScale(value) {
this._shaderValues.setNumber(PBRMaterial.NORMALSCALE, value);
}
get parallaxTexture() {
return this._shaderValues.getTexture(PBRMaterial.PARALLAXTEXTURE);
}
set parallaxTexture(value) {
if (value)
this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_PARALLAXTEXTURE);
else
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_PARALLAXTEXTURE);
this._shaderValues.setTexture(PBRMaterial.PARALLAXTEXTURE, value);
}
get parallaxTextureScale() {
return this._shaderValues.getNumber(PBRMaterial.PARALLAXSCALE);
}
set parallaxTextureScale(value) {
this._shaderValues.setNumber(PBRMaterial.PARALLAXSCALE, Math.max(0.005, Math.min(0.08, value)));
}
get occlusionTexture() {
return this._shaderValues.getTexture(PBRMaterial.OCCLUSIONTEXTURE);
}
set occlusionTexture(value) {
if (value)
this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_OCCLUSIONTEXTURE);
else
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_OCCLUSIONTEXTURE);
this._shaderValues.setTexture(PBRMaterial.OCCLUSIONTEXTURE, value);
}
get occlusionTextureStrength() {
return this._shaderValues.getNumber(PBRMaterial.OCCLUSIONSTRENGTH);
}
set occlusionTextureStrength(value) {
this._shaderValues.setNumber(PBRMaterial.OCCLUSIONSTRENGTH, Math.max(0.0, Math.min(1.0, value)));
}
get smoothness() {
return this._shaderValues.getNumber(PBRMaterial.SMOOTHNESS);
}
set smoothness(value) {
this._shaderValues.setNumber(PBRMaterial.SMOOTHNESS, Math.max(0.0, Math.min(1.0, value)));
}
get smoothnessTextureScale() {
return this._shaderValues.getNumber(PBRMaterial.SMOOTHNESSSCALE);
}
set smoothnessTextureScale(value) {
this._shaderValues.setNumber(PBRMaterial.SMOOTHNESSSCALE, Math.max(0.0, Math.min(1.0, value)));
}
get enableEmission() {
return this._shaderValues.hasDefine(PBRMaterial.SHADERDEFINE_EMISSION);
}
set enableEmission(value) {
if (value)
this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_EMISSION);
else
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_EMISSION);
}
get emissionColor() {
return this._shaderValues.getVector(PBRMaterial.EMISSIONCOLOR);
}
set emissionColor(value) {
this._shaderValues.setVector(PBRMaterial.EMISSIONCOLOR, value);
}
get emissionTexture() {
return this._shaderValues.getTexture(PBRMaterial.EMISSIONTEXTURE);
}
set emissionTexture(value) {
if (value)
this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_EMISSIONTEXTURE);
else
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_EMISSIONTEXTURE);
this._shaderValues.setTexture(PBRMaterial.EMISSIONTEXTURE, value);
}
get tilingOffset() {
return this._shaderValues.getVector(PBRMaterial.TILINGOFFSET);
}
set tilingOffset(value) {
if (value) {
this._shaderValues.setVector(PBRMaterial.TILINGOFFSET, value);
}
else {
this._shaderValues.getVector(PBRMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0);
}
}
set renderMode(value) {
switch (value) {
case exports.PBRRenderMode.Opaque:
this.alphaTest = false;
this.renderQueue = Material.RENDERQUEUE_OPAQUE;
this.depthWrite = true;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_DISABLE;
this.depthTest = RenderState.DEPTHTEST_LESS;
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND);
break;
case exports.PBRRenderMode.Cutout:
this.renderQueue = Material.RENDERQUEUE_ALPHATEST;
this.alphaTest = true;
this.depthWrite = true;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_DISABLE;
this.depthTest = RenderState.DEPTHTEST_LESS;
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND);
break;
case exports.PBRRenderMode.Fade:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.alphaTest = false;
this.depthWrite = false;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
this.depthTest = RenderState.DEPTHTEST_LESS;
this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND);
break;
case exports.PBRRenderMode.Transparent:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.alphaTest = false;
this.depthWrite = false;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_ONE;
this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
this.depthTest = RenderState.DEPTHTEST_LESS;
this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND);
break;
default:
throw new Error("PBRMaterial:unknown renderMode value.");
}
}
}
PBRMaterial.ALBEDOTEXTURE = Shader3D.propertyNameToID("u_AlbedoTexture");
PBRMaterial.ALBEDOCOLOR = Shader3D.propertyNameToID("u_AlbedoColor");
PBRMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset");
PBRMaterial.NORMALTEXTURE = Shader3D.propertyNameToID("u_NormalTexture");
PBRMaterial.NORMALSCALE = Shader3D.propertyNameToID("u_NormalScale");
PBRMaterial.SMOOTHNESS = Shader3D.propertyNameToID("u_Smoothness");
PBRMaterial.SMOOTHNESSSCALE = Shader3D.propertyNameToID("u_SmoothnessScale");
PBRMaterial.OCCLUSIONTEXTURE = Shader3D.propertyNameToID("u_OcclusionTexture");
PBRMaterial.OCCLUSIONSTRENGTH = Shader3D.propertyNameToID("u_occlusionStrength");
PBRMaterial.PARALLAXTEXTURE = Shader3D.propertyNameToID("u_ParallaxTexture");
PBRMaterial.PARALLAXSCALE = Shader3D.propertyNameToID("u_ParallaxScale");
PBRMaterial.EMISSIONTEXTURE = Shader3D.propertyNameToID("u_EmissionTexture");
PBRMaterial.EMISSIONCOLOR = Shader3D.propertyNameToID("u_EmissionColor");
PBRMaterial.renderQuality = exports.PBRRenderQuality.High;
var PBRPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#define SETUP_BRDF_INPUT specularSetup\r\n\r\n#include \"Lighting.glsl\";\r\n#include \"PBRFSInput.glsl\";\r\n#include \"LayaPBRBRDF.glsl\";\r\n#include \"GlobalIllumination.glsl\";\r\n#include \"Shadow.glsl\"\r\n#include \"PBRCore.glsl\";\r\n\r\nvoid main()\r\n{\r\n\tfragmentForward();\r\n}";
var PBRVS = "#include \"PBRVSInput.glsl\";\r\n#include \"Lighting.glsl\";\r\n#include \"PBRVertex.glsl\";\r\n\r\nvoid main()\r\n{\r\n\tvertexForward();\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}";
var PBRShadowCasterPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"ShadowCasterFS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=shadowCasterFragment();\r\n}";
var PBRShadowCasterVS = "#include \"ShadowCasterVS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = shadowCasterVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}";
var DepthNormalsTextureVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\"\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\nuniform mat4 u_View;\r\nuniform mat4 u_ViewProjection;\r\nuniform vec4 u_ProjectionParams;\r\n\r\n//传入法线\r\nvarying vec4 depthNormals;\r\n\r\n\r\nvec4 depthNormalsVertex()\r\n{\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\t\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tworldMat = worldMat * skinTransform;\r\n\t#endif\r\n\r\n\tvec4 positionWS = worldMat * a_Position;\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\r\n\tvec3 normalWS = normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem\r\n\t//depthNormals.xyz = normalWS;\r\n\t//存储View空间法线\r\n\tvec3 normalVS = mat3(u_View) * normalWS;\r\n\tdepthNormals.xyz = normalVS;\r\n\t\r\n\tvec4 positionCS = u_ViewProjection * positionWS;\r\n\tdepthNormals.w = (positionCS.z * 2.0 - positionCS.w)*u_ProjectionParams.w;\r\n\t\r\n return positionCS;\r\n}\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = depthNormalsVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}";
var DepthNormalsTextureFS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n#include \"DepthNormalUtil.glsl\";\r\n\r\nvarying vec4 depthNormals;\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=depthNormalsFragment(depthNormals);\r\n}";
class ShaderVariable {
constructor() {
this.textureID = -1;
}
}
class ShaderInstance extends Laya.Resource {
constructor(vs, ps, attributeMap, uniformMap, shaderPass) {
super();
this._stateParamsMap = [];
this._uploadMark = -1;
this._uploadRenderType = -1;
this._vs = vs;
this._ps = ps;
this._attributeMap = attributeMap;
this._uniformMap = uniformMap;
this._shaderPass = shaderPass;
this._globaluniformMap = {};
this._create();
this.lock = true;
}
_create() {
var gl = Laya.LayaGL.instance;
this._program = gl.createProgram();
this._vshader = this._createShader(gl, this._vs, gl.VERTEX_SHADER);
this._pshader = this._createShader(gl, this._ps, gl.FRAGMENT_SHADER);
gl.attachShader(this._program, this._vshader);
gl.attachShader(this._program, this._pshader);
for (var k in this._attributeMap)
gl.bindAttribLocation(this._program, this._attributeMap[k], k);
gl.linkProgram(this._program);
if (!Laya.Render.isConchApp && Shader3D.debugMode && !gl.getProgramParameter(this._program, gl.LINK_STATUS))
throw gl.getProgramInfoLog(this._program);
var sceneParms = [];
var cameraParms = [];
var spriteParms = [];
var materialParms = [];
var customParms = [];
this._customUniformParamsMap = [];
var nUniformNum = gl.getProgramParameter(this._program, gl.ACTIVE_UNIFORMS);
Laya.WebGLContext.useProgram(gl, this._program);
this._curActTexIndex = 0;
var one, i, n;
for (i = 0; i < nUniformNum; i++) {
var uniformData = gl.getActiveUniform(this._program, i);
var uniName = uniformData.name;
one = new ShaderVariable();
one.location = gl.getUniformLocation(this._program, uniName);
if (uniName.indexOf('[0]') > 0) {
one.name = uniName = uniName.substr(0, uniName.length - 3);
one.isArray = true;
}
else {
one.name = uniName;
one.isArray = false;
}
one.type = uniformData.type;
this._addShaderUnifiormFun(one);
var uniformPeriod = this._uniformMap[uniName];
if (uniformPeriod != null) {
one.dataOffset = Shader3D.propertyNameToID(uniName);
switch (uniformPeriod) {
case Shader3D.PERIOD_CUSTOM:
customParms.push(one);
break;
case Shader3D.PERIOD_MATERIAL:
materialParms.push(one);
break;
case Shader3D.PERIOD_SPRITE:
spriteParms.push(one);
break;
case Shader3D.PERIOD_CAMERA:
cameraParms.push(one);
break;
case Shader3D.PERIOD_SCENE:
sceneParms.push(one);
break;
default:
throw new Error("Shader3D: period is unkonw.");
}
}
else {
one.dataOffset = Shader3D.propertyNameToID(uniName);
this._globaluniformMap[uniName] = Shader3D.PERIOD_SCENE;
sceneParms.push(one);
}
}
this._sceneUniformParamsMap = Laya.LayaGL.instance.createCommandEncoder(sceneParms.length * 4 * 5 + 4, 64, true);
for (i = 0, n = sceneParms.length; i < n; i++)
this._sceneUniformParamsMap.addShaderUniform(sceneParms[i]);
this._cameraUniformParamsMap = Laya.LayaGL.instance.createCommandEncoder(cameraParms.length * 4 * 5 + 4, 64, true);
for (i = 0, n = cameraParms.length; i < n; i++)
this._cameraUniformParamsMap.addShaderUniform(cameraParms[i]);
this._spriteUniformParamsMap = Laya.LayaGL.instance.createCommandEncoder(spriteParms.length * 4 * 5 + 4, 64, true);
for (i = 0, n = spriteParms.length; i < n; i++)
this._spriteUniformParamsMap.addShaderUniform(spriteParms[i]);
this._materialUniformParamsMap = Laya.LayaGL.instance.createCommandEncoder(materialParms.length * 4 * 5 + 4, 64, true);
for (i = 0, n = materialParms.length; i < n; i++)
this._materialUniformParamsMap.addShaderUniform(materialParms[i]);
this._customUniformParamsMap.length = customParms.length;
for (i = 0, n = customParms.length; i < n; i++) {
var custom = customParms[i];
this._customUniformParamsMap[custom.dataOffset] = custom;
}
var stateMap = this._shaderPass._stateMap;
for (var s in stateMap)
this._stateParamsMap[stateMap[s]] = Shader3D.propertyNameToID(s);
}
_getRenderState(shaderDatas, stateIndex) {
var stateID = this._stateParamsMap[stateIndex];
if (stateID == null)
return null;
else
return shaderDatas[stateID];
}
_disposeResource() {
Laya.LayaGL.instance.deleteShader(this._vshader);
Laya.LayaGL.instance.deleteShader(this._pshader);
Laya.LayaGL.instance.deleteProgram(this._program);
this._vshader = this._pshader = this._program = null;
this._setGPUMemory(0);
this._curActTexIndex = 0;
}
_addShaderUnifiormFun(one) {
var gl = Laya.LayaGL.instance;
one.caller = this;
var isArray = one.isArray;
switch (one.type) {
case gl.BOOL:
one.fun = this._uniform1i;
one.uploadedValue = new Array(1);
break;
case gl.INT:
one.fun = isArray ? this._uniform1iv : this._uniform1i;
one.uploadedValue = new Array(1);
break;
case gl.FLOAT:
one.fun = isArray ? this._uniform1fv : this._uniform1f;
one.uploadedValue = new Array(1);
break;
case gl.FLOAT_VEC2:
one.fun = isArray ? this._uniform_vec2v : this._uniform_vec2;
one.uploadedValue = new Array(2);
break;
case gl.FLOAT_VEC3:
one.fun = isArray ? this._uniform_vec3v : this._uniform_vec3;
one.uploadedValue = new Array(3);
break;
case gl.FLOAT_VEC4:
one.fun = isArray ? this._uniform_vec4v : this._uniform_vec4;
one.uploadedValue = new Array(4);
break;
case gl.FLOAT_MAT2:
one.fun = this._uniformMatrix2fv;
break;
case gl.FLOAT_MAT3:
one.fun = this._uniformMatrix3fv;
break;
case gl.FLOAT_MAT4:
one.fun = isArray ? this._uniformMatrix4fv : this._uniformMatrix4f;
break;
case gl.SAMPLER_2D:
case gl.SAMPLER_2D_SHADOW:
gl.uniform1i(one.location, this._curActTexIndex);
one.textureID = Laya.WebGLContext._glTextureIDs[this._curActTexIndex++];
one.fun = this._uniform_sampler2D;
break;
case 0x8b5f:
gl.uniform1i(one.location, this._curActTexIndex);
one.textureID = Laya.WebGLContext._glTextureIDs[this._curActTexIndex++];
one.fun = this._uniform_sampler3D;
break;
case gl.SAMPLER_CUBE:
gl.uniform1i(one.location, this._curActTexIndex);
one.textureID = Laya.WebGLContext._glTextureIDs[this._curActTexIndex++];
one.fun = this._uniform_samplerCube;
break;
default:
throw new Error("compile shader err!");
}
}
_createShader(gl, str, type) {
var shader = gl.createShader(type);
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (Shader3D.debugMode && !gl.getShaderParameter(shader, gl.COMPILE_STATUS))
throw gl.getShaderInfoLog(shader);
return shader;
}
_uniform1f(one, value) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== value) {
Laya.LayaGL.instance.uniform1f(one.location, uploadedValue[0] = value);
return 1;
}
return 0;
}
_uniform1fv(one, value) {
if (value.length < 4) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) {
Laya.LayaGL.instance.uniform1fv(one.location, value);
uploadedValue[0] = value[0];
uploadedValue[1] = value[1];
uploadedValue[2] = value[2];
uploadedValue[3] = value[3];
return 1;
}
return 0;
}
else {
Laya.LayaGL.instance.uniform1fv(one.location, value);
return 1;
}
}
_uniform_vec2(one, v) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== v.x || uploadedValue[1] !== v.y) {
Laya.LayaGL.instance.uniform2f(one.location, uploadedValue[0] = v.x, uploadedValue[1] = v.y);
return 1;
}
return 0;
}
_uniform_vec2v(one, value) {
if (value.length < 2) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) {
Laya.LayaGL.instance.uniform2fv(one.location, value);
uploadedValue[0] = value[0];
uploadedValue[1] = value[1];
uploadedValue[2] = value[2];
uploadedValue[3] = value[3];
return 1;
}
return 0;
}
else {
Laya.LayaGL.instance.uniform2fv(one.location, value);
return 1;
}
}
_uniform_vec3(one, v) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== v.x || uploadedValue[1] !== v.y || uploadedValue[2] !== v.z) {
Laya.LayaGL.instance.uniform3f(one.location, uploadedValue[0] = v.x, uploadedValue[1] = v.y, uploadedValue[2] = v.z);
return 1;
}
return 0;
}
_uniform_vec3v(one, v) {
Laya.LayaGL.instance.uniform3fv(one.location, v);
return 1;
}
_uniform_vec4(one, v) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== v.x || uploadedValue[1] !== v.y || uploadedValue[2] !== v.z || uploadedValue[3] !== v.w) {
Laya.LayaGL.instance.uniform4f(one.location, uploadedValue[0] = v.x, uploadedValue[1] = v.y, uploadedValue[2] = v.z, uploadedValue[3] = v.w);
return 1;
}
return 0;
}
_uniform_vec4v(one, v) {
Laya.LayaGL.instance.uniform4fv(one.location, v);
return 1;
}
_uniformMatrix2fv(one, value) {
Laya.LayaGL.instance.uniformMatrix2fv(one.location, false, value);
return 1;
}
_uniformMatrix3fv(one, value) {
Laya.LayaGL.instance.uniformMatrix3fv(one.location, false, value);
return 1;
}
_uniformMatrix4f(one, m) {
var value = m.elements;
Laya.LayaGL.instance.uniformMatrix4fv(one.location, false, value);
return 1;
}
_uniformMatrix4fv(one, m) {
Laya.LayaGL.instance.uniformMatrix4fv(one.location, false, m);
return 1;
}
_uniform1i(one, value) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== value) {
Laya.LayaGL.instance.uniform1i(one.location, uploadedValue[0] = value);
return 1;
}
return 0;
}
_uniform1iv(one, value) {
Laya.LayaGL.instance.uniform1iv(one.location, value);
return 1;
}
_uniform_ivec2(one, value) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1]) {
Laya.LayaGL.instance.uniform2i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1]);
return 1;
}
return 0;
}
_uniform_ivec2v(one, value) {
Laya.LayaGL.instance.uniform2iv(one.location, value);
return 1;
}
_uniform_vec3i(one, value) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2]) {
Laya.LayaGL.instance.uniform3i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2]);
return 1;
}
return 0;
}
_uniform_vec3vi(one, value) {
Laya.LayaGL.instance.uniform3iv(one.location, value);
return 1;
}
_uniform_vec4i(one, value) {
var uploadedValue = one.uploadedValue;
if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) {
Laya.LayaGL.instance.uniform4i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2], uploadedValue[3] = value[3]);
return 1;
}
return 0;
}
_uniform_vec4vi(one, value) {
Laya.LayaGL.instance.uniform4iv(one.location, value);
return 1;
}
_uniform_sampler2D(one, texture) {
var value = texture._getSource() || texture.defaulteTexture._getSource();
var gl = Laya.LayaGL.instance;
Laya.WebGLContext.activeTexture(gl, one.textureID);
Laya.WebGLContext.bindTexture(gl, gl.TEXTURE_2D, value);
return 0;
}
_uniform_sampler3D(one, texture) {
var value = texture._getSource() || texture.defaulteTexture._getSource();
var gl = Laya.LayaGL.instance;
Laya.WebGLContext.activeTexture(gl, one.textureID);
Laya.WebGLContext.bindTexture(gl, WebGL2RenderingContext.TEXTURE_3D, value);
return 0;
}
_uniform_samplerCube(one, texture) {
var value = texture._getSource() || texture.defaulteTexture._getSource();
var gl = Laya.LayaGL.instance;
Laya.WebGLContext.activeTexture(gl, one.textureID);
Laya.WebGLContext.bindTexture(gl, gl.TEXTURE_CUBE_MAP, value);
return 0;
}
bind() {
return Laya.WebGLContext.useProgram(Laya.LayaGL.instance, this._program);
}
uploadUniforms(shaderUniform, shaderDatas, uploadUnTexture) {
Laya.Stat.shaderCall += Laya.LayaGLRunner.uploadShaderUniforms(Laya.LayaGL.instance, shaderUniform, shaderDatas, uploadUnTexture);
}
uploadRenderStateBlendDepth(shaderDatas) {
var gl = Laya.LayaGL.instance;
var renderState = this._shaderPass.renderState;
var datas = shaderDatas.getData();
var depthWrite = this._getRenderState(datas, Shader3D.RENDER_STATE_DEPTH_WRITE);
var depthTest = this._getRenderState(datas, Shader3D.RENDER_STATE_DEPTH_TEST);
var blend = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND);
depthWrite == null && (depthWrite = renderState.depthWrite);
depthTest == null && (depthTest = renderState.depthTest);
blend == null && (blend = renderState.blend);
Laya.WebGLContext.setDepthMask(gl, depthWrite);
if (depthTest === RenderState.DEPTHTEST_OFF)
Laya.WebGLContext.setDepthTest(gl, false);
else {
Laya.WebGLContext.setDepthTest(gl, true);
Laya.WebGLContext.setDepthFunc(gl, depthTest);
}
switch (blend) {
case RenderState.BLEND_DISABLE:
Laya.WebGLContext.setBlend(gl, false);
break;
case RenderState.BLEND_ENABLE_ALL:
var blendEquation = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_EQUATION);
var srcBlend = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_SRC);
var dstBlend = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_DST);
blendEquation == null && (blendEquation = renderState.blendEquation);
srcBlend == null && (srcBlend = renderState.srcBlend);
dstBlend == null && (dstBlend = renderState.dstBlend);
Laya.WebGLContext.setBlend(gl, true);
Laya.WebGLContext.setBlendEquation(gl, blendEquation);
Laya.WebGLContext.setBlendFunc(gl, srcBlend, dstBlend);
break;
case RenderState.BLEND_ENABLE_SEPERATE:
var blendEquationRGB = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_EQUATION_RGB);
var blendEquationAlpha = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_EQUATION_ALPHA);
var srcRGB = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_SRC_RGB);
var dstRGB = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_DST_RGB);
var srcAlpha = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_SRC_ALPHA);
var dstAlpha = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_DST_ALPHA);
blendEquationRGB == null && (blendEquationRGB = renderState.blendEquationRGB);
blendEquationAlpha == null && (blendEquationAlpha = renderState.blendEquationAlpha);
srcRGB == null && (srcRGB = renderState.srcBlendRGB);
dstRGB == null && (dstRGB = renderState.dstBlendRGB);
srcAlpha == null && (srcAlpha = renderState.srcBlendAlpha);
dstAlpha == null && (dstAlpha = renderState.dstBlendAlpha);
Laya.WebGLContext.setBlend(gl, true);
Laya.WebGLContext.setBlendEquationSeparate(gl, blendEquationRGB, blendEquationAlpha);
Laya.WebGLContext.setBlendFuncSeperate(gl, srcRGB, dstRGB, srcAlpha, dstAlpha);
break;
}
}
uploadRenderStateFrontFace(shaderDatas, isTarget, invertFront) {
var gl = Laya.LayaGL.instance;
var renderState = this._shaderPass.renderState;
var datas = shaderDatas.getData();
var cull = this._getRenderState(datas, Shader3D.RENDER_STATE_CULL);
cull == null && (cull = renderState.cull);
var forntFace;
switch (cull) {
case RenderState.CULL_NONE:
Laya.WebGLContext.setCullFace(gl, false);
break;
case RenderState.CULL_FRONT:
Laya.WebGLContext.setCullFace(gl, true);
if (isTarget) {
if (invertFront)
forntFace = gl.CCW;
else
forntFace = gl.CW;
}
else {
if (invertFront)
forntFace = gl.CW;
else
forntFace = gl.CCW;
}
Laya.WebGLContext.setFrontFace(gl, forntFace);
break;
case RenderState.CULL_BACK:
Laya.WebGLContext.setCullFace(gl, true);
if (isTarget) {
if (invertFront)
forntFace = gl.CW;
else
forntFace = gl.CCW;
}
else {
if (invertFront)
forntFace = gl.CCW;
else
forntFace = gl.CW;
}
Laya.WebGLContext.setFrontFace(gl, forntFace);
break;
}
}
uploadCustomUniform(index, data) {
Laya.Stat.shaderCall += Laya.LayaGLRunner.uploadCustomUniform(Laya.LayaGL.instance, this._customUniformParamsMap, index, data);
}
_uniformMatrix2fvForNative(one, value) {
Laya.LayaGL.instance.uniformMatrix2fvEx(one.location, false, value);
return 1;
}
_uniformMatrix3fvForNative(one, value) {
Laya.LayaGL.instance.uniformMatrix3fvEx(one.location, false, value);
return 1;
}
_uniformMatrix4fvForNative(one, m) {
Laya.LayaGL.instance.uniformMatrix4fvEx(one.location, false, m);
return 1;
}
}
class SingletonList {
constructor() {
this.elements = [];
this.length = 0;
}
_add(element) {
if (this.length === this.elements.length)
this.elements.push(element);
else
this.elements[this.length] = element;
}
add(element) {
if (this.length === this.elements.length)
this.elements.push(element);
else
this.elements[this.length] = element;
this.length++;
}
}
class SimpleSingletonList extends SingletonList {
constructor() {
super();
}
add(element) {
var index = element._getIndexInList();
if (index !== -1)
throw "SimpleSingletonList:" + element + " has in SingletonList.";
this._add(element);
element._setIndexInList(this.length++);
}
remove(element) {
var index = element._getIndexInList();
this.length--;
if (index !== this.length) {
var end = this.elements[this.length];
this.elements[index] = end;
end._setIndexInList(index);
}
element._setIndexInList(-1);
}
clear() {
var elements = this.elements;
for (var i = 0, n = this.length; i < n; i++)
elements[i]._setIndexInList(-1);
this.length = 0;
}
clearElement() {
this.elements = null;
this.length = 0;
}
}
class Color {
constructor(r = 1, g = 1, b = 1, a = 1) {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
static gammaToLinearSpace(value) {
if (value <= 0.04045)
return value / 12.92;
else if (value < 1.0)
return Math.pow((value + 0.055) / 1.055, 2.4);
else
return Math.pow(value, 2.4);
}
static linearToGammaSpace(value) {
if (value <= 0.0)
return 0.0;
else if (value <= 0.0031308)
return 12.92 * value;
else if (value <= 1.0)
return 1.055 * Math.pow(value, 0.41666) - 0.055;
else
return Math.pow(value, 0.41666);
}
toLinear(out) {
out.r = Color.gammaToLinearSpace(this.r);
out.g = Color.gammaToLinearSpace(this.g);
out.b = Color.gammaToLinearSpace(this.b);
}
toGamma(out) {
out.r = Color.linearToGammaSpace(this.r);
out.g = Color.linearToGammaSpace(this.g);
out.b = Color.linearToGammaSpace(this.b);
}
cloneTo(destObject) {
var destColor = destObject;
destColor.r = this.r;
destColor.g = this.g;
destColor.b = this.b;
destColor.a = this.a;
}
clone() {
var dest = new Color();
this.cloneTo(dest);
return dest;
}
forNativeElement() {
}
}
Color.RED = new Color(1, 0, 0, 1);
Color.GREEN = new Color(0, 1, 0, 1);
Color.BLUE = new Color(0, 0, 1, 1);
Color.CYAN = new Color(0, 1, 1, 1);
Color.YELLOW = new Color(1, 0.92, 0.016, 1);
Color.MAGENTA = new Color(1, 0, 1, 1);
Color.GRAY = new Color(0.5, 0.5, 0.5, 1);
Color.WHITE = new Color(1, 1, 1, 1);
Color.BLACK = new Color(0, 0, 0, 1);
class CameraCullInfo {
}
class ShadowCullInfo {
}
class FrustumCulling {
static __init__() {
}
static _drawTraversalCullingBound(renderList, debugTool) {
var renders = renderList.elements;
for (var i = 0, n = renderList.length; i < n; i++) {
var color = FrustumCulling._tempColor0;
color.r = 0;
color.g = 1;
color.b = 0;
color.a = 1;
Utils3D._drawBound(debugTool, renders[i].bounds._getBoundBox(), color);
}
}
static _traversalCulling(cameraCullInfo, scene, context, renderList, customShader, replacementTag, isShadowCasterCull) {
var renders = renderList.elements;
var boundFrustum = cameraCullInfo.boundFrustum;
var camPos = cameraCullInfo.position;
var cullMask = cameraCullInfo.cullingMask;
var loopCount = Laya.Stat.loopCount;
for (var i = 0, n = renderList.length; i < n; i++) {
var render = renders[i];
var canPass;
if (isShadowCasterCull)
canPass = render._castShadow && render._enable;
else
canPass = ((Math.pow(2, render._owner._layer) & cullMask) != 0) && render._enable;
if (canPass) {
Laya.Stat.frustumCulling++;
if (!cameraCullInfo.useOcclusionCulling || render._needRender(boundFrustum, context)) {
render._renderMark = loopCount;
render._distanceForSort = Vector3.distance(render.bounds.getCenter(), camPos);
var elements = render._renderElements;
for (var j = 0, m = elements.length; j < m; j++)
elements[j]._update(scene, context, customShader, replacementTag);
}
}
}
}
static renderObjectCulling(cameraCullInfo, scene, context, customShader, replacementTag, isShadowCasterCull) {
var opaqueQueue = scene._opaqueQueue;
var transparentQueue = scene._transparentQueue;
var renderList = scene._renders;
scene._clearRenderQueue();
var octree = scene._octree;
if (octree) {
octree.updateMotionObjects();
octree.shrinkRootIfPossible();
octree.getCollidingWithFrustum(cameraCullInfo, context, customShader, replacementTag, isShadowCasterCull);
}
FrustumCulling._traversalCulling(cameraCullInfo, scene, context, renderList, customShader, replacementTag, isShadowCasterCull);
if (FrustumCulling.debugFrustumCulling) {
var debugTool = scene._debugTool;
debugTool.clear();
if (octree) {
octree.drawAllBounds(debugTool);
octree.drawAllObjects(debugTool);
}
FrustumCulling._drawTraversalCullingBound(renderList, debugTool);
}
var count = opaqueQueue.elements.length;
(count > 0) && (opaqueQueue._quickSort(0, count - 1));
count = transparentQueue.elements.length;
(count > 0) && (transparentQueue._quickSort(0, count - 1));
}
static cullingShadow(cullInfo, scene, context) {
scene._clearRenderQueue();
var opaqueQueue = scene._opaqueQueue;
if (!scene._octree) {
var renderList = scene._renders;
var position = cullInfo.position;
var renders = renderList.elements;
var loopCount = Laya.Stat.loopCount;
for (var i = 0, n = renderList.length; i < n; i++) {
var render = renders[i];
var canPass = render._castShadow && render._enable;
if (canPass) {
Laya.Stat.frustumCulling++;
let pass = FrustumCulling.cullingRenderBounds(render.bounds, cullInfo);
if (pass) {
render._renderMark = loopCount;
render._distanceForSort = Vector3.distance(render.bounds.getCenter(), position);
var elements = render._renderElements;
for (var j = 0, m = elements.length; j < m; j++)
elements[j]._update(scene, context, null, null);
}
}
}
}
else {
let octree = scene._octree;
octree.updateMotionObjects();
octree.shrinkRootIfPossible();
octree._rootNode.getCollidingWithCastShadowFrustum(cullInfo, context);
}
return opaqueQueue.elements.length > 0 ? true : false;
}
static cullingRenderBounds(bounds, cullInfo) {
var cullPlaneCount = cullInfo.cullPlaneCount;
var cullPlanes = cullInfo.cullPlanes;
var min = bounds.getMin();
var max = bounds.getMax();
var minX = min.x;
var minY = min.y;
var minZ = min.z;
var maxX = max.x;
var maxY = max.y;
var maxZ = max.z;
var pass = true;
for (var j = 0; j < cullPlaneCount; j++) {
var plane = cullPlanes[j];
var normal = plane.normal;
if (plane.distance + (normal.x * (normal.x < 0.0 ? minX : maxX)) + (normal.y * (normal.y < 0.0 ? minY : maxY)) + (normal.z * (normal.z < 0.0 ? minZ : maxZ)) < 0.0) {
pass = false;
break;
}
}
return pass;
}
static cullingSpotShadow(cameraCullInfo, scene, context) {
var opaqueQueue = scene._opaqueQueue;
scene._clearRenderQueue();
if (!scene._octree) {
var renderList = scene._renders;
var renders = renderList.elements;
var loopCount = Laya.Stat.loopCount;
for (var i = 0, n = renderList.length; i < n; i++) {
var render = renders[i];
var canPass = render._castShadow && render._enable;
if (canPass) {
if (render._needRender(cameraCullInfo.boundFrustum, context)) {
var bounds = render.bounds;
render._renderMark = loopCount;
render._distanceForSort = Vector3.distance(bounds.getCenter(), cameraCullInfo.position);
var elements = render._renderElements;
for (var j = 0, m = elements.length; j < m; j++)
elements[j]._update(scene, context, null, null);
}
}
}
}
else {
let octree = scene._octree;
octree.updateMotionObjects();
octree.shrinkRootIfPossible();
octree.getCollidingWithFrustum(cameraCullInfo, context, null, null, true);
}
return opaqueQueue.elements.length > 0 ? true : false;
}
static renderObjectCullingNative(camera, scene, context, renderList, customShader, replacementTag) {
var i, j, m;
var opaqueQueue = scene._opaqueQueue;
var transparentQueue = scene._transparentQueue;
scene._clearRenderQueue();
var validCount = renderList.length;
var renders = renderList.elements;
for (i = 0; i < validCount; i++) {
renders[i].bounds;
renders[i]._updateForNative && renders[i]._updateForNative(context);
}
FrustumCulling.cullingNative(camera._boundFrustumBuffer, FrustumCulling._cullingBuffer, scene._cullingBufferIndices, validCount, scene._cullingBufferResult);
var loopCount = Laya.Stat.loopCount;
var camPos = context.camera._transform.position;
for (i = 0; i < validCount; i++) {
var render = renders[i];
if (!camera.useOcclusionCulling || (camera._isLayerVisible(render._owner._layer) && render._enable && scene._cullingBufferResult[i])) {
render._renderMark = loopCount;
render._distanceForSort = Vector3.distance(render.bounds.getCenter(), camPos);
var elements = render._renderElements;
for (j = 0, m = elements.length; j < m; j++) {
var element = elements[j];
element._update(scene, context, customShader, replacementTag);
}
}
}
var count = opaqueQueue.elements.length;
(count > 0) && (opaqueQueue._quickSort(0, count - 1));
count = transparentQueue.elements.length;
(count > 0) && (transparentQueue._quickSort(0, count - 1));
}
static cullingNative(boundFrustumBuffer, cullingBuffer, cullingBufferIndices, cullingCount, cullingBufferResult) {
return Laya.LayaGL.instance.culling(boundFrustumBuffer, cullingBuffer, cullingBufferIndices, cullingCount, cullingBufferResult);
}
}
FrustumCulling._tempColor0 = new Color();
FrustumCulling._cameraCullInfo = new CameraCullInfo();
FrustumCulling._shadowCullInfo = new ShadowCullInfo();
FrustumCulling.debugFrustumCulling = false;
class LightBound {
}
class ClusterData {
constructor() {
this.updateMark = -1;
this.pointLightCount = 0;
this.spotLightCount = 0;
this.indices = [];
}
}
class Cluster {
constructor(xSlices, ySlices, zSlices, maxLightsPerClusterAverage) {
this._updateMark = 0;
this._depthSliceParam = new Vector2();
this._xSlices = xSlices;
this._ySlices = ySlices;
this._zSlices = zSlices;
var clusterTexWidth = xSlices * ySlices;
var clisterTexHeight = zSlices * (1 + Math.ceil(maxLightsPerClusterAverage / 4));
this._clusterTexture = Utils3D._createFloatTextureBuffer(clusterTexWidth, clisterTexHeight);
this._clusterTexture.lock = true;
this._clusterPixels = new Float32Array(clusterTexWidth * clisterTexHeight * 4);
var clusterDatas = new Array(this._zSlices);
for (var z = 0; z < this._zSlices; z++) {
clusterDatas[z] = new Array(this._ySlices);
for (var y = 0; y < this._ySlices; y++) {
clusterDatas[z][y] = new Array(this._xSlices);
for (var x = 0; x < this._xSlices; x++)
clusterDatas[z][y][x] = new ClusterData();
}
}
this._clusterDatas = clusterDatas;
}
_placePointLightToClusters(lightIndex, lightBound) {
var clusterDatas = this._clusterDatas;
var updateMark = this._updateMark;
for (var z = lightBound.zMin, zEnd = lightBound.zMax; z < zEnd; z++) {
for (var y = lightBound.yMin, yEnd = lightBound.yMax; y < yEnd; y++) {
for (var x = lightBound.xMin, xEnd = lightBound.xMax; x < xEnd; x++) {
var data = clusterDatas[z][y][x];
if (data.updateMark != updateMark) {
data.pointLightCount = 0;
data.spotLightCount = 0;
data.updateMark = updateMark;
}
var indices = data.indices;
var lightCount = data.pointLightCount++;
if (lightCount < indices.length)
indices[lightCount] = lightIndex;
else
indices.push(lightIndex);
}
}
}
}
_placeSpotLightToClusters(lightIndex, lightBound) {
var clusterDatas = this._clusterDatas;
var updateMark = this._updateMark;
for (var z = lightBound.zMin, zEnd = lightBound.zMax; z < zEnd; z++) {
for (var y = lightBound.yMin, yEnd = lightBound.yMax; y < yEnd; y++) {
for (var x = lightBound.xMin, xEnd = lightBound.xMax; x < xEnd; x++) {
var data = clusterDatas[z][y][x];
if (data.updateMark != updateMark) {
data.pointLightCount = 0;
data.spotLightCount = 0;
data.updateMark = updateMark;
}
var indices = data.indices;
var lightCount = data.pointLightCount + data.spotLightCount++;
if (lightCount < indices.length)
indices[lightCount] = lightIndex;
else
indices.push(lightIndex);
}
}
}
}
_insertConePlane(origin, forward, radius, halfAngle, pNor) {
var V1 = Cluster._tempVector36;
var V2 = Cluster._tempVector37;
Vector3.cross(pNor, forward, V1);
Vector3.cross(V1, forward, V2);
Vector3.normalize(V2, V2);
var tanR = radius * Math.tan(halfAngle);
var capRimX = origin.x + radius * forward.x + tanR * V2.x;
var capRimY = origin.y + radius * forward.y + tanR * V2.y;
var capRimZ = origin.z + radius * forward.z + tanR * V2.z;
return capRimX * pNor.x + capRimY * pNor.y + capRimZ * pNor.z <= 0 || origin.x * pNor.x + origin.y * pNor.y + origin.z * pNor.z <= 0;
}
_shrinkSphereLightZPerspective(near, far, lightviewPos, radius, lightBound) {
var lvZ = lightviewPos.z;
var minZ = lvZ - radius;
var maxZ = lvZ + radius;
if ((minZ > far) || (maxZ <= near))
return false;
var depthSliceParam = this._depthSliceParam;
lightBound.zMin = Math.floor(Math.log2(Math.max(minZ, near)) * depthSliceParam.x - depthSliceParam.y);
lightBound.zMax = Math.min(Math.ceil(Math.log2(maxZ) * depthSliceParam.x - depthSliceParam.y), this._zSlices);
return true;
}
_shrinkSpotLightZPerspective(near, far, viewLightPos, viewConeCap, radius, halfAngle, lightBound) {
var pbX = viewConeCap.x, pbY = viewConeCap.y, pbZ = viewConeCap.z;
var rb = Math.tan(halfAngle) * radius;
var paX = viewLightPos.x, paY = viewLightPos.y, paZ = viewLightPos.z;
var aX = pbX - paX, aY = pbY - paY, aZ = pbZ - paZ;
var dotA = aX * aX + aY * aY + aZ * aZ;
var eZ = Math.sqrt(1.0 - aZ * aZ / dotA);
var minZ = Math.max(Math.min(paZ, pbZ - eZ * rb), viewLightPos.z - radius);
var maxZ = Math.min(Math.max(paZ, pbZ + eZ * rb), viewLightPos.z + radius);
if ((minZ > far) || (maxZ <= near))
return false;
var depthSliceParam = this._depthSliceParam;
lightBound.zMin = Math.floor(Math.log2(Math.max(minZ, near)) * depthSliceParam.x - depthSliceParam.y);
lightBound.zMax = Math.min(Math.ceil(Math.log2(maxZ) * depthSliceParam.x - depthSliceParam.y), this._zSlices);
return true;
}
_shrinkSphereLightByBoundOrth(halfX, halfY, near, far, lightviewPos, radius, lightBound) {
var lvZ = lightviewPos.z;
var minZ = lvZ - radius, maxZ = lvZ + radius;
if ((minZ > far) || (maxZ <= near))
return false;
var lvX = lightviewPos.x;
var minX = lvX - radius, maxX = lvX + radius;
if ((minX > halfX) || (maxX <= -halfX))
return false;
var lvY = lightviewPos.y;
var minY = lvY - radius, maxY = lvY + radius;
if ((minY > halfY) || (maxY <= -halfY))
return false;
var xSlices = this._xSlices, ySlices = this._ySlices;
var depthSliceParam = this._depthSliceParam;
var xStride = halfX * 2 / xSlices, yStride = halfY * 2 / ySlices;
lightBound.xMin = Math.max(Math.floor((minX + halfX) / xStride), 0);
lightBound.xMax = Math.min(Math.ceil((maxX + halfX) / xStride), xSlices);
lightBound.yMin = Math.max(Math.floor((halfY - maxY) / yStride), 0);
lightBound.yMax = Math.min(Math.ceil((halfY - minY) / yStride), ySlices);
lightBound.zMin = Math.floor(Math.log2(Math.max(minZ, near)) * depthSliceParam.x - depthSliceParam.y);
lightBound.zMax = Math.min(Math.ceil(Math.log2(maxZ) * depthSliceParam.x - depthSliceParam.y), this._zSlices);
return true;
}
_shrinkSpotLightByBoundOrth(halfX, halfY, near, far, viewLightPos, viewConeCap, radius, halfAngle, lightBound) {
var pbX = viewConeCap.x, pbY = viewConeCap.y, pbZ = viewConeCap.z;
var rb = Math.tan(halfAngle) * radius;
var paX = viewLightPos.x, paY = viewLightPos.y, paZ = viewLightPos.z;
var aX = pbX - paX, aY = pbY - paY, aZ = pbZ - paZ;
var dotA = aX * aX + aY * aY + aZ * aZ;
var eZ = Math.sqrt(1.0 - aZ * aZ / dotA);
var minZ = Math.max(Math.min(paZ, pbZ - eZ * rb), viewLightPos.z - radius);
var maxZ = Math.min(Math.max(paZ, pbZ + eZ * rb), viewLightPos.z + radius);
if ((minZ > far) || (maxZ <= near))
return false;
var eX = Math.sqrt(1.0 - aX * aX / dotA);
var minX = Math.max(Math.min(paX, pbX - eX * rb), viewLightPos.x - radius);
var maxX = Math.min(Math.max(paX, pbX + eX * rb), viewLightPos.x + radius);
if ((minX > halfX) || (maxX <= -halfX))
return false;
var eY = Math.sqrt(1.0 - aY * aY / dotA);
var minY = Math.max(Math.min(paY, pbY - eY * rb), viewLightPos.y - radius);
var maxY = Math.min(Math.max(paY, pbY + eY * rb), viewLightPos.y + radius);
if ((minY > halfY) || (maxY <= -halfY))
return false;
var xSlices = this._xSlices, ySlices = this._ySlices;
var depthSliceParam = this._depthSliceParam;
var xStride = halfX * 2 / xSlices, yStride = halfY * 2 / ySlices;
lightBound.xMin = Math.max(Math.floor((minX + halfX) / xStride), 0);
lightBound.xMax = Math.min(Math.ceil((maxX + halfX) / xStride), xSlices);
lightBound.yMin = Math.max(Math.floor((halfY - maxY) / yStride), 0);
lightBound.yMax = Math.min(Math.ceil((halfY - minY) / yStride), ySlices);
lightBound.zMin = Math.floor(Math.log2(Math.max(minZ, near)) * depthSliceParam.x - depthSliceParam.y);
lightBound.zMax = Math.min(Math.ceil(Math.log2(maxZ) * depthSliceParam.x - depthSliceParam.y), this._zSlices);
return true;
}
_shrinkXYByRadiusPerspective(lightviewPos, radius, lightBound, xPlanes, yPlanes) {
var xMin, yMin;
var xMax, yMax;
var lvX = lightviewPos.x, lvY = lightviewPos.y, lvZ = lightviewPos.z;
var i;
var n = this._ySlices + 1;
for (i = 0; i < n; i++) {
var plane = yPlanes[i];
if (lvY * plane.y + lvZ * plane.z < radius) {
yMin = Math.max(0, i - 1);
break;
}
}
if (i == n)
return false;
yMax = this._ySlices;
for (i = yMin + 1; i < n; i++) {
var plane = yPlanes[i];
if (lvY * plane.y + lvZ * plane.z <= -radius) {
yMax = Math.max(0, i);
break;
}
}
n = this._xSlices + 1;
for (i = 0; i < n; i++) {
var plane = xPlanes[i];
if (lvX * plane.x + lvZ * plane.z < radius) {
xMin = Math.max(0, i - 1);
break;
}
}
xMax = this._xSlices;
for (i = xMin + 1; i < n; i++) {
var plane = xPlanes[i];
if (lvX * plane.x + lvZ * plane.z <= -radius) {
xMax = Math.max(0, i);
break;
}
}
lightBound.xMin = xMin;
lightBound.xMax = xMax;
lightBound.yMin = yMin;
lightBound.yMax = yMax;
return true;
}
_shrinkSpotXYByConePerspective(lightviewPos, viewForward, radius, halfAngle, lightBound, xPlanes, yPlanes) {
var xMin, yMin;
var xMax, yMax;
var normal = Cluster._tempVector32;
var n = lightBound.yMax + 1;
for (var i = lightBound.yMin + 1; i < n; i++) {
if (this._insertConePlane(lightviewPos, viewForward, radius, halfAngle, yPlanes[i])) {
yMin = Math.max(0, i - 1);
break;
}
}
yMax = lightBound.yMax;
for (var i = yMin + 1; i < n; i++) {
var plane = yPlanes[i];
normal.setValue(0, -plane.y, -plane.z);
if (!this._insertConePlane(lightviewPos, viewForward, radius, halfAngle, normal)) {
yMax = Math.max(0, i);
break;
}
}
n = lightBound.xMax + 1;
for (var i = lightBound.xMin + 1; i < n; i++) {
if (this._insertConePlane(lightviewPos, viewForward, radius, halfAngle, xPlanes[i])) {
xMin = Math.max(0, i - 1);
break;
}
}
xMax = lightBound.xMax;
for (var i = xMin + 1; i < n; i++) {
var plane = xPlanes[i];
normal.setValue(-plane.x, 0, -plane.z);
if (!this._insertConePlane(lightviewPos, viewForward, radius, halfAngle, normal)) {
xMax = Math.max(0, i);
break;
}
}
lightBound.xMin = xMin;
lightBound.xMax = xMax;
lightBound.yMin = yMin;
lightBound.yMax = yMax;
}
_updatePointLightPerspective(near, far, viewMat, pointLight, lightIndex, xPlanes, yPlanes) {
var lightBound = Cluster._tempLightBound;
var lightviewPos = Cluster._tempVector30;
Vector3.transformV3ToV3(pointLight._transform.position, viewMat, lightviewPos);
lightviewPos.z *= -1;
if (!this._shrinkSphereLightZPerspective(near, far, lightviewPos, pointLight.range, lightBound))
return;
if (!this._shrinkXYByRadiusPerspective(lightviewPos, pointLight.range, lightBound, xPlanes, yPlanes))
return;
this._placePointLightToClusters(lightIndex, lightBound);
}
_updateSpotLightPerspective(near, far, viewMat, spotLight, lightIndex, xPlanes, yPlanes) {
var lightBound = Cluster._tempLightBound;
var viewPos = Cluster._tempVector30;
var forward = Cluster._tempVector31;
var viewConeCap = Cluster._tempVector34;
var position = spotLight._transform.position;
var range = spotLight.range;
spotLight._transform.worldMatrix.getForward(forward);
Vector3.normalize(forward, forward);
Vector3.scale(forward, range, viewConeCap);
Vector3.add(position, viewConeCap, viewConeCap);
Vector3.transformV3ToV3(position, viewMat, viewPos);
Vector3.transformV3ToV3(viewConeCap, viewMat, viewConeCap);
viewPos.z *= -1;
viewConeCap.z *= -1;
var halfAngle = (spotLight.spotAngle / 2) * Math.PI / 180;
if (!this._shrinkSpotLightZPerspective(near, far, viewPos, viewConeCap, range, halfAngle, lightBound))
return;
if (!this._shrinkXYByRadiusPerspective(viewPos, range, lightBound, xPlanes, yPlanes))
return;
var viewFor = Cluster._tempVector33;
viewFor.x = viewConeCap.x - viewPos.x, viewFor.y = viewConeCap.y - viewPos.y, viewFor.z = viewConeCap.z - viewPos.z;
Vector3.normalize(viewFor, viewFor);
this._shrinkSpotXYByConePerspective(viewPos, viewFor, range, halfAngle, lightBound, xPlanes, yPlanes);
this._placeSpotLightToClusters(lightIndex, lightBound);
}
_updatePointLightOrth(halfX, halfY, near, far, viewMat, pointLight, lightIndex) {
var lightBound = Cluster._tempLightBound;
var lightviewPos = Cluster._tempVector30;
Vector3.transformV3ToV3(pointLight._transform.position, viewMat, lightviewPos);
lightviewPos.z *= -1;
if (!this._shrinkSphereLightByBoundOrth(halfX, halfY, near, far, lightviewPos, pointLight.range, lightBound))
return;
this._placePointLightToClusters(lightIndex, lightBound);
}
_updateSpotLightOrth(halfX, halfY, near, far, viewMat, spotLight, lightIndex) {
var lightBound = Cluster._tempLightBound;
var viewPos = Cluster._tempVector30;
var forward = Cluster._tempVector31;
var viewConeCap = Cluster._tempVector34;
var position = spotLight._transform.position;
var range = spotLight.range;
spotLight._transform.worldMatrix.getForward(forward);
Vector3.normalize(forward, forward);
Vector3.scale(forward, range, viewConeCap);
Vector3.add(position, viewConeCap, viewConeCap);
Vector3.transformV3ToV3(position, viewMat, viewPos);
Vector3.transformV3ToV3(viewConeCap, viewMat, viewConeCap);
viewPos.z *= -1;
viewConeCap.z *= -1;
var halfAngle = (spotLight.spotAngle / 2) * Math.PI / 180;
if (!this._shrinkSpotLightByBoundOrth(halfX, halfY, near, far, viewPos, viewConeCap, range, halfAngle, lightBound))
return;
this._placeSpotLightToClusters(lightIndex, lightBound);
}
update(camera, scene) {
this._updateMark++;
var camNear = camera.nearPlane;
this._depthSliceParam.x = Config3D._config.lightClusterCount.z / Math.log2(camera.farPlane / camNear);
this._depthSliceParam.y = Math.log2(camNear) * this._depthSliceParam.x;
var near = camera.nearPlane;
var far = camera.farPlane;
var viewMat = camera.viewMatrix;
var curCount = scene._directionLights._length;
var pointLights = scene._pointLights;
var poiCount = pointLights._length;
var poiElements = pointLights._elements;
var spotLights = scene._spotLights;
var spoCount = spotLights._length;
var spoElements = spotLights._elements;
if (camera.orthographic) {
var halfY = camera.orthographicVerticalSize / 2.0;
var halfX = halfY * camera.aspectRatio;
for (var i = 0; i < poiCount; i++, curCount++)
this._updatePointLightOrth(halfX, halfY, near, far, viewMat, poiElements[i], curCount);
for (var i = 0; i < spoCount; i++, curCount++)
this._updateSpotLightOrth(halfX, halfY, near, far, viewMat, spoElements[i], curCount);
}
else {
camera._updateClusterPlaneXY();
var xPlanes = camera._clusterXPlanes;
var yPlanes = camera._clusterYPlanes;
for (var i = 0; i < poiCount; i++, curCount++)
this._updatePointLightPerspective(near, far, viewMat, poiElements[i], curCount, xPlanes, yPlanes);
for (var i = 0; i < spoCount; i++, curCount++)
this._updateSpotLightPerspective(near, far, viewMat, spoElements[i], curCount, xPlanes, yPlanes);
}
if (poiCount + spoCount > 0) {
var xSlices = this._xSlices, ySlices = this._ySlices, zSlices = this._zSlices;
var widthFloat = xSlices * ySlices * 4;
var lightOff = widthFloat * zSlices;
var clusterPixels = this._clusterPixels;
var clusterPixelsCount = clusterPixels.length;
var clusterDatas = this._clusterDatas;
var updateMark = this._updateMark;
var freeSpace = true;
for (var z = 0; z < zSlices; z++) {
for (var y = 0; y < ySlices; y++) {
for (var x = 0; x < xSlices; x++) {
var data = clusterDatas[z][y][x];
var clusterOff = (x + y * xSlices + z * xSlices * ySlices) * 4;
if (data.updateMark !== updateMark) {
clusterPixels[clusterOff] = 0;
clusterPixels[clusterOff + 1] = 0;
}
else {
if (freeSpace) {
var indices = data.indices;
var pCount = data.pointLightCount;
var sCount = data.spotLightCount;
var count = pCount + sCount;
if (lightOff + count < clusterPixelsCount) {
clusterPixels[clusterOff] = pCount;
clusterPixels[clusterOff + 1] = sCount;
clusterPixels[clusterOff + 2] = Math.floor(lightOff / widthFloat);
clusterPixels[clusterOff + 3] = lightOff % widthFloat;
for (var i = 0; i < count; i++)
clusterPixels[lightOff++] = indices[i];
}
else {
count = clusterPixelsCount - (lightOff + count);
pCount = Math.min(pCount, count);
clusterPixels[clusterOff] = pCount;
clusterPixels[clusterOff + 1] = Math.min(sCount, count - pCount);
clusterPixels[clusterOff + 2] = Math.floor(lightOff / widthFloat);
clusterPixels[clusterOff + 3] = lightOff % widthFloat;
for (var i = 0; i < count; i++)
clusterPixels[lightOff++] = indices[i];
freeSpace = false;
}
}
}
}
}
}
var width = this._clusterTexture.width;
this._clusterTexture.setSubPixels(0, 0, width, Math.ceil(lightOff / (4 * width)), clusterPixels);
}
}
}
Cluster._tempVector30 = new Vector3();
Cluster._tempVector31 = new Vector3();
Cluster._tempVector32 = new Vector3();
Cluster._tempVector33 = new Vector3();
Cluster._tempVector34 = new Vector3();
Cluster._tempVector35 = new Vector3();
Cluster._tempVector36 = new Vector3();
Cluster._tempVector37 = new Vector3();
Cluster._tempLightBound = new LightBound();
class SphericalHarmonicsL2 {
constructor() {
this._coefficients = new Float32Array(27);
}
getCoefficient(i, j) {
return this._coefficients[i * 9 + j];
}
setCoefficient(i, j, coefficient) {
this._coefficients[i * 9 + j] = coefficient;
}
setCoefficients(i, coefficient0, coefficient1, coefficient2, coefficient3, coefficient4, coefficient5, coefficient6, coefficient7, coefficient8) {
var offset = i * 9;
this._coefficients[offset] = coefficient0;
this._coefficients[++offset] = coefficient1;
this._coefficients[++offset] = coefficient2;
this._coefficients[++offset] = coefficient3;
this._coefficients[++offset] = coefficient4;
this._coefficients[++offset] = coefficient5;
this._coefficients[++offset] = coefficient6;
this._coefficients[++offset] = coefficient7;
this._coefficients[++offset] = coefficient8;
}
cloneTo(dest) {
if (this === dest)
return;
var coes = this._coefficients;
var destCoes = dest._coefficients;
for (var i = 0; i < 27; i++)
destCoes[i] = coes[i];
}
}
SphericalHarmonicsL2._default = new SphericalHarmonicsL2();
class MouseTouch {
constructor() {
this._pressedSprite = null;
this._pressedLoopCount = -1;
this.sprite = null;
this.mousePositionX = 0;
this.mousePositionY = 0;
}
}
class Touch {
constructor() {
this._indexInList = -1;
this._identifier = -1;
this._position = new Vector2();
}
get identifier() {
return this._identifier;
}
get position() {
return this._position;
}
_getIndexInList() {
return this._indexInList;
}
_setIndexInList(index) {
this._indexInList = index;
}
}
class Plane {
constructor(normal, d = 0) {
this.normal = normal;
this.distance = d;
}
static createPlaneBy3P(point0, point1, point2, out) {
var x1 = point1.x - point0.x;
var y1 = point1.y - point0.y;
var z1 = point1.z - point0.z;
var x2 = point2.x - point0.x;
var y2 = point2.y - point0.y;
var z2 = point2.z - point0.z;
var yz = (y1 * z2) - (z1 * y2);
var xz = (z1 * x2) - (x1 * z2);
var xy = (x1 * y2) - (y1 * x2);
var invPyth = 1.0 / (Math.sqrt((yz * yz) + (xz * xz) + (xy * xy)));
var x = yz * invPyth;
var y = xz * invPyth;
var z = xy * invPyth;
var normal = out.normal;
normal.x = x;
normal.y = y;
normal.z = z;
out.distance = -((x * point0.x) + (y * point0.y) + (z * point0.z));
}
normalize() {
var normalEX = this.normal.x;
var normalEY = this.normal.y;
var normalEZ = this.normal.z;
var magnitude = 1.0 / Math.sqrt(normalEX * normalEX + normalEY * normalEY + normalEZ * normalEZ);
this.normal.x = normalEX * magnitude;
this.normal.y = normalEY * magnitude;
this.normal.z = normalEZ * magnitude;
this.distance *= magnitude;
}
cloneTo(destObject) {
var dest = destObject;
this.normal.cloneTo(dest.normal);
dest.distance = this.distance;
}
clone() {
var dest = new Plane(new Vector3());
this.cloneTo(dest);
return dest;
}
}
Plane.PlaneIntersectionType_Back = 0;
Plane.PlaneIntersectionType_Front = 1;
Plane.PlaneIntersectionType_Intersecting = 2;
class Ray {
constructor(origin, direction) {
this.origin = origin;
this.direction = direction;
}
}
class ContainmentType {
}
ContainmentType.Disjoint = 0;
ContainmentType.Contains = 1;
ContainmentType.Intersects = 2;
class CollisionUtils {
constructor() {
}
static distancePlaneToPoint(plane, point) {
var dot = Vector3.dot(plane.normal, point);
return dot - plane.distance;
}
static distanceBoxToPoint(box, point) {
var boxMin = box.min;
var boxMineX = boxMin.x;
var boxMineY = boxMin.y;
var boxMineZ = boxMin.z;
var boxMax = box.max;
var boxMaxeX = boxMax.x;
var boxMaxeY = boxMax.y;
var boxMaxeZ = boxMax.z;
var pointeX = point.x;
var pointeY = point.y;
var pointeZ = point.z;
var distance = 0;
if (pointeX < boxMineX)
distance += (boxMineX - pointeX) * (boxMineX - pointeX);
if (pointeX > boxMaxeX)
distance += (boxMaxeX - pointeX) * (boxMaxeX - pointeX);
if (pointeY < boxMineY)
distance += (boxMineY - pointeY) * (boxMineY - pointeY);
if (pointeY > boxMaxeY)
distance += (boxMaxeY - pointeY) * (boxMaxeY - pointeY);
if (pointeZ < boxMineZ)
distance += (boxMineZ - pointeZ) * (boxMineZ - pointeZ);
if (pointeZ > boxMaxeZ)
distance += (boxMaxeZ - pointeZ) * (boxMaxeZ - pointeZ);
return Math.sqrt(distance);
}
static distanceBoxToBox(box1, box2) {
var box1Mine = box1.min;
var box1MineX = box1Mine.x;
var box1MineY = box1Mine.y;
var box1MineZ = box1Mine.z;
var box1Maxe = box1.max;
var box1MaxeX = box1Maxe.x;
var box1MaxeY = box1Maxe.y;
var box1MaxeZ = box1Maxe.z;
var box2Mine = box2.min;
var box2MineX = box2Mine.x;
var box2MineY = box2Mine.y;
var box2MineZ = box2Mine.z;
var box2Maxe = box2.max;
var box2MaxeX = box2Maxe.x;
var box2MaxeY = box2Maxe.y;
var box2MaxeZ = box2Maxe.z;
var distance = 0;
var delta;
if (box1MineX > box2MaxeX) {
delta = box1MineX - box2MaxeX;
distance += delta * delta;
}
else if (box2MineX > box1MaxeX) {
delta = box2MineX - box1MaxeX;
distance += delta * delta;
}
if (box1MineY > box2MaxeY) {
delta = box1MineY - box2MaxeY;
distance += delta * delta;
}
else if (box2MineY > box1MaxeY) {
delta = box2MineY - box1MaxeY;
distance += delta * delta;
}
if (box1MineZ > box2MaxeZ) {
delta = box1MineZ - box2MaxeZ;
distance += delta * delta;
}
else if (box2MineZ > box1MaxeZ) {
delta = box2MineZ - box1MaxeZ;
distance += delta * delta;
}
return Math.sqrt(distance);
}
static distanceSphereToPoint(sphere, point) {
var distance = Math.sqrt(Vector3.distanceSquared(sphere.center, point));
distance -= sphere.radius;
return Math.max(distance, 0);
}
static distanceSphereToSphere(sphere1, sphere2) {
var distance = Math.sqrt(Vector3.distanceSquared(sphere1.center, sphere2.center));
distance -= sphere1.radius + sphere2.radius;
return Math.max(distance, 0);
}
static intersectsRayAndTriangleRD(ray, vertex1, vertex2, vertex3, out) {
var rayO = ray.origin;
var rayOeX = rayO.x;
var rayOeY = rayO.y;
var rayOeZ = rayO.z;
var rayD = ray.direction;
var rayDeX = rayD.x;
var rayDeY = rayD.y;
var rayDeZ = rayD.z;
var v1eX = vertex1.x;
var v1eY = vertex1.y;
var v1eZ = vertex1.z;
var v2eX = vertex2.x;
var v2eY = vertex2.y;
var v2eZ = vertex2.z;
var v3eX = vertex3.x;
var v3eY = vertex3.y;
var v3eZ = vertex3.z;
var _tempV30eX = CollisionUtils._tempV30.x;
var _tempV30eY = CollisionUtils._tempV30.y;
var _tempV30eZ = CollisionUtils._tempV30.z;
_tempV30eX = v2eX - v1eX;
_tempV30eY = v2eY - v1eY;
_tempV30eZ = v2eZ - v1eZ;
var _tempV31eX = CollisionUtils._tempV31.x;
var _tempV31eY = CollisionUtils._tempV31.y;
var _tempV31eZ = CollisionUtils._tempV31.z;
_tempV31eX = v3eX - v1eX;
_tempV31eY = v3eY - v1eY;
_tempV31eZ = v3eZ - v1eZ;
var _tempV32eX = CollisionUtils._tempV32.x;
var _tempV32eY = CollisionUtils._tempV32.y;
var _tempV32eZ = CollisionUtils._tempV32.z;
_tempV32eX = (rayDeY * _tempV31eZ) - (rayDeZ * _tempV31eY);
_tempV32eY = (rayDeZ * _tempV31eX) - (rayDeX * _tempV31eZ);
_tempV32eZ = (rayDeX * _tempV31eY) - (rayDeY * _tempV31eX);
var determinant = (_tempV30eX * _tempV32eX) + (_tempV30eY * _tempV32eY) + (_tempV30eZ * _tempV32eZ);
if (MathUtils3D.isZero(determinant)) {
return false;
}
var inversedeterminant = 1 / determinant;
var _tempV33eX = CollisionUtils._tempV33.x;
var _tempV33eY = CollisionUtils._tempV33.y;
var _tempV33eZ = CollisionUtils._tempV33.z;
_tempV33eX = rayOeX - v1eX;
_tempV33eY = rayOeY - v1eY;
_tempV33eZ = rayOeZ - v1eZ;
var triangleU = (_tempV33eX * _tempV32eX) + (_tempV33eY * _tempV32eY) + (_tempV33eZ * _tempV32eZ);
triangleU *= inversedeterminant;
if (triangleU < 0 || triangleU > 1) {
return false;
}
var _tempV34eX = CollisionUtils._tempV34.x;
var _tempV34eY = CollisionUtils._tempV34.y;
var _tempV34eZ = CollisionUtils._tempV34.z;
_tempV34eX = (_tempV33eY * _tempV30eZ) - (_tempV33eZ * _tempV30eY);
_tempV34eY = (_tempV33eZ * _tempV30eX) - (_tempV33eX * _tempV30eZ);
_tempV34eZ = (_tempV33eX * _tempV30eY) - (_tempV33eY * _tempV30eX);
var triangleV = ((rayDeX * _tempV34eX) + (rayDeY * _tempV34eY)) + (rayDeZ * _tempV34eZ);
triangleV *= inversedeterminant;
if (triangleV < 0 || triangleU + triangleV > 1) {
return false;
}
var raydistance = (_tempV31eX * _tempV34eX) + (_tempV31eY * _tempV34eY) + (_tempV31eZ * _tempV34eZ);
raydistance *= inversedeterminant;
if (raydistance < 0) {
return false;
}
return true;
}
static intersectsRayAndTriangleRP(ray, vertex1, vertex2, vertex3, out) {
var distance;
if (!CollisionUtils.intersectsRayAndTriangleRD(ray, vertex1, vertex2, vertex3, distance)) {
out = Vector3._ZERO;
return false;
}
Vector3.scale(ray.direction, distance, CollisionUtils._tempV30);
Vector3.add(ray.origin, CollisionUtils._tempV30, out);
return true;
}
static intersectsRayAndPoint(ray, point) {
Vector3.subtract(ray.origin, point, CollisionUtils._tempV30);
var b = Vector3.dot(CollisionUtils._tempV30, ray.direction);
var c = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV30) - MathUtils3D.zeroTolerance;
if (c > 0 && b > 0)
return false;
var discriminant = b * b - c;
if (discriminant < 0)
return false;
return true;
}
static intersectsRayAndRay(ray1, ray2, out) {
var ray1o = ray1.origin;
var ray1oeX = ray1o.x;
var ray1oeY = ray1o.y;
var ray1oeZ = ray1o.z;
var ray1d = ray1.direction;
var ray1deX = ray1d.x;
var ray1deY = ray1d.y;
var ray1deZ = ray1d.z;
var ray2o = ray2.origin;
var ray2oeX = ray2o.x;
var ray2oeY = ray2o.y;
var ray2oeZ = ray2o.z;
var ray2d = ray2.direction;
var ray2deX = ray2d.x;
var ray2deY = ray2d.y;
var ray2deZ = ray2d.z;
Vector3.cross(ray1d, ray2d, CollisionUtils._tempV30);
var tempV3 = CollisionUtils._tempV30;
var denominator = Vector3.scalarLength(CollisionUtils._tempV30);
if (MathUtils3D.isZero(denominator)) {
if (MathUtils3D.nearEqual(ray2oeX, ray1oeX) && MathUtils3D.nearEqual(ray2oeY, ray1oeY) && MathUtils3D.nearEqual(ray2oeZ, ray1oeZ)) {
return true;
}
}
denominator = denominator * denominator;
var m11 = ray2oeX - ray1oeX;
var m12 = ray2oeY - ray1oeY;
var m13 = ray2oeZ - ray1oeZ;
var m21 = ray2deX;
var m22 = ray2deY;
var m23 = ray2deZ;
var m31 = tempV3.x;
var m32 = tempV3.y;
var m33 = tempV3.z;
var dets = m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32 - m11 * m23 * m32 - m12 * m21 * m33 - m13 * m22 * m31;
m21 = ray1deX;
m22 = ray1deY;
m23 = ray1deZ;
var s = dets / denominator;
Vector3.scale(ray1d, s, CollisionUtils._tempV30);
Vector3.scale(ray2d, s, CollisionUtils._tempV31);
Vector3.add(ray1o, CollisionUtils._tempV30, CollisionUtils._tempV32);
Vector3.add(ray2o, CollisionUtils._tempV31, CollisionUtils._tempV33);
var point1e = CollisionUtils._tempV32;
var point2e = CollisionUtils._tempV33;
if (!MathUtils3D.nearEqual(point2e.x, point1e.x) || !MathUtils3D.nearEqual(point2e.y, point1e.y) || !MathUtils3D.nearEqual(point2e.z, point1e.z)) {
return false;
}
return true;
}
static intersectsPlaneAndTriangle(plane, vertex1, vertex2, vertex3) {
var test1 = CollisionUtils.intersectsPlaneAndPoint(plane, vertex1);
var test2 = CollisionUtils.intersectsPlaneAndPoint(plane, vertex2);
var test3 = CollisionUtils.intersectsPlaneAndPoint(plane, vertex3);
if (test1 == Plane.PlaneIntersectionType_Front && test2 == Plane.PlaneIntersectionType_Front && test3 == Plane.PlaneIntersectionType_Front)
return Plane.PlaneIntersectionType_Front;
if (test1 == Plane.PlaneIntersectionType_Back && test2 == Plane.PlaneIntersectionType_Back && test3 == Plane.PlaneIntersectionType_Back)
return Plane.PlaneIntersectionType_Back;
return Plane.PlaneIntersectionType_Intersecting;
}
static intersectsRayAndPlaneRD(ray, plane) {
var planeNor = plane.normal;
var direction = Vector3.dot(planeNor, ray.direction);
if (Math.abs(direction) < MathUtils3D.zeroTolerance)
return -1;
var position = Vector3.dot(planeNor, ray.origin);
var distance = (-plane.distance - position) / direction;
if (distance < 0) {
if (distance < -MathUtils3D.zeroTolerance)
return -1;
distance = 0;
}
return distance;
}
static intersectsRayAndPlaneRP(ray, plane, out) {
var distance = CollisionUtils.intersectsRayAndPlaneRD(ray, plane);
if (distance == -1) {
out.setValue(0, 0, 0);
return false;
}
var scaDis = CollisionUtils._tempV30;
Vector3.scale(ray.direction, distance, scaDis);
Vector3.add(ray.origin, scaDis, out);
return true;
}
static intersectsRayAndBoxRD(ray, box) {
var rayoe = ray.origin;
var rayoeX = rayoe.x;
var rayoeY = rayoe.y;
var rayoeZ = rayoe.z;
var rayde = ray.direction;
var raydeX = rayde.x;
var raydeY = rayde.y;
var raydeZ = rayde.z;
var boxMine = box.min;
var boxMineX = boxMine.x;
var boxMineY = boxMine.y;
var boxMineZ = boxMine.z;
var boxMaxe = box.max;
var boxMaxeX = boxMaxe.x;
var boxMaxeY = boxMaxe.y;
var boxMaxeZ = boxMaxe.z;
var out = 0;
var tmax = MathUtils3D.MaxValue;
if (MathUtils3D.isZero(raydeX)) {
if (rayoeX < boxMineX || rayoeX > boxMaxeX) {
return -1;
}
}
else {
var inverse = 1 / raydeX;
var t1 = (boxMineX - rayoeX) * inverse;
var t2 = (boxMaxeX - rayoeX) * inverse;
if (t1 > t2) {
var temp = t1;
t1 = t2;
t2 = temp;
}
out = Math.max(t1, out);
tmax = Math.min(t2, tmax);
if (out > tmax) {
return -1;
}
}
if (MathUtils3D.isZero(raydeY)) {
if (rayoeY < boxMineY || rayoeY > boxMaxeY) {
return -1;
}
}
else {
var inverse1 = 1 / raydeY;
var t3 = (boxMineY - rayoeY) * inverse1;
var t4 = (boxMaxeY - rayoeY) * inverse1;
if (t3 > t4) {
var temp1 = t3;
t3 = t4;
t4 = temp1;
}
out = Math.max(t3, out);
tmax = Math.min(t4, tmax);
if (out > tmax) {
return -1;
}
}
if (MathUtils3D.isZero(raydeZ)) {
if (rayoeZ < boxMineZ || rayoeZ > boxMaxeZ) {
return -1;
}
}
else {
var inverse2 = 1 / raydeZ;
var t5 = (boxMineZ - rayoeZ) * inverse2;
var t6 = (boxMaxeZ - rayoeZ) * inverse2;
if (t5 > t6) {
var temp2 = t5;
t5 = t6;
t6 = temp2;
}
out = Math.max(t5, out);
tmax = Math.min(t6, tmax);
if (out > tmax) {
return -1;
}
}
return out;
}
static intersectsRayAndBoxRP(ray, box, out) {
var distance = CollisionUtils.intersectsRayAndBoxRD(ray, box);
if (distance === -1) {
Vector3._ZERO.cloneTo(out);
return distance;
}
Vector3.scale(ray.direction, distance, CollisionUtils._tempV30);
Vector3.add(ray.origin, CollisionUtils._tempV30, CollisionUtils._tempV31);
CollisionUtils._tempV31.cloneTo(out);
return distance;
}
static intersectsRayAndSphereRD(ray, sphere) {
var sphereR = sphere.radius;
Vector3.subtract(ray.origin, sphere.center, CollisionUtils._tempV30);
var b = Vector3.dot(CollisionUtils._tempV30, ray.direction);
var c = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV30) - (sphereR * sphereR);
if (c > 0 && b > 0) {
return -1;
}
var discriminant = b * b - c;
if (discriminant < 0) {
return -1;
}
var distance = -b - Math.sqrt(discriminant);
if (distance < 0)
distance = 0;
return distance;
}
static intersectsRayAndSphereRP(ray, sphere, out) {
var distance = CollisionUtils.intersectsRayAndSphereRD(ray, sphere);
if (distance === -1) {
Vector3._ZERO.cloneTo(out);
return distance;
}
Vector3.scale(ray.direction, distance, CollisionUtils._tempV30);
Vector3.add(ray.origin, CollisionUtils._tempV30, CollisionUtils._tempV31);
CollisionUtils._tempV31.cloneTo(out);
return distance;
}
static intersectsSphereAndTriangle(sphere, vertex1, vertex2, vertex3) {
var sphereC = sphere.center;
var sphereR = sphere.radius;
CollisionUtils.closestPointPointTriangle(sphereC, vertex1, vertex2, vertex3, CollisionUtils._tempV30);
Vector3.subtract(CollisionUtils._tempV30, sphereC, CollisionUtils._tempV31);
var dot = Vector3.dot(CollisionUtils._tempV31, CollisionUtils._tempV31);
return dot <= sphereR * sphereR;
}
static intersectsPlaneAndPoint(plane, point) {
var distance = Vector3.dot(plane.normal, point) + plane.distance;
if (distance > 0)
return Plane.PlaneIntersectionType_Front;
if (distance < 0)
return Plane.PlaneIntersectionType_Back;
return Plane.PlaneIntersectionType_Intersecting;
}
static intersectsPlaneAndPlane(plane1, plane2) {
Vector3.cross(plane1.normal, plane2.normal, CollisionUtils._tempV30);
var denominator = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV30);
if (MathUtils3D.isZero(denominator))
return false;
return true;
}
static intersectsPlaneAndPlaneRL(plane1, plane2, line) {
var plane1nor = plane1.normal;
var plane2nor = plane2.normal;
Vector3.cross(plane1nor, plane2nor, CollisionUtils._tempV34);
var denominator = Vector3.dot(CollisionUtils._tempV34, CollisionUtils._tempV34);
if (MathUtils3D.isZero(denominator))
return false;
Vector3.scale(plane2nor, plane1.distance, CollisionUtils._tempV30);
Vector3.scale(plane1nor, plane2.distance, CollisionUtils._tempV31);
Vector3.subtract(CollisionUtils._tempV30, CollisionUtils._tempV31, CollisionUtils._tempV32);
Vector3.cross(CollisionUtils._tempV32, CollisionUtils._tempV34, CollisionUtils._tempV33);
Vector3.normalize(CollisionUtils._tempV34, CollisionUtils._tempV34);
return true;
}
static intersectsPlaneAndBox(plane, box) {
var planeD = plane.distance;
var planeNor = plane.normal;
var planeNoreX = planeNor.x;
var planeNoreY = planeNor.y;
var planeNoreZ = planeNor.z;
var boxMine = box.min;
var boxMineX = boxMine.x;
var boxMineY = boxMine.y;
var boxMineZ = boxMine.z;
var boxMaxe = box.max;
var boxMaxeX = boxMaxe.x;
var boxMaxeY = boxMaxe.y;
var boxMaxeZ = boxMaxe.z;
CollisionUtils._tempV30.x = (planeNoreX > 0) ? boxMineX : boxMaxeX;
CollisionUtils._tempV30.y = (planeNoreY > 0) ? boxMineY : boxMaxeY;
CollisionUtils._tempV30.z = (planeNoreZ > 0) ? boxMineZ : boxMaxeZ;
CollisionUtils._tempV31.x = (planeNoreX > 0) ? boxMaxeX : boxMineX;
CollisionUtils._tempV31.y = (planeNoreY > 0) ? boxMaxeY : boxMineY;
CollisionUtils._tempV31.z = (planeNoreZ > 0) ? boxMaxeZ : boxMineZ;
var distance = Vector3.dot(planeNor, CollisionUtils._tempV30);
if (distance + planeD > 0)
return Plane.PlaneIntersectionType_Front;
distance = Vector3.dot(planeNor, CollisionUtils._tempV31);
if (distance + planeD < 0)
return Plane.PlaneIntersectionType_Back;
return Plane.PlaneIntersectionType_Intersecting;
}
static intersectsPlaneAndSphere(plane, sphere) {
var sphereR = sphere.radius;
var distance = Vector3.dot(plane.normal, sphere.center) + plane.distance;
if (distance > sphereR)
return Plane.PlaneIntersectionType_Front;
if (distance < -sphereR)
return Plane.PlaneIntersectionType_Back;
return Plane.PlaneIntersectionType_Intersecting;
}
static intersectsBoxAndBox(box1, box2) {
var box1Mine = box1.min;
var box1Maxe = box1.max;
var box2Mine = box2.min;
var box2Maxe = box2.max;
if (box1Mine.x > box2Maxe.x || box2Mine.x > box1Maxe.x)
return false;
if (box1Mine.y > box2Maxe.y || box2Mine.y > box1Maxe.y)
return false;
if (box1Mine.z > box2Maxe.z || box2Mine.z > box1Maxe.z)
return false;
return true;
}
static intersectsBoxAndSphere(box, sphere) {
var center = sphere.center;
var radius = sphere.radius;
var nearest = CollisionUtils._tempV30;
Vector3.Clamp(center, box.min, box.max, nearest);
var distance = Vector3.distanceSquared(center, nearest);
return distance <= radius * radius;
}
static intersectsSphereAndSphere(sphere1, sphere2) {
var radiisum = sphere1.radius + sphere2.radius;
return Vector3.distanceSquared(sphere1.center, sphere2.center) <= radiisum * radiisum;
}
static boxContainsPoint(box, point) {
var boxMine = box.min;
var boxMaxe = box.max;
if (boxMine.x <= point.x && boxMaxe.x >= point.x && boxMine.y <= point.y && boxMaxe.y >= point.y && boxMine.z <= point.z && boxMaxe.z >= point.z)
return ContainmentType.Contains;
return ContainmentType.Disjoint;
}
static boxContainsBox(box1, box2) {
var box1Mine = box1.min;
var box1MineX = box1Mine.x;
var box1MineY = box1Mine.y;
var box1MineZ = box1Mine.z;
var box1Maxe = box1.max;
var box1MaxeX = box1Maxe.x;
var box1MaxeY = box1Maxe.y;
var box1MaxeZ = box1Maxe.z;
var box2Mine = box2.min;
var box2MineX = box2Mine.x;
var box2MineY = box2Mine.y;
var box2MineZ = box2Mine.z;
var box2Maxe = box2.max;
var box2MaxeX = box2Maxe.x;
var box2MaxeY = box2Maxe.y;
var box2MaxeZ = box2Maxe.z;
if (box1MaxeX < box2MineX || box1MineX > box2MaxeX)
return ContainmentType.Disjoint;
if (box1MaxeY < box2MineY || box1MineY > box2MaxeY)
return ContainmentType.Disjoint;
if (box1MaxeZ < box2MineZ || box1MineZ > box2MaxeZ)
return ContainmentType.Disjoint;
if (box1MineX <= box2MineX && box2MaxeX <= box1MaxeX && box1MineY <= box2MineY && box2MaxeY <= box1MaxeY && box1MineZ <= box2MineZ && box2MaxeZ <= box1MaxeZ) {
return ContainmentType.Contains;
}
return ContainmentType.Intersects;
}
static boxContainsSphere(box, sphere) {
var boxMin = box.min;
var boxMineX = boxMin.x;
var boxMineY = boxMin.y;
var boxMineZ = boxMin.z;
var boxMax = box.max;
var boxMaxeX = boxMax.x;
var boxMaxeY = boxMax.y;
var boxMaxeZ = boxMax.z;
var sphereC = sphere.center;
var sphereCeX = sphereC.x;
var sphereCeY = sphereC.y;
var sphereCeZ = sphereC.z;
var sphereR = sphere.radius;
Vector3.Clamp(sphereC, boxMin, boxMax, CollisionUtils._tempV30);
var distance = Vector3.distanceSquared(sphereC, CollisionUtils._tempV30);
if (distance > sphereR * sphereR)
return ContainmentType.Disjoint;
if ((((boxMineX + sphereR <= sphereCeX) && (sphereCeX <= boxMaxeX - sphereR)) && ((boxMaxeX - boxMineX > sphereR) &&
(boxMineY + sphereR <= sphereCeY))) && (((sphereCeY <= boxMaxeY - sphereR) && (boxMaxeY - boxMineY > sphereR)) &&
(((boxMineZ + sphereR <= sphereCeZ) && (sphereCeZ <= boxMaxeZ - sphereR)) && (boxMaxeZ - boxMineZ > sphereR))))
return ContainmentType.Contains;
return ContainmentType.Intersects;
}
static sphereContainsPoint(sphere, point) {
if (Vector3.distanceSquared(point, sphere.center) <= sphere.radius * sphere.radius)
return ContainmentType.Contains;
return ContainmentType.Disjoint;
}
static sphereContainsTriangle(sphere, vertex1, vertex2, vertex3) {
var test1 = CollisionUtils.sphereContainsPoint(sphere, vertex1);
var test2 = CollisionUtils.sphereContainsPoint(sphere, vertex2);
var test3 = CollisionUtils.sphereContainsPoint(sphere, vertex3);
if (test1 == ContainmentType.Contains && test2 == ContainmentType.Contains && test3 == ContainmentType.Contains)
return ContainmentType.Contains;
if (CollisionUtils.intersectsSphereAndTriangle(sphere, vertex1, vertex2, vertex3))
return ContainmentType.Intersects;
return ContainmentType.Disjoint;
}
static sphereContainsBox(sphere, box) {
var sphereC = sphere.center;
var sphereCeX = sphereC.x;
var sphereCeY = sphereC.y;
var sphereCeZ = sphereC.z;
var sphereR = sphere.radius;
var boxMin = box.min;
var boxMineX = boxMin.x;
var boxMineY = boxMin.y;
var boxMineZ = boxMin.z;
var boxMax = box.max;
var boxMaxeX = boxMax.x;
var boxMaxeY = boxMax.y;
var boxMaxeZ = boxMax.z;
var _tempV30e = CollisionUtils._tempV30;
var _tempV30eX = _tempV30e.x;
var _tempV30eY = _tempV30e.y;
var _tempV30eZ = _tempV30e.z;
if (!CollisionUtils.intersectsBoxAndSphere(box, sphere))
return ContainmentType.Disjoint;
var radiusSquared = sphereR * sphereR;
_tempV30eX = sphereCeX - boxMineX;
_tempV30eY = sphereCeY - boxMaxeY;
_tempV30eZ = sphereCeZ - boxMaxeZ;
if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared)
return ContainmentType.Intersects;
_tempV30eX = sphereCeX - boxMaxeX;
_tempV30eY = sphereCeY - boxMaxeY;
_tempV30eZ = sphereCeZ - boxMaxeZ;
if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared)
return ContainmentType.Intersects;
_tempV30eX = sphereCeX - boxMaxeX;
_tempV30eY = sphereCeY - boxMineY;
_tempV30eZ = sphereCeZ - boxMaxeZ;
if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared)
return ContainmentType.Intersects;
_tempV30eX = sphereCeX - boxMineX;
_tempV30eY = sphereCeY - boxMineY;
_tempV30eZ = sphereCeZ - boxMaxeZ;
if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared)
return ContainmentType.Intersects;
_tempV30eX = sphereCeX - boxMineX;
_tempV30eY = sphereCeY - boxMaxeY;
_tempV30eZ = sphereCeZ - boxMineZ;
if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared)
return ContainmentType.Intersects;
_tempV30eX = sphereCeX - boxMaxeX;
_tempV30eY = sphereCeY - boxMaxeY;
_tempV30eZ = sphereCeZ - boxMineZ;
if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared)
return ContainmentType.Intersects;
_tempV30eX = sphereCeX - boxMaxeX;
_tempV30eY = sphereCeY - boxMineY;
_tempV30eZ = sphereCeZ - boxMineZ;
if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared)
return ContainmentType.Intersects;
_tempV30eX = sphereCeX - boxMineX;
_tempV30eY = sphereCeY - boxMineY;
_tempV30eZ = sphereCeZ - boxMineZ;
if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared)
return ContainmentType.Intersects;
return ContainmentType.Contains;
}
static sphereContainsSphere(sphere1, sphere2) {
var sphere1R = sphere1.radius;
var sphere2R = sphere2.radius;
var distance = Vector3.distance(sphere1.center, sphere2.center);
if (sphere1R + sphere2R < distance)
return ContainmentType.Disjoint;
if (sphere1R - sphere2R < distance)
return ContainmentType.Intersects;
return ContainmentType.Contains;
}
static closestPointPointTriangle(point, vertex1, vertex2, vertex3, out) {
Vector3.subtract(vertex2, vertex1, CollisionUtils._tempV30);
Vector3.subtract(vertex3, vertex1, CollisionUtils._tempV31);
Vector3.subtract(point, vertex1, CollisionUtils._tempV32);
Vector3.subtract(point, vertex2, CollisionUtils._tempV33);
Vector3.subtract(point, vertex3, CollisionUtils._tempV34);
var d1 = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV32);
var d2 = Vector3.dot(CollisionUtils._tempV31, CollisionUtils._tempV32);
var d3 = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV33);
var d4 = Vector3.dot(CollisionUtils._tempV31, CollisionUtils._tempV33);
var d5 = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV34);
var d6 = Vector3.dot(CollisionUtils._tempV31, CollisionUtils._tempV34);
if (d1 <= 0 && d2 <= 0) {
vertex1.cloneTo(out);
return;
}
if (d3 >= 0 && d4 <= d3) {
vertex2.cloneTo(out);
return;
}
var vc = d1 * d4 - d3 * d2;
if (vc <= 0 && d1 >= 0 && d3 <= 0) {
var v = d1 / (d1 - d3);
Vector3.scale(CollisionUtils._tempV30, v, out);
Vector3.add(vertex1, out, out);
return;
}
if (d6 >= 0 && d5 <= d6) {
vertex3.cloneTo(out);
return;
}
var vb = d5 * d2 - d1 * d6;
if (vb <= 0 && d2 >= 0 && d6 <= 0) {
var w = d2 / (d2 - d6);
Vector3.scale(CollisionUtils._tempV31, w, out);
Vector3.add(vertex1, out, out);
return;
}
var va = d3 * d6 - d5 * d4;
if (va <= 0 && (d4 - d3) >= 0 && (d5 - d6) >= 0) {
var w3 = (d4 - d3) / ((d4 - d3) + (d5 - d6));
Vector3.subtract(vertex3, vertex2, out);
Vector3.scale(out, w3, out);
Vector3.add(vertex2, out, out);
return;
}
var denom = 1 / (va + vb + vc);
var v2 = vb * denom;
var w2 = vc * denom;
Vector3.scale(CollisionUtils._tempV30, v2, CollisionUtils._tempV35);
Vector3.scale(CollisionUtils._tempV31, w2, CollisionUtils._tempV36);
Vector3.add(CollisionUtils._tempV35, CollisionUtils._tempV36, out);
Vector3.add(vertex1, out, out);
}
static closestPointPlanePoint(plane, point, out) {
var planeN = plane.normal;
var t = Vector3.dot(planeN, point) - plane.distance;
Vector3.scale(planeN, t, CollisionUtils._tempV30);
Vector3.subtract(point, CollisionUtils._tempV30, out);
}
static closestPointBoxPoint(box, point, out) {
Vector3.max(point, box.min, CollisionUtils._tempV30);
Vector3.min(CollisionUtils._tempV30, box.max, out);
}
static closestPointSpherePoint(sphere, point, out) {
var sphereC = sphere.center;
Vector3.subtract(point, sphereC, out);
Vector3.normalize(out, out);
Vector3.scale(out, sphere.radius, out);
Vector3.add(out, sphereC, out);
}
static closestPointSphereSphere(sphere1, sphere2, out) {
var sphere1C = sphere1.center;
Vector3.subtract(sphere2.center, sphere1C, out);
Vector3.normalize(out, out);
Vector3.scale(out, sphere1.radius, out);
Vector3.add(out, sphere1C, out);
}
}
CollisionUtils._tempV30 = new Vector3();
CollisionUtils._tempV31 = new Vector3();
CollisionUtils._tempV32 = new Vector3();
CollisionUtils._tempV33 = new Vector3();
CollisionUtils._tempV34 = new Vector3();
CollisionUtils._tempV35 = new Vector3();
CollisionUtils._tempV36 = new Vector3();
(function (FrustumCorner) {
FrustumCorner[FrustumCorner["FarBottomLeft"] = 0] = "FarBottomLeft";
FrustumCorner[FrustumCorner["FarTopLeft"] = 1] = "FarTopLeft";
FrustumCorner[FrustumCorner["FarTopRight"] = 2] = "FarTopRight";
FrustumCorner[FrustumCorner["FarBottomRight"] = 3] = "FarBottomRight";
FrustumCorner[FrustumCorner["nearBottomLeft"] = 4] = "nearBottomLeft";
FrustumCorner[FrustumCorner["nearTopLeft"] = 5] = "nearTopLeft";
FrustumCorner[FrustumCorner["nearTopRight"] = 6] = "nearTopRight";
FrustumCorner[FrustumCorner["nearBottomRight"] = 7] = "nearBottomRight";
FrustumCorner[FrustumCorner["unknown"] = 8] = "unknown";
})(exports.FrustumCorner || (exports.FrustumCorner = {}));
class BoundFrustum {
constructor(matrix) {
this._matrix = matrix;
this._near = new Plane(new Vector3());
this._far = new Plane(new Vector3());
this._left = new Plane(new Vector3());
this._right = new Plane(new Vector3());
this._top = new Plane(new Vector3());
this._bottom = new Plane(new Vector3());
BoundFrustum.getPlanesFromMatrix(this._matrix, this._near, this._far, this._left, this._right, this._top, this._bottom);
}
static getPlanesFromMatrix(m, np, fp, lp, rp, tp, bp) {
var matrixE = m.elements;
var m11 = matrixE[0];
var m12 = matrixE[1];
var m13 = matrixE[2];
var m14 = matrixE[3];
var m21 = matrixE[4];
var m22 = matrixE[5];
var m23 = matrixE[6];
var m24 = matrixE[7];
var m31 = matrixE[8];
var m32 = matrixE[9];
var m33 = matrixE[10];
var m34 = matrixE[11];
var m41 = matrixE[12];
var m42 = matrixE[13];
var m43 = matrixE[14];
var m44 = matrixE[15];
var nearNorE = np.normal;
nearNorE.x = m13;
nearNorE.y = m23;
nearNorE.z = m33;
np.distance = m43;
np.normalize();
var farNorE = fp.normal;
farNorE.x = m14 - m13;
farNorE.y = m24 - m23;
farNorE.z = m34 - m33;
fp.distance = m44 - m43;
fp.normalize();
var leftNorE = lp.normal;
leftNorE.x = m14 + m11;
leftNorE.y = m24 + m21;
leftNorE.z = m34 + m31;
lp.distance = m44 + m41;
lp.normalize();
var rightNorE = rp.normal;
rightNorE.x = m14 - m11;
rightNorE.y = m24 - m21;
rightNorE.z = m34 - m31;
rp.distance = m44 - m41;
rp.normalize();
var topNorE = tp.normal;
topNorE.x = m14 - m12;
topNorE.y = m24 - m22;
topNorE.z = m34 - m32;
tp.distance = m44 - m42;
tp.normalize();
var bottomNorE = bp.normal;
bottomNorE.x = m14 + m12;
bottomNorE.y = m24 + m22;
bottomNorE.z = m34 + m32;
bp.distance = m44 + m42;
bp.normalize();
}
get matrix() {
return this._matrix;
}
set matrix(matrix) {
matrix.cloneTo(this._matrix);
BoundFrustum.getPlanesFromMatrix(this._matrix, this._near, this._far, this._left, this._right, this._top, this._bottom);
}
get near() {
return this._near;
}
get far() {
return this._far;
}
get left() {
return this._left;
}
get right() {
return this._right;
}
get top() {
return this._top;
}
get bottom() {
return this._bottom;
}
equalsBoundFrustum(other) {
return this._matrix.equalsOtherMatrix(other.matrix);
}
equalsObj(obj) {
if (obj instanceof BoundFrustum) {
var bf = obj;
return this.equalsBoundFrustum(bf);
}
return false;
}
getPlane(index) {
switch (index) {
case 0:
return this._near;
case 1:
return this._far;
case 2:
return this._left;
case 3:
return this._right;
case 4:
return this._top;
case 5:
return this._bottom;
default:
return null;
}
}
static get3PlaneInterPoint(p1, p2, p3, out) {
var p1Nor = p1.normal;
var p2Nor = p2.normal;
var p3Nor = p3.normal;
Vector3.cross(p2Nor, p3Nor, BoundFrustum._tempV30);
Vector3.cross(p3Nor, p1Nor, BoundFrustum._tempV31);
Vector3.cross(p1Nor, p2Nor, BoundFrustum._tempV32);
var a = Vector3.dot(p1Nor, BoundFrustum._tempV30);
var b = Vector3.dot(p2Nor, BoundFrustum._tempV31);
var c = Vector3.dot(p3Nor, BoundFrustum._tempV32);
Vector3.scale(BoundFrustum._tempV30, -p1.distance / a, BoundFrustum._tempV33);
Vector3.scale(BoundFrustum._tempV31, -p2.distance / b, BoundFrustum._tempV34);
Vector3.scale(BoundFrustum._tempV32, -p3.distance / c, BoundFrustum._tempV35);
Vector3.add(BoundFrustum._tempV33, BoundFrustum._tempV34, BoundFrustum._tempV36);
Vector3.add(BoundFrustum._tempV35, BoundFrustum._tempV36, out);
}
getCorners(corners) {
BoundFrustum.get3PlaneInterPoint(this._near, this._bottom, this._right, corners[exports.FrustumCorner.nearBottomRight]);
BoundFrustum.get3PlaneInterPoint(this._near, this._top, this._right, corners[exports.FrustumCorner.nearTopRight]);
BoundFrustum.get3PlaneInterPoint(this._near, this._top, this._left, corners[exports.FrustumCorner.nearTopLeft]);
BoundFrustum.get3PlaneInterPoint(this._near, this._bottom, this._left, corners[exports.FrustumCorner.nearBottomLeft]);
BoundFrustum.get3PlaneInterPoint(this._far, this._bottom, this._right, corners[exports.FrustumCorner.FarBottomRight]);
BoundFrustum.get3PlaneInterPoint(this._far, this._top, this._right, corners[exports.FrustumCorner.FarTopRight]);
BoundFrustum.get3PlaneInterPoint(this._far, this._top, this._left, corners[exports.FrustumCorner.FarTopLeft]);
BoundFrustum.get3PlaneInterPoint(this._far, this._bottom, this._left, corners[exports.FrustumCorner.FarBottomLeft]);
}
containsPoint(point) {
var result = Plane.PlaneIntersectionType_Front;
var planeResult = Plane.PlaneIntersectionType_Front;
for (var i = 0; i < 6; i++) {
switch (i) {
case 0:
planeResult = CollisionUtils.intersectsPlaneAndPoint(this._near, point);
break;
case 1:
planeResult = CollisionUtils.intersectsPlaneAndPoint(this._far, point);
break;
case 2:
planeResult = CollisionUtils.intersectsPlaneAndPoint(this._left, point);
break;
case 3:
planeResult = CollisionUtils.intersectsPlaneAndPoint(this._right, point);
break;
case 4:
planeResult = CollisionUtils.intersectsPlaneAndPoint(this._top, point);
break;
case 5:
planeResult = CollisionUtils.intersectsPlaneAndPoint(this._bottom, point);
break;
}
switch (planeResult) {
case Plane.PlaneIntersectionType_Back:
return ContainmentType.Disjoint;
case Plane.PlaneIntersectionType_Intersecting:
result = Plane.PlaneIntersectionType_Intersecting;
break;
}
}
switch (result) {
case Plane.PlaneIntersectionType_Intersecting:
return ContainmentType.Intersects;
default:
return ContainmentType.Contains;
}
}
intersects(box) {
var min = box.min;
var max = box.max;
var minX = min.x;
var minY = min.y;
var minZ = min.z;
var maxX = max.x;
var maxY = max.y;
var maxZ = max.z;
var nearNormal = this._near.normal;
if (this._near.distance + (nearNormal.x * (nearNormal.x < 0 ? minX : maxX)) + (nearNormal.y * (nearNormal.y < 0 ? minY : maxY)) + (nearNormal.z * (nearNormal.z < 0 ? minZ : maxZ)) < 0)
return false;
var leftNormal = this._left.normal;
if (this._left.distance + (leftNormal.x * (leftNormal.x < 0 ? minX : maxX)) + (leftNormal.y * (leftNormal.y < 0 ? minY : maxY)) + (leftNormal.z * (leftNormal.z < 0 ? minZ : maxZ)) < 0)
return false;
var rightNormal = this._right.normal;
if (this._right.distance + (rightNormal.x * (rightNormal.x < 0 ? minX : maxX)) + (rightNormal.y * (rightNormal.y < 0 ? minY : maxY)) + (rightNormal.z * (rightNormal.z < 0 ? minZ : maxZ)) < 0)
return false;
var bottomNormal = this._bottom.normal;
if (this._bottom.distance + (bottomNormal.x * (bottomNormal.x < 0 ? minX : maxX)) + (bottomNormal.y * (bottomNormal.y < 0 ? minY : maxY)) + (bottomNormal.z * (bottomNormal.z < 0 ? minZ : maxZ)) < 0)
return false;
var topNormal = this._top.normal;
if (this._top.distance + (topNormal.x * (topNormal.x < 0 ? minX : maxX)) + (topNormal.y * (topNormal.y < 0 ? minY : maxY)) + (topNormal.z * (topNormal.z < 0 ? minZ : maxZ)) < 0)
return false;
var farNormal = this._far.normal;
if (this._far.distance + (farNormal.x * (farNormal.x < 0 ? minX : maxX)) + (farNormal.y * (farNormal.y < 0 ? minY : maxY)) + (farNormal.z * (farNormal.z < 0 ? minZ : maxZ)) < 0)
return false;
return true;
}
containsBoundBox(box) {
var p = BoundFrustum._tempV30, n = BoundFrustum._tempV31;
var boxMin = box.min;
var boxMax = box.max;
var result = ContainmentType.Contains;
for (var i = 0; i < 6; i++) {
var plane = this.getPlane(i);
var planeNor = plane.normal;
if (planeNor.x >= 0) {
p.x = boxMax.x;
n.x = boxMin.x;
}
else {
p.x = boxMin.x;
n.x = boxMax.x;
}
if (planeNor.y >= 0) {
p.y = boxMax.y;
n.y = boxMin.y;
}
else {
p.y = boxMin.y;
n.y = boxMax.y;
}
if (planeNor.z >= 0) {
p.z = boxMax.z;
n.z = boxMin.z;
}
else {
p.z = boxMin.z;
n.z = boxMax.z;
}
if (CollisionUtils.intersectsPlaneAndPoint(plane, p) === Plane.PlaneIntersectionType_Back)
return ContainmentType.Disjoint;
if (CollisionUtils.intersectsPlaneAndPoint(plane, n) === Plane.PlaneIntersectionType_Back)
result = ContainmentType.Intersects;
}
return result;
}
containsBoundSphere(sphere) {
var result = Plane.PlaneIntersectionType_Front;
var planeResult = Plane.PlaneIntersectionType_Front;
for (var i = 0; i < 6; i++) {
switch (i) {
case 0:
planeResult = CollisionUtils.intersectsPlaneAndSphere(this._near, sphere);
break;
case 1:
planeResult = CollisionUtils.intersectsPlaneAndSphere(this._far, sphere);
break;
case 2:
planeResult = CollisionUtils.intersectsPlaneAndSphere(this._left, sphere);
break;
case 3:
planeResult = CollisionUtils.intersectsPlaneAndSphere(this._right, sphere);
break;
case 4:
planeResult = CollisionUtils.intersectsPlaneAndSphere(this._top, sphere);
break;
case 5:
planeResult = CollisionUtils.intersectsPlaneAndSphere(this._bottom, sphere);
break;
}
switch (planeResult) {
case Plane.PlaneIntersectionType_Back:
return ContainmentType.Disjoint;
case Plane.PlaneIntersectionType_Intersecting:
result = Plane.PlaneIntersectionType_Intersecting;
break;
}
}
switch (result) {
case Plane.PlaneIntersectionType_Intersecting:
return ContainmentType.Intersects;
default:
return ContainmentType.Contains;
}
}
}
BoundFrustum._tempV30 = new Vector3();
BoundFrustum._tempV31 = new Vector3();
BoundFrustum._tempV32 = new Vector3();
BoundFrustum._tempV33 = new Vector3();
BoundFrustum._tempV34 = new Vector3();
BoundFrustum._tempV35 = new Vector3();
BoundFrustum._tempV36 = new Vector3();
class Viewport {
constructor(x, y, width, height) {
this.minDepth = 0.0;
this.maxDepth = 1.0;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
project(source, matrix, out) {
Vector3.transformV3ToV4(source, matrix, out);
var x = out.x, y = out.y, z = out.z;
var w = out.w;
if (w !== 1.0) {
x = x / w;
y = y / w;
z = z / w;
}
out.x = (x + 1.0) * 0.5 * this.width + this.x;
out.y = (-y + 1.0) * 0.5 * this.height + this.y;
out.z = z * (this.maxDepth - this.minDepth) + this.minDepth;
}
unprojectFromMat(source, matrix, out) {
var matrixEleme = matrix.elements;
out.x = (((source.x - this.x) / this.width) * 2.0) - 1.0;
out.y = -((((source.y - this.y) / this.height) * 2.0) - 1.0);
out.z = (source.z - this.minDepth) / (this.maxDepth - this.minDepth);
var a = (((out.x * matrixEleme[3]) + (out.y * matrixEleme[7])) + (out.z * matrixEleme[11])) + matrixEleme[15];
Vector3.transformV3ToV3(out, matrix, out);
if (a !== 1.0) {
out.x = out.x / a;
out.y = out.y / a;
out.z = out.z / a;
}
}
unprojectFromWVP(source, projection, view, world, out) {
Matrix4x4.multiply(projection, view, Viewport._tempMatrix4x4);
(world) && (Matrix4x4.multiply(Viewport._tempMatrix4x4, world, Viewport._tempMatrix4x4));
Viewport._tempMatrix4x4.invert(Viewport._tempMatrix4x4);
this.unprojectFromMat(source, Viewport._tempMatrix4x4, out);
}
cloneTo(out) {
out.x = this.x;
out.y = this.y;
out.width = this.width;
out.height = this.height;
out.minDepth = this.minDepth;
out.maxDepth = this.maxDepth;
}
}
Viewport._tempMatrix4x4 = new Matrix4x4();
class Picker {
constructor() {
}
static calculateCursorRay(point, viewPort, projectionMatrix, viewMatrix, world, out) {
var x = point.x;
var y = point.y;
var nearSource = Picker._tempVector30;
var nerSourceE = nearSource;
nerSourceE.x = x;
nerSourceE.y = y;
nerSourceE.z = viewPort.minDepth;
var farSource = Picker._tempVector31;
var farSourceE = farSource;
farSourceE.x = x;
farSourceE.y = y;
farSourceE.z = viewPort.maxDepth;
var nearPoint = out.origin;
var farPoint = Picker._tempVector32;
viewPort.unprojectFromWVP(nearSource, projectionMatrix, viewMatrix, world, nearPoint);
viewPort.unprojectFromWVP(farSource, projectionMatrix, viewMatrix, world, farPoint);
var outDire = out.direction;
outDire.x = farPoint.x - nearPoint.x;
outDire.y = farPoint.y - nearPoint.y;
outDire.z = farPoint.z - nearPoint.z;
Vector3.normalize(out.direction, out.direction);
}
static rayIntersectsTriangle(ray, vertex1, vertex2, vertex3) {
var result;
var edge1 = Picker._tempVector30, edge2 = Picker._tempVector31;
Vector3.subtract(vertex2, vertex1, edge1);
Vector3.subtract(vertex3, vertex1, edge2);
var directionCrossEdge2 = Picker._tempVector32;
Vector3.cross(ray.direction, edge2, directionCrossEdge2);
var determinant;
determinant = Vector3.dot(edge1, directionCrossEdge2);
if (determinant > -Number.MIN_VALUE && determinant < Number.MIN_VALUE) {
result = Number.NaN;
return result;
}
var inverseDeterminant = 1.0 / determinant;
var distanceVector = Picker._tempVector33;
Vector3.subtract(ray.origin, vertex1, distanceVector);
var triangleU;
triangleU = Vector3.dot(distanceVector, directionCrossEdge2);
triangleU *= inverseDeterminant;
if (triangleU < 0 || triangleU > 1) {
result = Number.NaN;
return result;
}
var distanceCrossEdge1 = Picker._tempVector34;
Vector3.cross(distanceVector, edge1, distanceCrossEdge1);
var triangleV;
triangleV = Vector3.dot(ray.direction, distanceCrossEdge1);
triangleV *= inverseDeterminant;
if (triangleV < 0 || triangleU + triangleV > 1) {
result = Number.NaN;
return result;
}
var rayDistance;
rayDistance = Vector3.dot(edge2, distanceCrossEdge1);
rayDistance *= inverseDeterminant;
if (rayDistance < 0) {
result = Number.NaN;
return result;
}
result = rayDistance;
return result;
}
}
Picker._tempVector30 = new Vector3();
Picker._tempVector31 = new Vector3();
Picker._tempVector32 = new Vector3();
Picker._tempVector33 = new Vector3();
Picker._tempVector34 = new Vector3();
(function (IndexFormat) {
IndexFormat[IndexFormat["UInt8"] = 0] = "UInt8";
IndexFormat[IndexFormat["UInt16"] = 1] = "UInt16";
IndexFormat[IndexFormat["UInt32"] = 2] = "UInt32";
})(exports.IndexFormat || (exports.IndexFormat = {}));
class IndexBuffer3D extends Laya.Buffer {
constructor(indexType, indexCount, bufferUsage = 0x88E4, canRead = false) {
super();
this._indexType = indexType;
this._indexCount = indexCount;
this._bufferUsage = bufferUsage;
this._bufferType = Laya.LayaGL.instance.ELEMENT_ARRAY_BUFFER;
this._canRead = canRead;
switch (indexType) {
case exports.IndexFormat.UInt32:
this._indexTypeByteCount = 4;
break;
case exports.IndexFormat.UInt16:
this._indexTypeByteCount = 2;
break;
case exports.IndexFormat.UInt8:
this._indexTypeByteCount = 1;
break;
default:
throw new Error("unidentification index type.");
}
var byteLength = this._indexTypeByteCount * indexCount;
var curBufSta = Laya.BufferStateBase._curBindedBufferState;
this._byteLength = byteLength;
if (curBufSta) {
if (curBufSta._bindedIndexBuffer === this) {
Laya.LayaGL.instance.bufferData(this._bufferType, byteLength, this._bufferUsage);
}
else {
curBufSta.unBind();
this.bind();
Laya.LayaGL.instance.bufferData(this._bufferType, byteLength, this._bufferUsage);
curBufSta.bind();
}
}
else {
this.bind();
Laya.LayaGL.instance.bufferData(this._bufferType, byteLength, this._bufferUsage);
}
if (canRead) {
switch (indexType) {
case exports.IndexFormat.UInt32:
this._buffer = new Uint32Array(indexCount);
break;
case exports.IndexFormat.UInt16:
this._buffer = new Uint16Array(indexCount);
break;
case exports.IndexFormat.UInt8:
this._buffer = new Uint8Array(indexCount);
break;
}
}
}
get indexType() {
return this._indexType;
}
get indexTypeByteCount() {
return this._indexTypeByteCount;
}
get indexCount() {
return this._indexCount;
}
get canRead() {
return this._canRead;
}
_bindForVAO() {
if (Laya.BufferStateBase._curBindedBufferState) {
var gl = Laya.LayaGL.instance;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._glBuffer);
}
else {
throw "IndexBuffer3D: must bind current BufferState.";
}
}
bind() {
if (Laya.BufferStateBase._curBindedBufferState) {
throw "IndexBuffer3D: must unbind current BufferState.";
}
else {
if (Laya.Buffer._bindedIndexBuffer !== this._glBuffer) {
var gl = Laya.LayaGL.instance;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._glBuffer);
Laya.Buffer._bindedIndexBuffer = this._glBuffer;
return true;
}
else {
return false;
}
}
}
setData(data, bufferOffset = 0, dataStartIndex = 0, dataCount = 4294967295) {
var byteCount = this._indexTypeByteCount;
if (dataStartIndex !== 0 || dataCount !== 4294967295) {
switch (this._indexType) {
case exports.IndexFormat.UInt32:
data = new Uint32Array(data.buffer, dataStartIndex * byteCount, dataCount);
break;
case exports.IndexFormat.UInt16:
data = new Uint16Array(data.buffer, dataStartIndex * byteCount, dataCount);
break;
case exports.IndexFormat.UInt8:
data = new Uint8Array(data.buffer, dataStartIndex * byteCount, dataCount);
break;
}
}
var curBufSta = Laya.BufferStateBase._curBindedBufferState;
if (curBufSta) {
if (curBufSta._bindedIndexBuffer === this) {
Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset * byteCount, data);
}
else {
curBufSta.unBind();
this.bind();
Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset * byteCount, data);
curBufSta.bind();
}
}
else {
this.bind();
Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset * byteCount, data);
}
if (this._canRead) {
if (bufferOffset !== 0 || dataStartIndex !== 0 || dataCount !== 4294967295) {
var maxLength = this._buffer.length - bufferOffset;
if (dataCount > maxLength)
dataCount = maxLength;
for (var i = 0; i < dataCount; i++)
this._buffer[bufferOffset + i] = data[i];
}
else {
this._buffer = data;
}
}
}
getData() {
if (this._canRead)
return this._buffer;
else
throw new Error("Can't read data from VertexBuffer with only write flag!");
}
destroy() {
super.destroy();
this._buffer = null;
this._byteLength = 0;
this._indexCount = 0;
}
}
class SkyMesh {
constructor() {
}
_render(state) {
}
}
class SkyBox extends SkyMesh {
constructor() {
super();
var gl = Laya.LayaGL.instance;
var halfHeight = 1.0;
var halfWidth = 1.0;
var halfDepth = 1.0;
var vertices = new Float32Array([-halfDepth, halfHeight, -halfWidth, halfDepth, halfHeight, -halfWidth, halfDepth, halfHeight, halfWidth, -halfDepth, halfHeight, halfWidth,
-halfDepth, -halfHeight, -halfWidth, halfDepth, -halfHeight, -halfWidth, halfDepth, -halfHeight, halfWidth, -halfDepth, -halfHeight, halfWidth]);
var indices = new Uint8Array([
0, 1, 2, 2, 3, 0,
4, 7, 6, 6, 5, 4,
0, 3, 7, 7, 4, 0,
1, 5, 6, 6, 2, 1,
3, 2, 6, 6, 7, 3,
0, 4, 5, 5, 1, 0
]);
var verDec = VertexMesh.getVertexDeclaration("POSITION");
this._vertexBuffer = new VertexBuffer3D(verDec.vertexStride * 8, gl.STATIC_DRAW, false);
this._vertexBuffer.vertexDeclaration = verDec;
this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt8, 36, gl.STATIC_DRAW, false);
this._vertexBuffer.setData(vertices.buffer);
this._indexBuffer.setData(indices);
var bufferState = new BufferState();
bufferState.bind();
bufferState.applyVertexBuffer(this._vertexBuffer);
bufferState.applyIndexBuffer(this._indexBuffer);
bufferState.unBind();
this._bufferState = bufferState;
}
static __init__() {
SkyBox.instance = new SkyBox();
}
_render(state) {
var gl = Laya.LayaGL.instance;
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_BYTE, 0);
Laya.Stat.trianglesFaces += 12;
Laya.Stat.renderBatches++;
}
}
class SkyRenderer {
constructor() {
this._mesh = SkyBox.instance;
}
get material() {
return this._material;
}
set material(value) {
if (this._material !== value) {
(this._material) && (this._material._removeReference());
(value) && (value._addReference());
this._material = value;
}
}
get mesh() {
return this._mesh;
}
set mesh(value) {
if (this._mesh !== value) {
this._mesh = value;
}
}
_isAvailable() {
return this._material && this._mesh ? true : false;
}
_render(context) {
if (this._material && this._mesh) {
var gl = Laya.LayaGL.instance;
var scene = context.scene;
var cameraShaderValue = context.cameraShaderValue;
var camera = context.camera;
var noteValue = ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_;
Laya.ILaya.Render.supportWebGLPlusRendering && ShaderData.setRuntimeValueMode(false);
Laya.WebGLContext.setCullFace(gl, false);
Laya.WebGLContext.setDepthFunc(gl, gl.LEQUAL);
Laya.WebGLContext.setDepthMask(gl, false);
var comDef = SkyRenderer._compileDefine;
this._material._shaderValues._defineDatas.cloneTo(comDef);
var shader = context.shader = this._material._shader.getSubShaderAt(0)._passes[0].withCompile(comDef);
var switchShader = shader.bind();
var switchShaderLoop = (Laya.Stat.loopCount !== shader._uploadMark);
var uploadScene = (shader._uploadScene !== scene) || switchShaderLoop;
if (uploadScene || switchShader) {
shader.uploadUniforms(shader._sceneUniformParamsMap, scene._shaderValues, uploadScene);
shader._uploadScene = scene;
}
var uploadCamera = (shader._uploadCameraShaderValue !== cameraShaderValue) || switchShaderLoop;
if (uploadCamera || switchShader) {
var viewMatrix = SkyRenderer._tempMatrix0;
var projectionMatrix = SkyRenderer._tempMatrix1;
camera.viewMatrix.cloneTo(viewMatrix);
camera.projectionMatrix.cloneTo(projectionMatrix);
viewMatrix.setTranslationVector(Vector3._ZERO);
if (camera.orthographic)
Matrix4x4.createPerspective(camera.fieldOfView, camera.aspectRatio, camera.nearPlane, camera.farPlane, projectionMatrix);
var epsilon = 1e-6;
var yScale = 1.0 / Math.tan(3.1416 * camera.fieldOfView / 180 * 0.5);
projectionMatrix.elements[0] = yScale / camera.aspectRatio;
projectionMatrix.elements[5] = yScale;
projectionMatrix.elements[10] = epsilon - 1.0;
projectionMatrix.elements[11] = -1.0;
projectionMatrix.elements[14] = -0;
camera._applyViewProject(context, viewMatrix, projectionMatrix);
shader.uploadUniforms(shader._cameraUniformParamsMap, cameraShaderValue, uploadCamera);
shader._uploadCameraShaderValue = cameraShaderValue;
}
var uploadMaterial = (shader._uploadMaterial !== this._material) || switchShaderLoop;
if (uploadMaterial || switchShader) {
shader.uploadUniforms(shader._materialUniformParamsMap, this._material._shaderValues, uploadMaterial);
shader._uploadMaterial = this._material;
}
this._mesh._bufferState.bind();
this._mesh._render(context);
Laya.ILaya.Render.supportWebGLPlusRendering && ShaderData.setRuntimeValueMode(noteValue);
Laya.WebGLContext.setDepthFunc(gl, gl.LESS);
Laya.WebGLContext.setDepthMask(gl, true);
camera._applyViewProject(context, camera.viewMatrix, camera.projectionMatrix);
}
}
destroy() {
if (this._material) {
this._material._removeReference();
this._material = null;
}
}
}
SkyRenderer._tempMatrix0 = new Matrix4x4();
SkyRenderer._tempMatrix1 = new Matrix4x4();
SkyRenderer._compileDefine = new DefineDatas();
class BaseCamera extends Sprite3D {
constructor(nearPlane = 0.3, farPlane = 1000) {
super();
this._skyRenderer = new SkyRenderer();
this._forward = new Vector3();
this._up = new Vector3();
this.clearColor = new Vector4(100 / 255, 149 / 255, 237 / 255, 255 / 255);
this._shaderValues = new ShaderData(null);
this._fieldOfView = 60;
this._useUserProjectionMatrix = false;
this._orthographic = false;
this._orthographicVerticalSize = 10;
this.renderingOrder = 0;
this._nearPlane = nearPlane;
this._farPlane = farPlane;
this.cullingMask = 2147483647;
this.useOcclusionCulling = true;
}
get skyRenderer() {
return this._skyRenderer;
}
get fieldOfView() {
return this._fieldOfView;
}
set fieldOfView(value) {
this._fieldOfView = value;
this._calculateProjectionMatrix();
}
get nearPlane() {
return this._nearPlane;
}
set nearPlane(value) {
this._nearPlane = value;
this._calculateProjectionMatrix();
}
get farPlane() {
return this._farPlane;
}
set farPlane(vaule) {
this._farPlane = vaule;
this._calculateProjectionMatrix();
}
get orthographic() {
return this._orthographic;
}
set orthographic(vaule) {
this._orthographic = vaule;
this._calculateProjectionMatrix();
}
get orthographicVerticalSize() {
return this._orthographicVerticalSize;
}
set orthographicVerticalSize(vaule) {
this._orthographicVerticalSize = vaule;
this._calculateProjectionMatrix();
}
get renderingOrder() {
return this._renderingOrder;
}
set renderingOrder(value) {
this._renderingOrder = value;
this._sortCamerasByRenderingOrder();
}
_sortCamerasByRenderingOrder() {
if (this.displayedInStage) {
var cameraPool = this.scene._cameraPool;
var n = cameraPool.length - 1;
for (var i = 0; i < n; i++) {
if (cameraPool[i].renderingOrder > cameraPool[n].renderingOrder) {
var tempCamera = cameraPool[i];
cameraPool[i] = cameraPool[n];
cameraPool[n] = tempCamera;
}
}
}
}
_calculateProjectionMatrix() {
}
_onScreenSizeChanged() {
this._calculateProjectionMatrix();
}
_prepareCameraToRender() {
var cameraSV = this._shaderValues;
this.transform.getForward(this._forward);
this.transform.getUp(this._up);
cameraSV.setVector3(BaseCamera.CAMERAPOS, this.transform.position);
cameraSV.setVector3(BaseCamera.CAMERADIRECTION, this._forward);
cameraSV.setVector3(BaseCamera.CAMERAUP, this._up);
}
render(shader = null, replacementTag = null) {
}
addLayer(layer) {
this.cullingMask |= Math.pow(2, layer);
}
removeLayer(layer) {
this.cullingMask &= ~Math.pow(2, layer);
}
addAllLayers() {
this.cullingMask = 2147483647;
}
removeAllLayers() {
this.cullingMask = 0;
}
resetProjectionMatrix() {
this._useUserProjectionMatrix = false;
this._calculateProjectionMatrix();
}
_onActive() {
this._scene._addCamera(this);
super._onActive();
}
_onInActive() {
this._scene._removeCamera(this);
super._onInActive();
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
this.orthographic = data.orthographic;
(data.orthographicVerticalSize !== undefined) && (this.orthographicVerticalSize = data.orthographicVerticalSize);
(data.fieldOfView !== undefined) && (this.fieldOfView = data.fieldOfView);
this.nearPlane = data.nearPlane;
this.farPlane = data.farPlane;
var color = data.clearColor;
this.clearColor = new Vector4(color[0], color[1], color[2], color[3]);
var skyboxMaterial = data.skyboxMaterial;
if (skyboxMaterial) {
this._skyRenderer.material = Laya.Loader.getRes(skyboxMaterial.path);
}
}
destroy(destroyChild = true) {
this._skyRenderer.destroy();
this._skyRenderer = null;
Laya.Laya.stage.off(Laya.Event.RESIZE, this, this._onScreenSizeChanged);
super.destroy(destroyChild);
}
_create() {
return new BaseCamera();
}
}
BaseCamera._tempMatrix4x40 = new Matrix4x4();
BaseCamera.CAMERAPOS = Shader3D.propertyNameToID("u_CameraPos");
BaseCamera.VIEWMATRIX = Shader3D.propertyNameToID("u_View");
BaseCamera.PROJECTMATRIX = Shader3D.propertyNameToID("u_Projection");
BaseCamera.VIEWPROJECTMATRIX = Shader3D.propertyNameToID("u_ViewProjection");
BaseCamera.CAMERADIRECTION = Shader3D.propertyNameToID("u_CameraDirection");
BaseCamera.CAMERAUP = Shader3D.propertyNameToID("u_CameraUp");
BaseCamera.VIEWPORT = Shader3D.propertyNameToID("u_Viewport");
BaseCamera.PROJECTION_PARAMS = Shader3D.propertyNameToID("u_ProjectionParams");
BaseCamera.DEPTHTEXTURE = Shader3D.propertyNameToID("u_CameraDepthTexture");
BaseCamera.DEPTHNORMALSTEXTURE = Shader3D.propertyNameToID("u_CameraDepthNormalsTexture");
BaseCamera.DEPTHZBUFFERPARAMS = Shader3D.propertyNameToID("u_ZBufferParams");
BaseCamera.SHADERDEFINE_DEPTH = Shader3D.getDefineByName("DEPTHMAP");
BaseCamera.SHADERDEFINE_DEPTHNORMALS = Shader3D.getDefineByName("DEPTHNORMALSMAP");
BaseCamera.RENDERINGTYPE_DEFERREDLIGHTING = "DEFERREDLIGHTING";
BaseCamera.RENDERINGTYPE_FORWARDRENDERING = "FORWARDRENDERING";
BaseCamera._invertYScaleMatrix = new Matrix4x4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
BaseCamera._invertYProjectionMatrix = new Matrix4x4();
BaseCamera._invertYProjectionViewMatrix = new Matrix4x4();
BaseCamera.CLEARFLAG_SOLIDCOLOR = 0;
BaseCamera.CLEARFLAG_SKY = 1;
BaseCamera.CLEARFLAG_DEPTHONLY = 2;
BaseCamera.CLEARFLAG_NONE = 3;
(function (ShadowMode) {
ShadowMode[ShadowMode["None"] = 0] = "None";
ShadowMode[ShadowMode["Hard"] = 1] = "Hard";
ShadowMode[ShadowMode["SoftLow"] = 2] = "SoftLow";
ShadowMode[ShadowMode["SoftHigh"] = 3] = "SoftHigh";
})(exports.ShadowMode || (exports.ShadowMode = {}));
class Scene3DShaderDeclaration {
}
(function (LightType) {
LightType[LightType["Directional"] = 0] = "Directional";
LightType[LightType["Spot"] = 1] = "Spot";
LightType[LightType["Point"] = 2] = "Point";
})(exports.LightType || (exports.LightType = {}));
class LightSprite extends Sprite3D {
constructor() {
super();
this._shadowMode = exports.ShadowMode.None;
this._isAlternate = false;
this._shadowResolution = 2048;
this._shadowDistance = 50.0;
this._shadowDepthBias = 1.0;
this._shadowNormalBias = 1.0;
this._shadowNearPlane = 0.1;
this._shadowStrength = 1.0;
this._lightWoldMatrix = new Matrix4x4();
this._intensity = 1.0;
this._intensityColor = new Vector3();
this.color = new Vector3(1.0, 1.0, 1.0);
this._lightmapBakedType = LightSprite.LIGHTMAPBAKEDTYPE_REALTIME;
}
get intensity() {
return this._intensity;
}
set intensity(value) {
this._intensity = value;
}
get shadowMode() {
return this._shadowMode;
}
set shadowMode(value) {
this._shadowMode = value;
}
get shadowDistance() {
return this._shadowDistance;
}
set shadowDistance(value) {
this._shadowDistance = value;
}
get shadowResolution() {
return this._shadowResolution;
}
set shadowResolution(value) {
this._shadowResolution = value;
}
get shadowDepthBias() {
return this._shadowDepthBias;
}
set shadowDepthBias(value) {
this._shadowDepthBias = value;
}
get shadowNormalBias() {
return this._shadowNormalBias;
}
set shadowNormalBias(value) {
this._shadowNormalBias = value;
}
get shadowStrength() {
return this._shadowStrength;
}
set shadowStrength(value) {
this._shadowStrength = value;
}
get shadowNearPlane() {
return this._shadowNearPlane;
}
set shadowNearPlane(value) {
this._shadowNearPlane = value;
}
get lightmapBakedType() {
return this._lightmapBakedType;
}
set lightmapBakedType(value) {
if (this._lightmapBakedType !== value) {
this._lightmapBakedType = value;
if (this.activeInHierarchy) {
if (value !== LightSprite.LIGHTMAPBAKEDTYPE_BAKED)
this._addToScene();
else
this._removeFromScene();
}
}
}
get lightWorldMatrix() {
var position = this.transform.position;
var quaterian = this.transform.rotation;
Matrix4x4.createAffineTransformation(position, quaterian, Vector3._ONE, this._lightWoldMatrix);
return this._lightWoldMatrix;
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
var colorData = data.color;
this.color.fromArray(colorData);
this.intensity = data.intensity;
this.lightmapBakedType = data.lightmapBakedType;
}
_cloneTo(destObject, rootSprite, dstSprite) {
super._cloneTo(destObject, rootSprite, dstSprite);
var spriteLight = destObject;
spriteLight.color = this.color.clone();
spriteLight.intensity = this.intensity;
spriteLight.lightmapBakedType = this.lightmapBakedType;
}
_addToScene() {
var scene = this._scene;
var maxLightCount = Config3D._config.maxLightCount;
if (scene._lightCount < maxLightCount) {
scene._lightCount++;
this._addToLightQueue();
this._isAlternate = false;
}
else {
scene._alternateLights.add(this);
this._isAlternate = true;
console.warn("LightSprite:light count has large than maxLightCount,the latest added light will be ignore.");
}
}
_removeFromScene() {
var scene = this._scene;
if (this._isAlternate) {
scene._alternateLights.remove(this);
}
else {
scene._lightCount--;
this._removeFromLightQueue();
if (scene._alternateLights._length > 0) {
var alternateLight = scene._alternateLights.shift();
alternateLight._addToLightQueue();
alternateLight._isAlternate = false;
scene._lightCount++;
}
}
}
_addToLightQueue() {
}
_removeFromLightQueue() {
}
_onActive() {
super._onActive();
(this.lightmapBakedType !== LightSprite.LIGHTMAPBAKEDTYPE_BAKED) && (this._addToScene());
}
_onInActive() {
super._onInActive();
(this.lightmapBakedType !== LightSprite.LIGHTMAPBAKEDTYPE_BAKED) && (this._removeFromScene());
}
_create() {
return new LightSprite();
}
get diffuseColor() {
console.log("LightSprite: discard property,please use color property instead.");
return this.color;
}
set diffuseColor(value) {
console.log("LightSprite: discard property,please use color property instead.");
this.color = value;
}
}
LightSprite.LIGHTMAPBAKEDTYPE_REALTIME = 0;
LightSprite.LIGHTMAPBAKEDTYPE_MIXED = 1;
LightSprite.LIGHTMAPBAKEDTYPE_BAKED = 2;
(function (ShadowCascadesMode) {
ShadowCascadesMode[ShadowCascadesMode["NoCascades"] = 0] = "NoCascades";
ShadowCascadesMode[ShadowCascadesMode["TwoCascades"] = 1] = "TwoCascades";
ShadowCascadesMode[ShadowCascadesMode["FourCascades"] = 2] = "FourCascades";
})(exports.ShadowCascadesMode || (exports.ShadowCascadesMode = {}));
var FrustumFace;
(function (FrustumFace) {
FrustumFace[FrustumFace["Near"] = 0] = "Near";
FrustumFace[FrustumFace["Far"] = 1] = "Far";
FrustumFace[FrustumFace["Left"] = 2] = "Left";
FrustumFace[FrustumFace["Right"] = 3] = "Right";
FrustumFace[FrustumFace["Bottom"] = 4] = "Bottom";
FrustumFace[FrustumFace["Top"] = 5] = "Top";
})(FrustumFace || (FrustumFace = {}));
class ShadowUtils {
static supportShadow() {
return Laya.LayaGL.layaGPUInstance._isWebGL2 || Laya.SystemUtils.supportRenderTextureFormat(Laya.RenderTextureFormat.Depth);
}
static init() {
if (Laya.LayaGL.layaGPUInstance._isWebGL2)
ShadowUtils._shadowTextureFormat = Laya.RenderTextureFormat.ShadowMap;
else
ShadowUtils._shadowTextureFormat = Laya.RenderTextureFormat.Depth;
}
static getTemporaryShadowTexture(witdh, height, depthFormat) {
var shadowMap = RenderTexture.createFromPool(witdh, height, ShadowUtils._shadowTextureFormat, depthFormat);
shadowMap.filterMode = Laya.FilterMode.Bilinear;
shadowMap.wrapModeU = Laya.WarpMode.Clamp;
shadowMap.wrapModeV = Laya.WarpMode.Clamp;
return shadowMap;
}
static getShadowBias(light, shadowProjectionMatrix, shadowResolution, out) {
var frustumSize;
if (light._lightType == exports.LightType.Directional) {
frustumSize = 2.0 / shadowProjectionMatrix.elements[0];
}
else if (light._lightType == exports.LightType.Spot) {
frustumSize = Math.tan(light.spotAngle * 0.5 * MathUtils3D.Deg2Rad) * light.range;
}
else {
console.warn("ShadowUtils:Only spot and directional shadow casters are supported now.");
frustumSize = 0.0;
}
var texelSize = frustumSize / shadowResolution;
var depthBias = -light._shadowDepthBias * texelSize;
var normalBias = -light._shadowNormalBias * texelSize;
if (light.shadowMode == exports.ShadowMode.SoftHigh) {
const kernelRadius = 2.5;
depthBias *= kernelRadius;
normalBias *= kernelRadius;
}
out.setValue(depthBias, normalBias, 0.0, 0.0);
}
static getCameraFrustumPlanes(cameraViewProjectMatrix, frustumPlanes) {
BoundFrustum.getPlanesFromMatrix(cameraViewProjectMatrix, frustumPlanes[FrustumFace.Near], frustumPlanes[FrustumFace.Far], frustumPlanes[FrustumFace.Left], frustumPlanes[FrustumFace.Right], frustumPlanes[FrustumFace.Top], frustumPlanes[FrustumFace.Bottom]);
}
static getFarWithRadius(radius, denominator) {
return Math.sqrt(radius * radius / denominator);
}
static getCascadesSplitDistance(twoSplitRatio, fourSplitRatio, cameraNear, shadowFar, fov, aspectRatio, cascadesMode, out) {
out[0] = cameraNear;
var range = shadowFar - cameraNear;
var tFov = Math.tan(fov * 0.5);
var denominator = 1.0 + tFov * tFov * (aspectRatio * aspectRatio + 1.0);
switch (cascadesMode) {
case exports.ShadowCascadesMode.NoCascades:
out[1] = ShadowUtils.getFarWithRadius(shadowFar, denominator);
break;
case exports.ShadowCascadesMode.TwoCascades:
out[1] = ShadowUtils.getFarWithRadius(cameraNear + range * twoSplitRatio, denominator);
out[2] = ShadowUtils.getFarWithRadius(shadowFar, denominator);
break;
case exports.ShadowCascadesMode.FourCascades:
out[1] = ShadowUtils.getFarWithRadius(cameraNear + range * fourSplitRatio.x, denominator);
out[2] = ShadowUtils.getFarWithRadius(cameraNear + range * fourSplitRatio.y, denominator);
out[3] = ShadowUtils.getFarWithRadius(cameraNear + range * fourSplitRatio.z, denominator);
out[4] = ShadowUtils.getFarWithRadius(shadowFar, denominator);
break;
}
}
static applySliceTransform(shadowSliceData, atlasWidth, atlasHeight, cascadeIndex, outShadowMatrices) {
var sliceE = ShadowUtils._tempMatrix0.elements;
var oneOverAtlasWidth = 1.0 / atlasWidth;
var oneOverAtlasHeight = 1.0 / atlasHeight;
sliceE[0] = shadowSliceData.resolution * oneOverAtlasWidth;
sliceE[5] = shadowSliceData.resolution * oneOverAtlasHeight;
sliceE[12] = shadowSliceData.offsetX * oneOverAtlasWidth;
sliceE[13] = shadowSliceData.offsetY * oneOverAtlasHeight;
sliceE[1] = sliceE[2] = sliceE[2] = sliceE[4] = sliceE[6] = sliceE[7] = sliceE[8] = sliceE[9] = sliceE[11] = sliceE[14] = 0;
sliceE[10] = sliceE[15] = 1;
var offset = cascadeIndex * 16;
Utils3D._mulMatrixArray(sliceE, outShadowMatrices, offset, outShadowMatrices, offset);
}
static getDirectionLightShadowCullPlanes(cameraFrustumPlanes, cascadeIndex, splitDistance, cameraNear, direction, shadowSliceData) {
var frustumCorners = ShadowUtils._frustumCorners;
var backPlaneFaces = ShadowUtils._backPlaneFaces;
var planeNeighbors = ShadowUtils._frustumPlaneNeighbors;
var twoPlaneCorners = ShadowUtils._frustumTwoPlaneCorners;
var edgePlanePoint2 = ShadowUtils._edgePlanePoint2;
var out = shadowSliceData.cullPlanes;
var near = cameraFrustumPlanes[FrustumFace.Near], far = cameraFrustumPlanes[FrustumFace.Far];
var left = cameraFrustumPlanes[FrustumFace.Left], right = cameraFrustumPlanes[FrustumFace.Right];
var bottom = cameraFrustumPlanes[FrustumFace.Bottom], top = cameraFrustumPlanes[FrustumFace.Top];
var splitNearDistance = splitDistance[cascadeIndex] - cameraNear;
var splitNear = ShadowUtils._adjustNearPlane;
var splitFar = ShadowUtils._adjustFarPlane;
near.normal.cloneTo(splitNear.normal);
far.normal.cloneTo(splitFar.normal);
splitNear.distance = near.distance - splitNearDistance;
splitFar.distance = Math.min(-near.distance + shadowSliceData.sphereCenterZ + shadowSliceData.splitBoundSphere.radius, far.distance);
BoundFrustum.get3PlaneInterPoint(splitNear, bottom, right, frustumCorners[exports.FrustumCorner.nearBottomRight]);
BoundFrustum.get3PlaneInterPoint(splitNear, top, right, frustumCorners[exports.FrustumCorner.nearTopRight]);
BoundFrustum.get3PlaneInterPoint(splitNear, top, left, frustumCorners[exports.FrustumCorner.nearTopLeft]);
BoundFrustum.get3PlaneInterPoint(splitNear, bottom, left, frustumCorners[exports.FrustumCorner.nearBottomLeft]);
BoundFrustum.get3PlaneInterPoint(splitFar, bottom, right, frustumCorners[exports.FrustumCorner.FarBottomRight]);
BoundFrustum.get3PlaneInterPoint(splitFar, top, right, frustumCorners[exports.FrustumCorner.FarTopRight]);
BoundFrustum.get3PlaneInterPoint(splitFar, top, left, frustumCorners[exports.FrustumCorner.FarTopLeft]);
BoundFrustum.get3PlaneInterPoint(splitFar, bottom, left, frustumCorners[exports.FrustumCorner.FarBottomLeft]);
var backIndex = 0;
for (var i = 0; i < 6; i++) {
var plane;
switch (i) {
case FrustumFace.Near:
plane = splitNear;
break;
case FrustumFace.Far:
plane = splitFar;
break;
default:
plane = cameraFrustumPlanes[i];
break;
}
if (Vector3.dot(plane.normal, direction) < 0.0) {
plane.cloneTo(out[backIndex]);
backPlaneFaces[backIndex] = i;
backIndex++;
}
}
var edgeIndex = backIndex;
for (var i = 0; i < backIndex; i++) {
var backFace = backPlaneFaces[i];
var neighborFaces = planeNeighbors[backFace];
for (var j = 0; j < 4; j++) {
var neighborFace = neighborFaces[j];
var notBackFace = true;
for (var k = 0; k < backIndex; k++)
if (neighborFace == backPlaneFaces[k]) {
notBackFace = false;
break;
}
if (notBackFace) {
var corners = twoPlaneCorners[backFace][neighborFace];
var point0 = frustumCorners[corners[0]];
var point1 = frustumCorners[corners[1]];
Vector3.add(point0, direction, edgePlanePoint2);
Plane.createPlaneBy3P(point0, point1, edgePlanePoint2, out[edgeIndex++]);
}
}
}
shadowSliceData.cullPlaneCount = edgeIndex;
}
static getBoundSphereByFrustum(near, far, fov, aspectRatio, cameraPos, forward, outBoundSphere) {
var centerZ;
var radius;
var k = Math.sqrt(1.0 + aspectRatio * aspectRatio) * Math.tan(fov / 2.0);
var k2 = k * k;
var farSNear = far - near;
var farANear = far + near;
if (k2 > farSNear / farANear) {
centerZ = far;
radius = far * k;
}
else {
centerZ = 0.5 * farANear * (1 + k2);
radius = 0.5 * Math.sqrt(farSNear * farSNear + 2.0 * (far * far + near * near) * k2 + farANear * farANear * k2 * k2);
}
var center = outBoundSphere.center;
outBoundSphere.radius = radius;
Vector3.scale(forward, centerZ, center);
Vector3.add(cameraPos, center, center);
return centerZ;
}
static getMaxTileResolutionInAtlas(atlasWidth, atlasHeight, tileCount) {
var resolution = Math.min(atlasWidth, atlasHeight);
var currentTileCount = Math.floor(atlasWidth / resolution) * Math.floor(atlasHeight / resolution);
while (currentTileCount < tileCount) {
resolution = Math.floor(resolution >> 1);
currentTileCount = Math.floor(atlasWidth / resolution) * Math.floor(atlasHeight / resolution);
}
return resolution;
}
static getDirectionalLightMatrices(lightUp, lightSide, lightForward, cascadeIndex, nearPlane, shadowResolution, shadowSliceData, shadowMatrices) {
var boundSphere = shadowSliceData.splitBoundSphere;
var center = boundSphere.center;
var radius = boundSphere.radius;
var halfShadowResolution = shadowResolution / 2;
var borderRadius = radius * halfShadowResolution / (halfShadowResolution - ShadowUtils.atlasBorderSize);
var borderDiam = borderRadius * 2.0;
var sizeUnit = shadowResolution / borderDiam;
var radiusUnit = borderDiam / shadowResolution;
var upLen = Math.ceil(Vector3.dot(center, lightUp) * sizeUnit) * radiusUnit;
var sideLen = Math.ceil(Vector3.dot(center, lightSide) * sizeUnit) * radiusUnit;
var forwardLen = Vector3.dot(center, lightForward);
center.x = lightUp.x * upLen + lightSide.x * sideLen + lightForward.x * forwardLen;
center.y = lightUp.y * upLen + lightSide.y * sideLen + lightForward.y * forwardLen;
center.z = lightUp.z * upLen + lightSide.z * sideLen + lightForward.z * forwardLen;
var origin = shadowSliceData.position;
var viewMatrix = shadowSliceData.viewMatrix;
var projectMatrix = shadowSliceData.projectionMatrix;
var viewProjectMatrix = shadowSliceData.viewProjectMatrix;
shadowSliceData.resolution = shadowResolution;
shadowSliceData.offsetX = (cascadeIndex % 2) * shadowResolution;
shadowSliceData.offsetY = Math.floor(cascadeIndex / 2) * shadowResolution;
Vector3.scale(lightForward, radius + nearPlane, origin);
Vector3.subtract(center, origin, origin);
Matrix4x4.createLookAt(origin, center, lightUp, viewMatrix);
Matrix4x4.createOrthoOffCenter(-borderRadius, borderRadius, -borderRadius, borderRadius, 0.0, radius * 2.0 + nearPlane, projectMatrix);
Matrix4x4.multiply(projectMatrix, viewMatrix, viewProjectMatrix);
Utils3D._mulMatrixArray(ShadowUtils._shadowMapScaleOffsetMatrix.elements, viewProjectMatrix.elements, 0, shadowMatrices, cascadeIndex * 16);
}
static getSpotLightShadowData(shadowSpotData, spotLight, resolution, shadowParams, shadowSpotMatrices, shadowMapSize) {
var out = shadowSpotData.position = spotLight.transform.position;
shadowSpotData.resolution = resolution;
shadowMapSize.setValue(1.0 / resolution, 1.0 / resolution, resolution, resolution);
shadowSpotData.offsetX = 0;
shadowSpotData.offsetY = 0;
var spotWorldMatrix = spotLight.lightWorldMatrix;
var viewMatrix = shadowSpotData.viewMatrix;
var projectMatrix = shadowSpotData.projectionMatrix;
var viewProjectMatrix = shadowSpotData.viewProjectMatrix;
var BoundFrustum = shadowSpotData.cameraCullInfo.boundFrustum;
spotWorldMatrix.invert(viewMatrix);
Matrix4x4.createPerspective(3.1416 * spotLight.spotAngle / 180.0, 1, 0.1, spotLight.range, projectMatrix);
shadowParams.y = spotLight.shadowStrength;
Matrix4x4.multiply(projectMatrix, viewMatrix, viewProjectMatrix);
BoundFrustum.matrix = viewProjectMatrix;
viewProjectMatrix.cloneTo(shadowSpotMatrices);
shadowSpotData.cameraCullInfo.position = out;
}
static prepareShadowReceiverShaderValues(light, shadowMapWidth, shadowMapHeight, shadowSliceDatas, cascadeCount, shadowMapSize, shadowParams, shadowMatrices, splitBoundSpheres) {
shadowMapSize.setValue(1.0 / shadowMapWidth, 1.0 / shadowMapHeight, shadowMapWidth, shadowMapHeight);
shadowParams.setValue(light._shadowStrength, 0.0, 0.0, 0.0);
if (cascadeCount > 1) {
const matrixFloatCount = 16;
for (var i = cascadeCount * matrixFloatCount, n = 4 * matrixFloatCount; i < n; i++)
shadowMatrices[i] = 0.0;
for (var i = 0; i < cascadeCount; i++) {
var boundSphere = shadowSliceDatas[i].splitBoundSphere;
var center = boundSphere.center;
var radius = boundSphere.radius;
var offset = i * 4;
splitBoundSpheres[offset] = center.x;
splitBoundSpheres[offset + 1] = center.y;
splitBoundSpheres[offset + 2] = center.z;
splitBoundSpheres[offset + 3] = radius * radius;
}
const sphereFloatCount = 4;
for (var i = cascadeCount * sphereFloatCount, n = 4 * sphereFloatCount; i < n; i++)
splitBoundSpheres[i] = 0.0;
}
}
}
ShadowUtils._tempMatrix0 = new Matrix4x4();
ShadowUtils._shadowMapScaleOffsetMatrix = new Matrix4x4(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0);
ShadowUtils._frustumCorners = [new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3()];
ShadowUtils._adjustNearPlane = new Plane(new Vector3());
ShadowUtils._adjustFarPlane = new Plane(new Vector3());
ShadowUtils._backPlaneFaces = new Array(5);
ShadowUtils._edgePlanePoint2 = new Vector3();
ShadowUtils._frustumPlaneNeighbors = [
[FrustumFace.Left, FrustumFace.Right, FrustumFace.Top, FrustumFace.Bottom],
[FrustumFace.Left, FrustumFace.Right, FrustumFace.Top, FrustumFace.Bottom],
[FrustumFace.Near, FrustumFace.Far, FrustumFace.Top, FrustumFace.Bottom],
[FrustumFace.Near, FrustumFace.Far, FrustumFace.Top, FrustumFace.Bottom],
[FrustumFace.Near, FrustumFace.Far, FrustumFace.Left, FrustumFace.Right],
[FrustumFace.Near, FrustumFace.Far, FrustumFace.Left, FrustumFace.Right]
];
ShadowUtils._frustumTwoPlaneCorners = [
[[exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.nearBottomLeft, exports.FrustumCorner.nearTopLeft], [exports.FrustumCorner.nearTopRight, exports.FrustumCorner.nearBottomRight], [exports.FrustumCorner.nearBottomRight, exports.FrustumCorner.nearBottomLeft], [exports.FrustumCorner.nearTopLeft, exports.FrustumCorner.nearTopRight]],
[[exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.FarTopLeft, exports.FrustumCorner.FarBottomLeft], [exports.FrustumCorner.FarBottomRight, exports.FrustumCorner.FarTopRight], [exports.FrustumCorner.FarBottomLeft, exports.FrustumCorner.FarBottomRight], [exports.FrustumCorner.FarTopRight, exports.FrustumCorner.FarTopLeft]],
[[exports.FrustumCorner.nearTopLeft, exports.FrustumCorner.nearBottomLeft], [exports.FrustumCorner.FarBottomLeft, exports.FrustumCorner.FarTopLeft], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.nearBottomLeft, exports.FrustumCorner.FarBottomLeft], [exports.FrustumCorner.FarTopLeft, exports.FrustumCorner.nearTopLeft]],
[[exports.FrustumCorner.nearBottomRight, exports.FrustumCorner.nearTopRight], [exports.FrustumCorner.FarTopRight, exports.FrustumCorner.FarBottomRight], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.FarBottomRight, exports.FrustumCorner.nearBottomRight], [exports.FrustumCorner.nearTopRight, exports.FrustumCorner.FarTopRight]],
[[exports.FrustumCorner.nearBottomLeft, exports.FrustumCorner.nearBottomRight], [exports.FrustumCorner.FarBottomRight, exports.FrustumCorner.FarBottomLeft], [exports.FrustumCorner.FarBottomLeft, exports.FrustumCorner.nearBottomLeft], [exports.FrustumCorner.nearBottomRight, exports.FrustumCorner.FarBottomRight], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown]],
[[exports.FrustumCorner.nearTopRight, exports.FrustumCorner.nearTopLeft], [exports.FrustumCorner.FarTopLeft, exports.FrustumCorner.FarTopRight], [exports.FrustumCorner.nearTopLeft, exports.FrustumCorner.FarTopLeft], [exports.FrustumCorner.FarTopRight, exports.FrustumCorner.nearTopRight], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown]]
];
ShadowUtils.atlasBorderSize = 4.0;
(function (DepthTextureMode) {
DepthTextureMode[DepthTextureMode["None"] = 0] = "None";
DepthTextureMode[DepthTextureMode["Depth"] = 1] = "Depth";
DepthTextureMode[DepthTextureMode["DepthNormals"] = 2] = "DepthNormals";
DepthTextureMode[DepthTextureMode["MotionVectors"] = 4] = "MotionVectors";
})(exports.DepthTextureMode || (exports.DepthTextureMode = {}));
class DepthPass {
constructor() {
this._zBufferParams = new Vector4();
}
update(camera, depthType) {
this._viewPort = camera.viewport;
this._camera = camera;
switch (depthType) {
case exports.DepthTextureMode.Depth:
camera.depthTexture = this._depthTexture = RenderTexture.createFromPool(this._viewPort.width, this._viewPort.height, Laya.RenderTextureFormat.Depth, Laya.RenderTextureDepthFormat.DEPTH_16);
break;
case exports.DepthTextureMode.DepthNormals:
camera.depthNormalTexture = this._depthNormalsTexture = RenderTexture.createFromPool(this._viewPort.width, this._viewPort.height, Laya.RenderTextureFormat.R8G8B8A8, Laya.RenderTextureDepthFormat.DEPTH_16);
break;
case exports.DepthTextureMode.MotionVectors:
break;
default:
throw ("there is UnDefined type of DepthTextureMode");
}
}
render(context, depthType) {
var scene = context.scene;
switch (depthType) {
case exports.DepthTextureMode.Depth:
var shaderValues = scene._shaderValues;
context.pipelineMode = "ShadowCaster";
ShaderData.setRuntimeValueMode(false);
this._depthTexture._start();
shaderValues.setVector(DepthPass.DEFINE_SHADOW_BIAS, DepthPass.SHADOW_BIAS);
var gl = Laya.LayaGL.instance;
var offsetX = this._viewPort.x;
var offsetY = this._viewPort.y;
gl.enable(gl.SCISSOR_TEST);
gl.viewport(offsetX, offsetY, this._viewPort.width, this._viewPort.height);
gl.scissor(offsetX, offsetY, this._viewPort.width, this._viewPort.height);
gl.clear(gl.DEPTH_BUFFER_BIT);
scene._opaqueQueue._render(context);
this._depthTexture._end();
ShaderData.setRuntimeValueMode(true);
this._setupDepthModeShaderValue(depthType, this._camera);
context.pipelineMode = context.configPipeLineMode;
break;
case exports.DepthTextureMode.DepthNormals:
var shaderValues = scene._shaderValues;
context.pipelineMode = "DepthNormal";
ShaderData.setRuntimeValueMode(false);
this._depthNormalsTexture._start();
var gl = Laya.LayaGL.instance;
var offsetX = this._viewPort.x;
var offsetY = this._viewPort.y;
gl.enable(gl.SCISSOR_TEST);
gl.viewport(offsetX, offsetY, this._viewPort.width, this._viewPort.height);
gl.scissor(offsetX, offsetY, this._viewPort.width, this._viewPort.height);
gl.clearColor(0.5, 0.5, 1.0, 0.0);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
scene._opaqueQueue._render(context);
this._depthNormalsTexture._end();
ShaderData.setRuntimeValueMode(true);
this._setupDepthModeShaderValue(depthType, this._camera);
context.pipelineMode = context.configPipeLineMode;
break;
case exports.DepthTextureMode.MotionVectors:
break;
default:
throw ("there is UnDefined type of DepthTextureMode");
}
}
_setupDepthModeShaderValue(depthType, camera) {
switch (depthType) {
case exports.DepthTextureMode.Depth:
var far = camera.farPlane;
var near = camera.nearPlane;
this._zBufferParams.setValue(1.0 - far / near, far / near, (near - far) / (near * far), 1 / near);
camera._shaderValues.setVector(DepthPass.DEFINE_SHADOW_BIAS, DepthPass.SHADOW_BIAS);
camera._shaderValues.setTexture(DepthPass.DEPTHTEXTURE, this._depthTexture);
camera._shaderValues.setVector(DepthPass.DEPTHZBUFFERPARAMS, this._zBufferParams);
break;
case exports.DepthTextureMode.DepthNormals:
camera._shaderValues.setTexture(DepthPass.DEPTHNORMALSTEXTURE, this._depthNormalsTexture);
break;
case exports.DepthTextureMode.MotionVectors:
break;
default:
throw ("there is UnDefined type of DepthTextureMode");
}
}
cleanUp() {
this._depthTexture && RenderTexture.recoverToPool(this._depthTexture);
this._depthNormalsTexture && RenderTexture.recoverToPool(this._depthNormalsTexture);
this._depthTexture = null;
this._depthNormalsTexture = null;
}
}
DepthPass.SHADOW_BIAS = new Vector4();
DepthPass.DEFINE_SHADOW_BIAS = Shader3D.propertyNameToID("u_ShadowBias");
DepthPass.DEPTHTEXTURE = Shader3D.propertyNameToID("u_CameraDepthTexture");
DepthPass.DEPTHNORMALSTEXTURE = Shader3D.propertyNameToID("u_CameraDepthNormalsTexture");
DepthPass.DEPTHZBUFFERPARAMS = Shader3D.propertyNameToID("u_ZBufferParams");
(function (CameraClearFlags) {
CameraClearFlags[CameraClearFlags["SolidColor"] = 0] = "SolidColor";
CameraClearFlags[CameraClearFlags["Sky"] = 1] = "Sky";
CameraClearFlags[CameraClearFlags["DepthOnly"] = 2] = "DepthOnly";
CameraClearFlags[CameraClearFlags["Nothing"] = 3] = "Nothing";
})(exports.CameraClearFlags || (exports.CameraClearFlags = {}));
(function (CameraEventFlags) {
CameraEventFlags[CameraEventFlags["BeforeForwardOpaque"] = 0] = "BeforeForwardOpaque";
CameraEventFlags[CameraEventFlags["BeforeSkyBox"] = 2] = "BeforeSkyBox";
CameraEventFlags[CameraEventFlags["BeforeTransparent"] = 4] = "BeforeTransparent";
CameraEventFlags[CameraEventFlags["BeforeImageEffect"] = 6] = "BeforeImageEffect";
CameraEventFlags[CameraEventFlags["AfterEveryThing"] = 8] = "AfterEveryThing";
})(exports.CameraEventFlags || (exports.CameraEventFlags = {}));
class Camera extends BaseCamera {
constructor(aspectRatio = 0, nearPlane = 0.3, farPlane = 1000) {
super(nearPlane, farPlane);
this._updateViewMatrix = true;
this._postProcess = null;
this._enableHDR = false;
this._viewportParams = new Vector4();
this._projectionParams = new Vector4();
this._needBuiltInRenderTexture = false;
this._offScreenRenderTexture = null;
this._internalRenderTexture = null;
this._internalCommandBuffer = new CommandBuffer();
this._cameraEventCommandBuffer = {};
this._clusterPlaneCacheFlag = new Vector2(-1, -1);
this._screenOffsetScale = new Vector4();
this.enableRender = true;
this.clearFlag = exports.CameraClearFlags.SolidColor;
this._viewMatrix = new Matrix4x4();
this._projectionMatrix = new Matrix4x4();
this._projectionViewMatrix = new Matrix4x4();
this._viewport = new Viewport(0, 0, 0, 0);
this._normalizedViewport = new Viewport(0, 0, 1, 1);
this._rayViewport = new Viewport(0, 0, 0, 0);
this._aspectRatio = aspectRatio;
this._boundFrustum = new BoundFrustum(new Matrix4x4());
this._calculateProjectionMatrix();
Laya.Laya.stage.on(Laya.Event.RESIZE, this, this._onScreenSizeChanged);
this.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged);
}
static drawRenderTextureByScene(camera, scene, renderTexture, shader = null, replacementTag = null) {
if (camera.renderTarget != renderTexture) {
camera.renderTarget && RenderTexture.recoverToPool(camera.renderTarget);
camera.renderTarget = renderTexture;
}
var viewport = camera.viewport;
var needInternalRT = camera._needInternalRenderTexture();
var context = RenderContext3D._instance;
var scene = context.scene = scene;
context.pipelineMode = context.configPipeLineMode;
if (needInternalRT) {
camera._internalRenderTexture = RenderTexture.createFromPool(viewport.width, viewport.height, camera._getRenderTextureFormat(), Laya.RenderTextureDepthFormat.DEPTH_16);
camera._internalRenderTexture.filterMode = Laya.FilterMode.Bilinear;
}
else {
camera._internalRenderTexture = null;
}
var needShadowCasterPass = camera._renderShadowMap(scene, context);
camera._preRenderMainPass(context, scene, needInternalRT, viewport);
camera._renderMainPass(context, viewport, scene, shader, replacementTag, needInternalRT);
camera._aftRenderMainPass(needShadowCasterPass);
return camera.renderTarget;
}
get aspectRatio() {
if (this._aspectRatio === 0) {
var vp = this.viewport;
return vp.width / vp.height;
}
return this._aspectRatio;
}
set aspectRatio(value) {
if (value < 0)
throw new Error("Camera: the aspect ratio has to be a positive real number.");
this._aspectRatio = value;
this._calculateProjectionMatrix();
}
get viewport() {
if (this._offScreenRenderTexture)
this._calculationViewport(this._normalizedViewport, this._offScreenRenderTexture.width, this._offScreenRenderTexture.height);
else
this._calculationViewport(this._normalizedViewport, RenderContext3D.clientWidth, RenderContext3D.clientHeight);
return this._viewport;
}
set viewport(value) {
var width;
var height;
if (this._offScreenRenderTexture) {
width = this._offScreenRenderTexture.width;
height = this._offScreenRenderTexture.height;
}
else {
width = RenderContext3D.clientWidth;
height = RenderContext3D.clientHeight;
}
this._normalizedViewport.x = value.x / width;
this._normalizedViewport.y = value.y / height;
this._normalizedViewport.width = value.width / width;
this._normalizedViewport.height = value.height / height;
this._calculationViewport(this._normalizedViewport, width, height);
this._calculateProjectionMatrix();
}
get normalizedViewport() {
return this._normalizedViewport;
}
set normalizedViewport(value) {
var width;
var height;
if (this._offScreenRenderTexture) {
width = this._offScreenRenderTexture.width;
height = this._offScreenRenderTexture.height;
}
else {
width = RenderContext3D.clientWidth;
height = RenderContext3D.clientHeight;
}
if (this._normalizedViewport !== value)
value.cloneTo(this._normalizedViewport);
this._calculationViewport(value, width, height);
this._calculateProjectionMatrix();
}
get viewMatrix() {
if (this._updateViewMatrix) {
var scale = this.transform.getWorldLossyScale();
var scaleX = scale.x;
var scaleY = scale.y;
var scaleZ = scale.z;
var viewMatE = this._viewMatrix.elements;
this.transform.worldMatrix.cloneTo(this._viewMatrix);
viewMatE[0] /= scaleX;
viewMatE[1] /= scaleX;
viewMatE[2] /= scaleX;
viewMatE[4] /= scaleY;
viewMatE[5] /= scaleY;
viewMatE[6] /= scaleY;
viewMatE[8] /= scaleZ;
viewMatE[9] /= scaleZ;
viewMatE[10] /= scaleZ;
this._viewMatrix.invert(this._viewMatrix);
this._updateViewMatrix = false;
}
return this._viewMatrix;
}
get projectionMatrix() {
return this._projectionMatrix;
}
set projectionMatrix(value) {
this._projectionMatrix = value;
this._useUserProjectionMatrix = true;
}
get projectionViewMatrix() {
Matrix4x4.multiply(this.projectionMatrix, this.viewMatrix, this._projectionViewMatrix);
return this._projectionViewMatrix;
}
get boundFrustum() {
this._boundFrustum.matrix = this.projectionViewMatrix;
return this._boundFrustum;
}
get renderTarget() {
return this._offScreenRenderTexture;
}
set renderTarget(value) {
var lastValue = this._offScreenRenderTexture;
if (lastValue !== value) {
(lastValue) && (lastValue._isCameraTarget = false);
(value) && (value._isCameraTarget = true);
this._offScreenRenderTexture = value;
this._calculateProjectionMatrix();
}
}
get postProcess() {
return this._postProcess;
}
set postProcess(value) {
this._postProcess = value;
if (!value)
return;
value && value._init(this);
}
get enableHDR() {
return this._enableHDR;
}
set enableHDR(value) {
if (value && !Laya.SystemUtils.supportRenderTextureFormat(Laya.RenderTextureFormat.R16G16B16A16)) {
console.warn("Camera:can't enable HDR in this device.");
return;
}
this._enableHDR = value;
}
get enableBuiltInRenderTexture() {
return this._needBuiltInRenderTexture;
}
set enableBuiltInRenderTexture(value) {
this._needBuiltInRenderTexture = value;
}
get depthTextureMode() {
return this._depthTextureMode;
}
set depthTextureMode(value) {
this._depthTextureMode = value;
}
_calculationViewport(normalizedViewport, width, height) {
var lx = normalizedViewport.x * width;
var ly = normalizedViewport.y * height;
var rx = lx + Math.max(normalizedViewport.width * width, 0);
var ry = ly + Math.max(normalizedViewport.height * height, 0);
var ceilLeftX = Math.ceil(lx);
var ceilLeftY = Math.ceil(ly);
var floorRightX = Math.floor(rx);
var floorRightY = Math.floor(ry);
var pixelLeftX = ceilLeftX - lx >= 0.5 ? Math.floor(lx) : ceilLeftX;
var pixelLeftY = ceilLeftY - ly >= 0.5 ? Math.floor(ly) : ceilLeftY;
var pixelRightX = rx - floorRightX >= 0.5 ? Math.ceil(rx) : floorRightX;
var pixelRightY = ry - floorRightY >= 0.5 ? Math.ceil(ry) : floorRightY;
this._viewport.x = pixelLeftX;
this._viewport.y = pixelLeftY;
this._viewport.width = pixelRightX - pixelLeftX;
this._viewport.height = pixelRightY - pixelLeftY;
}
_calculateProjectionMatrix() {
if (!this._useUserProjectionMatrix) {
if (this._orthographic) {
var halfHeight = this.orthographicVerticalSize * 0.5;
var halfWidth = halfHeight * this.aspectRatio;
Matrix4x4.createOrthoOffCenter(-halfWidth, halfWidth, -halfHeight, halfHeight, this.nearPlane, this.farPlane, this._projectionMatrix);
}
else {
Matrix4x4.createPerspective(3.1416 * this.fieldOfView / 180.0, this.aspectRatio, this.nearPlane, this.farPlane, this._projectionMatrix);
}
}
}
_isLayerVisible(layer) {
return (Math.pow(2, layer) & this.cullingMask) != 0;
}
_onTransformChanged(flag) {
flag &= Transform3D.TRANSFORM_WORLDMATRIX;
(flag) && (this._updateViewMatrix = true);
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
var clearFlagData = data.clearFlag;
(clearFlagData !== undefined) && (this.clearFlag = clearFlagData);
var viewport = data.viewport;
this.normalizedViewport = new Viewport(viewport[0], viewport[1], viewport[2], viewport[3]);
var enableHDR = data.enableHDR;
(enableHDR !== undefined) && (this.enableHDR = enableHDR);
}
clone() {
let camera = super.clone();
camera.clearFlag = this.clearFlag;
camera.viewport = this.viewport;
this.normalizedViewport.cloneTo(camera.normalizedViewport);
camera.enableHDR = this.enableHDR;
camera.farPlane = this.farPlane;
camera.nearPlane = this.nearPlane;
camera.fieldOfView = this.fieldOfView;
camera.orthographic = this.orthographic;
return camera;
}
_getCanvasWidth() {
if (this._offScreenRenderTexture)
return this._offScreenRenderTexture.width;
else
return RenderContext3D.clientWidth;
}
_getCanvasHeight() {
if (this._offScreenRenderTexture)
return this._offScreenRenderTexture.height;
else
return RenderContext3D.clientHeight;
}
_getRenderTexture() {
return this._internalRenderTexture || this._offScreenRenderTexture;
}
_needInternalRenderTexture() {
return (this._postProcess && this._postProcess.enable) || this._enableHDR || this._needBuiltInRenderTexture ? true : false;
}
_getRenderTextureFormat() {
if (this._enableHDR)
return Laya.RenderTextureFormat.R16G16B16A16;
else
return Laya.RenderTextureFormat.R8G8B8;
}
_prepareCameraToRender() {
super._prepareCameraToRender();
var vp = this.viewport;
this._viewportParams.setValue(vp.x, vp.y, vp.width, vp.height);
this._projectionParams.setValue(this._nearPlane, this._farPlane, RenderContext3D._instance.invertY ? -1 : 1, 1 / this.farPlane);
this._shaderValues.setVector(BaseCamera.VIEWPORT, this._viewportParams);
this._shaderValues.setVector(BaseCamera.PROJECTION_PARAMS, this._projectionParams);
}
_applyViewProject(context, viewMat, proMat) {
var projectView;
var shaderData = this._shaderValues;
if (context.invertY) {
Matrix4x4.multiply(BaseCamera._invertYScaleMatrix, proMat, BaseCamera._invertYProjectionMatrix);
Matrix4x4.multiply(BaseCamera._invertYProjectionMatrix, viewMat, BaseCamera._invertYProjectionViewMatrix);
proMat = BaseCamera._invertYProjectionMatrix;
projectView = BaseCamera._invertYProjectionViewMatrix;
}
else {
Matrix4x4.multiply(proMat, viewMat, this._projectionViewMatrix);
projectView = this._projectionViewMatrix;
}
context.viewMatrix = viewMat;
context.projectionMatrix = proMat;
context.projectionViewMatrix = projectView;
shaderData.setMatrix4x4(BaseCamera.VIEWMATRIX, viewMat);
shaderData.setMatrix4x4(BaseCamera.PROJECTMATRIX, proMat);
shaderData.setMatrix4x4(BaseCamera.VIEWPROJECTMATRIX, projectView);
}
_updateClusterPlaneXY() {
var fieldOfView = this.fieldOfView;
var aspectRatio = this.aspectRatio;
if (this._clusterPlaneCacheFlag.x !== fieldOfView || this._clusterPlaneCacheFlag.y !== aspectRatio) {
var clusterCount = Config3D._config.lightClusterCount;
var xSlixe = clusterCount.x, ySlice = clusterCount.y;
var xCount = xSlixe + 1, yCount = ySlice + 1;
var xPlanes = this._clusterXPlanes, yPlanes = this._clusterYPlanes;
if (!xPlanes) {
xPlanes = this._clusterXPlanes = new Array(xCount);
yPlanes = this._clusterYPlanes = new Array(yCount);
for (var i = 0; i < xCount; i++)
xPlanes[i] = new Vector3();
for (var i = 0; i < yCount; i++)
yPlanes[i] = new Vector3();
}
var halfY = Math.tan((this.fieldOfView / 2) * Math.PI / 180);
var halfX = this.aspectRatio * halfY;
var yLengthPerCluster = 2 * halfY / xSlixe;
var xLengthPerCluster = 2 * halfX / ySlice;
for (var i = 0; i < xCount; i++) {
var angle = -halfX + xLengthPerCluster * i;
var bigHypot = Math.sqrt(1 + angle * angle);
var normX = 1 / bigHypot;
var xPlane = xPlanes[i];
xPlane.setValue(normX, 0, -angle * normX);
}
for (var i = 0; i < yCount; i++) {
var angle = halfY - yLengthPerCluster * i;
var bigHypot = Math.sqrt(1 + angle * angle);
var normY = -1 / bigHypot;
var yPlane = yPlanes[i];
yPlane.setValue(0, normY, -angle * normY);
}
this._clusterPlaneCacheFlag.x = fieldOfView;
this._clusterPlaneCacheFlag.y = aspectRatio;
}
}
_applyCommandBuffer(event, context) {
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER);
var gl = Laya.LayaGL.instance;
var commandBufferArray = this._cameraEventCommandBuffer[event];
if (!commandBufferArray || commandBufferArray.length == 0)
return;
commandBufferArray.forEach(function (value) {
value._context = context;
value._apply();
});
(RenderTexture.currentActive) && (RenderTexture.currentActive._end());
if (this._internalRenderTexture || this._offScreenRenderTexture)
this._getRenderTexture()._start();
else {
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
gl.viewport(0, 0, context.viewport.width, context.viewport.height);
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER);
}
_renderShadowMap(scene, context) {
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP);
var shadowCasterPass;
var mainDirectLight = scene._mainDirectionLight;
var needShadowCasterPass = mainDirectLight && mainDirectLight.shadowMode !== exports.ShadowMode.None && ShadowUtils.supportShadow();
if (needShadowCasterPass) {
scene._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT);
scene._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW);
shadowCasterPass = ILaya3D.Scene3D._shadowCasterPass;
shadowCasterPass.update(this, mainDirectLight, ILaya3D.ShadowLightType.DirectionLight);
shadowCasterPass.render(context, scene, ILaya3D.ShadowLightType.DirectionLight);
}
else {
scene._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW);
}
var spotMainLight = scene._mainSpotLight;
var spotneedShadowCasterPass = spotMainLight && spotMainLight.shadowMode !== exports.ShadowMode.None && ShadowUtils.supportShadow();
if (spotneedShadowCasterPass) {
scene._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW);
scene._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT);
shadowCasterPass = ILaya3D.Scene3D._shadowCasterPass;
shadowCasterPass.update(this, spotMainLight, ILaya3D.ShadowLightType.SpotLight);
shadowCasterPass.render(context, scene, ILaya3D.ShadowLightType.SpotLight);
}
else {
scene._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT);
}
if (needShadowCasterPass)
scene._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW);
if (spotneedShadowCasterPass)
scene._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT);
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP);
return needShadowCasterPass || spotneedShadowCasterPass;
}
_preRenderMainPass(context, scene, needInternalRT, viewport) {
context.camera = this;
context.cameraShaderValue = this._shaderValues;
Camera._updateMark++;
scene._preRenderScript();
var gl = Laya.LayaGL.instance;
if (needInternalRT && !this._offScreenRenderTexture && (this.clearFlag == exports.CameraClearFlags.DepthOnly || this.clearFlag == exports.CameraClearFlags.Nothing)) {
if (this._enableHDR) {
var grabTexture = RenderTexture.createFromPool(viewport.width, viewport.height, Laya.RenderTextureFormat.R8G8B8, Laya.RenderTextureDepthFormat.DEPTH_16);
grabTexture.filterMode = Laya.FilterMode.Bilinear;
Laya.WebGLContext.bindTexture(gl, gl.TEXTURE_2D, grabTexture._getSource());
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, viewport.x, RenderContext3D.clientHeight - (viewport.y + viewport.height), viewport.width, viewport.height);
var blit = BlitScreenQuadCMD.create(grabTexture, this._internalRenderTexture);
blit.run();
blit.recover();
RenderTexture.recoverToPool(grabTexture);
}
else {
Laya.WebGLContext.bindTexture(gl, gl.TEXTURE_2D, this._internalRenderTexture._getSource());
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, viewport.x, RenderContext3D.clientHeight - (viewport.y + viewport.height), viewport.width, viewport.height);
}
}
}
_renderMainPass(context, viewport, scene, shader, replacementTag, needInternalRT) {
var gl = Laya.LayaGL.instance;
var renderTex = this._getRenderTexture();
context.viewport = viewport;
this._prepareCameraToRender();
var multiLighting = Config3D._config._multiLighting;
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CLUSTER);
(multiLighting) && (Cluster.instance.update(this, (scene)));
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CLUSTER);
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CULLING);
scene._preCulling(context, this, shader, replacementTag);
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CULLING);
if (this.depthTextureMode != 0) {
this._applyViewProject(context, this.viewMatrix, this._projectionMatrix);
this._renderDepthMode(context);
}
(renderTex) && (renderTex._start());
this._applyViewProject(context, this.viewMatrix, this._projectionMatrix);
scene._clear(gl, context);
this._applyCommandBuffer(exports.CameraEventFlags.BeforeForwardOpaque, context);
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE);
scene._renderScene(context, ILaya3D.Scene3D.SCENERENDERFLAG_RENDERQPAQUE);
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE);
this._applyCommandBuffer(exports.CameraEventFlags.BeforeSkyBox, context);
scene._renderScene(context, ILaya3D.Scene3D.SCENERENDERFLAG_SKYBOX);
this._applyCommandBuffer(exports.CameraEventFlags.BeforeTransparent, context);
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT);
scene._renderScene(context, ILaya3D.Scene3D.SCENERENDERFLAG_RENDERTRANSPARENT);
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT);
scene._postRenderScript();
this._applyCommandBuffer(exports.CameraEventFlags.BeforeImageEffect, context);
(renderTex) && (renderTex._end());
if (needInternalRT) {
if (this._postProcess && this._postProcess.enable) {
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS);
this._postProcess._render();
this._postProcess._applyPostProcessCommandBuffers();
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS);
}
else if (this._enableHDR || this._needBuiltInRenderTexture) {
var canvasWidth = this._getCanvasWidth(), canvasHeight = this._getCanvasHeight();
this._screenOffsetScale.setValue(viewport.x / canvasWidth, viewport.y / canvasHeight, viewport.width / canvasWidth, viewport.height / canvasHeight);
this._internalCommandBuffer._camera = this;
this._internalCommandBuffer.blitScreenQuad(this._internalRenderTexture, this._offScreenRenderTexture ? this._offScreenRenderTexture : null, this._screenOffsetScale, null, null, 0, true);
this._internalCommandBuffer._apply();
this._internalCommandBuffer.clear();
}
RenderTexture.recoverToPool(this._internalRenderTexture);
}
this._applyCommandBuffer(exports.CameraEventFlags.AfterEveryThing, context);
}
_renderDepthMode(context) {
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE);
var cameraDepthMode = this._depthTextureMode;
if ((cameraDepthMode & exports.DepthTextureMode.Depth) != 0) {
Camera.depthPass.update(this, exports.DepthTextureMode.Depth);
Camera.depthPass.render(context, exports.DepthTextureMode.Depth);
}
if ((cameraDepthMode & exports.DepthTextureMode.DepthNormals) != 0) {
Camera.depthPass.update(this, exports.DepthTextureMode.DepthNormals);
Camera.depthPass.render(context, exports.DepthTextureMode.DepthNormals);
}
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE);
}
get depthTexture() {
return this._depthTexture;
}
set depthTexture(value) {
this._depthTexture = value;
}
get depthNormalTexture() {
return this._depthNormalsTexture;
}
set depthNormalTexture(value) {
this._depthNormalsTexture = value;
}
_aftRenderMainPass(needShadowPass) {
if (needShadowPass)
ILaya3D.Scene3D._shadowCasterPass.cleanUp();
Camera.depthPass.cleanUp();
}
render(shader = null, replacementTag = null) {
if (!this.activeInHierarchy)
return;
var viewport = this.viewport;
var needInternalRT = this._needInternalRenderTexture();
var context = RenderContext3D._instance;
var scene = context.scene = this._scene;
context.pipelineMode = context.configPipeLineMode;
if (needInternalRT) {
this._internalRenderTexture = RenderTexture.createFromPool(viewport.width, viewport.height, this._getRenderTextureFormat(), Laya.RenderTextureDepthFormat.DEPTH_16, 4);
this._internalRenderTexture.filterMode = Laya.FilterMode.Bilinear;
}
else {
this._internalRenderTexture = null;
}
var needShadowCasterPass = this._renderShadowMap(scene, context);
this._preRenderMainPass(context, scene, needInternalRT, viewport);
this._renderMainPass(context, viewport, scene, shader, replacementTag, needInternalRT);
this._aftRenderMainPass(needShadowCasterPass);
}
viewportPointToRay(point, out) {
this._rayViewport.x = this.viewport.x;
this._rayViewport.y = this.viewport.y;
this._rayViewport.width = Laya.Laya.stage._width;
this._rayViewport.height = Laya.Laya.stage._height;
Picker.calculateCursorRay(point, this._rayViewport, this._projectionMatrix, this.viewMatrix, null, out);
}
normalizedViewportPointToRay(point, out) {
var finalPoint = Camera._tempVector20;
var vp = this.viewport;
finalPoint.x = point.x * vp.width;
finalPoint.y = point.y * vp.height;
Picker.calculateCursorRay(finalPoint, this.viewport, this._projectionMatrix, this.viewMatrix, null, out);
}
worldToViewportPoint(position, out) {
Matrix4x4.multiply(this._projectionMatrix, this._viewMatrix, this._projectionViewMatrix);
this.viewport.project(position, this._projectionViewMatrix, out);
out.x = out.x / Laya.Laya.stage.clientScaleX;
out.y = out.y / Laya.Laya.stage.clientScaleY;
}
worldToNormalizedViewportPoint(position, out) {
Matrix4x4.multiply(this._projectionMatrix, this._viewMatrix, this._projectionViewMatrix);
this.normalizedViewport.project(position, this._projectionViewMatrix, out);
out.x = out.x / Laya.Laya.stage.clientScaleX;
out.y = out.y / Laya.Laya.stage.clientScaleY;
}
convertScreenCoordToOrthographicCoord(source, out) {
if (this._orthographic) {
var clientWidth = RenderContext3D.clientWidth;
var clientHeight = RenderContext3D.clientHeight;
var ratioX = this.orthographicVerticalSize * this.aspectRatio / clientWidth;
var ratioY = this.orthographicVerticalSize / clientHeight;
out.x = (-clientWidth / 2 + source.x * Laya.Laya.stage.clientScaleX) * ratioX;
out.y = (clientHeight / 2 - source.y * Laya.Laya.stage.clientScaleY) * ratioY;
out.z = (this.nearPlane - this.farPlane) * (source.z + 1) / 2 - this.nearPlane;
Vector3.transformCoordinate(out, this.transform.worldMatrix, out);
return true;
}
else {
return false;
}
}
destroy(destroyChild = true) {
this._offScreenRenderTexture = null;
this.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged);
super.destroy(destroyChild);
}
addCommandBuffer(event, commandBuffer) {
var commandBufferArray = this._cameraEventCommandBuffer[event];
if (!commandBufferArray)
commandBufferArray = this._cameraEventCommandBuffer[event] = [];
if (commandBufferArray.indexOf(commandBuffer) < 0)
commandBufferArray.push(commandBuffer);
commandBuffer._camera = this;
}
removeCommandBuffer(event, commandBuffer) {
var commandBufferArray = this._cameraEventCommandBuffer[event];
if (commandBufferArray) {
var index = commandBufferArray.indexOf(commandBuffer);
if (index != -1)
commandBufferArray.splice(index, 1);
}
else
throw "Camera:unknown event.";
}
removeCommandBuffers(event) {
if (this._cameraEventCommandBuffer[event])
this._cameraEventCommandBuffer[event].length = 0;
}
_create() {
return new Camera();
}
}
Camera._tempVector20 = new Vector2();
Camera._updateMark = 0;
Camera.depthPass = new DepthPass();
class Input3D {
constructor() {
this._eventList = [];
this._mouseTouch = new MouseTouch();
this._touchPool = [];
this._touches = new SimpleSingletonList();
this._multiTouchEnabled = true;
this._pushEventList = ((e) => {
(e.cancelable) && (e.preventDefault());
this._eventList.push(e);
}).bind(this);
}
__init__(canvas, scene) {
this._scene = scene;
Physics3D._bullet && (Input3D._tempHitResult0 = new Laya.HitResult());
canvas.oncontextmenu = function (e) {
return false;
};
}
_onCanvasEvent(canvas) {
canvas.addEventListener('mousedown', this._pushEventList);
canvas.addEventListener('mouseup', this._pushEventList, true);
canvas.addEventListener('mousemove', this._pushEventList, true);
canvas.addEventListener("touchstart", this._pushEventList);
canvas.addEventListener("touchend", this._pushEventList, true);
canvas.addEventListener("touchmove", this._pushEventList, true);
canvas.addEventListener("touchcancel", this._pushEventList, true);
}
_offCanvasEvent(canvas) {
canvas.removeEventListener('mousedown', this._pushEventList);
canvas.removeEventListener('mouseup', this._pushEventList, true);
canvas.removeEventListener('mousemove', this._pushEventList, true);
canvas.removeEventListener("touchstart", this._pushEventList);
canvas.removeEventListener("touchend", this._pushEventList, true);
canvas.removeEventListener("touchmove", this._pushEventList, true);
canvas.removeEventListener("touchcancel", this._pushEventList, true);
this._eventList.length = 0;
this._touches.clear();
}
touchCount() {
return this._touches.length;
}
get multiTouchEnabled() {
return this._multiTouchEnabled;
}
set multiTouchEnabled(value) {
this._multiTouchEnabled = value;
}
_getTouch(touchID, type) {
var touch = this._touchPool[touchID];
if ((type == 0 && touch && touch._getIndexInList() != -1))
return null;
if (type == 1 && touch && (touch._getIndexInList() == -1))
return null;
if (!touch) {
touch = new Touch();
this._touchPool[touchID] = touch;
touch._identifier = touchID;
}
return touch;
}
_mouseTouchDown() {
var touch = this._mouseTouch;
var sprite = touch.sprite;
touch._pressedSprite = sprite;
touch._pressedLoopCount = Laya.Stat.loopCount;
if (sprite) {
var scripts = sprite._scripts;
if (scripts) {
for (var i = 0, n = scripts.length; i < n; i++)
scripts[i].onMouseDown();
}
}
}
_mouseTouchUp() {
var i, n;
var touch = this._mouseTouch;
var lastPressedSprite = touch._pressedSprite;
touch._pressedSprite = null;
touch._pressedLoopCount = -1;
var sprite = touch.sprite;
if (sprite) {
if (sprite === lastPressedSprite) {
var scripts = sprite._scripts;
if (scripts) {
for (i = 0, n = scripts.length; i < n; i++)
scripts[i].onMouseClick();
}
}
}
if (lastPressedSprite) {
var lastScripts = lastPressedSprite._scripts;
if (lastScripts) {
for (i = 0, n = lastScripts.length; i < n; i++)
lastScripts[i].onMouseUp();
}
}
}
_mouseTouchRayCast(cameras) {
if (!Physics3D._bullet && !Physics3D._cannon)
return;
var touchHitResult = Input3D._tempHitResult0;
var touchPos = Input3D._tempVector20;
var touchRay = Input3D._tempRay0;
touchHitResult.succeeded = false;
var x = this._mouseTouch.mousePositionX;
var y = this._mouseTouch.mousePositionY;
touchPos.x = x;
touchPos.y = y;
for (var i = cameras.length - 1; i >= 0; i--) {
var camera = cameras[i];
var viewport = camera.viewport;
if (touchPos.x >= viewport.x && touchPos.y >= viewport.y && touchPos.x <= viewport.width && touchPos.y <= viewport.height) {
camera.viewportPointToRay(touchPos, touchRay);
var sucess = this._scene._physicsSimulation.rayCast(touchRay, touchHitResult);
if (sucess || (camera.clearFlag === exports.CameraClearFlags.SolidColor || camera.clearFlag === exports.CameraClearFlags.Sky))
break;
}
}
var touch = this._mouseTouch;
var lastSprite = touch.sprite;
if (touchHitResult.succeeded) {
var touchSprite = touchHitResult.collider.owner;
touch.sprite = touchSprite;
var scripts = touchSprite._scripts;
if (lastSprite !== touchSprite) {
if (scripts) {
for (var j = 0, m = scripts.length; j < m; j++)
scripts[j].onMouseEnter();
}
}
}
else {
touch.sprite = null;
}
if (lastSprite && (lastSprite !== touchSprite)) {
var outScripts = lastSprite._scripts;
if (outScripts) {
for (j = 0, m = outScripts.length; j < m; j++)
outScripts[j].onMouseOut();
}
}
}
_changeTouches(changedTouches, flag) {
var offsetX = 0, offsetY = 0;
var lastCount = this._touches.length;
for (var j = 0, m = changedTouches.length; j < m; j++) {
var nativeTouch = changedTouches[j];
var identifier = nativeTouch.identifier;
if (!this._multiTouchEnabled && this._touches.length !== 0 && flag == 0)
continue;
var touch = this._getTouch(identifier, flag);
if (flag == 1 && !touch)
continue;
var pos = this._touchPool[identifier]._position;
var mousePoint = Input3D._tempPoint;
mousePoint.setTo(nativeTouch.pageX, nativeTouch.pageY);
Laya.ILaya.stage._canvasTransform.invertTransformPoint(mousePoint);
var posX = mousePoint.x;
var posY = mousePoint.y;
switch (flag) {
case 0:
if (!!touch)
this._touches.add(touch);
offsetX += posX;
offsetY += posY;
break;
case 1:
if (!!touch)
this._touches.remove(touch);
offsetX -= posX;
offsetY -= posY;
break;
case 2:
offsetX = posX - pos.x;
offsetY = posY - pos.y;
break;
}
pos.x = posX;
pos.y = posY;
}
var touchCount = this._touches.length;
if (touchCount === 0) {
this._mouseTouch.mousePositionX = 0;
this._mouseTouch.mousePositionY = 0;
}
else {
this._mouseTouch.mousePositionX = (this._mouseTouch.mousePositionX * lastCount + offsetX) / touchCount;
this._mouseTouch.mousePositionY = (this._mouseTouch.mousePositionY * lastCount + offsetY) / touchCount;
}
}
_update() {
var enablePhysics = Physics3D._enablePhysics && !Laya.PhysicsSimulation.disableSimulation;
var i, n, j, m;
n = this._eventList.length;
var cameras = this._scene._cameraPool;
if (n > 0) {
var rayCast = false;
for (i = 0; i < n; i++) {
var e = this._eventList[i];
switch (e.type) {
case "mousedown":
(enablePhysics) && (this._mouseTouchDown());
break;
case "mouseup":
(enablePhysics) && (this._mouseTouchUp());
break;
case "mousemove":
var mousePoint = Input3D._tempPoint;
mousePoint.setTo(e.pageX, e.pageY);
Laya.ILaya.stage._canvasTransform.invertTransformPoint(mousePoint);
this._mouseTouch.mousePositionX = mousePoint.x;
this._mouseTouch.mousePositionY = mousePoint.y;
(enablePhysics) && (rayCast = true);
break;
case "touchstart":
var lastLength = this._touches.length;
this._changeTouches(e.changedTouches, 0);
if (enablePhysics) {
(!Config3D._config.isUseCannonPhysicsEngine) && (this._mouseTouchRayCast(cameras));
(lastLength === 0) && (this._mouseTouchDown());
}
break;
case "touchend":
case "touchcancel":
this._changeTouches(e.changedTouches, 1);
(enablePhysics && this._touches.length === 0) && (this._mouseTouchUp());
break;
case "touchmove":
this._changeTouches(e.changedTouches, 2);
(enablePhysics) && (rayCast = true);
break;
default:
throw "Input3D:unkonwn event type.";
}
}
(rayCast) && (!Config3D._config.isUseCannonPhysicsEngine) && (this._mouseTouchRayCast(cameras));
this._eventList.length = 0;
}
if (enablePhysics) {
var mouseTouch = this._mouseTouch;
var pressedSprite = mouseTouch._pressedSprite;
if (pressedSprite && (Laya.Stat.loopCount > mouseTouch._pressedLoopCount)) {
var pressedScripts = pressedSprite._scripts;
if (pressedScripts) {
for (j = 0, m = pressedScripts.length; j < m; j++)
pressedScripts[j].onMouseDrag();
}
}
var touchSprite = mouseTouch.sprite;
if (touchSprite) {
var scripts = touchSprite._scripts;
if (scripts) {
for (j = 0, m = scripts.length; j < m; j++)
scripts[j].onMouseOver();
}
}
}
}
getTouch(index) {
if (index < this._touches.length) {
return this._touches.elements[index];
}
else {
return null;
}
}
}
Input3D._tempPoint = new Laya.Point();
Input3D._tempVector20 = new Vector2();
Input3D._tempRay0 = new Ray(new Vector3(), new Vector3());
class VertexPositionTexture0 {
constructor(position, textureCoordinate0) {
this._position = position;
this._textureCoordinate0 = textureCoordinate0;
}
static get vertexDeclaration() {
return VertexPositionTexture0._vertexDeclaration;
}
static __init__() {
VertexPositionTexture0._vertexDeclaration = new VertexDeclaration(20, [new VertexElement(0, VertexElementFormat.Vector3, VertexMesh.MESH_POSITION0),
new VertexElement(12, VertexElementFormat.Vector2, VertexMesh.MESH_TEXTURECOORDINATE0)]);
}
get position() {
return this._position;
}
get textureCoordinate0() {
return this._textureCoordinate0;
}
get vertexDeclaration() {
return VertexPositionTexture0._vertexDeclaration;
}
}
class SkyDome extends SkyMesh {
constructor(stacks = 48, slices = 48) {
super();
var gl = Laya.LayaGL.instance;
this._stacks = stacks;
this._slices = slices;
var vertexDeclaration = VertexPositionTexture0.vertexDeclaration;
var vertexFloatCount = vertexDeclaration.vertexStride / 4;
var numberVertices = (this._stacks + 1) * (this._slices + 1);
var numberIndices = (3 * this._stacks * (this._slices + 1)) * 2;
var vertices = new Float32Array(numberVertices * vertexFloatCount);
var indices = new Uint16Array(numberIndices);
var stackAngle = Math.PI / this._stacks;
var sliceAngle = (Math.PI * 2.0) / this._slices;
var vertexIndex = 0;
var vertexCount = 0;
var indexCount = 0;
for (var stack = 0; stack < (this._stacks + 1); stack++) {
var r = Math.sin(stack * stackAngle);
var y = Math.cos(stack * stackAngle);
for (var slice = 0; slice < (this._slices + 1); slice++) {
var x = r * Math.sin(slice * sliceAngle);
var z = r * Math.cos(slice * sliceAngle);
vertices[vertexCount + 0] = x * SkyDome._radius;
vertices[vertexCount + 1] = y * SkyDome._radius;
vertices[vertexCount + 2] = z * SkyDome._radius;
vertices[vertexCount + 3] = -(slice / this._slices) + 0.75;
vertices[vertexCount + 4] = stack / this._stacks;
vertexCount += vertexFloatCount;
if (stack != (this._stacks - 1)) {
indices[indexCount++] = vertexIndex + 1;
indices[indexCount++] = vertexIndex;
indices[indexCount++] = vertexIndex + (this._slices + 1);
indices[indexCount++] = vertexIndex + (this._slices + 1);
indices[indexCount++] = vertexIndex;
indices[indexCount++] = vertexIndex + (this._slices);
vertexIndex++;
}
}
}
this._vertexBuffer = new VertexBuffer3D(vertices.length * 4, gl.STATIC_DRAW, false);
this._vertexBuffer.vertexDeclaration = vertexDeclaration;
this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, indices.length, gl.STATIC_DRAW, false);
this._vertexBuffer.setData(vertices.buffer);
this._indexBuffer.setData(indices);
var bufferState = new BufferState();
bufferState.bind();
bufferState.applyVertexBuffer(this._vertexBuffer);
bufferState.applyIndexBuffer(this._indexBuffer);
bufferState.unBind();
this._bufferState = bufferState;
}
static __init__() {
SkyDome.instance = new SkyDome();
}
get stacks() {
return this._stacks;
}
get slices() {
return this._slices;
}
_render(state) {
var gl = Laya.LayaGL.instance;
var indexCount = this._indexBuffer.indexCount;
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0);
Laya.Stat.trianglesFaces += indexCount / 3;
Laya.Stat.renderBatches++;
}
}
SkyDome._radius = 1;
(function (TextureCubeFace) {
TextureCubeFace[TextureCubeFace["PositiveX"] = 0] = "PositiveX";
TextureCubeFace[TextureCubeFace["NegativeX"] = 1] = "NegativeX";
TextureCubeFace[TextureCubeFace["PositiveY"] = 2] = "PositiveY";
TextureCubeFace[TextureCubeFace["NegativeY"] = 3] = "NegativeY";
TextureCubeFace[TextureCubeFace["PositiveZ"] = 4] = "PositiveZ";
TextureCubeFace[TextureCubeFace["NegativeZ"] = 5] = "NegativeZ";
})(exports.TextureCubeFace || (exports.TextureCubeFace = {}));
class TextureCube extends Laya.BaseTexture {
constructor(size, format = Laya.TextureFormat.R8G8B8, mipmap = false) {
super(format, mipmap);
this._glTextureType = Laya.LayaGL.instance.TEXTURE_CUBE_MAP;
this._width = size;
this._height = size;
var gl = Laya.LayaGL.instance;
this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU);
this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV);
this._setFilterMode(this._filterMode);
this._setAnisotropy(this._anisoLevel);
if (this._mipmap) {
this._mipmapCount = Math.ceil(Math.log2(size)) + 1;
for (var i = 0; i < this._mipmapCount; i++)
this._setPixels([], i, Math.max(size >> i, 1), Math.max(size >> i, 1));
this._setGPUMemory(size * size * 4 * (1 + 1 / 3) * 6);
}
else {
this._mipmapCount = 1;
this._setGPUMemory(size * size * 4 * 6);
}
}
static get blackTexture() {
return TextureCube._blackTexture;
}
static get grayTexture() {
return TextureCube._grayTexture;
}
static __init__() {
var blackTexture = new TextureCube(1, Laya.TextureFormat.R8G8B8, false);
var grayTexture = new TextureCube(1, Laya.TextureFormat.R8G8B8, false);
var pixels = new Uint8Array(3);
pixels[0] = 0, pixels[1] = 0, pixels[2] = 0;
blackTexture.setSixSidePixels([pixels, pixels, pixels, pixels, pixels, pixels]);
blackTexture.lock = true;
pixels[0] = 128, pixels[1] = 128, pixels[2] = 128;
grayTexture.setSixSidePixels([pixels, pixels, pixels, pixels, pixels, pixels]);
grayTexture.lock = true;
TextureCube._grayTexture = grayTexture;
TextureCube._blackTexture = blackTexture;
}
static _parse(data, propertyParams = null, constructParams = null) {
var texture = constructParams ? new TextureCube(0, constructParams[0], constructParams[1]) : new TextureCube(0);
texture.setSixSideImageSources(data);
return texture;
}
static _parseBin(data, propertyParams = null, constructParams = null) {
var texture = constructParams ? new TextureCube(0, constructParams[0], constructParams[1]) : new TextureCube(0);
texture.setSixSideImageSources(data);
return texture;
}
static load(url, complete) {
var extension = (Laya.LoaderManager.createMap[Laya.Utils.getFilecompatibleExtension(url)]) ? Laya.Utils.getFilecompatibleExtension(url) : Laya.Utils.getFileExtension(url);
var type = Laya.LoaderManager.createMap[extension] ? Laya.LoaderManager.createMap[extension][0] : null;
Laya.ILaya.loader.create(url, complete, null, type);
}
get defaulteTexture() {
return TextureCube.grayTexture;
}
_setPixels(pixels, miplevel, width, height) {
var gl = Laya.LayaGL.instance;
var glFormat = this._getGLFormat();
Laya.WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture);
if (this.format === Laya.TextureFormat.R8G8B8) {
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[0]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[1]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[2]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[3]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[4]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[5]);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
}
else {
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[0]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[1]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[2]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[3]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[4]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[5]);
}
}
setSixSideImageSources(source, premultiplyAlpha = false) {
var width;
var height;
for (var i = 0; i < 6; i++) {
var img = source[i];
if (!img) {
console.log("TextureCube: image Source can't be null.");
return;
}
var nextWidth = img.width;
var nextHeight = img.height;
if (i > 0) {
if (width !== nextWidth) {
console.log("TextureCube: each side image's width and height must same.");
return;
}
}
width = nextWidth;
height = nextHeight;
if (width !== height) {
console.log("TextureCube: each side image's width and height must same.");
return;
}
}
this._width = width;
this._height = height;
var gl = Laya.LayaGL.instance;
Laya.WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture);
var glFormat = this._getGLFormat();
if (!Laya.Render.isConchApp) {
(premultiplyAlpha) && (gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true));
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[0]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[1]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[2]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[3]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[4]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[5]);
(premultiplyAlpha) && (gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false));
}
else {
if (premultiplyAlpha == true) {
for (var j = 0; j < 6; j++)
source[j].setPremultiplyAlpha(premultiplyAlpha);
}
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[0]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[1]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[2]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[3]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[4]);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[5]);
}
if (this._mipmap && this._isPot(width) && this._isPot(height)) {
gl.generateMipmap(this._glTextureType);
this._setGPUMemory(width * height * 4 * (1 + 1 / 3) * 6);
}
else {
this._setGPUMemory(width * height * 4 * 6);
}
this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU);
this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV);
this._setFilterMode(this._filterMode);
this._readyed = true;
this._activeResource();
}
setSixSidePixels(pixels, miplevel = 0) {
if (!pixels)
throw new Error("TextureCube:pixels can't be null.");
var width = Math.max(this._width >> miplevel, 1);
var height = Math.max(this._height >> miplevel, 1);
var pixelsCount = width * height * this._getFormatByteCount();
if (pixels[0].length < pixelsCount)
throw "TextureCube:pixels length should at least " + pixelsCount + ".";
this._setPixels(pixels, miplevel, width, height);
if (miplevel === 0) {
var gl = Laya.LayaGL.instance;
this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU);
this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV);
}
this._readyed = true;
this._activeResource();
}
setImageSource(face, imageSource, miplevel = 0) {
var width = this._width;
var height = this._height;
if (imageSource) {
if (width !== imageSource.width || height !== imageSource.height) {
console.log("TextureCube: imageSource's width and height must same.");
return;
}
}
var gl = Laya.LayaGL.instance;
Laya.WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture);
var glFormat = this._getGLFormat();
switch (face) {
case exports.TextureCubeFace.NegativeX:
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource);
break;
case exports.TextureCubeFace.PositiveX:
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource);
break;
case exports.TextureCubeFace.NegativeY:
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource);
break;
case exports.TextureCubeFace.PositiveY:
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource);
break;
case exports.TextureCubeFace.NegativeZ:
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource);
break;
case exports.TextureCubeFace.PositiveZ:
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource);
break;
}
if (this._mipmap && this._isPot(width) && this._isPot(height)) {
gl.generateMipmap(this._glTextureType);
this._setGPUMemory(width * height * 4 * (1 + 1 / 3) * 6);
}
else {
this._setGPUMemory(width * height * 4 * 6);
}
this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU);
this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV);
this._setFilterMode(this._filterMode);
this._readyed = true;
}
}
TextureCube.TEXTURECUBE = "TEXTURECUBE";
TextureCube.TEXTURECUBEBIN = "TEXTURECUBEBIN";
class LightQueue {
constructor() {
this._length = 0;
this._elements = [];
}
add(light) {
if (this._length === this._elements.length)
this._elements.push(light);
else
this._elements[this._length] = light;
this._length++;
}
remove(light) {
var index = this._elements.indexOf(light);
this._length--;
if (index !== this._length) {
var end = this._elements[this._length];
this._elements[index] = end;
}
}
shift() {
this._length--;
return this._elements.shift();
}
getBrightestLight() {
var maxIntIndex;
var maxIntensity = -1;
var elements = this._elements;
for (var i = 0; i < this._length; i++) {
var intensity = elements[i]._intensity;
if (maxIntensity < intensity) {
maxIntensity = intensity;
maxIntIndex = i;
}
}
return maxIntIndex;
}
normalLightOrdering(brightestIndex) {
var firstLight = this._elements[0];
this._elements[0] = this._elements[brightestIndex];
this._elements[brightestIndex] = firstLight;
}
}
class AlternateLightQueue extends LightQueue {
remove(light) {
var index = this._elements.indexOf(light);
this._elements.splice(index, 1);
this._length--;
}
}
class PixelLineMaterial extends Material {
constructor() {
super();
this.setShaderName("LineShader");
this._shaderValues.setVector(PixelLineMaterial.COLOR, new Vector4(1.0, 1.0, 1.0, 1.0));
}
static __initDefine__() {
}
get color() {
return this._shaderValues.getVector(PixelLineMaterial.COLOR);
}
set color(value) {
this._shaderValues.setVector(PixelLineMaterial.COLOR, value);
}
clone() {
var dest = new PixelLineMaterial();
this.cloneTo(dest);
return dest;
}
}
PixelLineMaterial.COLOR = Shader3D.propertyNameToID("u_Color");
class BoundBox {
constructor(min, max) {
this.min = min;
this.max = max;
}
_rotateExtents(extents, rotation, out) {
var extentsX = extents.x;
var extentsY = extents.y;
var extentsZ = extents.z;
var matElements = rotation.elements;
out.x = Math.abs(matElements[0] * extentsX) + Math.abs(matElements[4] * extentsY) + Math.abs(matElements[8] * extentsZ);
out.y = Math.abs(matElements[1] * extentsX) + Math.abs(matElements[5] * extentsY) + Math.abs(matElements[9] * extentsZ);
out.z = Math.abs(matElements[2] * extentsX) + Math.abs(matElements[6] * extentsY) + Math.abs(matElements[10] * extentsZ);
}
getCorners(corners) {
corners.length = 8;
var minX = this.min.x;
var minY = this.min.y;
var minZ = this.min.z;
var maxX = this.max.x;
var maxY = this.max.y;
var maxZ = this.max.z;
corners[0] = new Vector3(minX, maxY, maxZ);
corners[1] = new Vector3(maxX, maxY, maxZ);
corners[2] = new Vector3(maxX, minY, maxZ);
corners[3] = new Vector3(minX, minY, maxZ);
corners[4] = new Vector3(minX, maxY, minZ);
corners[5] = new Vector3(maxX, maxY, minZ);
corners[6] = new Vector3(maxX, minY, minZ);
corners[7] = new Vector3(minX, minY, minZ);
}
getCenter(out) {
Vector3.add(this.min, this.max, out);
Vector3.scale(out, 0.5, out);
}
getExtent(out) {
Vector3.subtract(this.max, this.min, out);
Vector3.scale(out, 0.5, out);
}
setCenterAndExtent(center, extent) {
Vector3.subtract(center, extent, this.min);
Vector3.add(center, extent, this.max);
}
tranform(matrix, out) {
var center = BoundBox._tempVector30;
var extent = BoundBox._tempVector31;
this.getCenter(center);
this.getExtent(extent);
Vector3.transformCoordinate(center, matrix, center);
this._rotateExtents(extent, matrix, extent);
out.setCenterAndExtent(center, extent);
}
toDefault() {
this.min.toDefault();
this.max.toDefault();
}
static createfromPoints(points, out) {
if (points == null)
throw new Error("points");
var min = out.min;
var max = out.max;
min.x = Number.MAX_VALUE;
min.y = Number.MAX_VALUE;
min.z = Number.MAX_VALUE;
max.x = -Number.MAX_VALUE;
max.y = -Number.MAX_VALUE;
max.z = -Number.MAX_VALUE;
for (var i = 0, n = points.length; i < n; ++i) {
Vector3.min(min, points[i], min);
Vector3.max(max, points[i], max);
}
}
static merge(box1, box2, out) {
Vector3.min(box1.min, box2.min, out.min);
Vector3.max(box1.max, box2.max, out.max);
}
cloneTo(destObject) {
var dest = destObject;
this.min.cloneTo(dest.min);
this.max.cloneTo(dest.max);
}
clone() {
var dest = new BoundBox(new Vector3(), new Vector3());
this.cloneTo(dest);
return dest;
}
}
BoundBox._tempVector30 = new Vector3();
BoundBox._tempVector31 = new Vector3();
class Bounds {
constructor(min, max) {
this._updateFlag = 0;
this._center = new Vector3();
this._extent = new Vector3();
this._boundBox = new BoundBox(new Vector3(), new Vector3());
min.cloneTo(this._boundBox.min);
max.cloneTo(this._boundBox.max);
this._setUpdateFlag(Bounds._UPDATE_CENTER | Bounds._UPDATE_EXTENT, true);
}
setMin(value) {
var min = this._boundBox.min;
if (value !== min)
value.cloneTo(min);
this._setUpdateFlag(Bounds._UPDATE_CENTER | Bounds._UPDATE_EXTENT, true);
this._setUpdateFlag(Bounds._UPDATE_MIN, false);
}
getMin() {
var min = this._boundBox.min;
if (this._getUpdateFlag(Bounds._UPDATE_MIN)) {
this._getMin(this.getCenter(), this.getExtent(), min);
this._setUpdateFlag(Bounds._UPDATE_MIN, false);
}
return min;
}
setMax(value) {
var max = this._boundBox.max;
if (value !== max)
value.cloneTo(max);
this._setUpdateFlag(Bounds._UPDATE_CENTER | Bounds._UPDATE_EXTENT, true);
this._setUpdateFlag(Bounds._UPDATE_MAX, false);
}
getMax() {
var max = this._boundBox.max;
if (this._getUpdateFlag(Bounds._UPDATE_MAX)) {
this._getMax(this.getCenter(), this.getExtent(), max);
this._setUpdateFlag(Bounds._UPDATE_MAX, false);
}
return max;
}
setCenter(value) {
if (value !== this._center)
value.cloneTo(this._center);
this._setUpdateFlag(Bounds._UPDATE_MIN | Bounds._UPDATE_MAX, true);
this._setUpdateFlag(Bounds._UPDATE_CENTER, false);
}
getCenter() {
if (this._getUpdateFlag(Bounds._UPDATE_CENTER)) {
this._getCenter(this.getMin(), this.getMax(), this._center);
this._setUpdateFlag(Bounds._UPDATE_CENTER, false);
}
return this._center;
}
setExtent(value) {
if (value !== this._extent)
value.cloneTo(this._extent);
this._setUpdateFlag(Bounds._UPDATE_MIN | Bounds._UPDATE_MAX, true);
this._setUpdateFlag(Bounds._UPDATE_EXTENT, false);
}
getExtent() {
if (this._getUpdateFlag(Bounds._UPDATE_EXTENT)) {
this._getExtent(this.getMin(), this.getMax(), this._extent);
this._setUpdateFlag(Bounds._UPDATE_EXTENT, false);
}
return this._extent;
}
_getUpdateFlag(type) {
return (this._updateFlag & type) != 0;
}
_setUpdateFlag(type, value) {
if (value)
this._updateFlag |= type;
else
this._updateFlag &= ~type;
}
_getCenter(min, max, out) {
Vector3.add(min, max, out);
Vector3.scale(out, 0.5, out);
}
_getExtent(min, max, out) {
Vector3.subtract(max, min, out);
Vector3.scale(out, 0.5, out);
}
_getMin(center, extent, out) {
Vector3.subtract(center, extent, out);
}
_getMax(center, extent, out) {
Vector3.add(center, extent, out);
}
_rotateExtents(extents, rotation, out) {
var extentsX = extents.x;
var extentsY = extents.y;
var extentsZ = extents.z;
var matE = rotation.elements;
out.x = Math.abs(matE[0] * extentsX) + Math.abs(matE[4] * extentsY) + Math.abs(matE[8] * extentsZ);
out.y = Math.abs(matE[1] * extentsX) + Math.abs(matE[5] * extentsY) + Math.abs(matE[9] * extentsZ);
out.z = Math.abs(matE[2] * extentsX) + Math.abs(matE[6] * extentsY) + Math.abs(matE[10] * extentsZ);
}
_tranform(matrix, out) {
var outCen = out._center;
var outExt = out._extent;
Vector3.transformCoordinate(this.getCenter(), matrix, outCen);
this._rotateExtents(this.getExtent(), matrix, outExt);
out._boundBox.setCenterAndExtent(outCen, outExt);
out._updateFlag = 0;
}
_getBoundBox() {
if (this._updateFlag & Bounds._UPDATE_MIN) {
var min = this._boundBox.min;
this._getMin(this.getCenter(), this.getExtent(), min);
this._setUpdateFlag(Bounds._UPDATE_MIN, false);
}
if (this._updateFlag & Bounds._UPDATE_MAX) {
var max = this._boundBox.max;
this._getMax(this.getCenter(), this.getExtent(), max);
this._setUpdateFlag(Bounds._UPDATE_MAX, false);
}
return this._boundBox;
}
calculateBoundsintersection(bounds) {
var ownMax = this.getMax();
var ownMin = this.getMin();
var calMax = bounds.getMax();
var calMin = bounds.getMin();
var tempV0 = Bounds.TEMP_VECTOR3_MAX0;
var tempV1 = Bounds.TEMP_VECTOR3_MAX1;
var thisExtends = this.getExtent();
var boundExtends = bounds.getExtent();
tempV0.setValue(Math.max(ownMax.x, calMax.x) - Math.min(ownMin.x, calMin.x), Math.max(ownMax.y, calMax.y) - Math.min(ownMin.y, calMin.y), Math.max(ownMax.z, calMax.z) - Math.min(ownMin.z, calMin.z));
tempV1.setValue((thisExtends.x + boundExtends.x) * 2.0, (thisExtends.y + boundExtends.y) * 2.0, (thisExtends.z + boundExtends.z) * 2.0);
if ((tempV0.x) > (tempV1.x))
return -1;
if ((tempV0.y) > (tempV1.y))
return -1;
if ((tempV0.z) > (tempV1.z))
return -1;
return (tempV1.x - tempV0.x) * (tempV1.y - tempV0.y) * (tempV1.z - tempV0.z);
}
cloneTo(destObject) {
var destBounds = destObject;
this.getMin().cloneTo(destBounds._boundBox.min);
this.getMax().cloneTo(destBounds._boundBox.max);
this.getCenter().cloneTo(destBounds._center);
this.getExtent().cloneTo(destBounds._extent);
destBounds._updateFlag = 0;
}
clone() {
var dest = new Bounds(new Vector3(), new Vector3());
this.cloneTo(dest);
return dest;
}
}
Bounds._UPDATE_MIN = 0x01;
Bounds._UPDATE_MAX = 0x02;
Bounds._UPDATE_CENTER = 0x04;
Bounds._UPDATE_EXTENT = 0x08;
Bounds.TEMP_VECTOR3_MAX0 = new Vector3();
Bounds.TEMP_VECTOR3_MAX1 = new Vector3();
class GeometryElement {
constructor() {
this._destroyed = false;
}
get destroyed() {
return this._destroyed;
}
_getType() {
throw "GeometryElement:must override it.";
}
_prepareRender(state) {
return true;
}
_render(state) {
throw "GeometryElement:must override it.";
}
destroy() {
if (this._destroyed)
return;
this._destroyed = true;
}
}
GeometryElement._typeCounter = 0;
class PixelLineVertex {
constructor() {
}
static get vertexDeclaration() {
return PixelLineVertex._vertexDeclaration;
}
static __init__() {
PixelLineVertex._vertexDeclaration = new VertexDeclaration(28, [new VertexElement(0, VertexElementFormat.Vector3, VertexMesh.MESH_POSITION0),
new VertexElement(12, VertexElementFormat.Vector4, VertexMesh.MESH_COLOR0)]);
}
get vertexDeclaration() {
return PixelLineVertex._vertexDeclaration;
}
}
class PixelLineFilter extends GeometryElement {
constructor(owner, maxLineCount) {
super();
this._floatCountPerVertices = 7;
this._minUpdate = Number.MAX_VALUE;
this._maxUpdate = Number.MIN_VALUE;
this._bufferState = new BufferState();
this._floatBound = new Float32Array(6);
this._calculateBound = false;
this._maxLineCount = 0;
this._lineCount = 0;
var pointCount = maxLineCount * 2;
this._owner = owner;
this._maxLineCount = maxLineCount;
this._vertices = new Float32Array(pointCount * this._floatCountPerVertices);
this._vertexBuffer = new VertexBuffer3D(PixelLineVertex.vertexDeclaration.vertexStride * pointCount, Laya.LayaGL.instance.STATIC_DRAW, false);
this._vertexBuffer.vertexDeclaration = PixelLineVertex.vertexDeclaration;
this._bufferState.bind();
this._bufferState.applyVertexBuffer(this._vertexBuffer);
this._bufferState.unBind();
var min = PixelLineFilter._tempVector0;
var max = PixelLineFilter._tempVector1;
min.setValue(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
max.setValue(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
this._bounds = new Bounds(min, max);
}
_getType() {
return PixelLineFilter._type;
}
_resizeLineData(maxCount) {
var pointCount = maxCount * 2;
var lastVertices = this._vertices;
this._vertexBuffer.destroy();
this._maxLineCount = maxCount;
var vertexCount = pointCount * this._floatCountPerVertices;
this._vertices = new Float32Array(vertexCount);
this._vertexBuffer = new VertexBuffer3D(PixelLineVertex.vertexDeclaration.vertexStride * pointCount, Laya.LayaGL.instance.STATIC_DRAW, false);
this._vertexBuffer.vertexDeclaration = PixelLineVertex.vertexDeclaration;
if (vertexCount < lastVertices.length) {
this._vertices.set(new Float32Array(lastVertices.buffer, 0, vertexCount));
this._vertexBuffer.setData(this._vertices.buffer, 0, 0, vertexCount * 4);
}
else {
this._vertices.set(lastVertices);
this._vertexBuffer.setData(this._vertices.buffer, 0, 0, lastVertices.length * 4);
}
this._bufferState.bind();
this._bufferState.applyVertexBuffer(this._vertexBuffer);
this._bufferState.unBind();
this._minUpdate = Number.MAX_VALUE;
this._maxUpdate = Number.MIN_VALUE;
}
_updateLineVertices(offset, startPosition, endPosition, startColor, endColor) {
if (startPosition) {
this._vertices[offset + 0] = startPosition.x;
this._vertices[offset + 1] = startPosition.y;
this._vertices[offset + 2] = startPosition.z;
}
if (startColor) {
this._vertices[offset + 3] = startColor.r;
this._vertices[offset + 4] = startColor.g;
this._vertices[offset + 5] = startColor.b;
this._vertices[offset + 6] = startColor.a;
}
if (endPosition) {
this._vertices[offset + 7] = endPosition.x;
this._vertices[offset + 8] = endPosition.y;
this._vertices[offset + 9] = endPosition.z;
}
if (endColor) {
this._vertices[offset + 10] = endColor.r;
this._vertices[offset + 11] = endColor.g;
this._vertices[offset + 12] = endColor.b;
this._vertices[offset + 13] = endColor.a;
}
this._minUpdate = Math.min(this._minUpdate, offset);
this._maxUpdate = Math.max(this._maxUpdate, offset + this._floatCountPerVertices * 2);
var bounds = this._bounds;
var floatBound = this._floatBound;
var min = bounds.getMin(), max = bounds.getMax();
Vector3.min(min, startPosition, min);
Vector3.min(min, endPosition, min);
Vector3.max(max, startPosition, max);
Vector3.max(max, endPosition, max);
bounds.setMin(min);
bounds.setMax(max);
floatBound[0] = min.x, floatBound[1] = min.y, floatBound[2] = min.z;
floatBound[3] = max.x, floatBound[4] = max.y, floatBound[5] = max.z;
}
_reCalculateBound() {
if (this._calculateBound) {
var vertices = this._vertices;
var min = PixelLineFilter._tempVector0;
var max = PixelLineFilter._tempVector1;
min.setValue(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
max.setValue(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
for (var i = 0; i < this._lineCount * 2; ++i) {
var offset = this._floatCountPerVertices * i;
var x = vertices[offset + 0], y = vertices[offset + 1], z = vertices[offset + 2];
min.x = Math.min(x, min.x);
min.y = Math.min(y, min.y);
min.z = Math.min(z, min.z);
max.x = Math.max(x, max.x);
max.y = Math.max(y, max.y);
max.z = Math.max(z, max.z);
}
this._bounds.setMin(min);
this._bounds.setMax(max);
var floatBound = this._floatBound;
floatBound[0] = min.x, floatBound[1] = min.y, floatBound[2] = min.z;
floatBound[3] = max.x, floatBound[4] = max.y, floatBound[5] = max.z;
this._calculateBound = false;
}
}
_removeLineData(index) {
var floatCount = this._floatCountPerVertices * 2;
var nextIndex = index + 1;
var offset = index * floatCount;
var vertices = this._vertices;
var rightPartVertices = new Float32Array(vertices.buffer, nextIndex * floatCount * 4, (this._lineCount - nextIndex) * floatCount);
vertices.set(rightPartVertices, offset);
this._minUpdate = Math.min(this._minUpdate, offset);
this._maxUpdate = Math.max(this._maxUpdate, offset + rightPartVertices.length);
this._lineCount--;
var floatBound = this._floatBound;
var startX = vertices[offset], startY = vertices[offset + 1], startZ = vertices[offset + 2];
var endX = vertices[offset + 7], endY = vertices[offset + 8], endZ = vertices[offset + 9];
var minX = floatBound[0], minY = floatBound[1], minZ = floatBound[2];
var maxX = floatBound[3], maxY = floatBound[4], maxZ = floatBound[5];
if ((startX === minX) || (startX === maxX) || (startY === minY) || (startY === maxY) || (startZ === minZ) || (startZ === maxZ) ||
(endX === minX) || (endX === maxX) || (endY === minY) || (endY === maxY) || (endZ === minZ) || (endZ === maxZ))
this._calculateBound = true;
}
_updateLineData(index, startPosition, endPosition, startColor, endColor) {
var floatCount = this._floatCountPerVertices * 2;
this._updateLineVertices(index * floatCount, startPosition, endPosition, startColor, endColor);
}
_updateLineDatas(index, data) {
var floatCount = this._floatCountPerVertices * 2;
var count = data.length;
for (var i = 0; i < count; i++) {
var line = data[i];
this._updateLineVertices((index + i) * floatCount, line.startPosition, line.endPosition, line.startColor, line.endColor);
}
}
_getLineData(index, out) {
var startPosition = out.startPosition;
var startColor = out.startColor;
var endPosition = out.endPosition;
var endColor = out.endColor;
var vertices = this._vertices;
var offset = index * this._floatCountPerVertices * 2;
startPosition.x = vertices[offset + 0];
startPosition.y = vertices[offset + 1];
startPosition.z = vertices[offset + 2];
startColor.r = vertices[offset + 3];
startColor.g = vertices[offset + 4];
startColor.b = vertices[offset + 5];
startColor.a = vertices[offset + 6];
endPosition.x = vertices[offset + 7];
endPosition.y = vertices[offset + 8];
endPosition.z = vertices[offset + 9];
endColor.r = vertices[offset + 10];
endColor.g = vertices[offset + 11];
endColor.b = vertices[offset + 12];
endColor.a = vertices[offset + 13];
}
_prepareRender(state) {
return true;
}
_render(state) {
if (this._minUpdate !== Number.MAX_VALUE && this._maxUpdate !== Number.MIN_VALUE) {
this._vertexBuffer.setData(this._vertices.buffer, this._minUpdate * 4, this._minUpdate * 4, (this._maxUpdate - this._minUpdate) * 4);
this._minUpdate = Number.MAX_VALUE;
this._maxUpdate = Number.MIN_VALUE;
}
if (this._lineCount > 0) {
this._bufferState.bind();
var gl = Laya.LayaGL.instance;
gl.drawArrays(gl.LINES, 0, this._lineCount * 2);
Laya.Stat.renderBatches++;
}
}
destroy() {
if (this._destroyed)
return;
super.destroy();
this._bufferState.destroy();
this._vertexBuffer.destroy();
this._bufferState = null;
this._vertexBuffer = null;
this._vertices = null;
}
}
PixelLineFilter._tempVector0 = new Vector3();
PixelLineFilter._tempVector1 = new Vector3();
PixelLineFilter._type = GeometryElement._typeCounter++;
class RenderableSprite3D extends Sprite3D {
constructor(name) {
super(name);
}
static __init__() {
RenderableSprite3D.SHADERDEFINE_RECEIVE_SHADOW = Shader3D.getDefineByName("RECEIVESHADOW");
RenderableSprite3D.SAHDERDEFINE_LIGHTMAP = Shader3D.getDefineByName("LIGHTMAP");
RenderableSprite3D.SHADERDEFINE_LIGHTMAP_DIRECTIONAL = Shader3D.getDefineByName("LIGHTMAP_DIRECTIONAL");
}
_onInActive() {
super._onInActive();
this._scene._removeRenderObject(this._render);
}
_onActive() {
super._onActive();
this._scene._addRenderObject(this._render);
}
_onActiveInScene() {
super._onActiveInScene();
if (ILaya3D.Laya3D._editerEnvironment) {
var scene = this._scene;
var pickColor = new Vector4();
scene._allotPickColorByID(this.id, pickColor);
scene._pickIdToSprite[this.id] = this;
this._render._shaderValues.setVector(RenderableSprite3D.PICKCOLOR, pickColor);
}
}
_addToInitStaticBatchManager() {
}
_setBelongScene(scene) {
super._setBelongScene(scene);
this._render._setBelongScene(scene);
}
_setUnBelongScene() {
if (!this.destroyed) {
this._render._shaderValues.removeDefine(RenderableSprite3D.SAHDERDEFINE_LIGHTMAP);
this._render._setUnBelongScene();
super._setUnBelongScene();
}
}
_changeHierarchyAnimator(animator) {
if (this._hierarchyAnimator) {
var renderableSprites = this._hierarchyAnimator._renderableSprites;
renderableSprites.splice(renderableSprites.indexOf(this), 1);
}
if (animator)
animator._renderableSprites.push(this);
super._changeHierarchyAnimator(animator);
}
destroy(destroyChild = true) {
super.destroy(destroyChild);
this._render._destroy();
this._render = null;
}
_create() {
return new RenderableSprite3D(this.name);
}
}
RenderableSprite3D.LIGHTMAPSCALEOFFSET = Shader3D.propertyNameToID("u_LightmapScaleOffset");
RenderableSprite3D.LIGHTMAP = Shader3D.propertyNameToID("u_LightMap");
RenderableSprite3D.LIGHTMAP_DIRECTION = Shader3D.propertyNameToID("u_LightMapDirection");
RenderableSprite3D.PICKCOLOR = Shader3D.propertyNameToID("u_PickColor");
RenderableSprite3D.REFLECTIONTEXTURE = Shader3D.propertyNameToID("u_ReflectTexture");
RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS = Shader3D.propertyNameToID("u_ReflectCubeHDRParams");
RenderableSprite3D.REFLECTIONCUBE_PROBEPOSITION = Shader3D.propertyNameToID("u_SpecCubeProbePosition");
RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMAX = Shader3D.propertyNameToID("u_SpecCubeBoxMax");
RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMIN = Shader3D.propertyNameToID("u_SpecCubeBoxMin");
class BatchMark {
constructor() {
this.updateMark = -1;
this.indexInList = -1;
this.batched = false;
}
}
class SubMeshInstanceBatch extends GeometryElement {
constructor() {
super();
this.instanceWorldMatrixData = new Float32Array(SubMeshInstanceBatch.maxInstanceCount * 16);
this.instanceSimpleAnimatorData = new Float32Array(SubMeshInstanceBatch.maxInstanceCount * 4);
var gl = Laya.LayaGL.instance;
this.instanceWorldMatrixBuffer = new VertexBuffer3D(this.instanceWorldMatrixData.length * 4, gl.DYNAMIC_DRAW);
this.instanceWorldMatrixBuffer.vertexDeclaration = VertexMesh.instanceWorldMatrixDeclaration;
this.instanceSimpleAnimatorBuffer = new VertexBuffer3D(this.instanceSimpleAnimatorData.length * 4, gl.DYNAMIC_DRAW);
this.instanceSimpleAnimatorBuffer.vertexDeclaration = VertexMesh.instanceSimpleAnimatorDeclaration;
}
static __init__() {
SubMeshInstanceBatch.instance = new SubMeshInstanceBatch();
}
_render(state) {
var gl = Laya.LayaGL.instance;
var element = state.renderElement;
var subMesh = element.instanceSubMesh;
var count = element.instanceBatchElementList.length;
var indexCount = subMesh._indexCount;
subMesh._mesh._instanceBufferState.bind();
Laya.LayaGL.layaGPUInstance.drawElementsInstanced(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, subMesh._indexStart * 2, count);
Laya.Stat.renderBatches++;
Laya.Stat.savedRenderBatches += count - 1;
Laya.Stat.trianglesFaces += indexCount * count / 3;
}
}
SubMeshInstanceBatch.maxInstanceCount = 1024;
class RenderElement {
constructor() {
this.renderSubShader = null;
this.renderType = RenderElement.RENDERTYPE_NORMAL;
}
getInvertFront() {
return this._transform._isFrontFaceInvert;
}
setTransform(transform) {
this._transform = transform;
}
setGeometry(geometry) {
this._geometry = geometry;
}
addToOpaqueRenderQueue(context, queue) {
queue.elements.add(this);
}
addToTransparentRenderQueue(context, queue) {
queue.elements.add(this);
queue.lastTransparentBatched = false;
queue.lastTransparentRenderElement = this;
}
_update(scene, context, customShader, replacementTag, subshaderIndex = 0) {
if (this.material) {
var subShader = this.material._shader.getSubShaderAt(0);
this.renderSubShader = null;
if (customShader) {
if (replacementTag) {
var oriTag = subShader.getFlag(replacementTag);
if (oriTag) {
var customSubShaders = customShader._subShaders;
for (var k = 0, p = customSubShaders.length; k < p; k++) {
var customSubShader = customSubShaders[k];
if (oriTag === customSubShader.getFlag(replacementTag)) {
this.renderSubShader = customSubShader;
break;
}
}
if (!this.renderSubShader)
return;
}
else {
return;
}
}
else {
this.renderSubShader = customShader.getSubShaderAt(subshaderIndex);
}
}
else {
this.renderSubShader = subShader;
}
var renderQueue = scene._getRenderQueue(this.material.renderQueue);
if (renderQueue.isTransparent)
this.addToTransparentRenderQueue(context, renderQueue);
else
this.addToOpaqueRenderQueue(context, renderQueue);
}
}
_render(context) {
var forceInvertFace = context.invertY;
var lastStateMaterial, lastStateShaderInstance, lastStateRender;
var updateMark = Camera._updateMark;
var scene = context.scene;
var cameraShaderValue = context.cameraShaderValue;
var transform = this._transform;
var geometry = this._geometry;
context.renderElement = this;
var updateRender = updateMark !== this.render._updateMark || this.renderType !== this.render._updateRenderType;
if (updateRender) {
this.render._renderUpdate(context, transform);
this.render._renderUpdateWithCamera(context, transform);
this.render._updateMark = updateMark;
this.render._updateRenderType = this.renderType;
}
else {
if (this.renderType == RenderElement.RENDERTYPE_INSTANCEBATCH) {
this.render._renderUpdate(context, transform);
this.render._renderUpdateWithCamera(context, transform);
}
}
var currentPipelineMode = context.pipelineMode;
if (geometry._prepareRender(context)) {
var passes = this.renderSubShader._passes;
for (var j = 0, m = passes.length; j < m; j++) {
var pass = passes[j];
if (pass._pipelineMode !== currentPipelineMode)
continue;
var comDef = RenderElement._compileDefine;
scene._shaderValues._defineDatas.cloneTo(comDef);
comDef.addDefineDatas(this.render._shaderValues._defineDatas);
comDef.addDefineDatas(this.material._shaderValues._defineDatas);
var shaderIns = context.shader = pass.withCompile(comDef);
var switchShader = shaderIns.bind();
var switchUpdateMark = (updateMark !== shaderIns._uploadMark);
var uploadScene = (shaderIns._uploadScene !== scene) || switchUpdateMark;
if (uploadScene || switchShader) {
shaderIns.uploadUniforms(shaderIns._sceneUniformParamsMap, scene._shaderValues, uploadScene);
shaderIns._uploadScene = scene;
}
var uploadSprite3D = (shaderIns._uploadRender !== this.render || shaderIns._uploadRenderType !== this.renderType) || switchUpdateMark;
if (uploadSprite3D || switchShader) {
shaderIns.uploadUniforms(shaderIns._spriteUniformParamsMap, this.render._shaderValues, uploadSprite3D);
shaderIns._uploadRender = this.render;
shaderIns._uploadRenderType = this.renderType;
}
var uploadCamera = shaderIns._uploadCameraShaderValue !== cameraShaderValue || switchUpdateMark;
if (uploadCamera || switchShader) {
shaderIns.uploadUniforms(shaderIns._cameraUniformParamsMap, cameraShaderValue, uploadCamera);
shaderIns._uploadCameraShaderValue = cameraShaderValue;
}
var uploadMaterial = (shaderIns._uploadMaterial !== this.material) || switchUpdateMark;
if (uploadMaterial || switchShader) {
shaderIns.uploadUniforms(shaderIns._materialUniformParamsMap, this.material._shaderValues, uploadMaterial);
shaderIns._uploadMaterial = this.material;
}
var matValues = this.material._shaderValues;
if (lastStateMaterial !== this.material || lastStateShaderInstance !== shaderIns) {
shaderIns.uploadRenderStateBlendDepth(matValues);
shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, this.getInvertFront());
lastStateMaterial = this.material;
lastStateShaderInstance = shaderIns;
lastStateRender = this.render;
}
else {
if (lastStateRender !== this.render) {
shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, this.getInvertFront());
lastStateRender = this.render;
}
}
geometry._render(context);
shaderIns._uploadMark = updateMark;
}
}
if (this.renderType !== RenderElement.RENDERTYPE_NORMAL)
this.render._revertBatchRenderUpdate(context);
}
destroy() {
this._transform = null;
this._geometry = null;
this.material = null;
this.render = null;
}
}
RenderElement.RENDERTYPE_NORMAL = 0;
RenderElement.RENDERTYPE_STATICBATCH = 1;
RenderElement.RENDERTYPE_INSTANCEBATCH = 2;
RenderElement.RENDERTYPE_VERTEXBATCH = 3;
RenderElement._compileDefine = new DefineDatas();
class SubMeshRenderElement extends RenderElement {
constructor() {
super();
this._dynamicWorldPositionNormalNeedUpdate = true;
}
_onWorldMatrixChanged() {
this._dynamicWorldPositionNormalNeedUpdate = true;
}
_computeWorldPositionsAndNormals(positionOffset, normalOffset, multiSubMesh, vertexCount) {
if (this._dynamicWorldPositionNormalNeedUpdate) {
var subMesh = this._geometry;
var vertexBuffer = subMesh._vertexBuffer;
var vertexFloatCount = vertexBuffer.vertexDeclaration.vertexStride / 4;
var oriVertexes = vertexBuffer.getFloat32Data();
var worldMat = this._transform.worldMatrix;
var rotation = this._transform.rotation;
var indices = subMesh._indices;
for (var i = 0; i < vertexCount; i++) {
var index = multiSubMesh ? indices[i] : i;
var oriOffset = index * vertexFloatCount;
var bakeOffset = i * 3;
Utils3D.transformVector3ArrayToVector3ArrayCoordinate(oriVertexes, oriOffset + positionOffset, worldMat, this._dynamicWorldPositions, bakeOffset);
(normalOffset !== -1) && (Utils3D.transformVector3ArrayByQuat(oriVertexes, oriOffset + normalOffset, rotation, this._dynamicWorldNormals, bakeOffset));
}
this._dynamicWorldPositionNormalNeedUpdate = false;
}
}
setTransform(transform) {
if (this._transform !== transform) {
(this._transform) && (this._transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatrixChanged));
(transform) && (transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatrixChanged));
this._dynamicWorldPositionNormalNeedUpdate = true;
this._transform = transform;
}
}
setGeometry(geometry) {
if (this._geometry !== geometry) {
var subMesh = geometry;
var mesh = subMesh._mesh;
if (mesh) {
var multiSubMesh = mesh._subMeshes.length > 1;
var dynBatVerCount = multiSubMesh ? subMesh._indexCount : mesh._vertexCount;
if (dynBatVerCount <= ILaya3D.SubMeshDynamicBatch.maxAllowVertexCount) {
var length = dynBatVerCount * 3;
this._dynamicVertexBatch = true;
this._dynamicWorldPositions = new Float32Array(length);
this._dynamicWorldNormals = new Float32Array(length);
this._dynamicVertexCount = dynBatVerCount;
this._dynamicMultiSubMesh = multiSubMesh;
}
else {
this._dynamicVertexBatch = false;
}
}
this._geometry = geometry;
}
}
addToOpaqueRenderQueue(context, queue) {
var subMeshStaticBatch = this.staticBatch;
var queueElements = queue.elements;
var elements = queueElements.elements;
if (subMeshStaticBatch && (!this.render._probReflection || this.render._probReflection._isScene) && SubMeshRenderElement.enableStaticBatch) {
var staManager = ILaya3D.MeshRenderStaticBatchManager.instance;
var staBatchMarks = staManager.getBatchOpaquaMark(this.render.lightmapIndex + 1, this.render.receiveShadow, this.material.id, subMeshStaticBatch._batchID);
if (staManager._updateCountMark === staBatchMarks.updateMark) {
var staBatchIndex = staBatchMarks.indexInList;
if (staBatchMarks.batched) {
elements[staBatchIndex].staticBatchElementList.add(this);
}
else {
var staOriElement = elements[staBatchIndex];
var staOriRender = staOriElement.render;
var staBatchElement = staManager._getBatchRenderElementFromPool();
staBatchElement.renderType = RenderElement.RENDERTYPE_STATICBATCH;
staBatchElement.setGeometry(subMeshStaticBatch);
staBatchElement.material = staOriElement.material;
var staRootOwner = subMeshStaticBatch.batchOwner;
var staBatchTransform = staRootOwner ? staRootOwner._transform : null;
staBatchElement.setTransform(staBatchTransform);
staBatchElement.render = staOriRender;
staBatchElement.renderSubShader = staOriElement.renderSubShader;
var staBatchList = staBatchElement.staticBatchElementList;
staBatchList.length = 0;
staBatchList.add(staOriElement);
staBatchList.add(this);
elements[staBatchIndex] = staBatchElement;
staBatchMarks.batched = true;
}
}
else {
staBatchMarks.updateMark = staManager._updateCountMark;
staBatchMarks.indexInList = queueElements.length;
staBatchMarks.batched = false;
queueElements.add(this);
}
}
else if (SubMeshRenderElement.enableDynamicBatch && this.renderSubShader._owner._enableInstancing && Laya.LayaGL.layaGPUInstance.supportInstance() && this.render.lightmapIndex < 0 && (!this.render._probReflection || this.render._probReflection._isScene)) {
var subMesh = this._geometry;
var insManager = ILaya3D.MeshRenderDynamicBatchManager.instance;
var insBatchMarks = insManager.getInstanceBatchOpaquaMark(this.render.receiveShadow, this.material.id, subMesh._id, this._transform._isFrontFaceInvert);
if (insManager._updateCountMark === insBatchMarks.updateMark) {
var insBatchIndex = insBatchMarks.indexInList;
if (insBatchMarks.batched) {
var instanceBatchElementList = elements[insBatchIndex].instanceBatchElementList;
if (instanceBatchElementList.length === SubMeshInstanceBatch.maxInstanceCount) {
insBatchMarks.updateMark = insManager._updateCountMark;
insBatchMarks.indexInList = queueElements.length;
insBatchMarks.batched = false;
queueElements.add(this);
}
else {
instanceBatchElementList.add(this);
}
}
else {
var insOriElement = elements[insBatchIndex];
var insOriRender = insOriElement.render;
var insBatchElement = insManager._getBatchRenderElementFromPool();
insBatchElement.renderType = RenderElement.RENDERTYPE_INSTANCEBATCH;
insBatchElement.setGeometry(SubMeshInstanceBatch.instance);
insBatchElement.material = insOriElement.material;
insBatchElement.setTransform(null);
insBatchElement.render = insOriRender;
insBatchElement.instanceSubMesh = subMesh;
insBatchElement.renderSubShader = insOriElement.renderSubShader;
var insBatchList = insBatchElement.instanceBatchElementList;
insBatchList.length = 0;
insBatchList.add(insOriElement);
insBatchList.add(this);
elements[insBatchIndex] = insBatchElement;
insBatchMarks.batched = true;
}
}
else {
insBatchMarks.updateMark = insManager._updateCountMark;
insBatchMarks.indexInList = queueElements.length;
insBatchMarks.batched = false;
queueElements.add(this);
}
}
else if (this._dynamicVertexBatch && SubMeshRenderElement.enableDynamicBatch) {
var verDec = this._geometry._vertexBuffer.vertexDeclaration;
var dynManager = ILaya3D.MeshRenderDynamicBatchManager.instance;
var dynBatchMarks = dynManager.getVertexBatchOpaquaMark(this.render.lightmapIndex + 1, this.render.receiveShadow, this.material.id, verDec.id);
if (dynManager._updateCountMark === dynBatchMarks.updateMark) {
var dynBatchIndex = dynBatchMarks.indexInList;
if (dynBatchMarks.batched) {
elements[dynBatchIndex].vertexBatchElementList.add(this);
}
else {
var dynOriElement = elements[dynBatchIndex];
var dynOriRender = dynOriElement.render;
var dynBatchElement = dynManager._getBatchRenderElementFromPool();
dynBatchElement.renderType = RenderElement.RENDERTYPE_VERTEXBATCH;
dynBatchElement.setGeometry(ILaya3D.SubMeshDynamicBatch.instance);
dynBatchElement.material = dynOriElement.material;
dynBatchElement.setTransform(null);
dynBatchElement.render = dynOriRender;
dynBatchElement.vertexBatchVertexDeclaration = verDec;
dynBatchElement.renderSubShader = dynOriElement.renderSubShader;
var dynBatchList = dynBatchElement.vertexBatchElementList;
dynBatchList.length = 0;
dynBatchList.add(dynOriElement);
dynBatchList.add(this);
elements[dynBatchIndex] = dynBatchElement;
dynBatchMarks.batched = true;
}
}
else {
dynBatchMarks.updateMark = dynManager._updateCountMark;
dynBatchMarks.indexInList = queueElements.length;
dynBatchMarks.batched = false;
queueElements.add(this);
}
}
else {
queueElements.add(this);
}
}
addToTransparentRenderQueue(context, queue) {
var subMeshStaticBatch = this.staticBatch;
var queueElements = queue.elements;
var elements = queueElements.elements;
if (subMeshStaticBatch && SubMeshRenderElement.enableStaticBatch) {
var staManager = ILaya3D.MeshRenderStaticBatchManager.instance;
var staLastElement = queue.lastTransparentRenderElement;
if (staLastElement) {
var staLastRender = staLastElement.render;
if (staLastElement._geometry._getType() !== this._geometry._getType() || staLastElement.staticBatch !== subMeshStaticBatch || staLastElement.material !== this.material || staLastRender.receiveShadow !== this.render.receiveShadow || staLastRender.lightmapIndex !== this.render.lightmapIndex) {
queueElements.add(this);
queue.lastTransparentBatched = false;
}
else {
if (queue.lastTransparentBatched) {
elements[queueElements.length - 1].staticBatchElementList.add((this));
}
else {
var staBatchElement = staManager._getBatchRenderElementFromPool();
staBatchElement.renderType = RenderElement.RENDERTYPE_STATICBATCH;
staBatchElement.setGeometry(subMeshStaticBatch);
staBatchElement.material = staLastElement.material;
var staRootOwner = subMeshStaticBatch.batchOwner;
var staBatchTransform = staRootOwner ? staRootOwner._transform : null;
staBatchElement.setTransform(staBatchTransform);
staBatchElement.render = this.render;
staBatchElement.renderSubShader = staLastElement.renderSubShader;
var staBatchList = staBatchElement.staticBatchElementList;
staBatchList.length = 0;
staBatchList.add(staLastElement);
staBatchList.add(this);
elements[queueElements.length - 1] = staBatchElement;
}
queue.lastTransparentBatched = true;
}
}
else {
queueElements.add(this);
queue.lastTransparentBatched = false;
}
}
else if (SubMeshRenderElement.enableDynamicBatch && this.renderSubShader._owner._enableInstancing && Laya.LayaGL.layaGPUInstance.supportInstance() && this.render.lightmapIndex < 0 && (!this.render._probReflection || this.render._probReflection._isScene)) {
var subMesh = this._geometry;
var insManager = ILaya3D.MeshRenderDynamicBatchManager.instance;
var insLastElement = queue.lastTransparentRenderElement;
if (insLastElement) {
var insLastRender = insLastElement.render;
if (insLastElement._geometry._getType() !== this._geometry._getType() || insLastElement._geometry !== subMesh || insLastElement.material !== this.material || insLastRender.receiveShadow !== this.render.receiveShadow) {
queueElements.add(this);
queue.lastTransparentBatched = false;
}
else {
if (queue.lastTransparentBatched) {
var instanceBatchElementList = elements[queueElements.length - 1].instanceBatchElementList;
if (instanceBatchElementList.length === SubMeshInstanceBatch.maxInstanceCount) {
queueElements.add(this);
queue.lastTransparentBatched = false;
}
else {
instanceBatchElementList.add(this);
queue.lastTransparentBatched = true;
}
}
else {
var insBatchElement = insManager._getBatchRenderElementFromPool();
insBatchElement.renderType = RenderElement.RENDERTYPE_INSTANCEBATCH;
insBatchElement.setGeometry(SubMeshInstanceBatch.instance);
insBatchElement.material = insLastElement.material;
insBatchElement.setTransform(null);
insBatchElement.render = this.render;
insBatchElement.instanceSubMesh = subMesh;
insBatchElement.renderSubShader = insLastElement.renderSubShader;
var insBatchList = insBatchElement.instanceBatchElementList;
insBatchList.length = 0;
insBatchList.add(insLastElement);
insBatchList.add(this);
elements[queueElements.length - 1] = insBatchElement;
queue.lastTransparentBatched = true;
}
}
}
else {
queueElements.add(this);
queue.lastTransparentBatched = false;
}
}
else if (this._dynamicVertexBatch && SubMeshRenderElement.enableDynamicBatch) {
var verDec = this._geometry._vertexBuffer.vertexDeclaration;
var dynManager = ILaya3D.MeshRenderDynamicBatchManager.instance;
var dynLastElement = queue.lastTransparentRenderElement;
if (dynLastElement) {
var dynLastRender = dynLastElement.render;
if (!dynLastElement._dynamicVertexBatch || dynLastElement._geometry._getType() !== this._geometry._getType() || dynLastElement._geometry._vertexBuffer._vertexDeclaration !== verDec || dynLastElement.material !== this.material || dynLastRender.receiveShadow !== this.render.receiveShadow || dynLastRender.lightmapIndex !== this.render.lightmapIndex) {
queueElements.add(this);
queue.lastTransparentBatched = false;
}
else {
if (queue.lastTransparentBatched) {
elements[queueElements.length - 1].vertexBatchElementList.add((this));
}
else {
var dynBatchElement = dynManager._getBatchRenderElementFromPool();
dynBatchElement.renderType = RenderElement.RENDERTYPE_VERTEXBATCH;
dynBatchElement.setGeometry(ILaya3D.SubMeshDynamicBatch.instance);
dynBatchElement.material = dynLastElement.material;
dynBatchElement.setTransform(null);
dynBatchElement.render = this.render;
dynBatchElement.vertexBatchVertexDeclaration = verDec;
dynBatchElement.renderSubShader = dynLastElement.renderSubShader;
var dynBatchList = dynBatchElement.vertexBatchElementList;
dynBatchList.length = 0;
dynBatchList.add(dynLastElement);
dynBatchList.add(this);
elements[queueElements.length - 1] = dynBatchElement;
}
queue.lastTransparentBatched = true;
}
}
else {
queueElements.add(this);
queue.lastTransparentBatched = false;
}
}
else {
queueElements.add(this);
}
queue.lastTransparentRenderElement = this;
}
getInvertFront() {
switch (this.renderType) {
case RenderElement.RENDERTYPE_NORMAL:
return this._transform._isFrontFaceInvert;
case RenderElement.RENDERTYPE_STATICBATCH:
case RenderElement.RENDERTYPE_VERTEXBATCH:
return false;
case RenderElement.RENDERTYPE_INSTANCEBATCH:
return this.instanceBatchElementList.elements[0]._transform._isFrontFaceInvert;
default:
throw "SubMeshRenderElement: unknown renderType";
}
}
destroy() {
super.destroy();
this._dynamicWorldPositions = null;
this._dynamicWorldNormals = null;
this.staticBatch = null;
this.staticBatchElementList = null;
this.vertexBatchElementList = null;
this.vertexBatchVertexDeclaration = null;
}
}
SubMeshRenderElement.enableDynamicBatch = true;
SubMeshRenderElement.enableStaticBatch = true;
class StaticBatchManager {
constructor() {
this._initBatchSprites = [];
this._staticBatches = {};
this._batchRenderElementPoolIndex = 0;
this._batchRenderElementPool = [];
}
static _addToStaticBatchQueue(sprite3D, renderableSprite3D) {
if (sprite3D instanceof RenderableSprite3D)
renderableSprite3D.push(sprite3D);
for (var i = 0, n = sprite3D.numChildren; i < n; i++)
StaticBatchManager._addToStaticBatchQueue(sprite3D._children[i], renderableSprite3D);
}
static _registerManager(manager) {
StaticBatchManager._managers.push(manager);
}
static combine(staticBatchRoot, renderableSprite3Ds = null) {
if (!renderableSprite3Ds) {
renderableSprite3Ds = [];
if (staticBatchRoot)
StaticBatchManager._addToStaticBatchQueue(staticBatchRoot, renderableSprite3Ds);
}
var batchSpritesCount = renderableSprite3Ds.length;
if (batchSpritesCount > 0) {
for (var i = 0; i < batchSpritesCount; i++) {
var sprite = renderableSprite3Ds[i];
if (!sprite.destroyed) {
if (sprite._render._isPartOfStaticBatch)
console.warn("StaticBatchManager: Sprite " + sprite.name + " has a part of Static Batch,it will be ignore.");
else
sprite._addToInitStaticBatchManager();
}
}
for (var k = 0, m = StaticBatchManager._managers.length; k < m; k++) {
var manager = StaticBatchManager._managers[k];
manager._initStaticBatchs(staticBatchRoot);
}
}
}
_partition(items, left, right) {
var pivot = items[Math.floor((right + left) / 2)];
while (left <= right) {
while (this._compare(items[left], pivot) < 0)
left++;
while (this._compare(items[right], pivot) > 0)
right--;
if (left < right) {
var temp = items[left];
items[left] = items[right];
items[right] = temp;
left++;
right--;
}
else if (left === right) {
left++;
break;
}
}
return left;
}
_quickSort(items, left, right) {
if (items.length > 1) {
var index = this._partition(items, left, right);
var leftIndex = index - 1;
if (left < leftIndex)
this._quickSort(items, left, leftIndex);
if (index < right)
this._quickSort(items, index, right);
}
}
_compare(left, right) {
throw "StaticBatch:must override this function.";
}
_initStaticBatchs(rootSprite) {
throw "StaticBatch:must override this function.";
}
_getBatchRenderElementFromPool() {
throw "StaticBatch:must override this function.";
}
_addBatchSprite(renderableSprite3D) {
this._initBatchSprites.push(renderableSprite3D);
}
_clear() {
this._batchRenderElementPoolIndex = 0;
}
_garbageCollection() {
throw "StaticBatchManager: must override it.";
}
dispose() {
this._staticBatches = null;
}
}
StaticBatchManager._managers = [];
class SubMeshStaticBatch extends GeometryElement {
constructor(batchOwner, vertexDeclaration) {
super();
this._bufferState = new BufferState();
this._batchID = SubMeshStaticBatch._batchIDCounter++;
this._batchElements = [];
this._currentBatchVertexCount = 0;
this._currentBatchIndexCount = 0;
this._vertexDeclaration = vertexDeclaration;
this.batchOwner = batchOwner;
}
_getStaticBatchBakedVertexs(batchVertices, batchOffset, batchOwnerTransform, transform, render, mesh) {
var vertexBuffer = mesh._vertexBuffer;
var vertexDeclaration = vertexBuffer.vertexDeclaration;
var positionOffset = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_POSITION0)._offset / 4;
var normalElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_NORMAL0);
var normalOffset = normalElement ? normalElement._offset / 4 : -1;
var colorElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_COLOR0);
var colorOffset = colorElement ? colorElement._offset / 4 : -1;
var uv0Element = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE0);
var uv0Offset = uv0Element ? uv0Element._offset / 4 : -1;
var uv1Element = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE1);
var uv1Offset = uv1Element ? uv1Element._offset / 4 : -1;
var tangentElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TANGENT0);
var sTangentOffset = tangentElement ? tangentElement._offset / 4 : -1;
var bakeVertexFloatCount = 18;
var oriVertexFloatCount = vertexDeclaration.vertexStride / 4;
var oriVertexes = vertexBuffer.getFloat32Data();
var worldMat;
if (batchOwnerTransform) {
var rootMat = batchOwnerTransform.worldMatrix;
rootMat.invert(SubMeshStaticBatch._tempMatrix4x40);
worldMat = SubMeshStaticBatch._tempMatrix4x41;
Matrix4x4.multiply(SubMeshStaticBatch._tempMatrix4x40, transform.worldMatrix, worldMat);
}
else {
worldMat = transform.worldMatrix;
}
var normalMat = SubMeshStaticBatch._tempMatrix4x42;
worldMat.invert(normalMat);
normalMat.transpose();
var rotation = SubMeshStaticBatch._tempQuaternion0;
worldMat.decomposeTransRotScale(SubMeshStaticBatch._tempVector30, rotation, SubMeshStaticBatch._tempVector31);
var lightmapScaleOffset = render.lightmapScaleOffset;
var vertexCount = mesh.vertexCount;
for (var i = 0; i < vertexCount; i++) {
var oriOffset = i * oriVertexFloatCount;
var bakeOffset = (i + batchOffset) * bakeVertexFloatCount;
Utils3D.transformVector3ArrayToVector3ArrayCoordinate(oriVertexes, oriOffset + positionOffset, worldMat, batchVertices, bakeOffset + 0);
if (normalOffset !== -1)
Utils3D.transformVector3ArrayToVector3ArrayNormal(oriVertexes, oriOffset + normalOffset, normalMat, batchVertices, bakeOffset + 3);
var j, m;
var bakOff = bakeOffset + 6;
if (colorOffset !== -1) {
var oriOff = oriOffset + colorOffset;
for (j = 0, m = 4; j < m; j++)
batchVertices[bakOff + j] = oriVertexes[oriOff + j];
}
else {
for (j = 0, m = 4; j < m; j++)
batchVertices[bakOff + j] = 1.0;
}
if (uv0Offset !== -1) {
var absUv0Offset = oriOffset + uv0Offset;
batchVertices[bakeOffset + 10] = oriVertexes[absUv0Offset];
batchVertices[bakeOffset + 11] = oriVertexes[absUv0Offset + 1];
}
if (lightmapScaleOffset) {
if (uv1Offset !== -1)
Utils3D.transformLightingMapTexcoordArray(oriVertexes, oriOffset + uv1Offset, lightmapScaleOffset, batchVertices, bakeOffset + 12);
else
Utils3D.transformLightingMapTexcoordArray(oriVertexes, oriOffset + uv0Offset, lightmapScaleOffset, batchVertices, bakeOffset + 12);
}
if (sTangentOffset !== -1) {
var absSTanegntOffset = oriOffset + sTangentOffset;
Utils3D.transformVector3ArrayToVector3ArrayNormal(oriVertexes, absSTanegntOffset, normalMat, batchVertices, bakeOffset + 14);
batchVertices[bakeOffset + 17] = oriVertexes[absSTanegntOffset + 3];
}
}
return vertexCount;
}
addTest(sprite) {
var vertexCount;
var subMeshVertexCount = sprite.meshFilter.sharedMesh.vertexCount;
vertexCount = this._currentBatchVertexCount + subMeshVertexCount;
if (vertexCount > SubMeshStaticBatch.maxBatchVertexCount)
return false;
return true;
}
add(sprite) {
var mesh = sprite.meshFilter.sharedMesh;
var subMeshVertexCount = mesh.vertexCount;
this._batchElements.push(sprite);
var render = sprite._render;
render._isPartOfStaticBatch = true;
render._staticBatch = this;
var renderElements = render._renderElements;
for (var i = 0, n = renderElements.length; i < n; i++)
renderElements[i].staticBatch = this;
this._currentBatchIndexCount += mesh._indexBuffer.indexCount;
this._currentBatchVertexCount += subMeshVertexCount;
}
remove(sprite) {
var mesh = sprite.meshFilter.sharedMesh;
var index = this._batchElements.indexOf(sprite);
if (index !== -1) {
this._batchElements.splice(index, 1);
var renderElements = sprite._render._renderElements;
for (var i = 0, n = renderElements.length; i < n; i++)
renderElements[i].staticBatch = null;
this._currentBatchIndexCount = this._currentBatchIndexCount - mesh._indexBuffer.indexCount;
this._currentBatchVertexCount = this._currentBatchVertexCount - mesh.vertexCount;
sprite._render._isPartOfStaticBatch = false;
}
}
finishInit() {
if (this._vertexBuffer) {
this._vertexBuffer.destroy();
this._indexBuffer.destroy();
Laya.Resource._addGPUMemory(-(this._vertexBuffer._byteLength + this._indexBuffer._byteLength));
}
var gl = Laya.LayaGL.instance;
var batchVertexCount = 0;
var batchIndexCount = 0;
var rootOwner = this.batchOwner;
var floatStride = this._vertexDeclaration.vertexStride / 4;
var vertexDatas = new Float32Array(floatStride * this._currentBatchVertexCount);
var indexDatas = new Uint16Array(this._currentBatchIndexCount);
this._vertexBuffer = new VertexBuffer3D(this._vertexDeclaration.vertexStride * this._currentBatchVertexCount, gl.STATIC_DRAW);
this._vertexBuffer.vertexDeclaration = this._vertexDeclaration;
this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, this._currentBatchIndexCount, gl.STATIC_DRAW);
for (var i = 0, n = this._batchElements.length; i < n; i++) {
var sprite = this._batchElements[i];
var mesh = sprite.meshFilter.sharedMesh;
var meshVerCount = this._getStaticBatchBakedVertexs(vertexDatas, batchVertexCount, rootOwner ? rootOwner._transform : null, sprite._transform, sprite._render, mesh);
var indices = mesh._indexBuffer.getData();
var indexOffset = batchVertexCount;
var indexEnd = batchIndexCount + indices.length;
var elements = sprite._render._renderElements;
for (var j = 0, m = mesh.subMeshCount; j < m; j++) {
var subMesh = mesh._subMeshes[j];
var start = batchIndexCount + subMesh._indexStart;
var element = elements[j];
element.staticBatchIndexStart = start;
element.staticBatchIndexEnd = start + subMesh._indexCount;
}
indexDatas.set(indices, batchIndexCount);
var k;
var isInvert = rootOwner ? (sprite._transform._isFrontFaceInvert !== rootOwner.transform._isFrontFaceInvert) : sprite._transform._isFrontFaceInvert;
if (isInvert) {
for (k = batchIndexCount; k < indexEnd; k += 3) {
indexDatas[k] = indexOffset + indexDatas[k];
var index1 = indexDatas[k + 1];
var index2 = indexDatas[k + 2];
indexDatas[k + 1] = indexOffset + index2;
indexDatas[k + 2] = indexOffset + index1;
}
}
else {
for (k = batchIndexCount; k < indexEnd; k += 3) {
indexDatas[k] = indexOffset + indexDatas[k];
indexDatas[k + 1] = indexOffset + indexDatas[k + 1];
indexDatas[k + 2] = indexOffset + indexDatas[k + 2];
}
}
batchIndexCount += indices.length;
batchVertexCount += meshVerCount;
}
this._vertexBuffer.setData(vertexDatas.buffer);
this._indexBuffer.setData(indexDatas);
var memorySize = this._vertexBuffer._byteLength + this._indexBuffer._byteLength;
Laya.Resource._addGPUMemory(memorySize);
this._bufferState.bind();
this._bufferState.applyVertexBuffer(this._vertexBuffer);
this._bufferState.applyIndexBuffer(this._indexBuffer);
this._bufferState.unBind();
}
_render(state) {
this._bufferState.bind();
var gl = Laya.LayaGL.instance;
var element = state.renderElement;
var staticBatchElementList = element.staticBatchElementList;
var batchElementList = staticBatchElementList.elements;
var from = 0;
var end = 0;
var count = staticBatchElementList.length;
for (var i = 1; i < count; i++) {
var lastElement = batchElementList[i - 1];
if (lastElement.staticBatchIndexEnd === batchElementList[i].staticBatchIndexStart) {
end++;
continue;
}
else {
var start = batchElementList[from].staticBatchIndexStart;
var indexCount = batchElementList[end].staticBatchIndexEnd - start;
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, start * 2);
from = ++end;
Laya.Stat.trianglesFaces += indexCount / 3;
}
}
start = batchElementList[from].staticBatchIndexStart;
indexCount = batchElementList[end].staticBatchIndexEnd - start;
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, start * 2);
Laya.Stat.renderBatches++;
Laya.Stat.savedRenderBatches += count - 1;
Laya.Stat.trianglesFaces += indexCount / 3;
}
dispose() {
var memorySize = this._vertexBuffer._byteLength + this._indexBuffer._byteLength;
Laya.Resource._addGPUMemory(-memorySize);
this._batchElements = null;
this.batchOwner = null;
this._vertexDeclaration = null;
this._bufferState.destroy();
this._vertexBuffer.destroy();
this._indexBuffer.destroy();
this._vertexBuffer = null;
this._indexBuffer = null;
this._bufferState = null;
}
}
SubMeshStaticBatch._tempVector30 = new Vector3();
SubMeshStaticBatch._tempVector31 = new Vector3();
SubMeshStaticBatch._tempQuaternion0 = new Quaternion();
SubMeshStaticBatch._tempMatrix4x40 = new Matrix4x4();
SubMeshStaticBatch._tempMatrix4x41 = new Matrix4x4();
SubMeshStaticBatch._tempMatrix4x42 = new Matrix4x4();
SubMeshStaticBatch.maxBatchVertexCount = 65535;
SubMeshStaticBatch._batchIDCounter = 0;
class MeshRenderStaticBatchManager extends StaticBatchManager {
constructor() {
super();
this._opaqueBatchMarks = [];
this._updateCountMark = 0;
}
static __init__() {
MeshRenderStaticBatchManager._verDec = VertexMesh.getVertexDeclaration("POSITION,NORMAL,COLOR,UV,UV1,TANGENT");
}
_compare(left, right) {
var lRender = left._render, rRender = right._render;
var leftGeo = left.meshFilter.sharedMesh, rightGeo = right.meshFilter.sharedMesh;
var lightOffset = lRender.lightmapIndex - rRender.lightmapIndex;
if (lightOffset === 0) {
var receiveShadowOffset = (lRender.receiveShadow ? 1 : 0) - (rRender.receiveShadow ? 1 : 0);
if (receiveShadowOffset === 0) {
var materialOffset = (lRender.sharedMaterial && rRender.sharedMaterial) ? lRender.sharedMaterial.id - rRender.sharedMaterial.id : 0;
if (materialOffset === 0) {
var verDec = leftGeo._vertexBuffer.vertexDeclaration.id - rightGeo._vertexBuffer.vertexDeclaration.id;
if (verDec === 0) {
return rightGeo._indexBuffer.indexCount - leftGeo._indexBuffer.indexCount;
}
else {
return verDec;
}
}
else {
return materialOffset;
}
}
else {
return receiveShadowOffset;
}
}
else {
return lightOffset;
}
}
_getBatchRenderElementFromPool() {
var renderElement = this._batchRenderElementPool[this._batchRenderElementPoolIndex++];
if (!renderElement) {
renderElement = new SubMeshRenderElement();
this._batchRenderElementPool[this._batchRenderElementPoolIndex - 1] = renderElement;
renderElement.staticBatchElementList = new SingletonList();
}
return renderElement;
}
_getStaticBatch(staticBatches, rootOwner, number) {
var subMeshStaticBatch = staticBatches[number];
if (!subMeshStaticBatch) {
subMeshStaticBatch = staticBatches[number] = new SubMeshStaticBatch(rootOwner, MeshRenderStaticBatchManager._verDec);
this._staticBatches[subMeshStaticBatch._batchID] = subMeshStaticBatch;
}
return subMeshStaticBatch;
}
_initStaticBatchs(rootOwner) {
var initBatchSprites = this._initBatchSprites;
this._quickSort(initBatchSprites, 0, initBatchSprites.length - 1);
var staticBatches = [];
var lastCanMerage = false;
var curStaticBatch;
var batchNumber = 0;
for (var i = 0, n = initBatchSprites.length; i < n; i++) {
var sprite = initBatchSprites[i];
if (lastCanMerage) {
if (curStaticBatch.addTest(sprite)) {
curStaticBatch.add(sprite);
}
else {
lastCanMerage = false;
batchNumber++;
}
}
else {
var lastIndex = n - 1;
if (i !== lastIndex) {
curStaticBatch = this._getStaticBatch(staticBatches, rootOwner, batchNumber);
curStaticBatch.add(sprite);
lastCanMerage = true;
}
}
}
for (i = 0, n = staticBatches.length; i < n; i++) {
var staticBatch = staticBatches[i];
staticBatch && staticBatch.finishInit();
}
this._initBatchSprites.length = 0;
}
_removeRenderSprite(sprite) {
var render = sprite._render;
var staticBatch = render._staticBatch;
var batchElements = staticBatch._batchElements;
var index = batchElements.indexOf(sprite);
if (index !== -1) {
batchElements.splice(index, 1);
render._staticBatch = null;
var renderElements = render._renderElements;
for (var i = 0, n = renderElements.length; i < n; i++)
renderElements[i].staticBatch = null;
}
if (batchElements.length === 0) {
delete this._staticBatches[staticBatch._batchID];
staticBatch.dispose();
}
}
_clear() {
super._clear();
this._updateCountMark++;
}
_garbageCollection() {
for (var key in this._staticBatches) {
var staticBatch = this._staticBatches[key];
if (staticBatch._batchElements.length === 0) {
staticBatch.dispose();
delete this._staticBatches[key];
}
}
}
getBatchOpaquaMark(lightMapIndex, receiveShadow, materialID, staticBatchID) {
var receiveShadowIndex = receiveShadow ? 1 : 0;
var staLightMapMarks = (this._opaqueBatchMarks[lightMapIndex]) || (this._opaqueBatchMarks[lightMapIndex] = []);
var staReceiveShadowMarks = (staLightMapMarks[receiveShadowIndex]) || (staLightMapMarks[receiveShadowIndex] = []);
var staMaterialMarks = (staReceiveShadowMarks[materialID]) || (staReceiveShadowMarks[materialID] = []);
return (staMaterialMarks[staticBatchID]) || (staMaterialMarks[staticBatchID] = new BatchMark);
}
}
MeshRenderStaticBatchManager.instance = new MeshRenderStaticBatchManager();
(function (ReflectionProbeMode) {
ReflectionProbeMode[ReflectionProbeMode["off"] = 0] = "off";
ReflectionProbeMode[ReflectionProbeMode["simple"] = 1] = "simple";
})(exports.ReflectionProbeMode || (exports.ReflectionProbeMode = {}));
class ReflectionProbe extends Sprite3D {
constructor() {
super();
this._boxProjection = false;
this._size = new Vector3();
this._offset = new Vector3();
this._reflectionHDRParams = new Vector4();
this._reflectionDecodeFormat = Laya.TextureDecodeFormat.Normal;
this._isScene = false;
}
get boxProjection() {
return this._boxProjection;
}
set boxProjection(value) {
this._boxProjection = value;
}
get importance() {
return this._importance;
}
set importance(value) {
this._importance = value;
}
get intensity() {
return this._intensity;
}
set intensity(value) {
value = Math.max(Math.min(value, 1.0), 0.0);
this._reflectionHDRParams.x = value;
if (this._reflectionDecodeFormat == Laya.TextureDecodeFormat.RGBM)
this._reflectionHDRParams.x *= 5.0;
this._intensity = value;
}
get reflectionTexture() {
return this._reflectionTexture;
}
set reflectionTexture(value) {
this._reflectionTexture = value;
this._reflectionTexture._addReference();
}
get bounds() {
return this._bounds;
}
set bounds(value) {
this._bounds = value;
}
get boundsMax() {
return this._bounds.getMax();
}
get boundsMin() {
return this._bounds.getMin();
}
get probePosition() {
return this.transform.position;
}
get reflectionHDRParams() {
return this._reflectionHDRParams;
}
set reflectionHDRParams(value) {
this._reflectionHDRParams = value;
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
this._boxProjection = data.boxProjection;
this._importance = data.importance;
this._reflectionTexture = Laya.Loader.getRes(data.reflection);
var position = this.transform.position;
this._size.fromArray(data.boxSize);
Vector3.scale(this._size, 0.5, ReflectionProbe.TEMPVECTOR3);
this._offset.fromArray(data.boxOffset);
var min = new Vector3();
var max = new Vector3();
Vector3.add(position, ReflectionProbe.TEMPVECTOR3, max);
Vector3.add(max, this._offset, max);
Vector3.subtract(position, ReflectionProbe.TEMPVECTOR3, min);
Vector3.add(min, this._offset, min);
this._reflectionDecodeFormat = data.reflectionDecodingFormat;
this.intensity = data.intensity;
if (!this._bounds)
this.bounds = new Bounds(min, max);
else {
this._bounds.setMin(min);
this._bounds.setMax(max);
}
}
_setIndexInReflectionList(value) {
this._indexInReflectProbList = value;
}
_getIndexInReflectionList() {
return this._indexInReflectProbList;
}
_onActive() {
super._onActive();
if (this._reflectionTexture)
this.scene._reflectionProbeManager.add(this);
}
_onInActive() {
super._onInActive();
if (this.reflectionTexture)
this.scene._reflectionProbeManager.remove(this);
}
destroy(destroyChild = true) {
if (this.destroyed)
return;
super.destroy(destroyChild);
this._reflectionTexture && this._reflectionTexture._removeReference();
this._reflectionTexture = null;
this._bounds = null;
}
_cloneTo(destObject, srcRoot, dstRoot) {
var dest = destObject;
dest.bounds = this.bounds;
dest.boxProjection = this.boxProjection;
dest.importance = this.importance;
dest._size = this._size;
dest._offset = this._offset;
dest.intensity = this.intensity;
dest.reflectionHDRParams = this.reflectionHDRParams;
super._cloneTo(destObject, srcRoot, dstRoot);
}
}
ReflectionProbe.TEMPVECTOR3 = new Vector3();
ReflectionProbe.defaultTextureHDRDecodeValues = new Vector4(1.0, 1.0, 0.0, 0.0);
class BaseRender extends Laya.EventDispatcher {
constructor(owner) {
super();
this._lightmapScaleOffset = new Vector4(1, 1, 0, 0);
this._indexInList = -1;
this._indexInCastShadowList = -1;
this._boundsChange = true;
this._castShadow = false;
this._supportOctree = true;
this._sharedMaterials = [];
this._renderMark = -1;
this._indexInOctreeMotionList = -1;
this._reflectionMode = exports.ReflectionProbeMode.simple;
this._updateMark = -1;
this._updateRenderType = -1;
this._isPartOfStaticBatch = false;
this._staticBatch = null;
this._id = ++BaseRender._uniqueIDCounter;
this._indexInCastShadowList = -1;
this._bounds = new Bounds(Vector3._ZERO, Vector3._ZERO);
this._renderElements = [];
this._owner = owner;
this._enable = true;
this._materialsInstance = [];
this._shaderValues = new ShaderData(null);
this.lightmapIndex = -1;
this.receiveShadow = false;
this.sortingFudge = 0.0;
(owner) && (this._owner.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange));
}
get id() {
return this._id;
}
get lightmapIndex() {
return this._lightmapIndex;
}
set lightmapIndex(value) {
this._lightmapIndex = value;
}
get lightmapScaleOffset() {
return this._lightmapScaleOffset;
}
set lightmapScaleOffset(value) {
if (!value)
throw "BaseRender: lightmapScaleOffset can't be null.";
this._lightmapScaleOffset = value;
this._shaderValues.setVector(RenderableSprite3D.LIGHTMAPSCALEOFFSET, value);
}
get enable() {
return this._enable;
}
set enable(value) {
this._enable = !!value;
}
get material() {
var material = this._sharedMaterials[0];
if (material && !this._materialsInstance[0]) {
var insMat = this._getInstanceMaterial(material, 0);
var renderElement = this._renderElements[0];
(renderElement) && (renderElement.material = insMat);
}
return this._sharedMaterials[0];
}
set material(value) {
this.sharedMaterial = value;
this._isSupportReflection();
}
get materials() {
for (var i = 0, n = this._sharedMaterials.length; i < n; i++) {
if (!this._materialsInstance[i]) {
var insMat = this._getInstanceMaterial(this._sharedMaterials[i], i);
var renderElement = this._renderElements[i];
(renderElement) && (renderElement.material = insMat);
}
}
return this._sharedMaterials.slice();
}
set materials(value) {
this.sharedMaterials = value;
this._isSupportReflection();
}
get sharedMaterial() {
return this._sharedMaterials[0];
}
set sharedMaterial(value) {
var lastValue = this._sharedMaterials[0];
if (lastValue !== value) {
this._sharedMaterials[0] = value;
this._materialsInstance[0] = false;
this._changeMaterialReference(lastValue, value);
var renderElement = this._renderElements[0];
(renderElement) && (renderElement.material = value);
}
this._isSupportReflection();
}
get sharedMaterials() {
return this._sharedMaterials.slice();
}
set sharedMaterials(value) {
var materialsInstance = this._materialsInstance;
var sharedMats = this._sharedMaterials;
for (var i = 0, n = sharedMats.length; i < n; i++) {
var lastMat = sharedMats[i];
(lastMat) && (lastMat._removeReference());
}
if (value) {
var count = value.length;
materialsInstance.length = count;
sharedMats.length = count;
for (i = 0; i < count; i++) {
lastMat = sharedMats[i];
var mat = value[i];
if (lastMat !== mat) {
materialsInstance[i] = false;
var renderElement = this._renderElements[i];
(renderElement) && (renderElement.material = mat);
}
if (mat) {
mat._addReference();
}
sharedMats[i] = mat;
}
}
else {
throw new Error("BaseRender: shadredMaterials value can't be null.");
}
this._isSupportReflection();
}
get bounds() {
if (this._boundsChange) {
this._calculateBoundingBox();
this._boundsChange = false;
}
return this._bounds;
}
set receiveShadow(value) {
if (this._receiveShadow !== value) {
this._receiveShadow = value;
if (value)
this._shaderValues.addDefine(RenderableSprite3D.SHADERDEFINE_RECEIVE_SHADOW);
else
this._shaderValues.removeDefine(RenderableSprite3D.SHADERDEFINE_RECEIVE_SHADOW);
}
}
get receiveShadow() {
return this._receiveShadow;
}
get castShadow() {
return this._castShadow;
}
set castShadow(value) {
this._castShadow = value;
}
get isPartOfStaticBatch() {
return this._isPartOfStaticBatch;
}
get isRender() {
return this._renderMark == -1 || this._renderMark == (Laya.Stat.loopCount - 1);
}
set reflectionMode(value) {
this._reflectionMode = value;
}
get reflectionMode() {
return this._reflectionMode;
}
_getOctreeNode() {
return this._octreeNode;
}
_setOctreeNode(value) {
if (!value) {
(this._indexInOctreeMotionList !== -1) && (this._octreeNode._octree.removeMotionObject(this));
}
this._octreeNode = value;
}
_getIndexInMotionList() {
return this._indexInOctreeMotionList;
}
_setIndexInMotionList(value) {
this._indexInOctreeMotionList = value;
}
_changeMaterialReference(lastValue, value) {
(lastValue) && (lastValue._removeReference());
value._addReference();
}
_getInstanceMaterial(material, index) {
var insMat = material.clone();
insMat.name = insMat.name + "(Instance)";
this._materialsInstance[index] = true;
this._changeMaterialReference(this._sharedMaterials[index], insMat);
this._sharedMaterials[index] = insMat;
return insMat;
}
_isSupportReflection() {
this._surportReflectionProbe = false;
var sharedMats = this._sharedMaterials;
for (var i = 0, n = sharedMats.length; i < n; i++) {
var mat = sharedMats[i];
this._surportReflectionProbe = (this._surportReflectionProbe || (mat && mat._shader._supportReflectionProbe));
}
}
_addReflectionProbeUpdate() {
if (this._surportReflectionProbe && this._reflectionMode == 1) {
this._scene && this._scene._reflectionProbeManager.addMotionObject(this);
}
}
_applyLightMapParams() {
var lightMaps = this._scene.lightmaps;
var shaderValues = this._shaderValues;
var lightmapIndex = this._lightmapIndex;
if (lightmapIndex >= 0 && lightmapIndex < lightMaps.length) {
var lightMap = lightMaps[lightmapIndex];
shaderValues.setTexture(RenderableSprite3D.LIGHTMAP, lightMap.lightmapColor);
shaderValues.addDefine(RenderableSprite3D.SAHDERDEFINE_LIGHTMAP);
if (lightMap.lightmapDirection) {
shaderValues.setTexture(RenderableSprite3D.LIGHTMAP_DIRECTION, lightMap.lightmapDirection);
shaderValues.addDefine(RenderableSprite3D.SHADERDEFINE_LIGHTMAP_DIRECTIONAL);
}
else {
shaderValues.removeDefine(RenderableSprite3D.SHADERDEFINE_LIGHTMAP_DIRECTIONAL);
}
}
else {
shaderValues.removeDefine(RenderableSprite3D.SAHDERDEFINE_LIGHTMAP);
shaderValues.removeDefine(RenderableSprite3D.SHADERDEFINE_LIGHTMAP_DIRECTIONAL);
}
}
_onWorldMatNeedChange(flag) {
this._boundsChange = true;
if (this._octreeNode) {
flag &= Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDSCALE;
if (flag) {
if (this._indexInOctreeMotionList === -1)
this._octreeNode._octree.addMotionObject(this);
}
}
this._addReflectionProbeUpdate();
}
_calculateBoundingBox() {
throw ("BaseRender: must override it.");
}
_getIndexInList() {
return this._indexInList;
}
_setIndexInList(index) {
this._indexInList = index;
}
_setBelongScene(scene) {
this._scene = scene;
}
_setUnBelongScene() {
this._scene = null;
}
_needRender(boundFrustum, context) {
return true;
}
_OctreeNoRender() {
}
_renderUpdate(context, transform) {
}
_renderUpdateWithCamera(context, transform) {
}
_revertBatchRenderUpdate(context) {
}
_destroy() {
(this._indexInOctreeMotionList !== -1) && (this._octreeNode._octree.removeMotionObject(this));
this.offAll();
var i = 0, n = 0;
for (i = 0, n = this._renderElements.length; i < n; i++)
this._renderElements[i].destroy();
for (i = 0, n = this._sharedMaterials.length; i < n; i++)
(this._sharedMaterials[i].destroyed) || (this._sharedMaterials[i]._removeReference());
this._renderElements = null;
this._owner = null;
this._sharedMaterials = null;
this._bounds = null;
this._lightmapScaleOffset = null;
this._scene = null;
}
markAsUnStatic() {
if (this._isPartOfStaticBatch) {
MeshRenderStaticBatchManager.instance._removeRenderSprite(this._owner);
this._isPartOfStaticBatch = false;
}
}
}
BaseRender._tempBoundBoxCorners = [new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3()];
BaseRender._uniqueIDCounter = 0;
BaseRender._defaultLightmapScaleOffset = new Vector4(1.0, 1.0, 0.0, 0.0);
class PixelLineRenderer extends BaseRender {
constructor(owner) {
super(owner);
this._projectionViewWorldMatrix = new Matrix4x4();
}
_calculateBoundingBox() {
var worldMat = this._owner.transform.worldMatrix;
var lineFilter = this._owner._geometryFilter;
lineFilter._reCalculateBound();
lineFilter._bounds._tranform(worldMat, this._bounds);
}
_renderUpdateWithCamera(context, transform) {
var projectionView = context.projectionViewMatrix;
var sv = this._shaderValues;
if (transform) {
var worldMat = transform.worldMatrix;
sv.setMatrix4x4(Sprite3D.WORLDMATRIX, worldMat);
Matrix4x4.multiply(projectionView, worldMat, this._projectionViewWorldMatrix);
sv.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix);
}
else {
sv.setMatrix4x4(Sprite3D.WORLDMATRIX, Matrix4x4.DEFAULT);
sv.setMatrix4x4(Sprite3D.MVPMATRIX, projectionView);
}
}
}
class PixelLineSprite3D extends RenderableSprite3D {
constructor(maxCount = 2, name = null) {
super(name);
this._isRenderActive = false;
this._isInRenders = false;
this._geometryFilter = new PixelLineFilter(this, maxCount);
this._render = new PixelLineRenderer(this);
this._changeRenderObjects(0, PixelLineMaterial.defaultMaterial);
}
get maxLineCount() {
return this._geometryFilter._maxLineCount;
}
set maxLineCount(value) {
this._geometryFilter._resizeLineData(value);
this._geometryFilter._lineCount = Math.min(this._geometryFilter._lineCount, value);
}
get lineCount() {
return this._geometryFilter._lineCount;
}
set lineCount(value) {
if (value > this.maxLineCount)
throw "PixelLineSprite3D: lineCount can't large than maxLineCount";
else
this._geometryFilter._lineCount = value;
}
get pixelLineRenderer() {
return this._render;
}
_onInActive() {
Laya.Stat.spriteCount--;
if (this._geometryFilter._lineCount != 0 && this._isRenderActive) {
this._scene._removeRenderObject(this._render);
this._isInRenders = false;
}
this._isRenderActive = false;
}
_onActive() {
Laya.Stat.spriteCount++;
this._isRenderActive = true;
if (this._geometryFilter._lineCount != 0) {
this._scene._addRenderObject(this._render);
this._isInRenders = true;
}
}
_changeRenderObjects(index, material) {
var renderObjects = this._render._renderElements;
(material) || (material = PixelLineMaterial.defaultMaterial);
var renderElement = renderObjects[index];
(renderElement) || (renderElement = renderObjects[index] = new RenderElement());
renderElement.setTransform(this._transform);
renderElement.setGeometry(this._geometryFilter);
renderElement.render = this._render;
renderElement.material = material;
}
addLine(startPosition, endPosition, startColor, endColor) {
if (this._geometryFilter._lineCount !== this._geometryFilter._maxLineCount)
this._geometryFilter._updateLineData(this._geometryFilter._lineCount++, startPosition, endPosition, startColor, endColor);
else
throw "PixelLineSprite3D: lineCount has equal with maxLineCount.";
if (this._isRenderActive && !this._isInRenders && this._geometryFilter._lineCount > 0) {
this._scene._addRenderObject(this._render);
this._isInRenders = true;
}
}
addLines(lines) {
var lineCount = this._geometryFilter._lineCount;
var addCount = lines.length;
if (lineCount + addCount > this._geometryFilter._maxLineCount) {
throw "PixelLineSprite3D: lineCount plus lines count must less than maxLineCount.";
}
else {
this._geometryFilter._updateLineDatas(lineCount, lines);
this._geometryFilter._lineCount += addCount;
}
if (this._isRenderActive && !this._isInRenders && this._geometryFilter._lineCount > 0) {
this._scene._addRenderObject(this._render);
this._isInRenders = true;
}
}
removeLine(index) {
if (index < this._geometryFilter._lineCount)
this._geometryFilter._removeLineData(index);
else
throw "PixelLineSprite3D: index must less than lineCount.";
if (this._isRenderActive && this._isInRenders && this._geometryFilter._lineCount == 0) {
this._scene._removeRenderObject(this._render);
this._isInRenders = false;
}
}
setLine(index, startPosition, endPosition, startColor, endColor) {
if (index < this._geometryFilter._lineCount)
this._geometryFilter._updateLineData(index, startPosition, endPosition, startColor, endColor);
else
throw "PixelLineSprite3D: index must less than lineCount.";
}
getLine(index, out) {
if (index < this.lineCount)
this._geometryFilter._getLineData(index, out);
else
throw "PixelLineSprite3D: index must less than lineCount.";
}
clear() {
this._geometryFilter._lineCount = 0;
if (this._isRenderActive && this._isInRenders) {
this._scene._removeRenderObject(this._render);
this._isInRenders = false;
}
}
_create() {
return new PixelLineSprite3D();
}
}
class RenderQueue {
constructor(isTransparent = false) {
this.isTransparent = false;
this.elements = new SingletonList();
this.lastTransparentRenderElement = null;
this.lastTransparentBatched = false;
this.isTransparent = isTransparent;
}
_compare(left, right) {
var renderQueue = left.material.renderQueue - right.material.renderQueue;
if (renderQueue === 0) {
var sort = this.isTransparent ? right.render._distanceForSort - left.render._distanceForSort : left.render._distanceForSort - right.render._distanceForSort;
return sort + right.render.sortingFudge - left.render.sortingFudge;
}
else {
return renderQueue;
}
}
_partitionRenderObject(left, right) {
var elements = this.elements.elements;
var pivot = elements[Math.floor((right + left) / 2)];
while (left <= right) {
while (this._compare(elements[left], pivot) < 0)
left++;
while (this._compare(elements[right], pivot) > 0)
right--;
if (left < right) {
var temp = elements[left];
elements[left] = elements[right];
elements[right] = temp;
left++;
right--;
}
else if (left === right) {
left++;
break;
}
}
return left;
}
_quickSort(left, right) {
if (this.elements.length > 1) {
var index = this._partitionRenderObject(left, right);
var leftIndex = index - 1;
if (left < leftIndex)
this._quickSort(left, leftIndex);
if (index < right)
this._quickSort(index, right);
}
}
_render(context) {
var elements = this.elements.elements;
for (var i = 0, n = this.elements.length; i < n; i++)
elements[i]._render(context);
}
clear() {
this.elements.length = 0;
this.lastTransparentRenderElement = null;
this.lastTransparentBatched = false;
}
}
class BoundsOctreeNode {
constructor(octree, parent, baseLength, center) {
this._bounds = new BoundBox(new Vector3(), new Vector3());
this._objects = [];
this._isContaion = false;
this.center = new Vector3();
this.baseLength = 0.0;
this._setValues(octree, parent, baseLength, center);
}
static _encapsulates(outerBound, innerBound) {
return CollisionUtils.boxContainsBox(outerBound, innerBound) == ContainmentType.Contains;
}
_setValues(octree, parent, baseLength, center) {
this._octree = octree;
this._parent = parent;
this.baseLength = baseLength;
center.cloneTo(this.center);
var min = this._bounds.min;
var max = this._bounds.max;
var halfSize = (octree._looseness * baseLength) / 2;
min.setValue(center.x - halfSize, center.y - halfSize, center.z - halfSize);
max.setValue(center.x + halfSize, center.y + halfSize, center.z + halfSize);
}
_getChildBound(index) {
if (this._children != null && this._children[index]) {
return this._children[index]._bounds;
}
else {
var quarter = this.baseLength / 4;
var halfChildSize = ((this.baseLength / 2) * this._octree._looseness) / 2;
var bounds = BoundsOctreeNode._tempBoundBox;
var min = bounds.min;
var max = bounds.max;
switch (index) {
case 0:
min.x = this.center.x - quarter - halfChildSize;
min.y = this.center.y + quarter - halfChildSize;
min.z = this.center.z - quarter - halfChildSize;
max.x = this.center.x - quarter + halfChildSize;
max.y = this.center.y + quarter + halfChildSize;
max.z = this.center.z - quarter + halfChildSize;
break;
case 1:
min.x = this.center.x + quarter - halfChildSize;
min.y = this.center.y + quarter - halfChildSize;
min.z = this.center.z - quarter - halfChildSize;
max.x = this.center.x + quarter + halfChildSize;
max.y = this.center.y + quarter + halfChildSize;
max.z = this.center.z - quarter + halfChildSize;
break;
case 2:
min.x = this.center.x - quarter - halfChildSize;
min.y = this.center.y + quarter - halfChildSize;
min.z = this.center.z + quarter - halfChildSize;
max.x = this.center.x - quarter + halfChildSize;
max.y = this.center.y + quarter + halfChildSize;
max.z = this.center.z + quarter + halfChildSize;
break;
case 3:
min.x = this.center.x + quarter - halfChildSize;
min.y = this.center.y + quarter - halfChildSize;
min.z = this.center.z + quarter - halfChildSize;
max.x = this.center.x + quarter + halfChildSize;
max.y = this.center.y + quarter + halfChildSize;
max.z = this.center.z + quarter + halfChildSize;
break;
case 4:
min.x = this.center.x - quarter - halfChildSize;
min.y = this.center.y - quarter - halfChildSize;
min.z = this.center.z - quarter - halfChildSize;
max.x = this.center.x - quarter + halfChildSize;
max.y = this.center.y - quarter + halfChildSize;
max.z = this.center.z - quarter + halfChildSize;
break;
case 5:
min.x = this.center.x + quarter - halfChildSize;
min.y = this.center.y - quarter - halfChildSize;
min.z = this.center.z - quarter - halfChildSize;
max.x = this.center.x + quarter + halfChildSize;
max.y = this.center.y - quarter + halfChildSize;
max.z = this.center.z - quarter + halfChildSize;
break;
case 6:
min.x = this.center.x - quarter - halfChildSize;
min.y = this.center.y - quarter - halfChildSize;
min.z = this.center.z + quarter - halfChildSize;
max.x = this.center.x - quarter + halfChildSize;
max.y = this.center.y - quarter + halfChildSize;
max.z = this.center.z + quarter + halfChildSize;
break;
case 7:
min.x = this.center.x + quarter - halfChildSize;
min.y = this.center.y - quarter - halfChildSize;
min.z = this.center.z + quarter - halfChildSize;
max.x = this.center.x + quarter + halfChildSize;
max.y = this.center.y - quarter + halfChildSize;
max.z = this.center.z + quarter + halfChildSize;
break;
}
return bounds;
}
}
_getChildCenter(index) {
if (this._children != null) {
return this._children[index].center;
}
else {
var quarter = this.baseLength / 4;
var childCenter = BoundsOctreeNode._tempVector30;
switch (index) {
case 0:
childCenter.x = this.center.x - quarter;
childCenter.y = this.center.y + quarter;
childCenter.z = this.center.z - quarter;
break;
case 1:
childCenter.x = this.center.x + quarter;
childCenter.y = this.center.y + quarter;
childCenter.z = this.center.z - quarter;
break;
case 2:
childCenter.x = this.center.x - quarter;
childCenter.y = this.center.y + quarter;
childCenter.z = this.center.z + quarter;
break;
case 3:
childCenter.x = this.center.x + quarter;
childCenter.y = this.center.y + quarter;
childCenter.z = this.center.z + quarter;
break;
case 4:
childCenter.x = this.center.x - quarter;
childCenter.y = this.center.y - quarter;
childCenter.z = this.center.z - quarter;
break;
case 5:
childCenter.x = this.center.x + quarter;
childCenter.y = this.center.y - quarter;
childCenter.z = this.center.z - quarter;
break;
case 6:
childCenter.x = this.center.x - quarter;
childCenter.y = this.center.y - quarter;
childCenter.z = this.center.z + quarter;
break;
case 7:
childCenter.x = this.center.x + quarter;
childCenter.y = this.center.y - quarter;
childCenter.z = this.center.z + quarter;
break;
}
return childCenter;
}
}
_getChild(index) {
var quarter = this.baseLength / 4;
this._children || (this._children = []);
switch (index) {
case 0:
return this._children[0] || (this._children[0] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + -quarter, this.center.y + quarter, this.center.z - quarter)));
case 1:
return this._children[1] || (this._children[1] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + quarter, this.center.y + quarter, this.center.z - quarter)));
case 2:
return this._children[2] || (this._children[2] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x - quarter, this.center.y + quarter, this.center.z + quarter)));
case 3:
return this._children[3] || (this._children[3] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + quarter, this.center.y + quarter, this.center.z + quarter)));
case 4:
return this._children[4] || (this._children[4] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x - quarter, this.center.y - quarter, this.center.z - quarter)));
case 5:
return this._children[5] || (this._children[5] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + quarter, this.center.y - quarter, this.center.z - quarter)));
case 6:
return this._children[6] || (this._children[6] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x - quarter, this.center.y - quarter, this.center.z + quarter)));
case 7:
return this._children[7] || (this._children[7] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + quarter, this.center.y - quarter, this.center.z + quarter)));
default:
throw "BoundsOctreeNode: unknown index.";
}
}
_shouldMerge() {
var objectCount = this._objects.length;
for (var i = 0; i < 8; i++) {
var child = this._children[i];
if (child) {
if (child._children != null)
return false;
objectCount += child._objects.length;
}
}
return objectCount <= BoundsOctreeNode._NUM_OBJECTS_ALLOWED;
}
_mergeChildren() {
for (var i = 0; i < 8; i++) {
var child = this._children[i];
if (child) {
child._parent = null;
var childObjects = child._objects;
for (var j = childObjects.length - 1; j >= 0; j--) {
var childObject = childObjects[j];
this._objects.push(childObject);
childObject._setOctreeNode(this);
}
}
}
this._children = null;
}
_merge() {
if (this._children === null) {
var parent = this._parent;
if (parent && parent._shouldMerge()) {
parent._mergeChildren();
parent._merge();
}
}
}
_checkAddNode(object) {
if (this._children == null) {
if (this._objects.length < BoundsOctreeNode._NUM_OBJECTS_ALLOWED || (this.baseLength / 2) < this._octree._minSize) {
return this;
}
for (var i = this._objects.length - 1; i >= 0; i--) {
var existObject = this._objects[i];
var fitChildIndex = this._bestFitChild(existObject.bounds.getCenter());
if (BoundsOctreeNode._encapsulates(this._getChildBound(fitChildIndex), existObject.bounds._getBoundBox())) {
this._objects.splice(this._objects.indexOf(existObject), 1);
this._getChild(fitChildIndex)._add(existObject);
}
}
}
var newFitChildIndex = this._bestFitChild(object.bounds.getCenter());
if (BoundsOctreeNode._encapsulates(this._getChildBound(newFitChildIndex), object.bounds._getBoundBox()))
return this._getChild(newFitChildIndex)._checkAddNode(object);
else
return this;
}
_add(object) {
var addNode = this._checkAddNode(object);
addNode._objects.push(object);
object._setOctreeNode(addNode);
}
_remove(object) {
var index = this._objects.indexOf(object);
this._objects.splice(index, 1);
object._setOctreeNode(null);
this._merge();
}
_addUp(object) {
if ((CollisionUtils.boxContainsBox(this._bounds, object.bounds._getBoundBox()) === ContainmentType.Contains)) {
this._add(object);
return true;
}
else {
if (this._parent)
return this._parent._addUp(object);
else
return false;
}
}
_getCollidingWithFrustum(cameraCullInfo, context, testVisible, customShader, replacementTag, isShadowCasterCull) {
var frustum = cameraCullInfo.boundFrustum;
var camPos = cameraCullInfo.position;
var cullMask = cameraCullInfo.cullingMask;
if (testVisible) {
var type = frustum.containsBoundBox(this._bounds);
Laya.Stat.octreeNodeCulling++;
if (type === ContainmentType.Disjoint) {
for (var i = 0, n = this._objects.length; i < n; i++) {
this._objects[i]._OctreeNoRender();
}
return;
}
testVisible = (type === ContainmentType.Intersects);
}
this._isContaion = !testVisible;
var scene = context.scene;
var loopCount = Laya.Stat.loopCount;
for (var i = 0, n = this._objects.length; i < n; i++) {
var render = this._objects[i];
var canPass;
if (isShadowCasterCull)
canPass = render._castShadow && render._enable;
else
canPass = (((Math.pow(2, render._owner._layer) & cullMask) != 0)) && render._enable;
if (canPass) {
if (testVisible) {
Laya.Stat.frustumCulling++;
if (!render._needRender(frustum, context))
continue;
}
render._renderMark = loopCount;
render._distanceForSort = Vector3.distance(render.bounds.getCenter(), camPos);
var elements = render._renderElements;
for (var j = 0, m = elements.length; j < m; j++) {
var element = elements[j];
element._update(scene, context, customShader, replacementTag);
}
}
}
if (this._children != null) {
for (i = 0; i < 8; i++) {
var child = this._children[i];
child && child._getCollidingWithFrustum(cameraCullInfo, context, testVisible, customShader, replacementTag, isShadowCasterCull);
}
}
}
_getCollidingWithCastShadowFrustum(cullInfo, context) {
var cullPlaneCount = cullInfo.cullPlaneCount;
var cullPlanes = cullInfo.cullPlanes;
var min = this._bounds.min;
var max = this._bounds.max;
var minX = min.x;
var minY = min.y;
var minZ = min.z;
var maxX = max.x;
var maxY = max.y;
var maxZ = max.z;
var pass = true;
for (var j = 0; j < cullPlaneCount; j++) {
var plane = cullPlanes[j];
var normal = plane.normal;
if (plane.distance + (normal.x * (normal.x < 0.0 ? minX : maxX)) + (normal.y * (normal.y < 0.0 ? minY : maxY)) + (normal.z * (normal.z < 0.0 ? minZ : maxZ)) < 0.0) {
pass = false;
break;
}
}
if (!pass)
return;
var scene = context.scene;
var loopCount = Laya.Stat.loopCount;
for (var i = 0, n = this._objects.length; i < n; i++) {
var render = this._objects[i];
var canPass;
let pass = true;
canPass = render._castShadow && render._enable;
if (canPass) {
for (var j = 0; j < cullPlaneCount; j++) {
var plane = cullPlanes[j];
var normal = plane.normal;
if (plane.distance + (normal.x * (normal.x < 0.0 ? minX : maxX)) + (normal.y * (normal.y < 0.0 ? minY : maxY)) + (normal.z * (normal.z < 0.0 ? minZ : maxZ)) < 0.0) {
pass = false;
break;
}
}
}
if (!pass || !canPass)
continue;
render._renderMark = loopCount;
render._distanceForSort = Vector3.distance(render.bounds.getCenter(), cullInfo.position);
var elements = render._renderElements;
for (var j = 0, m = elements.length; j < m; j++) {
var element = elements[j];
element._update(scene, context, null, null);
}
}
if (this._children != null) {
for (i = 0; i < 8; i++) {
var child = this._children[i];
child && child._getCollidingWithCastShadowFrustum(cullInfo, context);
}
}
}
_getCollidingWithBoundBox(checkBound, testVisible, result) {
if (testVisible) {
var type = CollisionUtils.boxContainsBox(this._bounds, checkBound);
if (type === ContainmentType.Disjoint)
return;
testVisible = (type === ContainmentType.Intersects);
}
if (testVisible) {
for (var i = 0, n = this._objects.length; i < n; i++) {
var object = this._objects[i];
if (CollisionUtils.intersectsBoxAndBox(object.bounds._getBoundBox(), checkBound)) {
result.push(object);
}
}
}
if (this._children != null) {
for (i = 0; i < 8; i++) {
var child = this._children[i];
child._getCollidingWithBoundBox(checkBound, testVisible, result);
}
}
}
_bestFitChild(boundCenter) {
return (boundCenter.x <= this.center.x ? 0 : 1) + (boundCenter.y >= this.center.y ? 0 : 4) + (boundCenter.z <= this.center.z ? 0 : 2);
}
_update(object) {
if (CollisionUtils.boxContainsBox(this._bounds, object.bounds._getBoundBox()) === ContainmentType.Contains) {
var addNode = this._checkAddNode(object);
if (addNode !== object._getOctreeNode()) {
addNode._objects.push(object);
object._setOctreeNode(addNode);
var index = this._objects.indexOf(object);
this._objects.splice(index, 1);
this._merge();
}
return true;
}
else {
if (this._parent) {
var sucess = this._parent._addUp(object);
if (sucess) {
index = this._objects.indexOf(object);
this._objects.splice(index, 1);
this._merge();
}
return sucess;
}
else {
return false;
}
}
}
add(object) {
if (!BoundsOctreeNode._encapsulates(this._bounds, object.bounds._getBoundBox()))
return false;
this._add(object);
return true;
}
remove(object) {
if (object._getOctreeNode() !== this)
return false;
this._remove(object);
return true;
}
update(object) {
if (object._getOctreeNode() !== this)
return false;
return this._update(object);
}
shrinkIfPossible(minLength) {
if (this.baseLength < minLength * 2)
return this;
var bestFit = -1;
for (var i = 0, n = this._objects.length; i < n; i++) {
var object = this._objects[i];
var newBestFit = this._bestFitChild(object.bounds.getCenter());
if (i == 0 || newBestFit == bestFit) {
var childBounds = this._getChildBound(newBestFit);
if (BoundsOctreeNode._encapsulates(childBounds, object.bounds._getBoundBox()))
(i == 0) && (bestFit = newBestFit);
else
return this;
}
else {
return this;
}
}
if (this._children != null) {
var childHadContent = false;
for (i = 0, n = this._children.length; i < n; i++) {
var child = this._children[i];
if (child && child.hasAnyObjects()) {
if (childHadContent)
return this;
if (bestFit >= 0 && bestFit != i)
return this;
childHadContent = true;
bestFit = i;
}
}
}
else {
if (bestFit != -1) {
var childCenter = this._getChildCenter(bestFit);
this._setValues(this._octree, null, this.baseLength / 2, childCenter);
}
return this;
}
if (bestFit != -1) {
var newRoot = this._children[bestFit];
newRoot._parent = null;
return newRoot;
}
else {
return this;
}
}
hasAnyObjects() {
if (this._objects.length > 0)
return true;
if (this._children != null) {
for (var i = 0; i < 8; i++) {
var child = this._children[i];
if (child && child.hasAnyObjects())
return true;
}
}
return false;
}
getCollidingWithBoundBox(checkBound, result) {
this._getCollidingWithBoundBox(checkBound, true, result);
}
getCollidingWithRay(ray, result, maxDistance = Number.MAX_VALUE) {
var distance = CollisionUtils.intersectsRayAndBoxRD(ray, this._bounds);
if (distance == -1 || distance > maxDistance)
return;
for (var i = 0, n = this._objects.length; i < n; i++) {
var object = this._objects[i];
distance = CollisionUtils.intersectsRayAndBoxRD(ray, object.bounds._getBoundBox());
if (distance !== -1 && distance <= maxDistance)
result.push(object);
}
if (this._children != null) {
for (i = 0; i < 8; i++) {
var child = this._children[i];
child.getCollidingWithRay(ray, result, maxDistance);
}
}
}
getCollidingWithFrustum(cameraCullInfo, context, customShader, replacementTag, isShadowCasterCull) {
this._getCollidingWithFrustum(cameraCullInfo, context, true, customShader, replacementTag, isShadowCasterCull);
}
getCollidingWithCastShadowFrustum(cameraCullInfo, contect) {
this._getCollidingWithCastShadowFrustum(cameraCullInfo, contect);
}
isCollidingWithBoundBox(checkBound) {
if (!(CollisionUtils.intersectsBoxAndBox(this._bounds, checkBound)))
return false;
for (var i = 0, n = this._objects.length; i < n; i++) {
var object = this._objects[i];
if (CollisionUtils.intersectsBoxAndBox(object.bounds._getBoundBox(), checkBound))
return true;
}
if (this._children != null) {
for (i = 0; i < 8; i++) {
var child = this._children[i];
if (child.isCollidingWithBoundBox(checkBound))
return true;
}
}
return false;
}
isCollidingWithRay(ray, maxDistance = Number.MAX_VALUE) {
var distance = CollisionUtils.intersectsRayAndBoxRD(ray, this._bounds);
if (distance == -1 || distance > maxDistance)
return false;
for (var i = 0, n = this._objects.length; i < n; i++) {
var object = this._objects[i];
distance = CollisionUtils.intersectsRayAndBoxRD(ray, object.bounds._getBoundBox());
if (distance !== -1 && distance <= maxDistance)
return true;
}
if (this._children != null) {
for (i = 0; i < 8; i++) {
var child = this._children[i];
if (child.isCollidingWithRay(ray, maxDistance))
return true;
}
}
return false;
}
getBound() {
return this._bounds;
}
drawAllBounds(debugLine, currentDepth, maxDepth) {
if (this._children === null && this._objects.length == 0)
return;
currentDepth++;
var color = BoundsOctreeNode._tempColor0;
if (this._isContaion) {
color.r = 0.0;
color.g = 0.0;
color.b = 1.0;
}
else {
var tint = maxDepth ? currentDepth / maxDepth : 0;
color.r = 1.0 - tint;
color.g = tint;
color.b = 0.0;
}
color.a = 0.3;
Utils3D._drawBound(debugLine, this._bounds, color);
if (this._children != null) {
for (var i = 0; i < 8; i++) {
var child = this._children[i];
child && child.drawAllBounds(debugLine, currentDepth, maxDepth);
}
}
}
drawAllObjects(debugLine, currentDepth, maxDepth) {
currentDepth++;
var color = BoundsOctreeNode._tempColor0;
if (this._isContaion) {
color.r = 0.0;
color.g = 0.0;
color.b = 1.0;
}
else {
var tint = maxDepth ? currentDepth / maxDepth : 0;
color.r = 1.0 - tint;
color.g = tint;
color.b = 0.0;
}
color.a = 1.0;
for (var i = 0, n = this._objects.length; i < n; i++)
Utils3D._drawBound(debugLine, this._objects[i].bounds._getBoundBox(), color);
if (this._children != null) {
for (i = 0; i < 8; i++) {
var child = this._children[i];
child && child.drawAllObjects(debugLine, currentDepth, maxDepth);
}
}
}
}
BoundsOctreeNode._tempVector30 = new Vector3();
BoundsOctreeNode._tempColor0 = new Color();
BoundsOctreeNode._tempBoundBox = new BoundBox(new Vector3(), new Vector3());
BoundsOctreeNode._NUM_OBJECTS_ALLOWED = 8;
class OctreeMotionList extends SingletonList {
constructor() {
super();
}
add(element) {
var index = element._getIndexInMotionList();
if (index !== -1)
throw "OctreeMotionList:element has in PhysicsUpdateList.";
this._add(element);
element._setIndexInMotionList(this.length++);
}
remove(element) {
var index = element._getIndexInMotionList();
this.length--;
if (index !== this.length) {
var end = this.elements[this.length];
this.elements[index] = end;
end._setIndexInMotionList(index);
}
element._setIndexInMotionList(-1);
}
}
class BoundsOctree {
constructor(initialWorldSize, initialWorldPos, minNodeSize, looseness) {
this._motionObjects = new OctreeMotionList();
this.count = 0;
if (minNodeSize > initialWorldSize) {
console.warn("Minimum node size must be at least as big as the initial world size. Was: " + minNodeSize + " Adjusted to: " + initialWorldSize);
minNodeSize = initialWorldSize;
}
this._initialSize = initialWorldSize;
this._minSize = minNodeSize;
this._looseness = Math.min(Math.max(looseness, 1.0), 2.0);
this._rootNode = new BoundsOctreeNode(this, null, initialWorldSize, initialWorldPos);
}
_getMaxDepth(node, depth) {
depth++;
var children = node._children;
if (children != null) {
var curDepth = depth;
for (var i = 0, n = children.length; i < n; i++) {
var child = children[i];
child && (depth = Math.max(this._getMaxDepth(child, curDepth), depth));
}
}
return depth;
}
_grow(growObjectCenter) {
var xDirection = growObjectCenter.x >= 0 ? 1 : -1;
var yDirection = growObjectCenter.y >= 0 ? 1 : -1;
var zDirection = growObjectCenter.z >= 0 ? 1 : -1;
var oldRoot = this._rootNode;
var half = this._rootNode.baseLength / 2;
var newLength = this._rootNode.baseLength * 2;
var rootCenter = this._rootNode.center;
var newCenter = new Vector3(rootCenter.x + xDirection * half, rootCenter.y + yDirection * half, rootCenter.z + zDirection * half);
this._rootNode = new BoundsOctreeNode(this, null, newLength, newCenter);
if (oldRoot.hasAnyObjects()) {
var rootPos = this._rootNode._bestFitChild(oldRoot.center);
var children = [];
for (var i = 0; i < 8; i++) {
if (i == rootPos) {
oldRoot._parent = this._rootNode;
children[i] = oldRoot;
}
}
this._rootNode._children = children;
}
}
add(object) {
var count = 0;
while (!this._rootNode.add(object)) {
var growCenter = BoundsOctree._tempVector30;
Vector3.subtract(object.bounds.getCenter(), this._rootNode.center, growCenter);
this._grow(growCenter);
if (++count > 20) {
throw "Aborted Add operation as it seemed to be going on forever (" + (count - 1) + ") attempts at growing the octree.";
}
}
this.count++;
}
remove(object) {
var removed = object._getOctreeNode().remove(object);
if (removed) {
this.count--;
}
return removed;
}
update(object) {
var count = 0;
var octreeNode = object._getOctreeNode();
if (octreeNode) {
while (!octreeNode._update(object)) {
var growCenter = BoundsOctree._tempVector30;
Vector3.subtract(object.bounds.getCenter(), this._rootNode.center, growCenter);
this._grow(growCenter);
if (++count > 20) {
throw "Aborted Add operation as it seemed to be going on forever (" + (count - 1) + ") attempts at growing the octree.";
}
}
return true;
}
else {
return false;
}
}
shrinkRootIfPossible() {
this._rootNode = this._rootNode.shrinkIfPossible(this._initialSize);
}
addMotionObject(object) {
this._motionObjects.add(object);
}
removeMotionObject(object) {
this._motionObjects.remove(object);
}
updateMotionObjects() {
var elements = this._motionObjects.elements;
for (var i = 0, n = this._motionObjects.length; i < n; i++) {
var object = elements[i];
this.update(object);
object._setIndexInMotionList(-1);
}
this._motionObjects.length = 0;
}
isCollidingWithBoundBox(checkBounds) {
return this._rootNode.isCollidingWithBoundBox(checkBounds);
}
isCollidingWithRay(ray, maxDistance = Number.MAX_VALUE) {
return this._rootNode.isCollidingWithRay(ray, maxDistance);
}
getCollidingWithBoundBox(checkBound, result) {
this._rootNode.getCollidingWithBoundBox(checkBound, result);
}
getCollidingWithRay(ray, result, maxDistance = Number.MAX_VALUE) {
this._rootNode.getCollidingWithRay(ray, result, maxDistance);
}
getCollidingWithFrustum(cameraCullInfo, context, shader, replacementTag, isShadowCasterCull) {
this._rootNode.getCollidingWithFrustum(cameraCullInfo, context, shader, replacementTag, isShadowCasterCull);
}
getMaxBounds() {
return this._rootNode.getBound();
}
drawAllBounds(pixelLine) {
var maxDepth = this._getMaxDepth(this._rootNode, -1);
this._rootNode.drawAllBounds(pixelLine, -1, maxDepth);
}
drawAllObjects(pixelLine) {
var maxDepth = this._getMaxDepth(this._rootNode, -1);
this._rootNode.drawAllObjects(pixelLine, -1, maxDepth);
}
}
BoundsOctree._tempVector30 = new Vector3();
class Lightmap {
}
class BoundSphere {
constructor(center, radius) {
this.center = center;
this.radius = radius;
}
toDefault() {
this.center.toDefault();
this.radius = 0;
}
static createFromSubPoints(points, start, count, out) {
if (points == null) {
throw new Error("points");
}
if (start < 0 || start >= points.length) {
throw new Error("start" + start + "Must be in the range [0, " + (points.length - 1) + "]");
}
if (count < 0 || (start + count) > points.length) {
throw new Error("count" + count + "Must be in the range <= " + points.length + "}");
}
var upperEnd = start + count;
var center = BoundSphere._tempVector3;
center.x = 0;
center.y = 0;
center.z = 0;
for (var i = start; i < upperEnd; ++i) {
Vector3.add(points[i], center, center);
}
var outCenter = out.center;
Vector3.scale(center, 1 / count, outCenter);
var radius = 0.0;
for (i = start; i < upperEnd; ++i) {
var distance = Vector3.distanceSquared(outCenter, points[i]);
if (distance > radius)
radius = distance;
}
out.radius = Math.sqrt(radius);
}
static createfromPoints(points, out) {
if (points == null) {
throw new Error("points");
}
BoundSphere.createFromSubPoints(points, 0, points.length, out);
}
intersectsRayDistance(ray) {
return CollisionUtils.intersectsRayAndSphereRD(ray, this);
}
intersectsRayPoint(ray, outPoint) {
return CollisionUtils.intersectsRayAndSphereRP(ray, this, outPoint);
}
cloneTo(destObject) {
var dest = destObject;
this.center.cloneTo(dest.center);
dest.radius = this.radius;
}
clone() {
var dest = new BoundSphere(new Vector3(), 0);
this.cloneTo(dest);
return dest;
}
}
BoundSphere._tempVector3 = new Vector3();
class ShadowSliceData {
constructor() {
this.cameraShaderValue = new ShaderData();
this.position = new Vector3();
this.viewMatrix = new Matrix4x4();
this.projectionMatrix = new Matrix4x4();
this.viewProjectMatrix = new Matrix4x4();
this.cullPlanes = [new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3())];
this.splitBoundSphere = new BoundSphere(new Vector3(), 0.0);
}
}
class ShadowSpotData {
constructor() {
this.cameraShaderValue = new ShaderData();
this.position = new Vector3;
this.viewMatrix = new Matrix4x4();
this.projectionMatrix = new Matrix4x4();
this.viewProjectMatrix = new Matrix4x4();
this.cameraCullInfo = new CameraCullInfo();
}
}
(function (ShadowLightType) {
ShadowLightType[ShadowLightType["DirectionLight"] = 0] = "DirectionLight";
ShadowLightType[ShadowLightType["SpotLight"] = 1] = "SpotLight";
ShadowLightType[ShadowLightType["PointLight"] = 2] = "PointLight";
})(exports.ShadowLightType || (exports.ShadowLightType = {}));
class ShadowCasterPass {
constructor() {
this._shadowBias = new Vector4();
this._shadowParams = new Vector4();
this._shadowMapSize = new Vector4();
this._shadowSpotMapSize = new Vector4();
this._shadowMatrices = new Float32Array(16 * (ShadowCasterPass._maxCascades));
this._shadowSpotMatrices = new Matrix4x4();
this._splitBoundSpheres = new Float32Array(ShadowCasterPass._maxCascades * 4);
this._cascadeCount = 0;
this._shadowMapWidth = 0;
this._shadowMapHeight = 0;
this._shadowSliceDatas = [new ShadowSliceData(), new ShadowSliceData(), new ShadowSliceData(), new ShadowSliceData()];
this._shadowSpotData = new ShadowSpotData();
this._lightUp = new Vector3();
this._lightSide = new Vector3();
this._lightForward = new Vector3();
this._shadowSpotData.cameraCullInfo.boundFrustum = new BoundFrustum(new Matrix4x4());
}
_setupShadowCasterShaderValues(context, shaderValues, shadowSliceData, LightParam, shadowparams, shadowBias, lightType) {
shaderValues.setVector(ShadowCasterPass.SHADOW_BIAS, shadowBias);
switch (lightType) {
case exports.LightType.Directional:
shaderValues.setVector3(ShadowCasterPass.SHADOW_LIGHT_DIRECTION, LightParam);
break;
case exports.LightType.Spot:
shaderValues.setVector(ShadowCasterPass.SHADOW_PARAMS, shadowparams);
break;
case exports.LightType.Point:
break;
}
var cameraSV = shadowSliceData.cameraShaderValue;
cameraSV.setMatrix4x4(BaseCamera.VIEWMATRIX, shadowSliceData.viewMatrix);
cameraSV.setMatrix4x4(BaseCamera.PROJECTMATRIX, shadowSliceData.projectionMatrix);
cameraSV.setMatrix4x4(BaseCamera.VIEWPROJECTMATRIX, shadowSliceData.viewProjectMatrix);
context.viewMatrix = shadowSliceData.viewMatrix;
context.projectionMatrix = shadowSliceData.projectionMatrix;
context.projectionViewMatrix = shadowSliceData.viewProjectMatrix;
}
_setupShadowReceiverShaderValues(shaderValues) {
var light = this._light;
if (light.shadowCascadesMode !== exports.ShadowCascadesMode.NoCascades)
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_CASCADE);
else
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_CASCADE);
switch (light.shadowMode) {
case exports.ShadowMode.Hard:
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW);
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH);
break;
case exports.ShadowMode.SoftLow:
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW);
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH);
break;
case exports.ShadowMode.SoftHigh:
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH);
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW);
break;
}
shaderValues.setTexture(ShadowCasterPass.SHADOW_MAP, this._shadowDirectLightMap);
shaderValues.setBuffer(ShadowCasterPass.SHADOW_MATRICES, this._shadowMatrices);
shaderValues.setVector(ShadowCasterPass.SHADOW_MAP_SIZE, this._shadowMapSize);
shaderValues.setVector(ShadowCasterPass.SHADOW_PARAMS, this._shadowParams);
shaderValues.setBuffer(ShadowCasterPass.SHADOW_SPLIT_SPHERES, this._splitBoundSpheres);
}
_setupSpotShadowReceiverShaderValues(shaderValues) {
var spotLight = this._light;
switch (spotLight.shadowMode) {
case exports.ShadowMode.Hard:
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH);
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW);
break;
case exports.ShadowMode.SoftLow:
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW);
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH);
break;
case exports.ShadowMode.SoftHigh:
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH);
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW);
break;
}
shaderValues.setTexture(ShadowCasterPass.SHADOW_SPOTMAP, this._shadowSpotLightMap);
shaderValues.setMatrix4x4(ShadowCasterPass.SHADOW_SPOTMATRICES, this._shadowSpotMatrices);
shaderValues.setVector(ShadowCasterPass.SHADOW_SPOTMAP_SIZE, this._shadowSpotMapSize);
shaderValues.setVector(ShadowCasterPass.SHADOW_PARAMS, this._shadowParams);
}
update(camera, light, lightType) {
switch (lightType) {
case exports.ShadowLightType.DirectionLight:
this._light = light;
var lightWorld = ShadowCasterPass._tempMatrix0;
var lightWorldE = lightWorld.elements;
var lightUp = this._lightUp;
var lightSide = this._lightSide;
var lightForward = this._lightForward;
Matrix4x4.createFromQuaternion(light._transform.rotation, lightWorld);
lightSide.setValue(lightWorldE[0], lightWorldE[1], lightWorldE[2]);
lightUp.setValue(lightWorldE[4], lightWorldE[5], lightWorldE[6]);
lightForward.setValue(-lightWorldE[8], -lightWorldE[9], -lightWorldE[10]);
var atlasResolution = light._shadowResolution;
var cascadesMode = light._shadowCascadesMode;
var cascadesCount;
var shadowTileResolution;
var shadowMapWidth, shadowMapHeight;
if (cascadesMode == exports.ShadowCascadesMode.NoCascades) {
cascadesCount = 1;
shadowTileResolution = atlasResolution;
shadowMapWidth = atlasResolution;
shadowMapHeight = atlasResolution;
}
else {
cascadesCount = cascadesMode == exports.ShadowCascadesMode.TwoCascades ? 2 : 4;
shadowTileResolution = ShadowUtils.getMaxTileResolutionInAtlas(atlasResolution, atlasResolution, cascadesCount);
shadowMapWidth = shadowTileResolution * 2;
shadowMapHeight = cascadesMode == exports.ShadowCascadesMode.TwoCascades ? shadowTileResolution : shadowTileResolution * 2;
}
this._cascadeCount = cascadesCount;
this._shadowMapWidth = shadowMapWidth;
this._shadowMapHeight = shadowMapHeight;
var splitDistance = ShadowCasterPass._cascadesSplitDistance;
var frustumPlanes = ShadowCasterPass._frustumPlanes;
var cameraNear = camera.nearPlane;
var shadowFar = Math.min(camera.farPlane, light._shadowDistance);
var shadowMatrices = this._shadowMatrices;
var boundSpheres = this._splitBoundSpheres;
ShadowUtils.getCascadesSplitDistance(light._shadowTwoCascadeSplits, light._shadowFourCascadeSplits, cameraNear, shadowFar, camera.fieldOfView * MathUtils3D.Deg2Rad, camera.aspectRatio, cascadesMode, splitDistance);
ShadowUtils.getCameraFrustumPlanes(camera.projectionViewMatrix, frustumPlanes);
var forward = ShadowCasterPass._tempVector30;
camera._transform.getForward(forward);
Vector3.normalize(forward, forward);
for (var i = 0; i < cascadesCount; i++) {
var sliceData = this._shadowSliceDatas[i];
sliceData.sphereCenterZ = ShadowUtils.getBoundSphereByFrustum(splitDistance[i], splitDistance[i + 1], camera.fieldOfView * MathUtils3D.Deg2Rad, camera.aspectRatio, camera._transform.position, forward, sliceData.splitBoundSphere);
ShadowUtils.getDirectionLightShadowCullPlanes(frustumPlanes, i, splitDistance, cameraNear, lightForward, sliceData);
ShadowUtils.getDirectionalLightMatrices(lightUp, lightSide, lightForward, i, light._shadowNearPlane, shadowTileResolution, sliceData, shadowMatrices);
if (cascadesCount > 1)
ShadowUtils.applySliceTransform(sliceData, shadowMapWidth, shadowMapHeight, i, shadowMatrices);
}
ShadowUtils.prepareShadowReceiverShaderValues(light, shadowMapWidth, shadowMapHeight, this._shadowSliceDatas, cascadesCount, this._shadowMapSize, this._shadowParams, shadowMatrices, boundSpheres);
break;
case exports.ShadowLightType.SpotLight:
this._light = light;
var lightWorld = ShadowCasterPass._tempMatrix0;
var lightForward = this._lightForward;
var shadowResolution = this._light._shadowResolution;
this._shadowMapWidth = shadowResolution;
this._shadowMapHeight = shadowResolution;
var shadowSpotData = this._shadowSpotData;
ShadowUtils.getSpotLightShadowData(shadowSpotData, this._light, shadowResolution, this._shadowParams, this._shadowSpotMatrices, this._shadowSpotMapSize);
break;
case exports.ShadowLightType.PointLight:
break;
default:
throw ("There is no shadow of this type");
}
}
render(context, scene, lightType) {
switch (lightType) {
case exports.ShadowLightType.DirectionLight:
var shaderValues = scene._shaderValues;
context.pipelineMode = "ShadowCaster";
ShaderData.setRuntimeValueMode(false);
var shadowMap = this._shadowDirectLightMap = ShadowUtils.getTemporaryShadowTexture(this._shadowMapWidth, this._shadowMapHeight, Laya.RenderTextureDepthFormat.DEPTH_16);
shadowMap._start();
var light = this._light;
for (var i = 0, n = this._cascadeCount; i < n; i++) {
var sliceData = this._shadowSliceDatas[i];
ShadowUtils.getShadowBias(light, sliceData.projectionMatrix, sliceData.resolution, this._shadowBias);
this._setupShadowCasterShaderValues(context, shaderValues, sliceData, this._lightForward, this._shadowParams, this._shadowBias, exports.LightType.Directional);
var shadowCullInfo = FrustumCulling._shadowCullInfo;
shadowCullInfo.position = sliceData.position;
shadowCullInfo.cullPlanes = sliceData.cullPlanes;
shadowCullInfo.cullPlaneCount = sliceData.cullPlaneCount;
shadowCullInfo.cullSphere = sliceData.splitBoundSphere;
shadowCullInfo.direction = this._lightForward;
var needRender = FrustumCulling.cullingShadow(shadowCullInfo, scene, context);
context.cameraShaderValue = sliceData.cameraShaderValue;
Camera._updateMark++;
var gl = Laya.LayaGL.instance;
var resolution = sliceData.resolution;
var offsetX = sliceData.offsetX;
var offsetY = sliceData.offsetY;
gl.enable(gl.SCISSOR_TEST);
gl.viewport(offsetX, offsetY, resolution, resolution);
gl.scissor(offsetX, offsetY, resolution, resolution);
gl.clear(gl.DEPTH_BUFFER_BIT);
if (needRender) {
gl.scissor(offsetX + 1, offsetY + 1, resolution - 2, resolution - 2);
scene._opaqueQueue._render(context);
}
}
shadowMap._end();
this._setupShadowReceiverShaderValues(shaderValues);
ShaderData.setRuntimeValueMode(true);
context.pipelineMode = context.configPipeLineMode;
break;
case exports.ShadowLightType.SpotLight:
var shaderValues = scene._shaderValues;
context.pipelineMode = "ShadowCaster";
ShaderData.setRuntimeValueMode(false);
var spotlight = this._light;
var shadowMap = this._shadowSpotLightMap = ShadowUtils.getTemporaryShadowTexture(this._shadowMapWidth, this._shadowMapHeight, Laya.RenderTextureDepthFormat.DEPTH_16);
shadowMap._start();
var shadowSpotData = this._shadowSpotData;
ShadowUtils.getShadowBias(spotlight, shadowSpotData.projectionMatrix, shadowSpotData.resolution, this._shadowBias);
this._setupShadowCasterShaderValues(context, shaderValues, shadowSpotData, this._light.transform.position, this._shadowParams, this._shadowBias, exports.LightType.Spot);
var needRender = FrustumCulling.cullingSpotShadow(shadowSpotData.cameraCullInfo, scene, context);
context.cameraShaderValue = shadowSpotData.cameraShaderValue;
Camera._updateMark++;
var gl = Laya.LayaGL.instance;
gl.enable(gl.SCISSOR_TEST);
gl.viewport(shadowSpotData.offsetX, shadowSpotData.offsetY, shadowSpotData.resolution, shadowSpotData.resolution);
gl.scissor(shadowSpotData.offsetX, shadowSpotData.offsetY, shadowSpotData.resolution, shadowSpotData.resolution);
gl.clear(gl.DEPTH_BUFFER_BIT);
if (needRender) {
gl.scissor(shadowSpotData.offsetX, shadowSpotData.offsetY, shadowSpotData.resolution, shadowSpotData.resolution);
scene._opaqueQueue._render(context);
}
shadowMap._end();
this._setupSpotShadowReceiverShaderValues(shaderValues);
ShaderData.setRuntimeValueMode(true);
context.pipelineMode = context.configPipeLineMode;
break;
case exports.ShadowLightType.PointLight:
break;
default:
throw ("There is no shadow of this type");
}
}
cleanUp() {
this._shadowDirectLightMap && RenderTexture.recoverToPool(this._shadowDirectLightMap);
this._shadowSpotLightMap && RenderTexture.recoverToPool(this._shadowSpotLightMap);
this._shadowDirectLightMap = null;
this._shadowSpotLightMap = null;
this._light = null;
}
}
ShadowCasterPass._tempVector30 = new Vector3();
ShadowCasterPass._tempMatrix0 = new Matrix4x4();
ShadowCasterPass.SHADOW_BIAS = Shader3D.propertyNameToID("u_ShadowBias");
ShadowCasterPass.SHADOW_LIGHT_DIRECTION = Shader3D.propertyNameToID("u_ShadowLightDirection");
ShadowCasterPass.SHADOW_SPLIT_SPHERES = Shader3D.propertyNameToID("u_ShadowSplitSpheres");
ShadowCasterPass.SHADOW_MATRICES = Shader3D.propertyNameToID("u_ShadowMatrices");
ShadowCasterPass.SHADOW_MAP_SIZE = Shader3D.propertyNameToID("u_ShadowMapSize");
ShadowCasterPass.SHADOW_MAP = Shader3D.propertyNameToID("u_ShadowMap");
ShadowCasterPass.SHADOW_PARAMS = Shader3D.propertyNameToID("u_ShadowParams");
ShadowCasterPass.SHADOW_SPOTMAP_SIZE = Shader3D.propertyNameToID("u_SpotShadowMapSize");
ShadowCasterPass.SHADOW_SPOTMAP = Shader3D.propertyNameToID("u_SpotShadowMap");
ShadowCasterPass.SHADOW_SPOTMATRICES = Shader3D.propertyNameToID("u_SpotViewProjectMatrix");
ShadowCasterPass._maxCascades = 4;
ShadowCasterPass._cascadesSplitDistance = new Array(ShadowCasterPass._maxCascades + 1);
ShadowCasterPass._frustumPlanes = new Array(new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()));
class DynamicBatchManager {
constructor() {
this._batchRenderElementPool = [];
}
static _registerManager(manager) {
DynamicBatchManager._managers.push(manager);
}
_clear() {
this._batchRenderElementPoolIndex = 0;
}
_getBatchRenderElementFromPool() {
throw "StaticBatch:must override this function.";
}
dispose() {
}
}
DynamicBatchManager._managers = [];
class ReflectionProbeList extends SingletonList {
constructor() {
super();
}
add(singleElement) {
this._add(singleElement);
singleElement._setIndexInReflectionList(this.length++);
}
remove(singleElement) {
var index = singleElement._getIndexInReflectionList();
this.length--;
if (index !== this.length) {
var end = this.elements[this.length];
this.elements[index] = end;
end._setIndexInReflectionList(index);
}
singleElement._setIndexInReflectionList(-1);
}
}
class ReflectionProbeManager {
constructor() {
this._reflectionProbes = new ReflectionProbeList();
this._motionObjects = new SingletonList();
this._needUpdateAllRender = false;
this._sceneReflectionProbe = new ReflectionProbe();
this._sceneReflectionProbe.bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
this._sceneReflectionProbe.boxProjection = false;
this._sceneReflectionProbe._isScene = true;
}
set sceneReflectionProbe(value) {
this._sceneReflectionProbe.reflectionTexture = value;
}
set sceneReflectionCubeHDRParam(value) {
this._sceneReflectionProbe.reflectionHDRParams = value;
}
_updateMotionObjects(baseRender) {
if (this._reflectionProbes.length == 0) {
baseRender._probReflection = this._sceneReflectionProbe;
return;
}
var elements = this._reflectionProbes.elements;
var maxOverlap = 0;
var mainProbe;
var renderBounds = baseRender.bounds;
var overlop;
for (var i = 0, n = this._reflectionProbes.length; i < n; i++) {
var renflectProbe = elements[i];
if (!mainProbe) {
overlop = renderBounds.calculateBoundsintersection(renflectProbe.bounds);
if (overlop < maxOverlap)
continue;
}
else {
if (mainProbe.importance > renflectProbe.importance)
continue;
overlop = renderBounds.calculateBoundsintersection(renflectProbe.bounds);
if (overlop < maxOverlap && mainProbe.importance == renflectProbe.importance)
continue;
}
mainProbe = renflectProbe;
maxOverlap = overlop;
}
if (!mainProbe && this._sceneReflectionProbe)
mainProbe = this._sceneReflectionProbe;
baseRender._probReflection = mainProbe;
}
add(reflectionProbe) {
this._reflectionProbes.add(reflectionProbe);
this._needUpdateAllRender = true;
}
remove(reflectionProbe) {
this._reflectionProbes.remove(reflectionProbe);
this._needUpdateAllRender = true;
}
addMotionObject(renderObject) {
this._motionObjects.add(renderObject);
}
update() {
var elements = this._motionObjects.elements;
for (var i = 0, n = this._motionObjects.length; i < n; i++) {
this._updateMotionObjects(elements[i]);
}
this.clearMotionObjects();
}
updateAllRenderObjects(baseRenders) {
var elements = baseRenders.elements;
for (var i = 0, n = baseRenders.length; i < n; i++) {
this._updateMotionObjects(elements[i]);
}
this._needUpdateAllRender = false;
}
clearMotionObjects() {
this._motionObjects.length = 0;
}
destroy() {
}
}
(function (AmbientMode) {
AmbientMode[AmbientMode["SolidColor"] = 0] = "SolidColor";
AmbientMode[AmbientMode["SphericalHarmonics"] = 1] = "SphericalHarmonics";
})(exports.AmbientMode || (exports.AmbientMode = {}));
class Scene3D extends Laya.Sprite {
constructor() {
super();
this._lightCount = 0;
this._pointLights = new LightQueue();
this._spotLights = new LightQueue();
this._directionLights = new LightQueue();
this._alternateLights = new AlternateLightQueue();
this._lightmaps = [];
this._skyRenderer = new SkyRenderer();
this._input = new Input3D();
this._timer = Laya.ILaya.timer;
this._time = 0;
this._shCoefficients = new Array(7);
this._ambientMode = exports.AmbientMode.SolidColor;
this._ambientSphericalHarmonics = new SphericalHarmonicsL2();
this._ambientSphericalHarmonicsIntensity = 1.0;
this._reflectionDecodeFormat = Laya.TextureDecodeFormat.Normal;
this._reflectionIntensity = 1.0;
this._collsionTestList = [];
this._renders = new SimpleSingletonList();
this._opaqueQueue = new RenderQueue(false);
this._transparentQueue = new RenderQueue(true);
this._cameraPool = [];
this._animatorPool = new SimpleSingletonList();
this._scriptPool = new Array();
this._tempScriptPool = new Array();
this._needClearScriptPool = false;
this._reflectionCubeHDRParams = new Vector4();
this._reflectionProbeManager = new ReflectionProbeManager();
this.currentCreationLayer = Math.pow(2, 0);
this.enableLight = true;
this._key = new Laya.SubmitKey();
this._pickIdToSprite = new Object();
this._reflectionMode = 0;
if (!Config3D._config.isUseCannonPhysicsEngine && Physics3D._bullet)
this._physicsSimulation = new Laya.PhysicsSimulation(Scene3D.physicsSettings);
else if (Physics3D._cannon) {
this._cannonPhysicsSimulation = new Laya.CannonPhysicsSimulation(Scene3D.cannonPhysicsSettings);
}
this._shaderValues = new ShaderData(null);
this.enableFog = false;
this.fogStart = 300;
this.fogRange = 1000;
this.fogColor = new Vector3(0.7, 0.7, 0.7);
this.ambientColor = new Vector3(0.212, 0.227, 0.259);
this.reflectionIntensity = 1.0;
this.reflection = TextureCube.blackTexture;
for (var i = 0; i < 7; i++)
this._shCoefficients[i] = new Vector4();
this._reflectionProbeManager.sceneReflectionCubeHDRParam = this._reflectionCubeHDRParams;
this._scene = this;
this._input.__init__(Laya.Render.canvas, this);
if (Scene3D.octreeCulling)
this._octree = new BoundsOctree(Scene3D.octreeInitialSize, Scene3D.octreeInitialCenter, Scene3D.octreeMinNodeSize, Scene3D.octreeLooseness);
if (FrustumCulling.debugFrustumCulling) {
this._debugTool = new PixelLineSprite3D();
var lineMaterial = new PixelLineMaterial();
lineMaterial.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
lineMaterial.alphaTest = false;
lineMaterial.depthWrite = false;
lineMaterial.cull = RenderState.CULL_BACK;
lineMaterial.blend = RenderState.BLEND_ENABLE_ALL;
lineMaterial.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
lineMaterial.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
lineMaterial.depthTest = RenderState.DEPTHTEST_LESS;
this._debugTool.pixelLineRenderer.sharedMaterial = lineMaterial;
}
}
static __init__() {
var con = Config3D._config;
var multiLighting = con._multiLighting;
if (multiLighting) {
const width = 4;
var maxLightCount = con.maxLightCount;
var clusterSlices = con.lightClusterCount;
Cluster.instance = new Cluster(clusterSlices.x, clusterSlices.y, clusterSlices.z, Math.min(con.maxLightCount, con._maxAreaLightCountPerClusterAverage));
Scene3D._lightTexture = Utils3D._createFloatTextureBuffer(width, maxLightCount);
Scene3D._lightTexture.lock = true;
Scene3D._lightPixles = new Float32Array(maxLightCount * width * 4);
}
Scene3DShaderDeclaration.SHADERDEFINE_FOG = Shader3D.getDefineByName("FOG");
Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT = Shader3D.getDefineByName("DIRECTIONLIGHT");
Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT = Shader3D.getDefineByName("POINTLIGHT");
Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT = Shader3D.getDefineByName("SPOTLIGHT");
Scene3DShaderDeclaration.SHADERDEFINE_SHADOW = Shader3D.getDefineByName("SHADOW");
Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_CASCADE = Shader3D.getDefineByName("SHADOW_CASCADE");
Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW = Shader3D.getDefineByName("SHADOW_SOFT_SHADOW_LOW");
Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH = Shader3D.getDefineByName("SHADOW_SOFT_SHADOW_HIGH");
Scene3DShaderDeclaration.SHADERDEFINE_GI_AMBIENT_SH = Shader3D.getDefineByName("GI_AMBIENT_SH");
Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT = Shader3D.getDefineByName("SHADOW_SPOT");
Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW = Shader3D.getDefineByName("SHADOW_SPOT_SOFT_SHADOW_LOW");
Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH = Shader3D.getDefineByName("SHADOW_SPOT_SOFT_SHADOW_HIGH");
var config = Config3D._config;
var configShaderValue = Scene3D._configDefineValues;
(config._multiLighting) || (configShaderValue.add(Shader3D.SHADERDEFINE_LEGACYSINGALLIGHTING));
if (Laya.LayaGL.layaGPUInstance._isWebGL2)
configShaderValue.add(Shader3D.SHADERDEFINE_GRAPHICS_API_GLES3);
else
configShaderValue.add(Shader3D.SHADERDEFINE_GRAPHICS_API_GLES2);
switch (config.pbrRenderQuality) {
case exports.PBRRenderQuality.High:
configShaderValue.add(PBRMaterial.SHADERDEFINE_LAYA_PBR_BRDF_HIGH);
break;
case exports.PBRRenderQuality.Low:
configShaderValue.add(PBRMaterial.SHADERDEFINE_LAYA_PBR_BRDF_LOW);
break;
default:
throw "Scene3D:unknown shader quality.";
}
if (config.isUseCannonPhysicsEngine) {
Physics3D._cannon && (Scene3D.cannonPhysicsSettings = new Laya.CannonPhysicsSettings());
}
else {
Physics3D._bullet && (Scene3D.physicsSettings = new Laya.PhysicsSettings());
}
}
static load(url, complete) {
Laya.ILaya.loader.create(url, complete, null, Scene3D.HIERARCHY);
}
get url() {
return this._url;
}
get enableFog() {
return this._enableFog;
}
set enableFog(value) {
if (this._enableFog !== value) {
this._enableFog = value;
if (value) {
this._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_FOG);
}
else
this._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_FOG);
}
}
get fogColor() {
return this._shaderValues.getVector3(Scene3D.FOGCOLOR);
}
set fogColor(value) {
this._shaderValues.setVector3(Scene3D.FOGCOLOR, value);
}
get fogStart() {
return this._shaderValues.getNumber(Scene3D.FOGSTART);
}
set fogStart(value) {
this._shaderValues.setNumber(Scene3D.FOGSTART, value);
}
get fogRange() {
return this._shaderValues.getNumber(Scene3D.FOGRANGE);
}
set fogRange(value) {
this._shaderValues.setNumber(Scene3D.FOGRANGE, value);
}
get ambientMode() {
return this._ambientMode;
}
set ambientMode(value) {
if (this._ambientMode !== value) {
switch (value) {
case exports.AmbientMode.SolidColor:
this._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_GI_AMBIENT_SH);
break;
case exports.AmbientMode.SphericalHarmonics:
this._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_GI_AMBIENT_SH);
break;
default:
throw "Scene3D: unknown ambientMode.";
}
this._ambientMode = value;
}
}
get ambientColor() {
return this._shaderValues.getVector3(Scene3D.AMBIENTCOLOR);
}
set ambientColor(value) {
this._shaderValues.setVector3(Scene3D.AMBIENTCOLOR, value);
}
get ambientSphericalHarmonics() {
return this._ambientSphericalHarmonics;
}
set ambientSphericalHarmonics(value) {
var originalSH = value || SphericalHarmonicsL2._default;
this._applySHCoefficients(originalSH, Math.pow(this._ambientSphericalHarmonicsIntensity, 2.2));
if (this._ambientSphericalHarmonics != value)
value.cloneTo(this._ambientSphericalHarmonics);
}
get ambientSphericalHarmonicsIntensity() {
return this._ambientSphericalHarmonicsIntensity;
}
set ambientSphericalHarmonicsIntensity(value) {
value = Math.max(Math.min(value, 8.0), 0.0);
if (this._ambientSphericalHarmonicsIntensity !== value) {
var originalSH = this._ambientSphericalHarmonics || SphericalHarmonicsL2._default;
this._applySHCoefficients(originalSH, Math.pow(value, 2.2));
this._ambientSphericalHarmonicsIntensity = value;
}
}
get reflection() {
return this._reflection;
}
set reflection(value) {
value = value ? value : TextureCube.blackTexture;
if (this._reflection != value) {
value._addReference();
this._reflectionProbeManager.sceneReflectionProbe = value;
this._reflection = value;
this._reflectionProbeManager._needUpdateAllRender = true;
}
}
get reflectionDecodingFormat() {
return this._reflectionDecodeFormat;
}
set reflectionDecodingFormat(value) {
if (this._reflectionDecodeFormat != value) {
this._reflectionCubeHDRParams.x = this._reflectionIntensity;
if (this._reflectionDecodeFormat == Laya.TextureDecodeFormat.RGBM)
this._reflectionCubeHDRParams.x *= 5.0;
this._reflectionDecodeFormat = value;
this._reflectionProbeManager.sceneReflectionCubeHDRParam = this._reflectionCubeHDRParams;
}
}
get reflectionIntensity() {
return this._reflectionIntensity;
}
set reflectionIntensity(value) {
value = Math.max(Math.min(value, 1.0), 0.0);
this._reflectionCubeHDRParams.x = value;
if (this._reflectionDecodeFormat == Laya.TextureDecodeFormat.RGBM)
this._reflectionCubeHDRParams.x *= 5.0;
this._reflectionIntensity = value;
this._reflectionProbeManager.sceneReflectionCubeHDRParam = this._reflectionCubeHDRParams;
}
get skyRenderer() {
return this._skyRenderer;
}
get physicsSimulation() {
return this._physicsSimulation;
}
get cannonPhysicsSimulation() {
return this._cannonPhysicsSimulation;
}
get timer() {
return this._timer;
}
set timer(value) {
this._timer = value;
}
get input() {
return this._input;
}
get lightmaps() {
return this._lightmaps.slice();
}
set lightmaps(value) {
var maps = this._lightmaps;
if (maps) {
for (var i = 0, n = maps.length; i < n; i++) {
var map = maps[i];
map.lightmapColor._removeReference();
map.lightmapDirection._removeReference();
}
}
if (value) {
var count = value.length;
maps.length = count;
for (i = 0; i < count; i++) {
var map = value[i];
map.lightmapColor && map.lightmapColor._addReference();
map.lightmapDirection && map.lightmapDirection._addReference();
maps[i] = map;
}
}
else {
maps.length = 0;
}
}
_applySHCoefficients(originalSH, intensity) {
var optSH = this._shCoefficients;
for (var i = 0; i < 3; i++) {
var shaderSHA = optSH[i];
var shaderSHB = optSH[i + 3];
shaderSHA.setValue(originalSH.getCoefficient(i, 3) * intensity, originalSH.getCoefficient(i, 1) * intensity, originalSH.getCoefficient(i, 2) * intensity, (originalSH.getCoefficient(i, 0) - originalSH.getCoefficient(i, 6)) * intensity);
shaderSHB.setValue(originalSH.getCoefficient(i, 4) * intensity, originalSH.getCoefficient(i, 5) * intensity, originalSH.getCoefficient(i, 6) * 3 * intensity, originalSH.getCoefficient(i, 7) * intensity);
}
optSH[6].setValue(originalSH.getCoefficient(0, 8) * intensity, originalSH.getCoefficient(1, 8) * intensity, originalSH.getCoefficient(2, 8) * intensity, 1);
var shaderValues = this._shaderValues;
shaderValues.setVector(Scene3D.AMBIENTSHAR, optSH[0]);
shaderValues.setVector(Scene3D.AMBIENTSHAG, optSH[1]);
shaderValues.setVector(Scene3D.AMBIENTSHAB, optSH[2]);
shaderValues.setVector(Scene3D.AMBIENTSHBR, optSH[3]);
shaderValues.setVector(Scene3D.AMBIENTSHBG, optSH[4]);
shaderValues.setVector(Scene3D.AMBIENTSHBB, optSH[5]);
shaderValues.setVector(Scene3D.AMBIENTSHC, optSH[6]);
}
_update() {
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D);
var delta = this.timer._delta / 1000;
this._time += delta;
this._shaderValues.setNumber(Scene3D.TIME, this._time);
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS);
var simulation = this._physicsSimulation;
if (Physics3D._enablePhysics && !Laya.PhysicsSimulation.disableSimulation && !Config3D._config.isUseCannonPhysicsEngine) {
simulation._updatePhysicsTransformFromRender();
Laya.PhysicsComponent._addUpdateList = false;
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE);
simulation._simulate(delta);
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE);
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION);
simulation._updateCharacters();
Laya.PhysicsComponent._addUpdateList = true;
simulation._updateCollisions();
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION);
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS);
simulation._eventScripts();
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS);
}
if (Physics3D._cannon && Config3D._config.isUseCannonPhysicsEngine) {
var cannonSimulation = this._cannonPhysicsSimulation;
cannonSimulation._updatePhysicsTransformFromRender();
Laya.CannonPhysicsComponent._addUpdateList = false;
cannonSimulation._simulate(delta);
Laya.CannonPhysicsComponent._addUpdateList = true;
cannonSimulation._updateCollisions();
cannonSimulation._eventScripts();
}
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS);
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_UPDATESCRIPT);
this._input._update();
this._clearScript();
this._updateScript();
Animator._update(this);
Laya.VideoTexture._update();
if (this._reflectionProbeManager._needUpdateAllRender)
this._reflectionProbeManager.updateAllRenderObjects(this._renders);
else
this._reflectionProbeManager.update();
this._lateUpdateScript();
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_UPDATESCRIPT);
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D);
}
_binarySearchIndexInCameraPool(camera) {
var start = 0;
var end = this._cameraPool.length - 1;
var mid;
while (start <= end) {
mid = Math.floor((start + end) / 2);
var midValue = this._cameraPool[mid]._renderingOrder;
if (midValue == camera._renderingOrder)
return mid;
else if (midValue > camera._renderingOrder)
end = mid - 1;
else
start = mid + 1;
}
return start;
}
_allotPickColorByID(id, pickColor) {
var pickColorR = Math.floor(id / (255 * 255));
id -= pickColorR * 255 * 255;
var pickColorG = Math.floor(id / 255);
id -= pickColorG * 255;
var pickColorB = id;
pickColor.x = pickColorR / 255;
pickColor.y = pickColorG / 255;
pickColor.z = pickColorB / 255;
pickColor.w = 1.0;
}
_searchIDByPickColor(pickColor) {
var id = pickColor.x * 255 * 255 + pickColor.y * 255 + pickColor.z;
return id;
}
onEnable() {
this._input._onCanvasEvent(Laya.Render.canvas);
}
onDisable() {
this._input._offCanvasEvent(Laya.Render.canvas);
}
_setCreateURL(url) {
this._url = Laya.URL.formatURL(url);
}
_getGroup() {
return this._group;
}
_setGroup(value) {
this._group = value;
}
_clearScript() {
if (this._needClearScriptPool) {
var scripts = this._scriptPool;
for (var i = 0, n = scripts.length; i < n; i++) {
var script = scripts[i];
if (script) {
script._indexInPool = this._tempScriptPool.length;
this._tempScriptPool.push(script);
}
}
this._scriptPool = this._tempScriptPool;
scripts.length = 0;
this._tempScriptPool = scripts;
this._needClearScriptPool = false;
}
}
_updateScript() {
var scripts = this._scriptPool;
for (var i = 0, n = scripts.length; i < n; i++) {
var script = scripts[i];
(script && script.enabled) && (script.onUpdate());
}
}
_lateUpdateScript() {
var scripts = this._scriptPool;
for (var i = 0, n = scripts.length; i < n; i++) {
var script = scripts[i];
(script && script.enabled) && (script.onLateUpdate());
}
}
_onActive() {
super._onActive();
Laya.ILaya.stage._scene3Ds.push(this);
}
_onInActive() {
super._onInActive();
var scenes = Laya.ILaya.stage._scene3Ds;
scenes.splice(scenes.indexOf(this), 1);
}
_prepareSceneToRender() {
var shaderValues = this._shaderValues;
var multiLighting = Config3D._config._multiLighting;
if (multiLighting) {
var ligTex = Scene3D._lightTexture;
var ligPix = Scene3D._lightPixles;
const pixelWidth = ligTex.width;
const floatWidth = pixelWidth * 4;
var curCount = 0;
var dirCount = this._directionLights._length;
var dirElements = this._directionLights._elements;
if (dirCount > 0) {
var sunLightIndex = this._directionLights.getBrightestLight();
this._mainDirectionLight = dirElements[sunLightIndex];
this._directionLights.normalLightOrdering(sunLightIndex);
for (var i = 0; i < dirCount; i++, curCount++) {
var dirLight = dirElements[i];
var dir = dirLight._direction;
var intCor = dirLight._intensityColor;
var off = floatWidth * curCount;
Vector3.scale(dirLight.color, dirLight._intensity, intCor);
dirLight.transform.worldMatrix.getForward(dir);
Vector3.normalize(dir, dir);
ligPix[off] = intCor.x;
ligPix[off + 1] = intCor.y;
ligPix[off + 2] = intCor.z;
ligPix[off + 4] = dir.x;
ligPix[off + 5] = dir.y;
ligPix[off + 6] = dir.z;
if (i == 0) {
shaderValues.setVector3(Scene3D.SUNLIGHTDIRCOLOR, intCor);
shaderValues.setVector3(Scene3D.SUNLIGHTDIRECTION, dir);
}
}
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT);
}
else {
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT);
}
var poiCount = this._pointLights._length;
if (poiCount > 0) {
var poiElements = this._pointLights._elements;
var mainPointLightIndex = this._pointLights.getBrightestLight();
this._mainPointLight = poiElements[mainPointLightIndex];
this._pointLights.normalLightOrdering(mainPointLightIndex);
for (var i = 0; i < poiCount; i++, curCount++) {
var poiLight = poiElements[i];
var pos = poiLight.transform.position;
var intCor = poiLight._intensityColor;
var off = floatWidth * curCount;
Vector3.scale(poiLight.color, poiLight._intensity, intCor);
ligPix[off] = intCor.x;
ligPix[off + 1] = intCor.y;
ligPix[off + 2] = intCor.z;
ligPix[off + 3] = poiLight.range;
ligPix[off + 4] = pos.x;
ligPix[off + 5] = pos.y;
ligPix[off + 6] = pos.z;
}
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT);
}
else {
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT);
}
var spoCount = this._spotLights._length;
if (spoCount > 0) {
var spoElements = this._spotLights._elements;
var mainSpotLightIndex = this._spotLights.getBrightestLight();
this._mainSpotLight = spoElements[mainSpotLightIndex];
this._spotLights.normalLightOrdering(mainSpotLightIndex);
for (var i = 0; i < spoCount; i++, curCount++) {
var spoLight = spoElements[i];
var dir = spoLight._direction;
var pos = spoLight.transform.position;
var intCor = spoLight._intensityColor;
var off = floatWidth * curCount;
Vector3.scale(spoLight.color, spoLight._intensity, intCor);
spoLight.transform.worldMatrix.getForward(dir);
Vector3.normalize(dir, dir);
ligPix[off] = intCor.x;
ligPix[off + 1] = intCor.y;
ligPix[off + 2] = intCor.z;
ligPix[off + 3] = spoLight.range;
ligPix[off + 4] = pos.x;
ligPix[off + 5] = pos.y;
ligPix[off + 6] = pos.z;
ligPix[off + 7] = spoLight.spotAngle * Math.PI / 180;
ligPix[off + 8] = dir.x;
ligPix[off + 9] = dir.y;
ligPix[off + 10] = dir.z;
}
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
}
else {
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
}
(curCount > 0) && (ligTex.setSubPixels(0, 0, pixelWidth, curCount, ligPix, 0));
shaderValues.setTexture(Scene3D.LIGHTBUFFER, ligTex);
shaderValues.setInt(Scene3D.DIRECTIONLIGHTCOUNT, this._directionLights._length);
shaderValues.setTexture(Scene3D.CLUSTERBUFFER, Cluster.instance._clusterTexture);
}
else {
if (this._directionLights._length > 0) {
var dirLight = this._directionLights._elements[0];
this._mainDirectionLight = dirLight;
Vector3.scale(dirLight.color, dirLight._intensity, dirLight._intensityColor);
dirLight.transform.worldMatrix.getForward(dirLight._direction);
Vector3.normalize(dirLight._direction, dirLight._direction);
shaderValues.setVector3(Scene3D.LIGHTDIRCOLOR, dirLight._intensityColor);
shaderValues.setVector3(Scene3D.LIGHTDIRECTION, dirLight._direction);
shaderValues.setVector3(Scene3D.SUNLIGHTDIRCOLOR, dirLight._intensityColor);
shaderValues.setVector3(Scene3D.SUNLIGHTDIRECTION, dirLight._direction);
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT);
}
else {
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT);
}
if (this._pointLights._length > 0) {
var poiLight = this._pointLights._elements[0];
this._mainPointLight = poiLight;
Vector3.scale(poiLight.color, poiLight._intensity, poiLight._intensityColor);
shaderValues.setVector3(Scene3D.POINTLIGHTCOLOR, poiLight._intensityColor);
shaderValues.setVector3(Scene3D.POINTLIGHTPOS, poiLight.transform.position);
shaderValues.setNumber(Scene3D.POINTLIGHTRANGE, poiLight.range);
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT);
}
else {
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT);
}
if (this._spotLights._length > 0) {
var spotLight = this._spotLights._elements[0];
this._mainSpotLight = spotLight;
Vector3.scale(spotLight.color, spotLight._intensity, spotLight._intensityColor);
shaderValues.setVector3(Scene3D.SPOTLIGHTCOLOR, spotLight._intensityColor);
shaderValues.setVector3(Scene3D.SPOTLIGHTPOS, spotLight.transform.position);
spotLight.transform.worldMatrix.getForward(spotLight._direction);
Vector3.normalize(spotLight._direction, spotLight._direction);
shaderValues.setVector3(Scene3D.SPOTLIGHTDIRECTION, spotLight._direction);
shaderValues.setNumber(Scene3D.SPOTLIGHTRANGE, spotLight.range);
shaderValues.setNumber(Scene3D.SPOTLIGHTSPOTANGLE, spotLight.spotAngle * Math.PI / 180);
shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
}
else {
shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT);
}
}
}
_addScript(script) {
if (script._indexInPool != -1)
return;
var scripts = this._scriptPool;
script._indexInPool = scripts.length;
scripts.push(script);
}
_removeScript(script) {
if (script._indexInPool == -1)
return;
this._scriptPool[script._indexInPool] = null;
script._indexInPool = -1;
this._needClearScriptPool = true;
}
_preRenderScript() {
var scripts = this._scriptPool;
for (var i = 0, n = scripts.length; i < n; i++) {
var script = scripts[i];
(script && script.enabled) && (script.onPreRender());
}
}
_postRenderScript() {
var scripts = this._scriptPool;
for (var i = 0, n = scripts.length; i < n; i++) {
var script = scripts[i];
(script && script.enabled) && (script.onPostRender());
}
}
_addCamera(camera) {
var index = this._binarySearchIndexInCameraPool(camera);
var order = camera._renderingOrder;
var count = this._cameraPool.length;
while (index < count && this._cameraPool[index]._renderingOrder <= order)
index++;
this._cameraPool.splice(index, 0, camera);
}
_removeCamera(camera) {
this._cameraPool.splice(this._cameraPool.indexOf(camera), 1);
}
_preCulling(context, camera, shader, replacementTag) {
var cameraCullInfo = FrustumCulling._cameraCullInfo;
cameraCullInfo.position = camera._transform.position;
cameraCullInfo.cullingMask = camera.cullingMask;
cameraCullInfo.boundFrustum = camera.boundFrustum;
cameraCullInfo.useOcclusionCulling = camera.useOcclusionCulling;
FrustumCulling.renderObjectCulling(cameraCullInfo, this, context, shader, replacementTag, false);
}
_clear(gl, state) {
var viewport = state.viewport;
var camera = state.camera;
var renderTex = camera._getRenderTexture();
var vpX, vpY;
var vpW = viewport.width;
var vpH = viewport.height;
if (camera._needInternalRenderTexture()) {
vpX = 0;
vpY = 0;
}
else {
vpX = viewport.x;
vpY = camera._getCanvasHeight() - viewport.y - vpH;
}
gl.viewport(vpX, vpY, vpW, vpH);
var flag;
var clearFlag = camera.clearFlag;
if (clearFlag === exports.CameraClearFlags.Sky && !(camera.skyRenderer._isAvailable() || this._skyRenderer._isAvailable()))
clearFlag = exports.CameraClearFlags.SolidColor;
switch (clearFlag) {
case exports.CameraClearFlags.SolidColor:
var clearColor = camera.clearColor;
gl.enable(gl.SCISSOR_TEST);
gl.scissor(vpX, vpY, vpW, vpH);
if (clearColor)
gl.clearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
else
gl.clearColor(0, 0, 0, 0);
if (renderTex) {
flag = gl.COLOR_BUFFER_BIT;
switch (renderTex.depthStencilFormat) {
case Laya.RenderTextureDepthFormat.DEPTH_16:
flag |= gl.DEPTH_BUFFER_BIT;
break;
case Laya.RenderTextureDepthFormat.STENCIL_8:
flag |= gl.STENCIL_BUFFER_BIT;
break;
case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8:
flag |= gl.DEPTH_BUFFER_BIT;
flag |= gl.STENCIL_BUFFER_BIT;
break;
}
}
else {
flag = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT;
}
Laya.WebGLContext.setDepthMask(gl, true);
gl.clear(flag);
gl.disable(gl.SCISSOR_TEST);
break;
case exports.CameraClearFlags.Sky:
case exports.CameraClearFlags.DepthOnly:
gl.enable(gl.SCISSOR_TEST);
gl.scissor(vpX, vpY, vpW, vpH);
if (renderTex) {
switch (renderTex.depthStencilFormat) {
case Laya.RenderTextureDepthFormat.DEPTH_16:
flag = gl.DEPTH_BUFFER_BIT;
break;
case Laya.RenderTextureDepthFormat.STENCIL_8:
flag = gl.STENCIL_BUFFER_BIT;
break;
case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8:
flag = gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT;
break;
}
}
else {
flag = gl.DEPTH_BUFFER_BIT;
}
Laya.WebGLContext.setDepthMask(gl, true);
gl.clear(flag);
gl.disable(gl.SCISSOR_TEST);
break;
case exports.CameraClearFlags.Nothing:
break;
default:
throw new Error("Scene3D:camera clearFlag invalid.");
}
}
_renderScene(context, renderFlag) {
var camera = context.camera;
switch (renderFlag) {
case Scene3D.SCENERENDERFLAG_RENDERQPAQUE:
this._opaqueQueue._render(context);
break;
case Scene3D.SCENERENDERFLAG_SKYBOX:
if (camera.clearFlag === exports.CameraClearFlags.Sky) {
if (camera.skyRenderer._isAvailable())
camera.skyRenderer._render(context);
else if (this._skyRenderer._isAvailable())
this._skyRenderer._render(context);
}
break;
case Scene3D.SCENERENDERFLAG_RENDERTRANSPARENT:
this._transparentQueue._render(context);
if (FrustumCulling.debugFrustumCulling) {
var renderElements = this._debugTool._render._renderElements;
for (var i = 0, n = renderElements.length; i < n; i++) {
renderElements[i]._update(this, context, null, null);
renderElements[i]._render(context);
}
}
break;
}
}
_parse(data, spriteMap) {
var lightMapsData = data.lightmaps;
if (lightMapsData) {
var lightMapCount = lightMapsData.length;
var lightmaps = new Array(lightMapCount);
for (var i = 0; i < lightMapCount; i++) {
var lightMap = new Lightmap();
var lightMapData = lightMapsData[i];
if (lightMapData.path) {
lightMap.lightmapColor = Laya.Loader.getRes(lightMapData.path);
}
else {
lightMap.lightmapColor = Laya.Loader.getRes(lightMapData.color.path);
if (lightMapData.direction)
lightMap.lightmapDirection = Laya.Loader.getRes(lightMapData.direction.path);
}
lightmaps[i] = lightMap;
}
this.lightmaps = lightmaps;
}
var ambientColorData = data.ambientColor;
if (ambientColorData) {
var ambCol = this.ambientColor;
ambCol.fromArray(ambientColorData);
this.ambientColor = ambCol;
}
var skyData = data.sky;
if (skyData) {
this._skyRenderer.material = Laya.Loader.getRes(skyData.material.path);
switch (skyData.mesh) {
case "SkyBox":
this._skyRenderer.mesh = SkyBox.instance;
break;
case "SkyDome":
this._skyRenderer.mesh = SkyDome.instance;
break;
default:
this.skyRenderer.mesh = SkyBox.instance;
}
}
this.enableFog = data.enableFog;
this.fogStart = data.fogStart;
this.fogRange = data.fogRange;
var fogColorData = data.fogColor;
if (fogColorData) {
var fogCol = this.fogColor;
fogCol.fromArray(fogColorData);
this.fogColor = fogCol;
}
var ambientSphericalHarmonicsData = data.ambientSphericalHarmonics;
if (ambientSphericalHarmonicsData) {
var ambientSH = this.ambientSphericalHarmonics;
for (var i = 0; i < 3; i++) {
var off = i * 9;
ambientSH.setCoefficients(i, ambientSphericalHarmonicsData[off], ambientSphericalHarmonicsData[off + 1], ambientSphericalHarmonicsData[off + 2], ambientSphericalHarmonicsData[off + 3], ambientSphericalHarmonicsData[off + 4], ambientSphericalHarmonicsData[off + 5], ambientSphericalHarmonicsData[off + 6], ambientSphericalHarmonicsData[off + 7], ambientSphericalHarmonicsData[off + 8]);
}
this.ambientSphericalHarmonics = ambientSH;
}
var reflectionData = data.reflection;
(reflectionData != undefined) && (this.reflection = Laya.Loader.getRes(reflectionData));
var reflectionDecodingFormatData = data.reflectionDecodingFormat;
(reflectionDecodingFormatData != undefined) && (this.reflectionDecodingFormat = reflectionDecodingFormatData);
var ambientModeData = data.ambientMode;
(ambientModeData != undefined) && (this.ambientMode = ambientModeData);
var ambientSphericalHarmonicsIntensityData = data.ambientSphericalHarmonicsIntensity;
(ambientSphericalHarmonicsIntensityData != undefined) && (this.ambientSphericalHarmonicsIntensity = ambientSphericalHarmonicsIntensityData);
var reflectionIntensityData = data.reflectionIntensity;
(reflectionIntensityData != undefined) && (this.reflectionIntensity = reflectionIntensityData);
}
_addRenderObject(render) {
if (this._octree && render._supportOctree) {
this._octree.add(render);
}
else {
this._renders.add(render);
}
render._addReflectionProbeUpdate();
}
_removeRenderObject(render) {
if (this._octree && render._supportOctree) {
this._octree.remove(render);
}
else {
this._renders.remove(render);
}
}
_getRenderQueue(index) {
if (index <= 2500)
return this._opaqueQueue;
else
return this._transparentQueue;
}
_clearRenderQueue() {
this._opaqueQueue.clear();
this._transparentQueue.clear();
var staticBatchManagers = StaticBatchManager._managers;
for (var i = 0, n = staticBatchManagers.length; i < n; i++)
staticBatchManagers[i]._clear();
var dynamicBatchManagers = DynamicBatchManager._managers;
for (var i = 0, n = dynamicBatchManagers.length; i < n; i++)
dynamicBatchManagers[i]._clear();
}
destroy(destroyChild = true) {
if (this.destroyed)
return;
super.destroy(destroyChild);
this._skyRenderer.destroy();
this._skyRenderer = null;
this._directionLights = null;
this._pointLights = null;
this._spotLights = null;
this._alternateLights = null;
this._shaderValues = null;
this._renders.clearElement();
this._animatorPool.clearElement();
this._renders = null;
this._animatorPool = null;
this._cameraPool = null;
this._octree = null;
this._physicsSimulation && this._physicsSimulation._destroy();
this._reflection._removeReference();
this._reflection = null;
var maps = this._lightmaps;
if (maps) {
for (var i = 0, n = maps.length; i < n; i++) {
var map = maps[i];
map.lightmapColor && map.lightmapColor._removeReference();
map.lightmapDirection && map.lightmapDirection._removeReference();
}
}
this._lightmaps = null;
this._reflectionProbeManager.destroy();
Laya.Loader.clearRes(this.url);
}
render(ctx) {
ctx._curSubmit = Laya.SubmitBase.RENDERBASE;
this._children.length > 0 && ctx.addRenderObject(this);
}
renderSubmit() {
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D);
this._prepareSceneToRender();
var i, n, n1;
Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER);
for (i = 0, n = this._cameraPool.length, n1 = n - 1; i < n; i++) {
if (Laya.Render.supportWebGLPlusRendering)
ShaderData.setRuntimeValueMode((i == n1) ? true : false);
var camera = this._cameraPool[i];
camera.enableRender && camera.render();
}
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER);
Laya.Context.set2DRenderConfig();
Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D);
return 1;
}
getRenderType() {
return 0;
}
releaseRender() {
}
reUse(context, pos) {
return 0;
}
setGlobalShaderValue(name, shaderDataType, value) {
var shaderOffset = Shader3D.propertyNameToID(name);
switch (shaderDataType) {
case exports.ShaderDataType.Int:
this._shaderValues.setInt(shaderOffset, value);
break;
case exports.ShaderDataType.Number:
this._shaderValues.setNumber(shaderOffset, value);
break;
case exports.ShaderDataType.Bool:
this._shaderValues.setBool(shaderOffset, value);
break;
case exports.ShaderDataType.Matrix4x4:
this._shaderValues.setMatrix4x4(shaderOffset, value);
break;
case exports.ShaderDataType.Quaternion:
this._shaderValues.setQuaternion(shaderOffset, value);
break;
case exports.ShaderDataType.Texture:
this._shaderValues.setTexture(shaderOffset, value);
break;
case exports.ShaderDataType.Vector4:
this._shaderValues.setVector(shaderOffset, value);
break;
case exports.ShaderDataType.Vector2:
this._shaderValues.setVector2(shaderOffset, value);
break;
case exports.ShaderDataType.Vector3:
this._shaderValues.setVector3(shaderOffset, value);
break;
case exports.ShaderDataType.Buffer:
this._shaderValues.setBuffer(shaderOffset, value);
break;
}
}
get customReflection() {
return this._reflection;
}
set customReflection(value) {
if (this._reflection != value) {
value._addReference();
this._reflectionProbeManager.sceneReflectionProbe = value;
this._reflection = value;
}
}
get reflectionMode() {
return this._reflectionMode;
}
set reflectionMode(value) {
this._reflectionMode = value;
}
setlightmaps(value) {
var maps = this._lightmaps;
for (var i = 0, n = maps.length; i < n; i++)
maps[i].lightmapColor._removeReference();
if (value) {
var count = value.length;
maps.length = count;
for (i = 0; i < count; i++) {
var lightMap = value[i];
lightMap._addReference();
(maps[i]) || (maps[i] = new Lightmap());
maps[i].lightmapColor = lightMap;
}
}
else {
throw new Error("Scene3D: value value can't be null.");
}
}
getlightmaps() {
var lightmapColors = new Array(this._lightmaps.length);
for (var i = 0; i < this._lightmaps.length; i++) {
lightmapColors[i] = this._lightmaps[i].lightmapColor;
}
return lightmapColors;
}
}
Scene3D._shadowCasterPass = new ShadowCasterPass();
Scene3D.HIERARCHY = "HIERARCHY";
Scene3D.octreeCulling = false;
Scene3D.octreeInitialSize = 64.0;
Scene3D.octreeInitialCenter = new Vector3(0, 0, 0);
Scene3D.octreeMinNodeSize = 2.0;
Scene3D.octreeLooseness = 1.25;
Scene3D.REFLECTIONMODE_SKYBOX = 0;
Scene3D.REFLECTIONMODE_CUSTOM = 1;
Scene3D.SCENERENDERFLAG_RENDERQPAQUE = 0;
Scene3D.SCENERENDERFLAG_SKYBOX = 1;
Scene3D.SCENERENDERFLAG_RENDERTRANSPARENT = 2;
Scene3D.FOGCOLOR = Shader3D.propertyNameToID("u_FogColor");
Scene3D.FOGSTART = Shader3D.propertyNameToID("u_FogStart");
Scene3D.FOGRANGE = Shader3D.propertyNameToID("u_FogRange");
Scene3D.DIRECTIONLIGHTCOUNT = Shader3D.propertyNameToID("u_DirationLightCount");
Scene3D.LIGHTBUFFER = Shader3D.propertyNameToID("u_LightBuffer");
Scene3D.CLUSTERBUFFER = Shader3D.propertyNameToID("u_LightClusterBuffer");
Scene3D.SUNLIGHTDIRECTION = Shader3D.propertyNameToID("u_SunLight.direction");
Scene3D.SUNLIGHTDIRCOLOR = Shader3D.propertyNameToID("u_SunLight.color");
Scene3D.AMBIENTSHAR = Shader3D.propertyNameToID("u_AmbientSHAr");
Scene3D.AMBIENTSHAG = Shader3D.propertyNameToID("u_AmbientSHAg");
Scene3D.AMBIENTSHAB = Shader3D.propertyNameToID("u_AmbientSHAb");
Scene3D.AMBIENTSHBR = Shader3D.propertyNameToID("u_AmbientSHBr");
Scene3D.AMBIENTSHBG = Shader3D.propertyNameToID("u_AmbientSHBg");
Scene3D.AMBIENTSHBB = Shader3D.propertyNameToID("u_AmbientSHBb");
Scene3D.AMBIENTSHC = Shader3D.propertyNameToID("u_AmbientSHC");
Scene3D.LIGHTDIRECTION = Shader3D.propertyNameToID("u_DirectionLight.direction");
Scene3D.LIGHTDIRCOLOR = Shader3D.propertyNameToID("u_DirectionLight.color");
Scene3D.POINTLIGHTPOS = Shader3D.propertyNameToID("u_PointLight.position");
Scene3D.POINTLIGHTRANGE = Shader3D.propertyNameToID("u_PointLight.range");
Scene3D.POINTLIGHTATTENUATION = Shader3D.propertyNameToID("u_PointLight.attenuation");
Scene3D.POINTLIGHTCOLOR = Shader3D.propertyNameToID("u_PointLight.color");
Scene3D.SPOTLIGHTPOS = Shader3D.propertyNameToID("u_SpotLight.position");
Scene3D.SPOTLIGHTDIRECTION = Shader3D.propertyNameToID("u_SpotLight.direction");
Scene3D.SPOTLIGHTSPOTANGLE = Shader3D.propertyNameToID("u_SpotLight.spot");
Scene3D.SPOTLIGHTRANGE = Shader3D.propertyNameToID("u_SpotLight.range");
Scene3D.SPOTLIGHTCOLOR = Shader3D.propertyNameToID("u_SpotLight.color");
Scene3D.AMBIENTCOLOR = Shader3D.propertyNameToID("u_AmbientColor");
Scene3D.TIME = Shader3D.propertyNameToID("u_Time");
Scene3D._configDefineValues = new DefineDatas();
class ShaderPass extends Laya.ShaderCompile {
constructor(owner, vs, ps, stateMap) {
super(vs, ps, null);
this._cacheSharders = {};
this._cacheShaderHierarchy = 1;
this._renderState = new RenderState();
this._validDefine = new DefineDatas();
this._tags = {};
this._owner = owner;
this._stateMap = stateMap;
for (var k in this.defs)
this._validDefine.add(Shader3D.getDefineByName(k));
}
get renderState() {
return this._renderState;
}
_compileToTree(parent, lines, start, includefiles, defs) {
var node, preNode;
var text, name, fname;
var ofs, words, noUseNode;
var i, n, j;
for (i = start; i < lines.length; i++) {
text = lines[i];
if (text.length < 1)
continue;
ofs = text.indexOf("//");
if (ofs === 0)
continue;
if (ofs >= 0)
text = text.substr(0, ofs);
node = noUseNode || new Laya.ShaderNode(includefiles);
noUseNode = null;
node.text = text;
node.noCompile = true;
if ((ofs = text.indexOf("#")) >= 0) {
name = "#";
for (j = ofs + 1, n = text.length; j < n; j++) {
var c = text.charAt(j);
if (c === ' ' || c === '\t' || c === '?')
break;
name += c;
}
node.name = name;
switch (name) {
case "#ifdef":
case "#ifndef":
node.src = text;
node.noCompile = text.match(/[!&|()=<>]/) != null;
if (!node.noCompile) {
words = text.replace(/^\s*/, '').split(/\s+/);
node.setCondition(words[1], name === "#ifdef" ? Laya.ShaderCompile.IFDEF_YES : Laya.ShaderCompile.IFDEF_ELSE);
node.text = "//" + node.text;
}
else {
console.log("function():Boolean{return " + text.substr(ofs + node.name.length) + "}");
}
node.setParent(parent);
parent = node;
if (defs) {
words = text.substr(j).split(Laya.ShaderCompile._splitToWordExps3);
for (j = 0; j < words.length; j++) {
text = words[j];
text.length && (defs[text] = true);
}
}
continue;
case "#if":
case "#elif":
node.src = text;
node.noCompile = true;
if (name == "#elif") {
parent = parent.parent;
preNode = parent.childs[parent.childs.length - 1];
preNode.text = preNode.src;
preNode.noCompile = true;
preNode.condition = null;
}
node.setParent(parent);
parent = node;
if (defs) {
words = text.substr(j).split(Laya.ShaderCompile._splitToWordExps3);
for (j = 0; j < words.length; j++) {
text = words[j];
text.length && text != "defined" && (defs[text] = true);
}
}
continue;
case "#else":
node.src = text;
parent = parent.parent;
preNode = parent.childs[parent.childs.length - 1];
node.noCompile = preNode.noCompile;
if (!node.noCompile) {
node.condition = preNode.condition;
node.conditionType = preNode.conditionType == Laya.ShaderCompile.IFDEF_YES ? Laya.ShaderCompile.IFDEF_ELSE : Laya.ShaderCompile.IFDEF_YES;
node.text = "//" + node.text + " " + preNode.text + " " + node.conditionType;
}
node.setParent(parent);
parent = node;
continue;
case "#endif":
parent = parent.parent;
preNode = parent.childs[parent.childs.length - 1];
node.noCompile = preNode.noCompile;
if (!node.noCompile) {
node.text = "//" + node.text;
}
node.setParent(parent);
continue;
case "#include":
words = Laya.ShaderCompile.splitToWords(text, null);
var inlcudeFile = Laya.ShaderCompile.includes[words[1]];
if (!inlcudeFile) {
throw "ShaderCompile error no this include file:" + words[1];
}
if ((ofs = words[0].indexOf("?")) < 0) {
node.setParent(parent);
text = inlcudeFile.getWith(words[2] == 'with' ? words[3] : null);
this._compileToTree(node, text.split('\n'), 0, includefiles, defs);
node.text = "";
continue;
}
node.setCondition(words[0].substr(ofs + 1), Laya.ShaderCompile.IFDEF_YES);
node.text = inlcudeFile.getWith(words[2] == 'with' ? words[3] : null);
break;
case "#import":
words = Laya.ShaderCompile.splitToWords(text, null);
fname = words[1];
includefiles.push({ node: node, file: Laya.ShaderCompile.includes[fname], ofs: node.text.length });
continue;
}
}
else {
preNode = parent.childs[parent.childs.length - 1];
if (preNode && !preNode.name) {
includefiles.length > 0 && Laya.ShaderCompile.splitToWords(text, preNode);
noUseNode = node;
preNode.text += "\n" + text;
continue;
}
includefiles.length > 0 && Laya.ShaderCompile.splitToWords(text, node);
}
node.setParent(parent);
}
}
_resizeCacheShaderMap(cacheMap, hierarchy, resizeLength) {
var end = this._cacheShaderHierarchy - 1;
if (hierarchy == end) {
for (var k in cacheMap) {
var shader = cacheMap[k];
for (var i = 0, n = resizeLength - end; i < n; i++) {
if (i == n - 1)
cacheMap[0] = shader;
else
cacheMap = cacheMap[i == 0 ? k : 0] = {};
}
}
}
else {
++hierarchy;
for (var k in cacheMap)
this._resizeCacheShaderMap(cacheMap[k], hierarchy, resizeLength);
}
}
_addDebugShaderVariantCollection(compileDefine, outDebugDefines, outDebugDefineMask) {
var dbugShaderVariantInfo = Shader3D._debugShaderVariantInfo;
var debugSubShader = this._owner;
var debugShader = debugSubShader._owner;
var mask = compileDefine._mask;
Shader3D._getNamesByDefineData(compileDefine, outDebugDefines);
outDebugDefineMask.length = mask.length;
for (var i = 0, n = mask.length; i < n; i++)
outDebugDefineMask[i] = mask[i];
if (dbugShaderVariantInfo)
dbugShaderVariantInfo.setValue(debugShader, debugShader._subShaders.indexOf(debugSubShader), debugSubShader._passes.indexOf(this), outDebugDefines);
else
Shader3D._debugShaderVariantInfo = dbugShaderVariantInfo = new ShaderVariant(debugShader, debugShader._subShaders.indexOf(debugSubShader), debugSubShader._passes.indexOf(this), outDebugDefines);
Shader3D.debugShaderVariantCollection.add(dbugShaderVariantInfo);
}
withCompile(compileDefine) {
var debugDefineString = ShaderPass._debugDefineString;
var debugDefineMask = ShaderPass._debugDefineMask;
var debugMaskLength;
compileDefine._intersectionDefineDatas(this._validDefine);
if (Shader3D.debugMode) {
debugMaskLength = compileDefine._length;
this._addDebugShaderVariantCollection(compileDefine, debugDefineString, debugDefineMask);
}
compileDefine.addDefineDatas(Scene3D._configDefineValues);
var cacheShaders = this._cacheSharders;
var maskLength = compileDefine._length;
if (maskLength > this._cacheShaderHierarchy) {
this._resizeCacheShaderMap(cacheShaders, 0, maskLength);
this._cacheShaderHierarchy = maskLength;
}
var mask = compileDefine._mask;
var endIndex = compileDefine._length - 1;
var maxEndIndex = this._cacheShaderHierarchy - 1;
for (var i = 0; i < maxEndIndex; i++) {
var subMask = endIndex < i ? 0 : mask[i];
var subCacheShaders = cacheShaders[subMask];
(subCacheShaders) || (cacheShaders[subMask] = subCacheShaders = {});
cacheShaders = subCacheShaders;
}
var cacheKey = endIndex < maxEndIndex ? 0 : mask[maxEndIndex];
var shader = cacheShaders[cacheKey];
if (shader)
return shader;
var defineString = ShaderPass._defineString;
Shader3D._getNamesByDefineData(compileDefine, defineString);
var config = Config3D._config;
var clusterSlices = config.lightClusterCount;
var defMap = {};
var vertexHead;
var fragmentHead;
var defineStr = "";
if (Laya.WebGL._isWebGL2) {
vertexHead =
`#version 300 es\n
#define attribute in
#define varying out
#define texture2D texture\n`;
fragmentHead =
`#version 300 es\n
#define varying in
out highp vec4 pc_fragColor;
#define gl_FragColor pc_fragColor
#define gl_FragDepthEXT gl_FragDepth
#define texture2D texture
#define textureCube texture
#define texture2DProj textureProj
#define texture2DLodEXT textureLod
#define texture2DProjLodEXT textureProjLod
#define textureCubeLodEXT textureLod
#define texture2DGradEXT textureGrad
#define texture2DProjGradEXT textureProjGrad
#define textureCubeGradEXT textureGrad\n`;
}
else {
vertexHead = "";
fragmentHead =
`#ifdef GL_EXT_shader_texture_lod
#extension GL_EXT_shader_texture_lod : enable
#endif
#if !defined(GL_EXT_shader_texture_lod)
#define texture1DLodEXT texture1D
#define texture2DLodEXT texture2D
#define texture2DProjLodEXT texture2DProj
#define texture3DLodEXT texture3D
#define textureCubeLodEXT textureCube
#endif\n`;
}
defineStr += "#define MAX_LIGHT_COUNT " + config.maxLightCount + "\n";
defineStr += "#define MAX_LIGHT_COUNT_PER_CLUSTER " + config._maxAreaLightCountPerClusterAverage + "\n";
defineStr += "#define CLUSTER_X_COUNT " + clusterSlices.x + "\n";
defineStr += "#define CLUSTER_Y_COUNT " + clusterSlices.y + "\n";
defineStr += "#define CLUSTER_Z_COUNT " + clusterSlices.z + "\n";
defineStr += "#define SHADER_CAPAILITY_LEVEL " + Laya.SystemUtils._shaderCapailityLevel + "\n";
for (var i = 0, n = defineString.length; i < n; i++) {
var def = defineString[i];
defineStr += "#define " + def + "\n";
defMap[def] = true;
}
var vs = this._VS.toscript(defMap, []);
var vsVersion = '';
if (vs[0].indexOf('#version') == 0) {
vsVersion = vs[0] + '\n';
vs.shift();
}
var ps = this._PS.toscript(defMap, []);
var psVersion = '';
if (ps[0].indexOf('#version') == 0) {
psVersion = ps[0] + '\n';
ps.shift();
}
shader = new ShaderInstance(vsVersion + vertexHead + defineStr + vs.join('\n'), psVersion + fragmentHead + defineStr + ps.join('\n'), this._owner._attributeMap, this._owner._uniformMap || this._owner._owner._uniformMap, this);
cacheShaders[cacheKey] = shader;
if (Shader3D.debugMode) {
var defStr = "";
var defMask = "";
for (var i = 0, n = debugMaskLength; i < n; i++)
(i == n - 1) ? defMask += debugDefineMask[i] : defMask += debugDefineMask[i] + ",";
for (var i = 0, n = debugDefineString.length; i < n; i++)
(i == n - 1) ? defStr += debugDefineString[i] : defStr += debugDefineString[i] + ",";
console.log("%cLayaAir: Shader Compile Information---ShaderName:" + this._owner._owner._name + " SubShaderIndex:" + this._owner._owner._subShaders.indexOf(this._owner) + " PassIndex:" + this._owner._passes.indexOf(this) + " DefineMask:[" + defMask + "]" + " DefineNames:[" + defStr + "]", "color:green");
}
return shader;
}
setTag(key, value) {
if (value)
this._tags[key] = value;
else
delete this._tags[key];
}
getTag(key) {
return this._tags[key];
}
}
ShaderPass._defineString = [];
ShaderPass._debugDefineString = [];
ShaderPass._debugDefineMask = [];
class SubShader {
constructor(attributeMap, uniformMap) {
this._flags = {};
this._passes = [];
this._attributeMap = attributeMap;
this._uniformMap = uniformMap;
}
setFlag(key, value) {
if (value)
this._flags[key] = value;
else
delete this._flags[key];
}
getFlag(key) {
return this._flags[key];
}
addShaderPass(vs, ps, stateMap = null, pipelineMode = "Forward") {
var shaderPass = new ShaderPass(this, vs, ps, stateMap);
shaderPass._pipelineMode = pipelineMode;
this._passes.push(shaderPass);
return shaderPass;
}
}
(function (PBRSpecularSmoothnessSource) {
PBRSpecularSmoothnessSource[PBRSpecularSmoothnessSource["SpecularTextureAlpha"] = 0] = "SpecularTextureAlpha";
PBRSpecularSmoothnessSource[PBRSpecularSmoothnessSource["AlbedoTextureAlpha"] = 1] = "AlbedoTextureAlpha";
})(exports.PBRSpecularSmoothnessSource || (exports.PBRSpecularSmoothnessSource = {}));
class PBRSpecularMaterial extends PBRMaterial {
constructor() {
super();
this.setShaderName("PBRSpecular");
this._shaderValues.setVector(PBRSpecularMaterial.SPECULARCOLOR, new Vector4(0.2, 0.2, 0.2, 1.0));
}
static __init__() {
PBRSpecularMaterial.SHADERDEFINE_SPECULARGLOSSTEXTURE = Shader3D.getDefineByName("SPECULARGLOSSTEXTURE");
PBRSpecularMaterial.SHADERDEFINE_SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA = Shader3D.getDefineByName("SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA");
var attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0,
'a_Normal': VertexMesh.MESH_NORMAL0,
'a_Tangent0': VertexMesh.MESH_TANGENT0,
'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0,
'a_Texcoord1': VertexMesh.MESH_TEXTURECOORDINATE1,
'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0,
'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0,
'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0,
'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR
};
var uniformMap = {
'u_Bones': Shader3D.PERIOD_CUSTOM,
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_WorldMat': Shader3D.PERIOD_SPRITE,
'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE,
'u_LightMap': Shader3D.PERIOD_SPRITE,
'u_LightMapDirection': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE,
'u_ReflectCubeHDRParams': Shader3D.PERIOD_SPRITE,
'u_ReflectTexture': Shader3D.PERIOD_SPRITE,
'u_SpecCubeProbePosition': Shader3D.PERIOD_SPRITE,
'u_SpecCubeBoxMax': Shader3D.PERIOD_SPRITE,
'u_SpecCubeBoxMin': Shader3D.PERIOD_SPRITE,
'u_CameraPos': Shader3D.PERIOD_CAMERA,
'u_View': Shader3D.PERIOD_CAMERA,
'u_ProjectionParams': Shader3D.PERIOD_CAMERA,
'u_Viewport': Shader3D.PERIOD_CAMERA,
'u_ViewProjection': Shader3D.PERIOD_CAMERA,
'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL,
'u_AlbedoColor': Shader3D.PERIOD_MATERIAL,
'u_EmissionColor': Shader3D.PERIOD_MATERIAL,
'u_AlbedoTexture': Shader3D.PERIOD_MATERIAL,
'u_NormalTexture': Shader3D.PERIOD_MATERIAL,
'u_ParallaxTexture': Shader3D.PERIOD_MATERIAL,
'u_OcclusionTexture': Shader3D.PERIOD_MATERIAL,
'u_EmissionTexture': Shader3D.PERIOD_MATERIAL,
'u_Smoothness': Shader3D.PERIOD_MATERIAL,
'u_SmoothnessScale': Shader3D.PERIOD_MATERIAL,
'u_occlusionStrength': Shader3D.PERIOD_MATERIAL,
'u_NormalScale': Shader3D.PERIOD_MATERIAL,
'u_ParallaxScale': Shader3D.PERIOD_MATERIAL,
'u_TilingOffset': Shader3D.PERIOD_MATERIAL,
'u_SpecGlossTexture': Shader3D.PERIOD_MATERIAL,
'u_SpecularColor': Shader3D.PERIOD_MATERIAL,
'u_AmbientColor': Shader3D.PERIOD_SCENE,
'u_FogStart': Shader3D.PERIOD_SCENE,
'u_FogRange': Shader3D.PERIOD_SCENE,
'u_FogColor': Shader3D.PERIOD_SCENE,
'u_DirationLightCount': Shader3D.PERIOD_SCENE,
'u_LightBuffer': Shader3D.PERIOD_SCENE,
'u_LightClusterBuffer': Shader3D.PERIOD_SCENE,
'u_ShadowBias': Shader3D.PERIOD_SCENE,
'u_ShadowLightDirection': Shader3D.PERIOD_SCENE,
'u_ShadowMap': Shader3D.PERIOD_SCENE,
'u_ShadowParams': Shader3D.PERIOD_SCENE,
'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE,
'u_ShadowMatrices': Shader3D.PERIOD_SCENE,
'u_ShadowMapSize': Shader3D.PERIOD_SCENE,
'u_SpotShadowMap': Shader3D.PERIOD_SCENE,
'u_SpotViewProjectMatrix': Shader3D.PERIOD_SCENE,
'u_ShadowLightPosition': Shader3D.PERIOD_SCENE,
'u_AmbientSHAr': Shader3D.PERIOD_SCENE,
'u_AmbientSHAg': Shader3D.PERIOD_SCENE,
'u_AmbientSHAb': Shader3D.PERIOD_SCENE,
'u_AmbientSHBr': Shader3D.PERIOD_SCENE,
'u_AmbientSHBg': Shader3D.PERIOD_SCENE,
'u_AmbientSHBb': Shader3D.PERIOD_SCENE,
'u_AmbientSHC': Shader3D.PERIOD_SCENE,
'u_DirectionLight.direction': Shader3D.PERIOD_SCENE,
'u_DirectionLight.color': Shader3D.PERIOD_SCENE,
'u_PointLight.position': Shader3D.PERIOD_SCENE,
'u_PointLight.range': Shader3D.PERIOD_SCENE,
'u_PointLight.color': Shader3D.PERIOD_SCENE,
'u_SpotLight.position': Shader3D.PERIOD_SCENE,
'u_SpotLight.direction': Shader3D.PERIOD_SCENE,
'u_SpotLight.range': Shader3D.PERIOD_SCENE,
'u_SpotLight.spot': Shader3D.PERIOD_SCENE,
'u_SpotLight.color': Shader3D.PERIOD_SCENE
};
var stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
var shader = Shader3D.add("PBRSpecular", attributeMap, uniformMap, true, true);
var subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(PBRVS, PBRPS, stateMap, "Forward");
subShader.addShaderPass(PBRShadowCasterVS, PBRShadowCasterPS, stateMap, "ShadowCaster");
subShader.addShaderPass(DepthNormalsTextureVS, DepthNormalsTextureFS, stateMap, "DepthNormal");
}
get specularTexture() {
return this._shaderValues.getTexture(PBRSpecularMaterial.SPECULARTEXTURE);
}
set specularTexture(value) {
if (value)
this._shaderValues.addDefine(PBRSpecularMaterial.SHADERDEFINE_SPECULARGLOSSTEXTURE);
else
this._shaderValues.removeDefine(PBRSpecularMaterial.SHADERDEFINE_SPECULARGLOSSTEXTURE);
this._shaderValues.setTexture(PBRSpecularMaterial.SPECULARTEXTURE, value);
}
get specularColor() {
return this._shaderValues.getVector(PBRSpecularMaterial.SPECULARCOLOR);
}
set specularColor(value) {
this._shaderValues.setVector(PBRSpecularMaterial.SPECULARCOLOR, value);
}
clone() {
var dest = new PBRSpecularMaterial();
this.cloneTo(dest);
return dest;
}
}
PBRSpecularMaterial.SPECULARTEXTURE = Shader3D.propertyNameToID("u_SpecGlossTexture");
PBRSpecularMaterial.SPECULARCOLOR = Shader3D.propertyNameToID("u_SpecularColor");
var PBRPS$1 = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n#include \"Shadow.glsl\"\r\n#include \"PBRFSInput.glsl\";\r\n#include \"LayaPBRBRDF.glsl\";\r\n#include \"GlobalIllumination.glsl\";\r\n#include \"PBRCore.glsl\";\r\n\r\nvoid main()\r\n{\r\n\tfragmentForward();\r\n}";
var PBRVS$1 = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\"\r\n#include \"Shadow.glsl\"\r\n#include \"PBRVSInput.glsl\";\r\n#include \"PBRVertex.glsl\";\r\n\r\nvoid main()\r\n{\r\n\tvertexForward();\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}";
var PBRShadowCasterPS$1 = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"ShadowCasterFS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=shadowCasterFragment();\r\n}";
var PBRShadowCasterVS$1 = "#include \"ShadowCasterVS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = shadowCasterVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}";
(function (PBRMetallicSmoothnessSource) {
PBRMetallicSmoothnessSource[PBRMetallicSmoothnessSource["MetallicGlossTextureAlpha"] = 0] = "MetallicGlossTextureAlpha";
PBRMetallicSmoothnessSource[PBRMetallicSmoothnessSource["AlbedoTextureAlpha"] = 1] = "AlbedoTextureAlpha";
})(exports.PBRMetallicSmoothnessSource || (exports.PBRMetallicSmoothnessSource = {}));
class PBRStandardMaterial extends PBRMaterial {
constructor() {
super();
this._smoothnessSource = 0;
this.setShaderName("PBR");
this._shaderValues.setNumber(PBRStandardMaterial.METALLIC, 0.0);
}
static __init__() {
PBRStandardMaterial.SHADERDEFINE_METALLICGLOSSTEXTURE = Shader3D.getDefineByName("METALLICGLOSSTEXTURE");
PBRStandardMaterial.SHADERDEFINE_SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA = Shader3D.getDefineByName("SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA");
var attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0,
'a_Normal': VertexMesh.MESH_NORMAL0,
'a_Tangent0': VertexMesh.MESH_TANGENT0,
'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0,
'a_Texcoord1': VertexMesh.MESH_TEXTURECOORDINATE1,
'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0,
'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0,
'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0,
'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR
};
var uniformMap = {
'u_Bones': Shader3D.PERIOD_CUSTOM,
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_WorldMat': Shader3D.PERIOD_SPRITE,
'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE,
'u_LightMap': Shader3D.PERIOD_SPRITE,
'u_LightMapDirection': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE,
'u_ReflectCubeHDRParams': Shader3D.PERIOD_SPRITE,
'u_ReflectTexture': Shader3D.PERIOD_SPRITE,
'u_SpecCubeProbePosition': Shader3D.PERIOD_SPRITE,
'u_SpecCubeBoxMax': Shader3D.PERIOD_SPRITE,
'u_SpecCubeBoxMin': Shader3D.PERIOD_SPRITE,
'u_CameraPos': Shader3D.PERIOD_CAMERA,
'u_View': Shader3D.PERIOD_CAMERA,
'u_ProjectionParams': Shader3D.PERIOD_CAMERA,
'u_Viewport': Shader3D.PERIOD_CAMERA,
'u_ViewProjection': Shader3D.PERIOD_CAMERA,
'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL,
'u_AlbedoColor': Shader3D.PERIOD_MATERIAL,
'u_EmissionColor': Shader3D.PERIOD_MATERIAL,
'u_AlbedoTexture': Shader3D.PERIOD_MATERIAL,
'u_NormalTexture': Shader3D.PERIOD_MATERIAL,
'u_ParallaxTexture': Shader3D.PERIOD_MATERIAL,
'u_OcclusionTexture': Shader3D.PERIOD_MATERIAL,
'u_EmissionTexture': Shader3D.PERIOD_MATERIAL,
'u_Smoothness': Shader3D.PERIOD_MATERIAL,
'u_SmoothnessScale': Shader3D.PERIOD_MATERIAL,
'u_occlusionStrength': Shader3D.PERIOD_MATERIAL,
'u_NormalScale': Shader3D.PERIOD_MATERIAL,
'u_ParallaxScale': Shader3D.PERIOD_MATERIAL,
'u_TilingOffset': Shader3D.PERIOD_MATERIAL,
'u_MetallicGlossTexture': Shader3D.PERIOD_MATERIAL,
'u_Metallic': Shader3D.PERIOD_MATERIAL,
'u_AmbientColor': Shader3D.PERIOD_SCENE,
'u_FogStart': Shader3D.PERIOD_SCENE,
'u_FogRange': Shader3D.PERIOD_SCENE,
'u_FogColor': Shader3D.PERIOD_SCENE,
'u_DirationLightCount': Shader3D.PERIOD_SCENE,
'u_LightBuffer': Shader3D.PERIOD_SCENE,
'u_LightClusterBuffer': Shader3D.PERIOD_SCENE,
'u_ShadowBias': Shader3D.PERIOD_SCENE,
'u_ShadowLightDirection': Shader3D.PERIOD_SCENE,
'u_ShadowMap': Shader3D.PERIOD_SCENE,
'u_ShadowParams': Shader3D.PERIOD_SCENE,
'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE,
'u_ShadowMatrices': Shader3D.PERIOD_SCENE,
'u_ShadowMapSize': Shader3D.PERIOD_SCENE,
'u_SpotShadowMap': Shader3D.PERIOD_SCENE,
'u_SpotViewProjectMatrix': Shader3D.PERIOD_SCENE,
'u_ShadowLightPosition': Shader3D.PERIOD_SCENE,
'u_AmbientSHAr': Shader3D.PERIOD_SCENE,
'u_AmbientSHAg': Shader3D.PERIOD_SCENE,
'u_AmbientSHAb': Shader3D.PERIOD_SCENE,
'u_AmbientSHBr': Shader3D.PERIOD_SCENE,
'u_AmbientSHBg': Shader3D.PERIOD_SCENE,
'u_AmbientSHBb': Shader3D.PERIOD_SCENE,
'u_AmbientSHC': Shader3D.PERIOD_SCENE,
'u_DirectionLight.direction': Shader3D.PERIOD_SCENE,
'u_DirectionLight.color': Shader3D.PERIOD_SCENE,
'u_PointLight.position': Shader3D.PERIOD_SCENE,
'u_PointLight.range': Shader3D.PERIOD_SCENE,
'u_PointLight.color': Shader3D.PERIOD_SCENE,
'u_SpotLight.position': Shader3D.PERIOD_SCENE,
'u_SpotLight.direction': Shader3D.PERIOD_SCENE,
'u_SpotLight.range': Shader3D.PERIOD_SCENE,
'u_SpotLight.spot': Shader3D.PERIOD_SCENE,
'u_SpotLight.color': Shader3D.PERIOD_SCENE
};
var stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
var shader = Shader3D.add("PBR", attributeMap, uniformMap, true, true);
var subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(PBRVS$1, PBRPS$1, stateMap, "Forward");
subShader.addShaderPass(PBRShadowCasterVS$1, PBRShadowCasterPS$1, stateMap, "ShadowCaster");
subShader.addShaderPass(DepthNormalsTextureVS, DepthNormalsTextureFS, stateMap, "DepthNormal");
}
get metallicGlossTexture() {
return this._shaderValues.getTexture(PBRStandardMaterial.METALLICGLOSSTEXTURE);
}
set metallicGlossTexture(value) {
if (value)
this._shaderValues.addDefine(PBRStandardMaterial.SHADERDEFINE_METALLICGLOSSTEXTURE);
else
this._shaderValues.removeDefine(PBRStandardMaterial.SHADERDEFINE_METALLICGLOSSTEXTURE);
this._shaderValues.setTexture(PBRStandardMaterial.METALLICGLOSSTEXTURE, value);
}
get metallic() {
return this._shaderValues.getNumber(PBRStandardMaterial.METALLIC);
}
set metallic(value) {
this._shaderValues.setNumber(PBRStandardMaterial.METALLIC, Math.max(0.0, Math.min(1.0, value)));
}
get smoothnessSource() {
return this._smoothnessSource;
}
set smoothnessSource(value) {
if (value)
this._shaderValues.addDefine(PBRStandardMaterial.SHADERDEFINE_SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA);
else
this._shaderValues.removeDefine(PBRStandardMaterial.SHADERDEFINE_SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA);
this._smoothnessSource = value;
}
clone() {
var dest = new PBRStandardMaterial();
this.cloneTo(dest);
return dest;
}
}
PBRStandardMaterial.METALLICGLOSSTEXTURE = Shader3D.propertyNameToID("u_MetallicGlossTexture");
PBRStandardMaterial.METALLIC = Shader3D.propertyNameToID("u_Metallic");
class SkyBoxMaterial extends Material {
constructor() {
super();
this.setShaderName("SkyBox");
this.tintColor = new Vector4(0.5, 0.5, 0.5, 0.5);
this.exposure = 1.0;
this.rotation = 0;
}
static __initDefine__() {
}
get tintColor() {
return this._shaderValues.getVector(SkyBoxMaterial.TINTCOLOR);
}
set tintColor(value) {
this._shaderValues.setVector(SkyBoxMaterial.TINTCOLOR, value);
}
get exposure() {
return this._shaderValues.getNumber(SkyBoxMaterial.EXPOSURE);
}
set exposure(value) {
this._shaderValues.setNumber(SkyBoxMaterial.EXPOSURE, value);
}
get rotation() {
return this._shaderValues.getNumber(SkyBoxMaterial.ROTATION);
}
set rotation(value) {
this._shaderValues.setNumber(SkyBoxMaterial.ROTATION, value);
}
get textureCube() {
return this._shaderValues.getTexture(SkyBoxMaterial.TEXTURECUBE);
}
set textureCube(value) {
this._shaderValues.setTexture(SkyBoxMaterial.TEXTURECUBE, value);
}
clone() {
var dest = new SkyBoxMaterial();
this.cloneTo(dest);
return dest;
}
}
SkyBoxMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_TintColor");
SkyBoxMaterial.EXPOSURE = Shader3D.propertyNameToID("u_Exposure");
SkyBoxMaterial.ROTATION = Shader3D.propertyNameToID("u_Rotation");
SkyBoxMaterial.TEXTURECUBE = Shader3D.propertyNameToID("u_CubeTexture");
class SkyProceduralMaterial extends Material {
constructor() {
super();
this.setShaderName("SkyBoxProcedural");
this.sunDisk = SkyProceduralMaterial.SUN_HIGH_QUALITY;
this.sunSize = 0.04;
this.sunSizeConvergence = 5;
this.atmosphereThickness = 1.0;
this.skyTint = new Vector4(0.5, 0.5, 0.5, 1.0);
this.groundTint = new Vector4(0.369, 0.349, 0.341, 1.0);
this.exposure = 1.3;
}
static __initDefine__() {
SkyProceduralMaterial.SHADERDEFINE_SUN_HIGH_QUALITY = Shader3D.getDefineByName("SUN_HIGH_QUALITY");
SkyProceduralMaterial.SHADERDEFINE_SUN_SIMPLE = Shader3D.getDefineByName("SUN_SIMPLE");
}
get sunDisk() {
return this._sunDisk;
}
set sunDisk(value) {
switch (value) {
case SkyProceduralMaterial.SUN_HIGH_QUALITY:
this._shaderValues.removeDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_SIMPLE);
this._shaderValues.addDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_HIGH_QUALITY);
break;
case SkyProceduralMaterial.SUN_SIMPLE:
this._shaderValues.removeDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_HIGH_QUALITY);
this._shaderValues.addDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_SIMPLE);
break;
case SkyProceduralMaterial.SUN_NODE:
this._shaderValues.removeDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_HIGH_QUALITY);
this._shaderValues.removeDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_SIMPLE);
break;
default:
throw "SkyBoxProceduralMaterial: unknown sun value.";
}
this._sunDisk = value;
}
get sunSize() {
return this._shaderValues.getNumber(SkyProceduralMaterial.SUNSIZE);
}
set sunSize(value) {
value = Math.min(Math.max(0.0, value), 1.0);
this._shaderValues.setNumber(SkyProceduralMaterial.SUNSIZE, value);
}
get sunSizeConvergence() {
return this._shaderValues.getNumber(SkyProceduralMaterial.SUNSIZECONVERGENCE);
}
set sunSizeConvergence(value) {
value = Math.min(Math.max(0.0, value), 20.0);
this._shaderValues.setNumber(SkyProceduralMaterial.SUNSIZECONVERGENCE, value);
}
get atmosphereThickness() {
return this._shaderValues.getNumber(SkyProceduralMaterial.ATMOSPHERETHICKNESS);
}
set atmosphereThickness(value) {
value = Math.min(Math.max(0.0, value), 5.0);
this._shaderValues.setNumber(SkyProceduralMaterial.ATMOSPHERETHICKNESS, value);
}
get skyTint() {
return this._shaderValues.getVector(SkyProceduralMaterial.SKYTINT);
}
set skyTint(value) {
this._shaderValues.setVector(SkyProceduralMaterial.SKYTINT, value);
}
get groundTint() {
return this._shaderValues.getVector(SkyProceduralMaterial.GROUNDTINT);
}
set groundTint(value) {
this._shaderValues.setVector(SkyProceduralMaterial.GROUNDTINT, value);
}
get exposure() {
return this._shaderValues.getNumber(SkyProceduralMaterial.EXPOSURE);
}
set exposure(value) {
value = Math.min(Math.max(0.0, value), 8.0);
this._shaderValues.setNumber(SkyProceduralMaterial.EXPOSURE, value);
}
clone() {
var dest = new SkyProceduralMaterial();
this.cloneTo(dest);
return dest;
}
}
SkyProceduralMaterial.SUN_NODE = 0;
SkyProceduralMaterial.SUN_SIMPLE = 1;
SkyProceduralMaterial.SUN_HIGH_QUALITY = 2;
SkyProceduralMaterial.SUNSIZE = Shader3D.propertyNameToID("u_SunSize");
SkyProceduralMaterial.SUNSIZECONVERGENCE = Shader3D.propertyNameToID("u_SunSizeConvergence");
SkyProceduralMaterial.ATMOSPHERETHICKNESS = Shader3D.propertyNameToID("u_AtmosphereThickness");
SkyProceduralMaterial.SKYTINT = Shader3D.propertyNameToID("u_SkyTint");
SkyProceduralMaterial.GROUNDTINT = Shader3D.propertyNameToID("u_GroundTint");
SkyProceduralMaterial.EXPOSURE = Shader3D.propertyNameToID("u_Exposure");
class UnlitMaterial extends Material {
constructor() {
super();
this.setShaderName("Unlit");
this._shaderValues.setVector(UnlitMaterial.ALBEDOCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0));
this._shaderValues.setVector(UnlitMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0));
this.renderMode = UnlitMaterial.RENDERMODE_OPAQUE;
this.albedoIntensity = 1.0;
}
static __initDefine__() {
UnlitMaterial.SHADERDEFINE_ALBEDOTEXTURE = Shader3D.getDefineByName("ALBEDOTEXTURE");
UnlitMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR = Shader3D.getDefineByName("ENABLEVERTEXCOLOR");
}
get _ColorR() {
return this.albedoColor.x;
}
set _ColorR(value) {
let albedo = this.albedoColor;
albedo.x = value;
this.albedoColor = albedo;
}
get _ColorG() {
return this.albedoColor.y;
}
set _ColorG(value) {
let albedo = this.albedoColor;
albedo.y = value;
this.albedoColor = albedo;
}
get _ColorB() {
return this.albedoColor.z;
}
set _ColorB(value) {
let albedo = this.albedoColor;
albedo.z = value;
this.albedoColor = albedo;
}
get _ColorA() {
return this.albedoColor.w;
}
set _ColorA(value) {
let albedo = this.albedoColor;
albedo.w = value;
this.albedoColor = albedo;
}
get _Color() {
return this._shaderValues.getVector(UnlitMaterial.ALBEDOCOLOR);
}
set _Color(value) {
this.albedoColor = value;
}
get _AlbedoIntensity() {
return this._albedoIntensity;
}
set _AlbedoIntensity(value) {
if (this._albedoIntensity !== value) {
var finalAlbedo = this._shaderValues.getVector(UnlitMaterial.ALBEDOCOLOR);
Vector4.scale(this.albedoColor, value, finalAlbedo);
this._albedoIntensity = value;
this._shaderValues.setVector(UnlitMaterial.ALBEDOCOLOR, finalAlbedo);
}
}
get _MainTex_STX() {
return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).x;
}
set _MainTex_STX(x) {
var tilOff = this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET);
tilOff.x = x;
this.tilingOffset = tilOff;
}
get _MainTex_STY() {
return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).y;
}
set _MainTex_STY(y) {
var tilOff = this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET);
tilOff.y = y;
this.tilingOffset = tilOff;
}
get _MainTex_STZ() {
return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).z;
}
set _MainTex_STZ(z) {
var tilOff = this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET);
tilOff.z = z;
this.tilingOffset = tilOff;
}
get _MainTex_STW() {
return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).w;
}
set _MainTex_STW(w) {
var tilOff = this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET);
tilOff.w = w;
this.tilingOffset = tilOff;
}
get _MainTex_ST() {
return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET);
}
set _MainTex_ST(value) {
this.tilingOffset = value;
}
get _Cutoff() {
return this.alphaTestValue;
}
set _Cutoff(value) {
this.alphaTestValue = value;
}
get albedoColorR() {
return this._ColorR;
}
set albedoColorR(value) {
this._ColorR = value;
}
get albedoColorG() {
return this._ColorG;
}
set albedoColorG(value) {
this._ColorG = value;
}
get albedoColorB() {
return this._ColorB;
}
set albedoColorB(value) {
this._ColorB = value;
}
get albedoColorA() {
return this._ColorA;
}
set albedoColorA(value) {
this._ColorA = value;
}
get albedoColor() {
return this._shaderValues.getVector(UnlitMaterial.ALBEDOCOLOR);
}
set albedoColor(value) {
var finalAlbedo = this._shaderValues.getVector(UnlitMaterial.ALBEDOCOLOR);
Vector4.scale(value, this._albedoIntensity, finalAlbedo);
this._shaderValues.setVector(UnlitMaterial.ALBEDOCOLOR, finalAlbedo);
}
get albedoIntensity() {
return this._albedoIntensity;
}
set albedoIntensity(value) {
this._AlbedoIntensity = value;
}
get albedoTexture() {
return this._shaderValues.getTexture(UnlitMaterial.ALBEDOTEXTURE);
}
set albedoTexture(value) {
if (value)
this._shaderValues.addDefine(UnlitMaterial.SHADERDEFINE_ALBEDOTEXTURE);
else
this._shaderValues.removeDefine(UnlitMaterial.SHADERDEFINE_ALBEDOTEXTURE);
this._shaderValues.setTexture(UnlitMaterial.ALBEDOTEXTURE, value);
}
get tilingOffsetX() {
return this._MainTex_STX;
}
set tilingOffsetX(x) {
this._MainTex_STX = x;
}
get tilingOffsetY() {
return this._MainTex_STY;
}
set tilingOffsetY(y) {
this._MainTex_STY = y;
}
get tilingOffsetZ() {
return this._MainTex_STZ;
}
set tilingOffsetZ(z) {
this._MainTex_STZ = z;
}
get tilingOffsetW() {
return this._MainTex_STW;
}
set tilingOffsetW(w) {
this._MainTex_STW = w;
}
get tilingOffset() {
return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET);
}
set tilingOffset(value) {
if (value) {
this._shaderValues.setVector(UnlitMaterial.TILINGOFFSET, value);
}
else {
this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0);
}
}
get enableVertexColor() {
return this._shaderValues.hasDefine(UnlitMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR);
}
set enableVertexColor(value) {
if (value)
this._shaderValues.addDefine(UnlitMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR);
else
this._shaderValues.removeDefine(UnlitMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR);
}
set renderMode(value) {
switch (value) {
case UnlitMaterial.RENDERMODE_OPAQUE:
this.alphaTest = false;
this.renderQueue = Material.RENDERQUEUE_OPAQUE;
this.depthWrite = true;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_DISABLE;
this.depthTest = RenderState.DEPTHTEST_LESS;
break;
case UnlitMaterial.RENDERMODE_CUTOUT:
this.renderQueue = Material.RENDERQUEUE_ALPHATEST;
this.alphaTest = true;
this.depthWrite = true;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_DISABLE;
this.depthTest = RenderState.DEPTHTEST_LESS;
break;
case UnlitMaterial.RENDERMODE_TRANSPARENT:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.alphaTest = false;
this.depthWrite = false;
this.cull = RenderState.CULL_BACK;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
this.depthTest = RenderState.DEPTHTEST_LESS;
break;
default:
throw new Error("UnlitMaterial : renderMode value error.");
}
}
clone() {
var dest = new UnlitMaterial();
this.cloneTo(dest);
return dest;
}
}
UnlitMaterial.RENDERMODE_OPAQUE = 0;
UnlitMaterial.RENDERMODE_CUTOUT = 1;
UnlitMaterial.RENDERMODE_TRANSPARENT = 2;
UnlitMaterial.RENDERMODE_ADDTIVE = 3;
UnlitMaterial.ALBEDOTEXTURE = Shader3D.propertyNameToID("u_AlbedoTexture");
UnlitMaterial.ALBEDOCOLOR = Shader3D.propertyNameToID("u_AlbedoColor");
UnlitMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset");
class WaterPrimaryMaterial extends Material {
constructor() {
super();
this.setShaderName("WaterPrimary");
this._shaderValues.setVector(WaterPrimaryMaterial.HORIZONCOLOR, new Vector4(0.172, 0.463, 0.435, 0));
this._shaderValues.setNumber(WaterPrimaryMaterial.WAVESCALE, 0.15);
this._shaderValues.setVector(WaterPrimaryMaterial.WAVESPEED, new Vector4(19, 9, -16, -7));
}
static __initDefine__() {
WaterPrimaryMaterial.SHADERDEFINE_MAINTEXTURE = Shader3D.getDefineByName("MAINTEXTURE");
WaterPrimaryMaterial.SHADERDEFINE_NORMALTEXTURE = Shader3D.getDefineByName("NORMALTEXTURE");
}
get horizonColor() {
return this._shaderValues.getVector(WaterPrimaryMaterial.HORIZONCOLOR);
}
set horizonColor(value) {
this._shaderValues.setVector(WaterPrimaryMaterial.HORIZONCOLOR, value);
}
get mainTexture() {
return this._shaderValues.getTexture(WaterPrimaryMaterial.MAINTEXTURE);
}
set mainTexture(value) {
if (value)
this._shaderValues.addDefine(WaterPrimaryMaterial.SHADERDEFINE_MAINTEXTURE);
else
this._shaderValues.removeDefine(WaterPrimaryMaterial.SHADERDEFINE_MAINTEXTURE);
this._shaderValues.setTexture(WaterPrimaryMaterial.MAINTEXTURE, value);
}
get normalTexture() {
return this._shaderValues.getTexture(WaterPrimaryMaterial.NORMALTEXTURE);
}
set normalTexture(value) {
if (value)
this._shaderValues.addDefine(WaterPrimaryMaterial.SHADERDEFINE_NORMALTEXTURE);
else
this._shaderValues.removeDefine(WaterPrimaryMaterial.SHADERDEFINE_NORMALTEXTURE);
this._shaderValues.setTexture(WaterPrimaryMaterial.NORMALTEXTURE, value);
}
get waveScale() {
return this._shaderValues.getNumber(WaterPrimaryMaterial.WAVESCALE);
}
set waveScale(value) {
this._shaderValues.setNumber(WaterPrimaryMaterial.WAVESCALE, value);
}
get waveSpeed() {
return this._shaderValues.getVector(WaterPrimaryMaterial.WAVESPEED);
}
set waveSpeed(value) {
this._shaderValues.setVector(WaterPrimaryMaterial.WAVESPEED, value);
}
clone() {
var dest = new WaterPrimaryMaterial();
this.cloneTo(dest);
return dest;
}
}
WaterPrimaryMaterial.HORIZONCOLOR = Shader3D.propertyNameToID("u_HorizonColor");
WaterPrimaryMaterial.MAINTEXTURE = Shader3D.propertyNameToID("u_MainTexture");
WaterPrimaryMaterial.NORMALTEXTURE = Shader3D.propertyNameToID("u_NormalTexture");
WaterPrimaryMaterial.WAVESCALE = Shader3D.propertyNameToID("u_WaveScale");
WaterPrimaryMaterial.WAVESPEED = Shader3D.propertyNameToID("u_WaveSpeed");
class MeshRenderer extends BaseRender {
constructor(owner) {
super(owner);
this._revertStaticBatchDefineUV1 = false;
this._projectionViewWorldMatrix = new Matrix4x4();
}
_createRenderElement() {
return new SubMeshRenderElement();
}
_onMeshChange(mesh) {
if (mesh) {
var count = mesh.subMeshCount;
this._renderElements.length = count;
for (var i = 0; i < count; i++) {
var renderElement = this._renderElements[i];
if (!renderElement) {
var material = this.sharedMaterials[i];
renderElement = this._renderElements[i] = this._createRenderElement();
renderElement.setTransform(this._owner._transform);
renderElement.render = this;
renderElement.material = material ? material : BlinnPhongMaterial.defaultMaterial;
}
renderElement.setGeometry(mesh.getSubMesh(i));
}
}
else {
this._renderElements.length = 0;
}
this._boundsChange = true;
}
_calculateBoundingBox() {
var sharedMesh = this._owner.meshFilter.sharedMesh;
if (sharedMesh) {
var worldMat = this._owner.transform.worldMatrix;
sharedMesh.bounds._tranform(worldMat, this._bounds);
}
}
_needRender(boundFrustum, context) {
if (boundFrustum)
return boundFrustum.intersects(this.bounds._getBoundBox());
else
return true;
}
_renderUpdate(context, transform) {
this._applyLightMapParams();
var element = context.renderElement;
switch (element.renderType) {
case RenderElement.RENDERTYPE_NORMAL:
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, transform.worldMatrix);
break;
case RenderElement.RENDERTYPE_STATICBATCH:
if (transform)
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, transform.worldMatrix);
else
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, Matrix4x4.DEFAULT);
if (!this._shaderValues.hasDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1)) {
this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1);
this._revertStaticBatchDefineUV1 = true;
}
else {
this._revertStaticBatchDefineUV1 = false;
}
this._shaderValues.setVector(RenderableSprite3D.LIGHTMAPSCALEOFFSET, BaseRender._defaultLightmapScaleOffset);
break;
case RenderElement.RENDERTYPE_VERTEXBATCH:
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, Matrix4x4.DEFAULT);
break;
case RenderElement.RENDERTYPE_INSTANCEBATCH:
var worldMatrixData = SubMeshInstanceBatch.instance.instanceWorldMatrixData;
var insBatches = element.instanceBatchElementList;
var elements = insBatches.elements;
var count = insBatches.length;
for (var i = 0; i < count; i++)
worldMatrixData.set(elements[i]._transform.worldMatrix.elements, i * 16);
var worldBuffer = SubMeshInstanceBatch.instance.instanceWorldMatrixBuffer;
worldBuffer.orphanStorage();
worldBuffer.setData(worldMatrixData.buffer, 0, 0, count * 16 * 4);
this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE);
break;
}
if (!this._probReflection)
return;
if (this._reflectionMode == exports.ReflectionProbeMode.off) {
this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION);
this._shaderValues.setVector(RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS, ReflectionProbe.defaultTextureHDRDecodeValues);
this._shaderValues.setTexture(RenderableSprite3D.REFLECTIONTEXTURE, TextureCube.blackTexture);
}
else {
if (!this._probReflection.boxProjection) {
this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION);
}
else {
this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION);
this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEPOSITION, this._probReflection.probePosition);
this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMAX, this._probReflection.boundsMax);
this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMIN, this._probReflection.boundsMin);
}
this._shaderValues.setTexture(RenderableSprite3D.REFLECTIONTEXTURE, this._probReflection.reflectionTexture);
this._shaderValues.setVector(RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS, this._probReflection.reflectionHDRParams);
}
}
_renderUpdateWithCamera(context, transform) {
var projectionView = context.projectionViewMatrix;
if (projectionView) {
var element = context.renderElement;
switch (element.renderType) {
case RenderElement.RENDERTYPE_NORMAL:
case RenderElement.RENDERTYPE_STATICBATCH:
case RenderElement.RENDERTYPE_VERTEXBATCH:
if (transform) {
Matrix4x4.multiply(projectionView, transform.worldMatrix, this._projectionViewWorldMatrix);
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix);
}
else {
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, projectionView);
}
break;
}
}
}
_revertBatchRenderUpdate(context) {
var element = context.renderElement;
switch (element.renderType) {
case RenderElement.RENDERTYPE_STATICBATCH:
if (this._revertStaticBatchDefineUV1)
this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1);
this._shaderValues.setVector(RenderableSprite3D.LIGHTMAPSCALEOFFSET, this.lightmapScaleOffset);
break;
case RenderElement.RENDERTYPE_INSTANCEBATCH:
this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE);
break;
}
}
_destroy() {
(this._isPartOfStaticBatch) && (MeshRenderStaticBatchManager.instance._removeRenderSprite(this._owner));
super._destroy();
}
}
class MeshFilter {
constructor(owner) {
this._owner = owner;
}
get sharedMesh() {
return this._sharedMesh;
}
set sharedMesh(value) {
if (this._sharedMesh !== value) {
var defineDatas = this._owner._render._shaderValues;
var lastValue = this._sharedMesh;
if (lastValue) {
lastValue._removeReference();
this._getMeshDefine(lastValue, MeshFilter._meshVerticeDefine);
for (var i = 0, n = MeshFilter._meshVerticeDefine.length; i < n; i++)
defineDatas.removeDefine(MeshFilter._meshVerticeDefine[i]);
}
if (value) {
value._addReference();
this._getMeshDefine(value, MeshFilter._meshVerticeDefine);
for (var i = 0, n = MeshFilter._meshVerticeDefine.length; i < n; i++)
defineDatas.addDefine(MeshFilter._meshVerticeDefine[i]);
}
this._owner._render._onMeshChange(value);
this._sharedMesh = value;
}
}
_getMeshDefine(mesh, out) {
out.length = 0;
var define;
for (var i = 0, n = mesh._subMeshes.length; i < n; i++) {
var subMesh = mesh.getSubMesh(i);
var vertexElements = subMesh._vertexBuffer._vertexDeclaration._vertexElements;
for (var j = 0, m = vertexElements.length; j < m; j++) {
var vertexElement = vertexElements[j];
var name = vertexElement._elementUsage;
switch (name) {
case VertexMesh.MESH_COLOR0:
out.push(MeshSprite3DShaderDeclaration.SHADERDEFINE_COLOR);
break;
case VertexMesh.MESH_TEXTURECOORDINATE0:
out.push(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV0);
break;
case VertexMesh.MESH_TEXTURECOORDINATE1:
out.push(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1);
break;
}
}
}
return define;
}
destroy() {
this._owner = null;
(this._sharedMesh) && (this._sharedMesh._removeReference(), this._sharedMesh = null);
}
}
MeshFilter._meshVerticeDefine = [];
class SubMeshDynamicBatch extends GeometryElement {
constructor() {
super();
this._bufferState = new BufferState();
var gl = Laya.LayaGL.instance;
var maxVerDec = VertexMesh.getVertexDeclaration("POSITION,NORMAL,COLOR,UV,UV1,TANGENT");
var maxByteCount = maxVerDec.vertexStride * SubMeshDynamicBatch.maxIndicesCount;
this._vertices = new Float32Array(maxByteCount / 4);
this._vertexBuffer = new VertexBuffer3D(maxByteCount, gl.DYNAMIC_DRAW);
this._indices = new Int16Array(SubMeshDynamicBatch.maxIndicesCount);
this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, this._indices.length, gl.DYNAMIC_DRAW);
var memorySize = this._vertexBuffer._byteLength + this._indexBuffer._byteLength;
Laya.Resource._addMemory(memorySize, memorySize);
}
static __init__() {
SubMeshDynamicBatch.instance = new SubMeshDynamicBatch();
}
_getBatchVertices(vertexDeclaration, batchVertices, batchOffset, element, subMesh) {
var vertexFloatCount = vertexDeclaration.vertexStride / 4;
var oriVertexes = subMesh._vertexBuffer.getFloat32Data();
var multiSubMesh = element._dynamicMultiSubMesh;
var vertexCount = element._dynamicVertexCount;
element._computeWorldPositionsAndNormals(this._positionOffset, this._normalOffset, multiSubMesh, vertexCount);
var worldPositions = element._dynamicWorldPositions;
var worldNormals = element._dynamicWorldNormals;
var indices = subMesh._indices;
for (var i = 0; i < vertexCount; i++) {
var index = multiSubMesh ? indices[i] : i;
var oriOffset = index * vertexFloatCount;
var bakeOffset = (i + batchOffset) * vertexFloatCount;
var oriOff = i * 3;
var bakOff = bakeOffset + this._positionOffset;
batchVertices[bakOff] = worldPositions[oriOff];
batchVertices[bakOff + 1] = worldPositions[oriOff + 1];
batchVertices[bakOff + 2] = worldPositions[oriOff + 2];
if (this._normalOffset !== -1) {
bakOff = bakeOffset + this._normalOffset;
batchVertices[bakOff] = worldNormals[oriOff];
batchVertices[bakOff + 1] = worldNormals[oriOff + 1];
batchVertices[bakOff + 2] = worldNormals[oriOff + 2];
}
if (this._colorOffset !== -1) {
bakOff = bakeOffset + this._colorOffset;
oriOff = oriOffset + this._colorOffset;
batchVertices[bakOff] = oriVertexes[oriOff];
batchVertices[bakOff + 1] = oriVertexes[oriOff + 1];
batchVertices[bakOff + 2] = oriVertexes[oriOff + 2];
batchVertices[bakOff + 3] = oriVertexes[oriOff + 3];
}
if (this._uv0Offset !== -1) {
bakOff = bakeOffset + this._uv0Offset;
oriOff = oriOffset + this._uv0Offset;
batchVertices[bakOff] = oriVertexes[oriOff];
batchVertices[bakOff + 1] = oriVertexes[oriOff + 1];
}
if (this._sTangentOffset !== -1) {
bakOff = bakeOffset + this._sTangentOffset;
oriOff = oriOffset + this._sTangentOffset;
batchVertices[bakOff] = oriVertexes[oriOff];
batchVertices[bakOff + 1] = oriVertexes[oriOff + 1];
batchVertices[bakOff + 2] = oriVertexes[oriOff + 2];
batchVertices[bakOff + 3] = oriVertexes[oriOff + 3];
bakOff = bakeOffset + this._sTangentOffset;
oriOff = oriOffset + this._sTangentOffset;
batchVertices[bakOff] = oriVertexes[oriOff];
batchVertices[bakOff + 1] = oriVertexes[oriOff + 1];
batchVertices[bakOff + 2] = oriVertexes[oriOff + 2];
batchVertices[bakOff + 3] = oriVertexes[oriOff + 3];
}
}
}
_getBatchIndices(batchIndices, batchIndexCount, batchVertexCount, transform, subMesh, multiSubMesh) {
var subIndices = subMesh._indices;
var k, m, batchOffset;
var isInvert = transform._isFrontFaceInvert;
if (multiSubMesh) {
if (isInvert) {
for (k = 0, m = subIndices.length; k < m; k += 3) {
batchOffset = batchIndexCount + k;
var index = batchVertexCount + k;
batchIndices[batchOffset] = index;
batchIndices[batchOffset + 1] = index + 2;
batchIndices[batchOffset + 2] = index + 1;
}
}
else {
for (k = 0, m = subIndices.length; k < m; k += 3) {
batchOffset = batchIndexCount + k;
index = batchVertexCount + k;
batchIndices[batchOffset] = index;
batchIndices[batchOffset + 1] = index + 1;
batchIndices[batchOffset + 2] = index + 2;
}
}
}
else {
if (isInvert) {
for (k = 0, m = subIndices.length; k < m; k += 3) {
batchOffset = batchIndexCount + k;
batchIndices[batchOffset] = batchVertexCount + subIndices[k];
batchIndices[batchOffset + 1] = batchVertexCount + subIndices[k + 2];
batchIndices[batchOffset + 2] = batchVertexCount + subIndices[k + 1];
}
}
else {
for (k = 0, m = subIndices.length; k < m; k += 3) {
batchOffset = batchIndexCount + k;
batchIndices[batchOffset] = batchVertexCount + subIndices[k];
batchIndices[batchOffset + 1] = batchVertexCount + subIndices[k + 1];
batchIndices[batchOffset + 2] = batchVertexCount + subIndices[k + 2];
}
}
}
}
_flush(vertexCount, indexCount) {
var gl = Laya.LayaGL.instance;
this._vertexBuffer.setData(this._vertices.buffer, 0, 0, vertexCount * (this._bufferState.vertexDeclaration.vertexStride));
this._indexBuffer.setData(this._indices, 0, 0, indexCount);
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0);
}
_prepareRender(state) {
var element = state.renderElement;
var vertexDeclaration = element.vertexBatchVertexDeclaration;
this._bufferState = ILaya3D.MeshRenderDynamicBatchManager.instance._getBufferState(vertexDeclaration);
this._positionOffset = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_POSITION0)._offset / 4;
var normalElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_NORMAL0);
this._normalOffset = normalElement ? normalElement._offset / 4 : -1;
var colorElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_COLOR0);
this._colorOffset = colorElement ? colorElement._offset / 4 : -1;
var uv0Element = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE0);
this._uv0Offset = uv0Element ? uv0Element._offset / 4 : -1;
var uv1Element = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE1);
this._uv1Offset = uv1Element ? uv1Element._offset / 4 : -1;
var tangentElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TANGENT0);
this._sTangentOffset = tangentElement ? tangentElement._offset / 4 : -1;
return true;
}
_render(context) {
this._bufferState.bind();
var element = context.renderElement;
var vertexDeclaration = element.vertexBatchVertexDeclaration;
var batchElements = element.vertexBatchElementList;
var batchVertexCount = 0;
var batchIndexCount = 0;
var renderBatchCount = 0;
var elementCount = batchElements.length;
var elements = batchElements.elements;
for (var i = 0; i < elementCount; i++) {
var subElement = elements[i];
var subMesh = subElement._geometry;
var indexCount = subMesh._indexCount;
if (batchIndexCount + indexCount > SubMeshDynamicBatch.maxIndicesCount) {
this._flush(batchVertexCount, batchIndexCount);
renderBatchCount++;
Laya.Stat.trianglesFaces += batchIndexCount / 3;
batchVertexCount = batchIndexCount = 0;
}
var transform = subElement._transform;
this._getBatchVertices(vertexDeclaration, this._vertices, batchVertexCount, subElement, subMesh);
this._getBatchIndices(this._indices, batchIndexCount, batchVertexCount, transform, subMesh, subElement._dynamicMultiSubMesh);
batchVertexCount += subElement._dynamicVertexCount;
batchIndexCount += indexCount;
}
this._flush(batchVertexCount, batchIndexCount);
renderBatchCount++;
Laya.Stat.renderBatches += renderBatchCount;
Laya.Stat.savedRenderBatches += elementCount - renderBatchCount;
Laya.Stat.trianglesFaces += batchIndexCount / 3;
}
}
SubMeshDynamicBatch.maxAllowVertexCount = 10;
SubMeshDynamicBatch.maxAllowAttribueCount = 900;
SubMeshDynamicBatch.maxIndicesCount = 32000;
class MeshRenderDynamicBatchManager extends DynamicBatchManager {
constructor() {
super();
this._instanceBatchOpaqueMarks = [];
this._vertexBatchOpaqueMarks = [];
this._cacheBufferStates = [];
this._updateCountMark = 0;
}
getInstanceBatchOpaquaMark(receiveShadow, materialID, subMeshID, invertFace) {
var instanceReceiveShadowMarks = (this._instanceBatchOpaqueMarks[receiveShadow ? 0 : 1]) || (this._instanceBatchOpaqueMarks[receiveShadow ? 0 : 1] = []);
var instanceMaterialMarks = (instanceReceiveShadowMarks[materialID]) || (instanceReceiveShadowMarks[materialID] = []);
var instancSubMeshMarks = (instanceMaterialMarks[subMeshID]) || (instanceMaterialMarks[subMeshID] = []);
return instancSubMeshMarks[invertFace ? 1 : 0] || (instancSubMeshMarks[invertFace ? 1 : 0] = new BatchMark());
}
getVertexBatchOpaquaMark(lightMapIndex, receiveShadow, materialID, verDecID) {
var dynLightMapMarks = (this._vertexBatchOpaqueMarks[lightMapIndex]) || (this._vertexBatchOpaqueMarks[lightMapIndex] = []);
var dynReceiveShadowMarks = (dynLightMapMarks[receiveShadow ? 0 : 1]) || (dynLightMapMarks[receiveShadow ? 0 : 1] = []);
var dynMaterialMarks = (dynReceiveShadowMarks[materialID]) || (dynReceiveShadowMarks[materialID] = []);
return dynMaterialMarks[verDecID] || (dynMaterialMarks[verDecID] = new BatchMark());
}
_getBufferState(vertexDeclaration) {
var bufferState = this._cacheBufferStates[vertexDeclaration.id];
if (!bufferState) {
var instance = SubMeshDynamicBatch.instance;
bufferState = new BufferState();
bufferState.bind();
var vertexBuffer = instance._vertexBuffer;
vertexBuffer.vertexDeclaration = vertexDeclaration;
bufferState.applyVertexBuffer(vertexBuffer);
bufferState.applyIndexBuffer(instance._indexBuffer);
bufferState.unBind();
this._cacheBufferStates[vertexDeclaration.id] = bufferState;
}
return bufferState;
}
_getBatchRenderElementFromPool() {
var renderElement = this._batchRenderElementPool[this._batchRenderElementPoolIndex++];
if (!renderElement) {
renderElement = new SubMeshRenderElement();
this._batchRenderElementPool[this._batchRenderElementPoolIndex - 1] = renderElement;
renderElement.vertexBatchElementList = new SingletonList();
renderElement.instanceBatchElementList = new SingletonList();
}
return renderElement;
}
_clear() {
super._clear();
this._updateCountMark++;
}
}
MeshRenderDynamicBatchManager.instance = new MeshRenderDynamicBatchManager();
class MeshSprite3D extends RenderableSprite3D {
constructor(mesh = null, name = null) {
super(name);
this._meshFilter = new MeshFilter(this);
this._render = new MeshRenderer(this);
(mesh) && (this._meshFilter.sharedMesh = mesh);
}
static __init__() {
MeshSprite3DShaderDeclaration.SHADERDEFINE_UV0 = Shader3D.getDefineByName("UV");
MeshSprite3DShaderDeclaration.SHADERDEFINE_COLOR = Shader3D.getDefineByName("COLOR");
MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1 = Shader3D.getDefineByName("UV1");
MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE = Shader3D.getDefineByName("GPU_INSTANCE");
MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION = Shader3D.getDefineByName("SPECCUBE_BOX_PROJECTION");
StaticBatchManager._registerManager(MeshRenderStaticBatchManager.instance);
DynamicBatchManager._registerManager(MeshRenderDynamicBatchManager.instance);
}
get meshFilter() {
return this._meshFilter;
}
get meshRenderer() {
return this._render;
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
var render = this.meshRenderer;
var lightmapIndex = data.lightmapIndex;
(lightmapIndex != null) && (render.lightmapIndex = lightmapIndex);
var lightmapScaleOffsetArray = data.lightmapScaleOffset;
(lightmapScaleOffsetArray) && (render.lightmapScaleOffset = new Vector4(lightmapScaleOffsetArray[0], lightmapScaleOffsetArray[1], lightmapScaleOffsetArray[2], lightmapScaleOffsetArray[3]));
(data.meshPath != undefined) && (this.meshFilter.sharedMesh = Laya.Loader.getRes(data.meshPath));
(data.enableRender != undefined) && (render.enable = data.enableRender);
(data.receiveShadows != undefined) && (render.receiveShadow = data.receiveShadows);
(data.castShadow != undefined) && (render.castShadow = data.castShadow);
var materials = data.materials;
if (materials) {
var sharedMaterials = render.sharedMaterials;
var materialCount = materials.length;
sharedMaterials.length = materialCount;
for (var i = 0; i < materialCount; i++) {
sharedMaterials[i] = Laya.Loader.getRes(materials[i].path);
}
render.sharedMaterials = sharedMaterials;
}
}
_addToInitStaticBatchManager() {
if (this.meshFilter.sharedMesh)
MeshRenderStaticBatchManager.instance._addBatchSprite(this);
}
_cloneTo(destObject, rootSprite, dstSprite) {
var meshSprite3D = destObject;
meshSprite3D._meshFilter.sharedMesh = this._meshFilter.sharedMesh;
var meshRender = this._render;
var destMeshRender = meshSprite3D._render;
destMeshRender.enable = meshRender.enable;
destMeshRender.sharedMaterials = meshRender.sharedMaterials;
destMeshRender.castShadow = meshRender.castShadow;
var lightmapScaleOffset = meshRender.lightmapScaleOffset;
lightmapScaleOffset && (destMeshRender.lightmapScaleOffset = lightmapScaleOffset.clone());
destMeshRender.lightmapIndex = meshRender.lightmapIndex;
destMeshRender.receiveShadow = meshRender.receiveShadow;
destMeshRender.sortingFudge = meshRender.sortingFudge;
super._cloneTo(destObject, rootSprite, dstSprite);
}
destroy(destroyChild = true) {
if (this.destroyed)
return;
super.destroy(destroyChild);
this._meshFilter.destroy();
}
_create() {
return new MeshSprite3D();
}
}
class GradientMode {
}
GradientMode.Blend = 0;
GradientMode.Fixed = 1;
class Gradient {
constructor(maxColorRGBKeyCount, maxColorAlphaKeyCount) {
this._mode = 0;
this._maxColorRGBKeysCount = 0;
this._maxColorAlphaKeysCount = 0;
this._colorRGBKeysCount = 0;
this._colorAlphaKeysCount = 0;
this._alphaElements = null;
this._rgbElements = null;
this._maxColorRGBKeysCount = maxColorRGBKeyCount;
this._maxColorAlphaKeysCount = maxColorAlphaKeyCount;
this._rgbElements = new Float32Array(maxColorRGBKeyCount * 4);
this._alphaElements = new Float32Array(maxColorAlphaKeyCount * 2);
}
get mode() {
return this._mode;
}
set mode(value) {
this._mode = value;
}
get colorRGBKeysCount() {
return this._colorRGBKeysCount;
}
get colorAlphaKeysCount() {
return this._colorAlphaKeysCount;
}
get maxColorRGBKeysCount() {
return this._maxColorRGBKeysCount;
}
get maxColorAlphaKeysCount() {
return this._maxColorAlphaKeysCount;
}
addColorRGB(key, value) {
if (this._colorRGBKeysCount < this._maxColorRGBKeysCount) {
var offset = this._colorRGBKeysCount * 4;
this._rgbElements[offset] = key;
this._rgbElements[offset + 1] = value.r;
this._rgbElements[offset + 2] = value.g;
this._rgbElements[offset + 3] = value.b;
this._colorRGBKeysCount++;
}
else {
console.warn("Gradient:warning:data count must lessEqual than " + this._maxColorRGBKeysCount);
}
}
addColorAlpha(key, value) {
if (this._colorAlphaKeysCount < this._maxColorAlphaKeysCount) {
var offset = this._colorAlphaKeysCount * 2;
this._alphaElements[offset] = key;
this._alphaElements[offset + 1] = value;
this._colorAlphaKeysCount++;
}
else {
console.warn("Gradient:warning:data count must lessEqual than " + this._maxColorAlphaKeysCount);
}
}
updateColorRGB(index, key, value) {
if (index < this._colorRGBKeysCount) {
var offset = index * 4;
this._rgbElements[offset] = key;
this._rgbElements[offset + 1] = value.r;
this._rgbElements[offset + 2] = value.g;
this._rgbElements[offset + 3] = value.b;
}
else {
console.warn("Gradient:warning:index must lessEqual than colorRGBKeysCount:" + this._colorRGBKeysCount);
}
}
updateColorAlpha(index, key, value) {
if (index < this._colorAlphaKeysCount) {
var offset = index * 2;
this._alphaElements[offset] = key;
this._alphaElements[offset + 1] = value;
}
else {
console.warn("Gradient:warning:index must lessEqual than colorAlphaKeysCount:" + this._colorAlphaKeysCount);
}
}
evaluateColorRGB(lerpFactor, out, startSearchIndex = 0, reverseSearch = false) {
lerpFactor = Math.min(Math.max(lerpFactor, 0.0), 1.0);
var rgbElements = this._rgbElements;
var curIndex = startSearchIndex;
if (reverseSearch) {
for (var i = curIndex; i >= 0; i--) {
var offset = i * 4;
var left = rgbElements[offset];
if (lerpFactor === left) {
out.r = rgbElements[offset + 1];
out.g = rgbElements[offset + 2];
out.b = rgbElements[offset + 3];
return curIndex;
}
switch (this._mode) {
case GradientMode.Blend:
if (lerpFactor > left) {
var right = rgbElements[offset + 4];
if (lerpFactor > right)
throw "Gradient:wrong startSearchIndex.";
var diff = right - left;
var y1 = right - lerpFactor;
var y2 = lerpFactor - left;
out.r = (y1 * rgbElements[offset + 1] + y2 * rgbElements[offset + 5]) / diff;
out.g = (y1 * rgbElements[offset + 2] + y2 * rgbElements[offset + 6]) / diff;
out.b = (y1 * rgbElements[offset + 3] + y2 * rgbElements[offset + 7]) / diff;
return curIndex;
}
else {
curIndex--;
continue;
}
case GradientMode.Fixed:
if (lerpFactor > left) {
if (lerpFactor > rgbElements[offset + 4])
throw "Gradient:wrong startSearchIndex.";
out.r = rgbElements[offset + 5];
out.g = rgbElements[offset + 6];
out.b = rgbElements[offset + 7];
return curIndex;
}
else {
curIndex--;
continue;
}
default:
throw "Gradient:unknown mode.";
}
}
}
else {
for (var i = 0, n = this._rgbElements.length; i < n; i++) {
offset = i * 4;
var right = rgbElements[offset];
if (lerpFactor === right) {
out.r = rgbElements[offset + 1];
out.g = rgbElements[offset + 2];
out.b = rgbElements[offset + 3];
return curIndex;
}
switch (this._mode) {
case GradientMode.Blend:
if (lerpFactor < right) {
var left = rgbElements[offset - 4];
if (lerpFactor < left)
throw "Gradient:wrong startSearchIndex.";
var diff = right - left;
var y1 = right - lerpFactor;
var y2 = lerpFactor - left;
out.r = (y1 * rgbElements[offset - 3] + y2 * rgbElements[offset + 1]) / diff;
out.g = (y1 * rgbElements[offset - 2] + y2 * rgbElements[offset + 2]) / diff;
out.b = (y1 * rgbElements[offset - 1] + y2 * rgbElements[offset + 3]) / diff;
return curIndex;
}
else {
curIndex++;
continue;
}
case GradientMode.Fixed:
if (lerpFactor < right) {
if (lerpFactor < rgbElements[offset - 4])
throw "Gradient:wrong startSearchIndex.";
out.r = rgbElements[offset + 1];
out.g = rgbElements[offset + 2];
out.b = rgbElements[offset + 3];
return curIndex;
}
else {
curIndex++;
continue;
}
default:
throw "Gradient:unknown mode.";
}
}
}
return curIndex;
}
evaluateColorAlpha(lerpFactor, outColor, startSearchIndex = 0, reverseSearch = false) {
lerpFactor = Math.min(Math.max(lerpFactor, 0.0), 1.0);
var alphaElements = this._alphaElements;
var curIndex = startSearchIndex;
if (reverseSearch) {
for (var i = curIndex; i >= 0; i--) {
var offset = i * 2;
var left = alphaElements[offset];
if (lerpFactor === left) {
outColor.a = alphaElements[offset + 1];
return curIndex;
}
switch (this._mode) {
case GradientMode.Blend:
if (lerpFactor > left) {
var right = alphaElements[offset + 2];
if (lerpFactor > right)
throw "Gradient:wrong startSearchIndex.";
var diff = right - left;
var x1 = right - lerpFactor;
var x2 = lerpFactor - left;
outColor.a = (x1 * alphaElements[offset + 1] + x2 * alphaElements[offset + 3]) / diff;
return curIndex;
}
else {
curIndex--;
continue;
}
case GradientMode.Fixed:
if (lerpFactor > left) {
if (lerpFactor > alphaElements[offset + 2])
throw "Gradient:wrong startSearchIndex.";
outColor.a = alphaElements[offset + 3];
return curIndex;
}
else {
curIndex--;
continue;
}
default:
throw "Gradient:unknown mode.";
}
}
}
else {
for (var i = curIndex, n = this._alphaElements.length; i < n; i++) {
var offset = i * 2;
var right = alphaElements[offset];
if (lerpFactor === right) {
outColor.a = alphaElements[offset + 1];
return curIndex;
}
switch (this._mode) {
case GradientMode.Blend:
if (lerpFactor < right) {
var left = alphaElements[offset - 2];
if (lerpFactor < left)
throw "Gradient:wrong startSearchIndex.";
var diff = right - left;
var x1 = right - lerpFactor;
var x2 = lerpFactor - left;
outColor.a = (x1 * alphaElements[offset - 1] + x2 * alphaElements[offset + 1]) / diff;
return curIndex;
}
else {
curIndex++;
continue;
}
case GradientMode.Fixed:
if (lerpFactor < right) {
if (lerpFactor < alphaElements[offset - 2])
throw "Gradient:wrong startSearchIndex.";
outColor.a = alphaElements[offset + 1];
return curIndex;
}
else {
curIndex++;
continue;
}
default:
throw "Gradient:unknown mode.";
}
}
}
return curIndex;
}
cloneTo(destObject) {
var destGradientDataColor = destObject;
var i, n;
destGradientDataColor._colorAlphaKeysCount = this._colorAlphaKeysCount;
var destAlphaElements = destGradientDataColor._alphaElements;
for (i = 0, n = this._alphaElements.length; i < n; i++)
destAlphaElements[i] = this._alphaElements[i];
destGradientDataColor._colorRGBKeysCount = this._colorRGBKeysCount;
var destRGBElements = destGradientDataColor._rgbElements;
for (i = 0, n = this._rgbElements.length; i < n; i++)
destRGBElements[i] = this._rgbElements[i];
}
clone() {
var destGradientDataColor = new Gradient(this._maxColorRGBKeysCount, this._maxColorAlphaKeysCount);
this.cloneTo(destGradientDataColor);
return destGradientDataColor;
}
}
class Burst {
constructor(time, minCount, maxCount) {
this._time = time;
this._minCount = minCount;
this._maxCount = maxCount;
}
get time() {
return this._time;
}
get minCount() {
return this._minCount;
}
get maxCount() {
return this._maxCount;
}
cloneTo(destObject) {
var destBurst = destObject;
destBurst._time = this._time;
destBurst._minCount = this._minCount;
destBurst._maxCount = this._maxCount;
}
clone() {
var destBurst = new Burst(this._time, this._minCount, this._maxCount);
this.cloneTo(destBurst);
return destBurst;
}
}
class GradientColor {
constructor() {
this._type = 0;
this._constant = null;
this._constantMin = null;
this._constantMax = null;
this._gradient = null;
this._gradientMin = null;
this._gradientMax = null;
}
static createByConstant(constant) {
var gradientColor = new GradientColor();
gradientColor._type = 0;
gradientColor._constant = constant;
return gradientColor;
}
static createByGradient(gradient) {
var gradientColor = new GradientColor();
gradientColor._type = 1;
gradientColor._gradient = gradient;
return gradientColor;
}
static createByRandomTwoConstant(minConstant, maxConstant) {
var gradientColor = new GradientColor();
gradientColor._type = 2;
gradientColor._constantMin = minConstant;
gradientColor._constantMax = maxConstant;
return gradientColor;
}
static createByRandomTwoGradient(minGradient, maxGradient) {
var gradientColor = new GradientColor();
gradientColor._type = 3;
gradientColor._gradientMin = minGradient;
gradientColor._gradientMax = maxGradient;
return gradientColor;
}
get type() {
return this._type;
}
get constant() {
return this._constant;
}
get constantMin() {
return this._constantMin;
}
get constantMax() {
return this._constantMax;
}
get gradient() {
return this._gradient;
}
get gradientMin() {
return this._gradientMin;
}
get gradientMax() {
return this._gradientMax;
}
cloneTo(destObject) {
var destGradientColor = destObject;
destGradientColor._type = this._type;
this._constant.cloneTo(destGradientColor._constant);
this._constantMin.cloneTo(destGradientColor._constantMin);
this._constantMax.cloneTo(destGradientColor._constantMax);
this._gradient.cloneTo(destGradientColor._gradient);
this._gradientMin.cloneTo(destGradientColor._gradientMin);
this._gradientMax.cloneTo(destGradientColor._gradientMax);
}
clone() {
var destGradientColor = new GradientColor();
this.cloneTo(destGradientColor);
return destGradientColor;
}
}
class ColorOverLifetime {
constructor(color) {
this._color = color;
}
get color() {
return this._color;
}
cloneTo(destObject) {
var destColorOverLifetime = destObject;
this._color.cloneTo(destColorOverLifetime._color);
destColorOverLifetime.enable = this.enable;
}
clone() {
var destColor;
switch (this._color.type) {
case 0:
destColor = GradientColor.createByConstant(this._color.constant.clone());
break;
case 1:
destColor = GradientColor.createByGradient(this._color.gradient.clone());
break;
case 2:
destColor = GradientColor.createByRandomTwoConstant(this._color.constantMin.clone(), this._color.constantMax.clone());
break;
case 3:
destColor = GradientColor.createByRandomTwoGradient(this._color.gradientMin.clone(), this._color.gradientMax.clone());
break;
}
var destColorOverLifetime = new ColorOverLifetime(destColor);
destColorOverLifetime.enable = this.enable;
return destColorOverLifetime;
}
}
class FrameOverTime {
constructor() {
this._type = 0;
this._constant = 0;
this._overTime = null;
this._constantMin = 0;
this._constantMax = 0;
this._overTimeMin = null;
this._overTimeMax = null;
}
static createByConstant(constant = 0) {
var rotationOverLifetime = new FrameOverTime();
rotationOverLifetime._type = 0;
rotationOverLifetime._constant = constant;
return rotationOverLifetime;
}
static createByOverTime(overTime) {
var rotationOverLifetime = new FrameOverTime();
rotationOverLifetime._type = 1;
rotationOverLifetime._overTime = overTime;
return rotationOverLifetime;
}
static createByRandomTwoConstant(constantMin = 0, constantMax = 0) {
var rotationOverLifetime = new FrameOverTime();
rotationOverLifetime._type = 2;
rotationOverLifetime._constantMin = constantMin;
rotationOverLifetime._constantMax = constantMax;
return rotationOverLifetime;
}
static createByRandomTwoOverTime(gradientFrameMin, gradientFrameMax) {
var rotationOverLifetime = new FrameOverTime();
rotationOverLifetime._type = 3;
rotationOverLifetime._overTimeMin = gradientFrameMin;
rotationOverLifetime._overTimeMax = gradientFrameMax;
return rotationOverLifetime;
}
get type() {
return this._type;
}
get constant() {
return this._constant;
}
get frameOverTimeData() {
return this._overTime;
}
get constantMin() {
return this._constantMin;
}
get constantMax() {
return this._constantMax;
}
get frameOverTimeDataMin() {
return this._overTimeMin;
}
get frameOverTimeDataMax() {
return this._overTimeMax;
}
cloneTo(destObject) {
var destFrameOverTime = destObject;
destFrameOverTime._type = this._type;
destFrameOverTime._constant = this._constant;
(this._overTime) && (this._overTime.cloneTo(destFrameOverTime._overTime));
destFrameOverTime._constantMin = this._constantMin;
destFrameOverTime._constantMax = this._constantMax;
(this._overTimeMin) && (this._overTimeMin.cloneTo(destFrameOverTime._overTimeMin));
(this._overTimeMax) && (this._overTimeMax.cloneTo(destFrameOverTime._overTimeMax));
}
clone() {
var destFrameOverTime = new FrameOverTime();
this.cloneTo(destFrameOverTime);
return destFrameOverTime;
}
}
class GradientAngularVelocity {
constructor() {
this._type = 0;
this._separateAxes = false;
this._constant = 0;
this._constantSeparate = null;
this._gradient = null;
this._gradientX = null;
this._gradientY = null;
this._gradientZ = null;
this._gradientW = null;
this._constantMin = 0;
this._constantMax = 0;
this._constantMinSeparate = null;
this._constantMaxSeparate = null;
this._gradientMin = null;
this._gradientMax = null;
this._gradientXMin = null;
this._gradientXMax = null;
this._gradientYMin = null;
this._gradientYMax = null;
this._gradientZMin = null;
this._gradientZMax = null;
this._gradientWMin = null;
this._gradientWMax = null;
}
static createByConstant(constant) {
var gradientAngularVelocity = new GradientAngularVelocity();
gradientAngularVelocity._type = 0;
gradientAngularVelocity._separateAxes = false;
gradientAngularVelocity._constant = constant;
return gradientAngularVelocity;
}
static createByConstantSeparate(separateConstant) {
var gradientAngularVelocity = new GradientAngularVelocity();
gradientAngularVelocity._type = 0;
gradientAngularVelocity._separateAxes = true;
gradientAngularVelocity._constantSeparate = separateConstant;
return gradientAngularVelocity;
}
static createByGradient(gradient) {
var gradientAngularVelocity = new GradientAngularVelocity();
gradientAngularVelocity._type = 1;
gradientAngularVelocity._separateAxes = false;
gradientAngularVelocity._gradient = gradient;
return gradientAngularVelocity;
}
static createByGradientSeparate(gradientX, gradientY, gradientZ) {
var gradientAngularVelocity = new GradientAngularVelocity();
gradientAngularVelocity._type = 1;
gradientAngularVelocity._separateAxes = true;
gradientAngularVelocity._gradientX = gradientX;
gradientAngularVelocity._gradientY = gradientY;
gradientAngularVelocity._gradientZ = gradientZ;
return gradientAngularVelocity;
}
static createByRandomTwoConstant(constantMin, constantMax) {
var gradientAngularVelocity = new GradientAngularVelocity();
gradientAngularVelocity._type = 2;
gradientAngularVelocity._separateAxes = false;
gradientAngularVelocity._constantMin = constantMin;
gradientAngularVelocity._constantMax = constantMax;
return gradientAngularVelocity;
}
static createByRandomTwoConstantSeparate(separateConstantMin, separateConstantMax) {
var gradientAngularVelocity = new GradientAngularVelocity();
gradientAngularVelocity._type = 2;
gradientAngularVelocity._separateAxes = true;
gradientAngularVelocity._constantMinSeparate = separateConstantMin;
gradientAngularVelocity._constantMaxSeparate = separateConstantMax;
return gradientAngularVelocity;
}
static createByRandomTwoGradient(gradientMin, gradientMax) {
var gradientAngularVelocity = new GradientAngularVelocity();
gradientAngularVelocity._type = 3;
gradientAngularVelocity._separateAxes = false;
gradientAngularVelocity._gradientMin = gradientMin;
gradientAngularVelocity._gradientMax = gradientMax;
return gradientAngularVelocity;
}
static createByRandomTwoGradientSeparate(gradientXMin, gradientXMax, gradientYMin, gradientYMax, gradientZMin, gradientZMax, gradientWMin, gradientWMax) {
var gradientAngularVelocity = new GradientAngularVelocity();
gradientAngularVelocity._type = 3;
gradientAngularVelocity._separateAxes = true;
gradientAngularVelocity._gradientXMin = gradientXMin;
gradientAngularVelocity._gradientXMax = gradientXMax;
gradientAngularVelocity._gradientYMin = gradientYMin;
gradientAngularVelocity._gradientYMax = gradientYMax;
gradientAngularVelocity._gradientZMin = gradientZMin;
gradientAngularVelocity._gradientZMax = gradientZMax;
gradientAngularVelocity._gradientWMin = gradientWMin;
gradientAngularVelocity._gradientWMax = gradientWMax;
return gradientAngularVelocity;
}
get type() {
return this._type;
}
get separateAxes() {
return this._separateAxes;
}
get constant() {
return this._constant;
}
get constantSeparate() {
return this._constantSeparate;
}
get gradient() {
return this._gradient;
}
get gradientX() {
return this._gradientX;
}
get gradientY() {
return this._gradientY;
}
get gradientZ() {
return this._gradientZ;
}
get gradientW() {
return this._gradientW;
}
get constantMin() {
return this._constantMin;
}
get constantMax() {
return this._constantMax;
}
get constantMinSeparate() {
return this._constantMinSeparate;
}
get constantMaxSeparate() {
return this._constantMaxSeparate;
}
get gradientMin() {
return this._gradientMin;
}
get gradientMax() {
return this._gradientMax;
}
get gradientXMin() {
return this._gradientXMin;
}
get gradientXMax() {
return this._gradientXMax;
}
get gradientYMin() {
return this._gradientYMin;
}
get gradientYMax() {
return this._gradientYMax;
}
get gradientZMin() {
return this._gradientZMin;
}
get gradientZMax() {
return this._gradientZMax;
}
get gradientWMin() {
return this._gradientWMin;
}
get gradientWMax() {
return this._gradientWMax;
}
cloneTo(destObject) {
var destGradientAngularVelocity = destObject;
destGradientAngularVelocity._type = this._type;
destGradientAngularVelocity._separateAxes = this._separateAxes;
destGradientAngularVelocity._constant = this._constant;
this._constantSeparate.cloneTo(destGradientAngularVelocity._constantSeparate);
this._gradient.cloneTo(destGradientAngularVelocity._gradient);
this._gradientX.cloneTo(destGradientAngularVelocity._gradientX);
this._gradientY.cloneTo(destGradientAngularVelocity._gradientY);
this._gradientZ.cloneTo(destGradientAngularVelocity._gradientZ);
destGradientAngularVelocity._constantMin = this._constantMin;
destGradientAngularVelocity._constantMax = this._constantMax;
this._constantMinSeparate.cloneTo(destGradientAngularVelocity._constantMinSeparate);
this._constantMaxSeparate.cloneTo(destGradientAngularVelocity._constantMaxSeparate);
this._gradientMin.cloneTo(destGradientAngularVelocity._gradientMin);
this._gradientMax.cloneTo(destGradientAngularVelocity._gradientMax);
this._gradientXMin.cloneTo(destGradientAngularVelocity._gradientXMin);
this._gradientXMax.cloneTo(destGradientAngularVelocity._gradientXMax);
this._gradientYMin.cloneTo(destGradientAngularVelocity._gradientYMin);
this._gradientYMax.cloneTo(destGradientAngularVelocity._gradientYMax);
this._gradientZMin.cloneTo(destGradientAngularVelocity._gradientZMin);
this._gradientZMax.cloneTo(destGradientAngularVelocity._gradientZMax);
}
clone() {
var destGradientAngularVelocity = new GradientAngularVelocity();
this.cloneTo(destGradientAngularVelocity);
return destGradientAngularVelocity;
}
}
class GradientDataInt {
constructor() {
this._currentLength = 0;
this._elements = new Float32Array(8);
}
get gradientCount() {
return this._currentLength / 2;
}
add(key, value) {
if (this._currentLength < 8) {
if ((this._currentLength === 6) && ((key !== 1))) {
key = 1;
console.log("Warning:the forth key is be force set to 1.");
}
this._elements[this._currentLength++] = key;
this._elements[this._currentLength++] = value;
}
else {
console.log("Warning:data count must lessEqual than 4");
}
}
cloneTo(destObject) {
var destGradientDataInt = destObject;
destGradientDataInt._currentLength = this._currentLength;
var destElements = destGradientDataInt._elements;
for (var i = 0, n = this._elements.length; i < n; i++) {
destElements[i] = this._elements[i];
}
}
clone() {
var destGradientDataInt = new GradientDataInt();
this.cloneTo(destGradientDataInt);
return destGradientDataInt;
}
}
class GradientDataNumber {
constructor() {
this._currentLength = 0;
this._elements = new Float32Array(8);
}
get gradientCount() {
return this._currentLength / 2;
}
add(key, value) {
if (this._currentLength < 8) {
if ((this._currentLength === 6) && ((key !== 1))) {
key = 1;
console.log("GradientDataNumber warning:the forth key is be force set to 1.");
}
this._elements[this._currentLength++] = key;
this._elements[this._currentLength++] = value;
}
else {
console.log("GradientDataNumber warning:data count must lessEqual than 4");
}
}
getKeyByIndex(index) {
return this._elements[index * 2];
}
getValueByIndex(index) {
return this._elements[index * 2 + 1];
}
getAverageValue() {
var total = 0;
var count = 0;
for (var i = 0, n = this._currentLength - 2; i < n; i += 2) {
var subValue = this._elements[i + 1];
subValue += this._elements[i + 3];
subValue = subValue * (this._elements[i + 2] - this._elements[i]);
total += subValue;
count++;
}
return total / count;
}
cloneTo(destObject) {
var destGradientDataNumber = destObject;
destGradientDataNumber._currentLength = this._currentLength;
var destElements = destGradientDataNumber._elements;
for (var i = 0, n = this._elements.length; i < n; i++)
destElements[i] = this._elements[i];
}
clone() {
var destGradientDataNumber = new GradientDataNumber();
this.cloneTo(destGradientDataNumber);
return destGradientDataNumber;
}
}
class GradientSize {
constructor() {
this._type = 0;
this._separateAxes = false;
this._gradient = null;
this._gradientX = null;
this._gradientY = null;
this._gradientZ = null;
this._constantMin = 0;
this._constantMax = 0;
this._constantMinSeparate = null;
this._constantMaxSeparate = null;
this._gradientMin = null;
this._gradientMax = null;
this._gradientXMin = null;
this._gradientXMax = null;
this._gradientYMin = null;
this._gradientYMax = null;
this._gradientZMin = null;
this._gradientZMax = null;
}
static createByGradient(gradient) {
var gradientSize = new GradientSize();
gradientSize._type = 0;
gradientSize._separateAxes = false;
gradientSize._gradient = gradient;
return gradientSize;
}
static createByGradientSeparate(gradientX, gradientY, gradientZ) {
var gradientSize = new GradientSize();
gradientSize._type = 0;
gradientSize._separateAxes = true;
gradientSize._gradientX = gradientX;
gradientSize._gradientY = gradientY;
gradientSize._gradientZ = gradientZ;
return gradientSize;
}
static createByRandomTwoConstant(constantMin, constantMax) {
var gradientSize = new GradientSize();
gradientSize._type = 1;
gradientSize._separateAxes = false;
gradientSize._constantMin = constantMin;
gradientSize._constantMax = constantMax;
return gradientSize;
}
static createByRandomTwoConstantSeparate(constantMinSeparate, constantMaxSeparate) {
var gradientSize = new GradientSize();
gradientSize._type = 1;
gradientSize._separateAxes = true;
gradientSize._constantMinSeparate = constantMinSeparate;
gradientSize._constantMaxSeparate = constantMaxSeparate;
return gradientSize;
}
static createByRandomTwoGradient(gradientMin, gradientMax) {
var gradientSize = new GradientSize();
gradientSize._type = 2;
gradientSize._separateAxes = false;
gradientSize._gradientMin = gradientMin;
gradientSize._gradientMax = gradientMax;
return gradientSize;
}
static createByRandomTwoGradientSeparate(gradientXMin, gradientXMax, gradientYMin, gradientYMax, gradientZMin, gradientZMax) {
var gradientSize = new GradientSize();
gradientSize._type = 2;
gradientSize._separateAxes = true;
gradientSize._gradientXMin = gradientXMin;
gradientSize._gradientXMax = gradientXMax;
gradientSize._gradientYMin = gradientYMin;
gradientSize._gradientYMax = gradientYMax;
gradientSize._gradientZMin = gradientZMin;
gradientSize._gradientZMax = gradientZMax;
return gradientSize;
}
get type() {
return this._type;
}
get separateAxes() {
return this._separateAxes;
}
get gradient() {
return this._gradient;
}
get gradientX() {
return this._gradientX;
}
get gradientY() {
return this._gradientY;
}
get gradientZ() {
return this._gradientZ;
}
get constantMin() {
return this._constantMin;
}
get constantMax() {
return this._constantMax;
}
get constantMinSeparate() {
return this._constantMinSeparate;
}
get constantMaxSeparate() {
return this._constantMaxSeparate;
}
get gradientMin() {
return this._gradientMin;
}
get gradientMax() {
return this._gradientMax;
}
get gradientXMin() {
return this._gradientXMin;
}
get gradientXMax() {
return this._gradientXMax;
}
get gradientYMin() {
return this._gradientYMin;
}
get gradientYMax() {
return this._gradientYMax;
}
get gradientZMin() {
return this._gradientZMin;
}
get gradientZMax() {
return this._gradientZMax;
}
getMaxSizeInGradient(meshMode = false) {
var i, n;
var maxSize = -Number.MAX_VALUE;
switch (this._type) {
case 0:
if (this._separateAxes) {
for (i = 0, n = this._gradientX.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradientX.getValueByIndex(i));
for (i = 0, n = this._gradientY.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradientY.getValueByIndex(i));
if (meshMode) {
for (i = 0, n = this._gradientZ.gradientCount; i < n; i++) {
maxSize = Math.max(maxSize, this._gradientZ.getValueByIndex(i));
}
}
}
else {
for (i = 0, n = this._gradient.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradient.getValueByIndex(i));
}
break;
case 1:
if (this._separateAxes) {
maxSize = Math.max(this._constantMinSeparate.x, this._constantMaxSeparate.x);
maxSize = Math.max(maxSize, this._constantMinSeparate.y);
if (meshMode) {
maxSize = maxSize = Math.max(maxSize, this._constantMaxSeparate.z);
}
}
else {
maxSize = Math.max(this._constantMin, this._constantMax);
}
break;
case 2:
if (this._separateAxes) {
for (i = 0, n = this._gradientXMin.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradientXMin.getValueByIndex(i));
for (i = 0, n = this._gradientXMax.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradientXMax.getValueByIndex(i));
for (i = 0, n = this._gradientYMin.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradientYMin.getValueByIndex(i));
for (i = 0, n = this._gradientZMax.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradientZMax.getValueByIndex(i));
if (meshMode) {
for (i = 0, n = this._gradientZMin.gradientCount; i < n; i++) {
maxSize = Math.max(maxSize, this._gradientZMin.getValueByIndex(i));
}
for (i = 0, n = this._gradientZMax.gradientCount; i < n; i++) {
maxSize = Math.max(maxSize, this._gradientZMax.getValueByIndex(i));
}
}
}
else {
for (i = 0, n = this._gradientMin.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradientMin.getValueByIndex(i));
for (i = 0, n = this._gradientMax.gradientCount; i < n; i++)
maxSize = Math.max(maxSize, this._gradientMax.getValueByIndex(i));
}
break;
}
return maxSize;
}
cloneTo(destObject) {
var destGradientSize = destObject;
destGradientSize._type = this._type;
destGradientSize._separateAxes = this._separateAxes;
this._gradient.cloneTo(destGradientSize._gradient);
this._gradientX.cloneTo(destGradientSize._gradientX);
this._gradientY.cloneTo(destGradientSize._gradientY);
this._gradientZ.cloneTo(destGradientSize._gradientZ);
destGradientSize._constantMin = this._constantMin;
destGradientSize._constantMax = this._constantMax;
this._constantMinSeparate.cloneTo(destGradientSize._constantMinSeparate);
this._constantMaxSeparate.cloneTo(destGradientSize._constantMaxSeparate);
this._gradientMin.cloneTo(destGradientSize._gradientMin);
this._gradientMax.cloneTo(destGradientSize._gradientMax);
this._gradientXMin.cloneTo(destGradientSize._gradientXMin);
this._gradientXMax.cloneTo(destGradientSize._gradientXMax);
this._gradientYMin.cloneTo(destGradientSize._gradientYMin);
this._gradientYMax.cloneTo(destGradientSize._gradientYMax);
this._gradientZMin.cloneTo(destGradientSize._gradientZMin);
this._gradientZMax.cloneTo(destGradientSize._gradientZMax);
}
clone() {
var destGradientSize = new GradientSize();
this.cloneTo(destGradientSize);
return destGradientSize;
}
}
class GradientVelocity {
constructor() {
this._type = 0;
this._constant = null;
this._gradientX = null;
this._gradientY = null;
this._gradientZ = null;
this._constantMin = null;
this._constantMax = null;
this._gradientXMin = null;
this._gradientXMax = null;
this._gradientYMin = null;
this._gradientYMax = null;
this._gradientZMin = null;
this._gradientZMax = null;
}
static createByConstant(constant) {
var gradientVelocity = new GradientVelocity();
gradientVelocity._type = 0;
gradientVelocity._constant = constant;
return gradientVelocity;
}
static createByGradient(gradientX, gradientY, gradientZ) {
var gradientVelocity = new GradientVelocity();
gradientVelocity._type = 1;
gradientVelocity._gradientX = gradientX;
gradientVelocity._gradientY = gradientY;
gradientVelocity._gradientZ = gradientZ;
return gradientVelocity;
}
static createByRandomTwoConstant(constantMin, constantMax) {
var gradientVelocity = new GradientVelocity();
gradientVelocity._type = 2;
gradientVelocity._constantMin = constantMin;
gradientVelocity._constantMax = constantMax;
return gradientVelocity;
}
static createByRandomTwoGradient(gradientXMin, gradientXMax, gradientYMin, gradientYMax, gradientZMin, gradientZMax) {
var gradientVelocity = new GradientVelocity();
gradientVelocity._type = 3;
gradientVelocity._gradientXMin = gradientXMin;
gradientVelocity._gradientXMax = gradientXMax;
gradientVelocity._gradientYMin = gradientYMin;
gradientVelocity._gradientYMax = gradientYMax;
gradientVelocity._gradientZMin = gradientZMin;
gradientVelocity._gradientZMax = gradientZMax;
return gradientVelocity;
}
get type() {
return this._type;
}
get constant() {
return this._constant;
}
get gradientX() {
return this._gradientX;
}
get gradientY() {
return this._gradientY;
}
get gradientZ() {
return this._gradientZ;
}
get constantMin() {
return this._constantMin;
}
get constantMax() {
return this._constantMax;
}
get gradientXMin() {
return this._gradientXMin;
}
get gradientXMax() {
return this._gradientXMax;
}
get gradientYMin() {
return this._gradientYMin;
}
get gradientYMax() {
return this._gradientYMax;
}
get gradientZMin() {
return this._gradientZMin;
}
get gradientZMax() {
return this._gradientZMax;
}
cloneTo(destObject) {
var destGradientVelocity = destObject;
destGradientVelocity._type = this._type;
this._constant.cloneTo(destGradientVelocity._constant);
this._gradientX.cloneTo(destGradientVelocity._gradientX);
this._gradientY.cloneTo(destGradientVelocity._gradientY);
this._gradientZ.cloneTo(destGradientVelocity._gradientZ);
this._constantMin.cloneTo(destGradientVelocity._constantMin);
this._constantMax.cloneTo(destGradientVelocity._constantMax);
this._gradientXMin.cloneTo(destGradientVelocity._gradientXMin);
this._gradientXMax.cloneTo(destGradientVelocity._gradientXMax);
this._gradientYMin.cloneTo(destGradientVelocity._gradientYMin);
this._gradientYMax.cloneTo(destGradientVelocity._gradientYMax);
this._gradientZMin.cloneTo(destGradientVelocity._gradientZMin);
this._gradientZMax.cloneTo(destGradientVelocity._gradientZMax);
}
clone() {
var destGradientVelocity = new GradientVelocity();
this.cloneTo(destGradientVelocity);
return destGradientVelocity;
}
}
class RotationOverLifetime {
constructor(angularVelocity) {
this._angularVelocity = angularVelocity;
}
get angularVelocity() {
return this._angularVelocity;
}
cloneTo(destObject) {
var destRotationOverLifetime = destObject;
this._angularVelocity.cloneTo(destRotationOverLifetime._angularVelocity);
destRotationOverLifetime.enable = this.enable;
}
clone() {
var destAngularVelocity;
switch (this._angularVelocity.type) {
case 0:
if (this._angularVelocity.separateAxes)
destAngularVelocity = GradientAngularVelocity.createByConstantSeparate(this._angularVelocity.constantSeparate.clone());
else
destAngularVelocity = GradientAngularVelocity.createByConstant(this._angularVelocity.constant);
break;
case 1:
if (this._angularVelocity.separateAxes)
destAngularVelocity = GradientAngularVelocity.createByGradientSeparate(this._angularVelocity.gradientX.clone(), this._angularVelocity.gradientY.clone(), this._angularVelocity.gradientZ.clone());
else
destAngularVelocity = GradientAngularVelocity.createByGradient(this._angularVelocity.gradient.clone());
break;
case 2:
if (this._angularVelocity.separateAxes)
destAngularVelocity = GradientAngularVelocity.createByRandomTwoConstantSeparate(this._angularVelocity.constantMinSeparate.clone(), this._angularVelocity.constantMaxSeparate.clone());
else
destAngularVelocity = GradientAngularVelocity.createByRandomTwoConstant(this._angularVelocity.constantMin, this._angularVelocity.constantMax);
break;
case 3:
if (this._angularVelocity.separateAxes)
destAngularVelocity = GradientAngularVelocity.createByRandomTwoGradientSeparate(this._angularVelocity.gradientXMin.clone(), this._angularVelocity.gradientYMin.clone(), this._angularVelocity.gradientZMin.clone(), this._angularVelocity.gradientWMin.clone(), this._angularVelocity.gradientXMax.clone(), this._angularVelocity.gradientYMax.clone(), this._angularVelocity.gradientZMax.clone(), this._angularVelocity.gradientWMax.clone());
else
destAngularVelocity = GradientAngularVelocity.createByRandomTwoGradient(this._angularVelocity.gradientMin.clone(), this._angularVelocity.gradientMax.clone());
break;
}
var destRotationOverLifetime = new RotationOverLifetime(destAngularVelocity);
destRotationOverLifetime.enable = this.enable;
return destRotationOverLifetime;
}
}
(function (ParticleSystemShapeType) {
ParticleSystemShapeType[ParticleSystemShapeType["Box"] = 0] = "Box";
ParticleSystemShapeType[ParticleSystemShapeType["Circle"] = 1] = "Circle";
ParticleSystemShapeType[ParticleSystemShapeType["Cone"] = 2] = "Cone";
ParticleSystemShapeType[ParticleSystemShapeType["Hemisphere"] = 3] = "Hemisphere";
ParticleSystemShapeType[ParticleSystemShapeType["Sphere"] = 4] = "Sphere";
})(exports.ParticleSystemShapeType || (exports.ParticleSystemShapeType = {}));
class BaseShape {
constructor() {
this.enable = true;
this.randomDirection = 0;
}
_getShapeBoundBox(boundBox) {
throw new Error("BaseShape: must override it.");
}
_getSpeedBoundBox(boundBox) {
throw new Error("BaseShape: must override it.");
}
generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) {
throw new Error("BaseShape: must override it.");
}
_calculateProceduralBounds(boundBox, emitterPosScale, minMaxBounds) {
this._getShapeBoundBox(boundBox);
var min = boundBox.min;
var max = boundBox.max;
Vector3.multiply(min, emitterPosScale, min);
Vector3.multiply(max, emitterPosScale, max);
var speedBounds = new BoundBox(new Vector3(), new Vector3());
if (this.randomDirection) {
speedBounds.min = new Vector3(-1, -1, -1);
speedBounds.max = new Vector3(1, 1, 1);
}
else {
this._getSpeedBoundBox(speedBounds);
}
var maxSpeedBound = new BoundBox(new Vector3(), new Vector3());
var maxSpeedMin = maxSpeedBound.min;
var maxSpeedMax = maxSpeedBound.max;
Vector3.scale(speedBounds.min, minMaxBounds.y, maxSpeedMin);
Vector3.scale(speedBounds.max, minMaxBounds.y, maxSpeedMax);
Vector3.add(boundBox.min, maxSpeedMin, maxSpeedMin);
Vector3.add(boundBox.max, maxSpeedMax, maxSpeedMax);
Vector3.min(boundBox.min, maxSpeedMin, boundBox.min);
Vector3.max(boundBox.max, maxSpeedMin, boundBox.max);
var minSpeedBound = new BoundBox(new Vector3(), new Vector3());
var minSpeedMin = minSpeedBound.min;
var minSpeedMax = minSpeedBound.max;
Vector3.scale(speedBounds.min, minMaxBounds.x, minSpeedMin);
Vector3.scale(speedBounds.max, minMaxBounds.x, minSpeedMax);
Vector3.min(minSpeedBound.min, minSpeedMax, maxSpeedMin);
Vector3.max(minSpeedBound.min, minSpeedMax, maxSpeedMax);
Vector3.min(boundBox.min, maxSpeedMin, boundBox.min);
Vector3.max(boundBox.max, maxSpeedMin, boundBox.max);
}
cloneTo(destObject) {
var destShape = destObject;
destShape.enable = this.enable;
}
clone() {
var destShape = new BaseShape();
this.cloneTo(destShape);
return destShape;
}
}
class ShapeUtils {
static _randomPointUnitArcCircle(arc, out, rand = null) {
var angle;
if (rand)
angle = rand.getFloat() * arc;
else
angle = Math.random() * arc;
out.x = Math.cos(angle);
out.y = Math.sin(angle);
}
static _randomPointInsideUnitArcCircle(arc, out, rand = null) {
ShapeUtils._randomPointUnitArcCircle(arc, out, rand);
var range;
if (rand)
range = Math.pow(rand.getFloat(), 1.0 / 2.0);
else
range = Math.pow(Math.random(), 1.0 / 2.0);
out.x = out.x * range;
out.y = out.y * range;
}
static _randomPointUnitCircle(out, rand = null) {
var angle;
if (rand)
angle = rand.getFloat() * Math.PI * 2;
else
angle = Math.random() * Math.PI * 2;
out.x = Math.cos(angle);
out.y = Math.sin(angle);
}
static _randomPointInsideUnitCircle(out, rand = null) {
ShapeUtils._randomPointUnitCircle(out);
var range;
if (rand)
range = Math.pow(rand.getFloat(), 1.0 / 2.0);
else
range = Math.pow(Math.random(), 1.0 / 2.0);
out.x = out.x * range;
out.y = out.y * range;
}
static _randomPointUnitSphere(out, rand = null) {
var z;
var a;
if (rand) {
z = out.z = rand.getFloat() * 2 - 1.0;
a = rand.getFloat() * Math.PI * 2;
}
else {
z = out.z = Math.random() * 2 - 1.0;
a = Math.random() * Math.PI * 2;
}
var r = Math.sqrt(1.0 - z * z);
out.x = r * Math.cos(a);
out.y = r * Math.sin(a);
}
static _randomPointInsideUnitSphere(out, rand = null) {
ShapeUtils._randomPointUnitSphere(out);
var range;
if (rand)
range = Math.pow(rand.getFloat(), 1.0 / 3.0);
else
range = Math.pow(Math.random(), 1.0 / 3.0);
out.x = out.x * range;
out.y = out.y * range;
out.z = out.z * range;
}
static _randomPointInsideHalfUnitBox(out, rand = null) {
if (rand) {
out.x = (rand.getFloat() - 0.5);
out.y = (rand.getFloat() - 0.5);
out.z = (rand.getFloat() - 0.5);
}
else {
out.x = (Math.random() - 0.5);
out.y = (Math.random() - 0.5);
out.z = (Math.random() - 0.5);
}
}
constructor() {
}
}
class BoxShape extends BaseShape {
constructor() {
super();
this.shapeType = exports.ParticleSystemShapeType.Box;
this.x = 1.0;
this.y = 1.0;
this.z = 1.0;
}
_getShapeBoundBox(boundBox) {
var min = boundBox.min;
min.x = -this.x * 0.5;
min.y = -this.y * 0.5;
min.z = -this.z * 0.5;
var max = boundBox.max;
max.x = this.x * 0.5;
max.y = this.y * 0.5;
max.z = this.z * 0.5;
}
_getSpeedBoundBox(boundBox) {
var min = boundBox.min;
min.x = 0.0;
min.y = 0.0;
min.z = 0.0;
var max = boundBox.max;
max.x = 0.0;
max.y = 1.0;
max.z = 0.0;
}
generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) {
if (rand) {
rand.seed = randomSeeds[16];
ShapeUtils._randomPointInsideHalfUnitBox(position, rand);
randomSeeds[16] = rand.seed;
}
else {
ShapeUtils._randomPointInsideHalfUnitBox(position);
}
position.x = this.x * position.x;
position.y = this.y * position.y;
position.z = this.z * position.z;
if (this.randomDirection) {
if (rand) {
rand.seed = randomSeeds[17];
ShapeUtils._randomPointUnitSphere(direction, rand);
randomSeeds[17] = rand.seed;
}
else {
ShapeUtils._randomPointUnitSphere(direction);
}
}
else {
direction.x = 0.0;
direction.y = 0.0;
direction.z = 1.0;
}
}
cloneTo(destObject) {
super.cloneTo(destObject);
var destShape = destObject;
destShape.x = this.x;
destShape.y = this.y;
destShape.z = this.z;
destShape.randomDirection = this.randomDirection;
}
clone() {
var destShape = new BoxShape();
this.cloneTo(destShape);
return destShape;
}
}
class CircleShape extends BaseShape {
constructor() {
super();
this.shapeType = exports.ParticleSystemShapeType.Circle;
this.radius = 1.0;
this.arc = 360.0 / 180.0 * Math.PI;
this.emitFromEdge = false;
}
_getShapeBoundBox(boundBox) {
var min = boundBox.min;
min.x = min.z = -this.radius;
min.y = 0;
var max = boundBox.max;
max.x = max.z = this.radius;
max.y = 0;
}
_getSpeedBoundBox(boundBox) {
var min = boundBox.min;
min.x = min.y = -1;
min.z = 0;
var max = boundBox.max;
max.x = max.y = 1;
max.z = 0;
}
generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) {
var positionPoint = CircleShape._tempPositionPoint;
if (rand) {
rand.seed = randomSeeds[16];
if (this.emitFromEdge)
ShapeUtils._randomPointUnitArcCircle(this.arc, CircleShape._tempPositionPoint, rand);
else
ShapeUtils._randomPointInsideUnitArcCircle(this.arc, CircleShape._tempPositionPoint, rand);
randomSeeds[16] = rand.seed;
}
else {
if (this.emitFromEdge)
ShapeUtils._randomPointUnitArcCircle(this.arc, CircleShape._tempPositionPoint);
else
ShapeUtils._randomPointInsideUnitArcCircle(this.arc, CircleShape._tempPositionPoint);
}
position.x = -positionPoint.x;
position.y = positionPoint.y;
position.z = 0;
Vector3.scale(position, this.radius, position);
if (this.randomDirection) {
if (rand) {
rand.seed = randomSeeds[17];
ShapeUtils._randomPointUnitSphere(direction, rand);
randomSeeds[17] = rand.seed;
}
else {
ShapeUtils._randomPointUnitSphere(direction);
}
}
else {
position.cloneTo(direction);
}
}
cloneTo(destObject) {
super.cloneTo(destObject);
var destShape = destObject;
destShape.radius = this.radius;
destShape.arc = this.arc;
destShape.emitFromEdge = this.emitFromEdge;
destShape.randomDirection = this.randomDirection;
}
clone() {
var destShape = new CircleShape();
this.cloneTo(destShape);
return destShape;
}
}
CircleShape._tempPositionPoint = new Vector2();
class ConeShape extends BaseShape {
constructor() {
super();
this.shapeType = exports.ParticleSystemShapeType.Cone;
this.angle = 25.0 / 180.0 * Math.PI;
this.radius = 1.0;
this.length = 5.0;
this.emitType = 0;
}
_getShapeBoundBox(boundBox) {
const coneRadius2 = this.radius + this.length * Math.sin(this.angle);
const coneLength = this.length * Math.cos(this.angle);
var min = boundBox.min;
min.x = min.y = -coneRadius2;
min.z = 0;
var max = boundBox.max;
max.x = max.y = coneRadius2;
max.z = coneLength;
}
_getSpeedBoundBox(boundBox) {
const sinA = Math.sin(this.angle);
var min = boundBox.min;
min.x = min.y = -sinA;
min.z = 0;
var max = boundBox.max;
max.x = max.y = sinA;
max.z = 1;
}
generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) {
var positionPointE = ConeShape._tempPositionPoint;
var positionX;
var positionY;
var directionPointE;
var dirCosA = Math.cos(this.angle);
var dirSinA = Math.sin(this.angle);
switch (this.emitType) {
case 0:
if (rand) {
rand.seed = randomSeeds[16];
ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempPositionPoint, rand);
randomSeeds[16] = rand.seed;
}
else {
ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempPositionPoint);
}
positionX = positionPointE.x;
positionY = positionPointE.y;
position.x = positionX * this.radius;
position.y = positionY * this.radius;
position.z = 0;
if (this.randomDirection) {
if (rand) {
rand.seed = randomSeeds[17];
ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempDirectionPoint, rand);
randomSeeds[17] = rand.seed;
}
else {
ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempDirectionPoint);
}
directionPointE = ConeShape._tempDirectionPoint;
direction.x = directionPointE.x * dirSinA;
direction.y = directionPointE.y * dirSinA;
}
else {
direction.x = positionX * dirSinA;
direction.y = positionY * dirSinA;
}
direction.z = dirCosA;
break;
case 1:
if (rand) {
rand.seed = randomSeeds[16];
ShapeUtils._randomPointUnitCircle(ConeShape._tempPositionPoint, rand);
randomSeeds[16] = rand.seed;
}
else {
ShapeUtils._randomPointUnitCircle(ConeShape._tempPositionPoint);
}
positionX = positionPointE.x;
positionY = positionPointE.y;
position.x = positionX * this.radius;
position.y = positionY * this.radius;
position.z = 0;
if (this.randomDirection) {
if (rand) {
rand.seed = randomSeeds[17];
ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempDirectionPoint, rand);
randomSeeds[17] = rand.seed;
}
else {
ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempDirectionPoint);
}
directionPointE = ConeShape._tempDirectionPoint;
direction.x = directionPointE.x * dirSinA;
direction.y = directionPointE.y * dirSinA;
}
else {
direction.x = positionX * dirSinA;
direction.y = positionY * dirSinA;
}
direction.z = dirCosA;
break;
case 2:
if (rand) {
rand.seed = randomSeeds[16];
ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempPositionPoint, rand);
}
else {
ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempPositionPoint);
}
positionX = positionPointE.x;
positionY = positionPointE.y;
position.x = positionX * this.radius;
position.y = positionY * this.radius;
position.z = 0;
direction.x = positionX * dirSinA;
direction.y = positionY * dirSinA;
direction.z = dirCosA;
Vector3.normalize(direction, direction);
if (rand) {
Vector3.scale(direction, this.length * rand.getFloat(), direction);
randomSeeds[16] = rand.seed;
}
else {
Vector3.scale(direction, this.length * Math.random(), direction);
}
Vector3.add(position, direction, position);
if (this.randomDirection) {
if (rand) {
rand.seed = randomSeeds[17];
ShapeUtils._randomPointUnitSphere(direction, rand);
randomSeeds[17] = rand.seed;
}
else {
ShapeUtils._randomPointUnitSphere(direction);
}
}
break;
case 3:
if (rand) {
rand.seed = randomSeeds[16];
ShapeUtils._randomPointUnitCircle(ConeShape._tempPositionPoint, rand);
}
else {
ShapeUtils._randomPointUnitCircle(ConeShape._tempPositionPoint);
}
positionX = positionPointE.x;
positionY = positionPointE.y;
position.x = positionX * this.radius;
position.y = positionY * this.radius;
position.z = 0;
direction.x = positionX * dirSinA;
direction.y = positionY * dirSinA;
direction.z = dirCosA;
Vector3.normalize(direction, direction);
if (rand) {
Vector3.scale(direction, this.length * rand.getFloat(), direction);
randomSeeds[16] = rand.seed;
}
else {
Vector3.scale(direction, this.length * Math.random(), direction);
}
Vector3.add(position, direction, position);
if (this.randomDirection) {
if (rand) {
rand.seed = randomSeeds[17];
ShapeUtils._randomPointUnitSphere(direction, rand);
randomSeeds[17] = rand.seed;
}
else {
ShapeUtils._randomPointUnitSphere(direction);
}
}
break;
default:
throw new Error("ConeShape:emitType is invalid.");
}
}
cloneTo(destObject) {
super.cloneTo(destObject);
var destShape = destObject;
destShape.angle = this.angle;
destShape.radius = this.radius;
destShape.length = this.length;
destShape.emitType = this.emitType;
destShape.randomDirection = this.randomDirection;
}
clone() {
var destShape = new ConeShape();
this.cloneTo(destShape);
return destShape;
}
}
ConeShape._tempPositionPoint = new Vector2();
ConeShape._tempDirectionPoint = new Vector2();
class HemisphereShape extends BaseShape {
constructor() {
super();
this.shapeType = exports.ParticleSystemShapeType.Hemisphere;
this.radius = 1.0;
this.emitFromShell = false;
}
_getShapeBoundBox(boundBox) {
var min = boundBox.min;
min.x = min.y = min.z = -this.radius;
var max = boundBox.max;
max.x = max.y = this.radius;
max.z = 0;
}
_getSpeedBoundBox(boundBox) {
var min = boundBox.min;
min.x = min.y = -1;
min.z = 0;
var max = boundBox.max;
max.x = max.y = max.z = 1;
}
generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) {
if (rand) {
rand.seed = randomSeeds[16];
if (this.emitFromShell)
ShapeUtils._randomPointUnitSphere(position, rand);
else
ShapeUtils._randomPointInsideUnitSphere(position, rand);
randomSeeds[16] = rand.seed;
}
else {
if (this.emitFromShell)
ShapeUtils._randomPointUnitSphere(position);
else
ShapeUtils._randomPointInsideUnitSphere(position);
}
Vector3.scale(position, this.radius, position);
var z = position.z;
(z < 0.0) && (position.z = z * -1.0);
if (this.randomDirection) {
if (rand) {
rand.seed = randomSeeds[17];
ShapeUtils._randomPointUnitSphere(direction, rand);
randomSeeds[17] = rand.seed;
}
else {
ShapeUtils._randomPointUnitSphere(direction);
}
}
else {
position.cloneTo(direction);
}
}
cloneTo(destObject) {
super.cloneTo(destObject);
var destShape = destObject;
destShape.radius = this.radius;
destShape.emitFromShell = this.emitFromShell;
destShape.randomDirection = this.randomDirection;
}
clone() {
var destShape = new HemisphereShape();
this.cloneTo(destShape);
return destShape;
}
}
class SphereShape extends BaseShape {
constructor() {
super();
this.shapeType = exports.ParticleSystemShapeType.Sphere;
this.radius = 1.0;
this.emitFromShell = false;
}
_getShapeBoundBox(boundBox) {
var min = boundBox.min;
min.x = min.y = min.z = -this.radius;
var max = boundBox.max;
max.x = max.y = max.z = this.radius;
}
_getSpeedBoundBox(boundBox) {
var min = boundBox.min;
min.x = min.y = min.z = -1;
var max = boundBox.max;
max.x = max.y = max.z = 1;
}
generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) {
if (rand) {
rand.seed = randomSeeds[16];
if (this.emitFromShell)
ShapeUtils._randomPointUnitSphere(position, rand);
else
ShapeUtils._randomPointInsideUnitSphere(position, rand);
randomSeeds[16] = rand.seed;
}
else {
if (this.emitFromShell)
ShapeUtils._randomPointUnitSphere(position);
else
ShapeUtils._randomPointInsideUnitSphere(position);
}
Vector3.scale(position, this.radius, position);
if (this.randomDirection) {
if (rand) {
rand.seed = randomSeeds[17];
ShapeUtils._randomPointUnitSphere(direction, rand);
randomSeeds[17] = rand.seed;
}
else {
ShapeUtils._randomPointUnitSphere(direction);
}
}
else {
position.cloneTo(direction);
}
}
cloneTo(destObject) {
super.cloneTo(destObject);
var destShape = destObject;
destShape.radius = this.radius;
destShape.emitFromShell = this.emitFromShell;
destShape.randomDirection = this.randomDirection;
}
clone() {
var destShape = new SphereShape();
this.cloneTo(destShape);
return destShape;
}
}
class SizeOverLifetime {
constructor(size) {
this._size = size;
}
get size() {
return this._size;
}
cloneTo(destObject) {
var destSizeOverLifetime = destObject;
this._size.cloneTo(destSizeOverLifetime._size);
destSizeOverLifetime.enable = this.enable;
}
clone() {
var destSize;
switch (this._size.type) {
case 0:
if (this._size.separateAxes)
destSize = GradientSize.createByGradientSeparate(this._size.gradientX.clone(), this._size.gradientY.clone(), this._size.gradientZ.clone());
else
destSize = GradientSize.createByGradient(this._size.gradient.clone());
break;
case 1:
if (this._size.separateAxes)
destSize = GradientSize.createByRandomTwoConstantSeparate(this._size.constantMinSeparate.clone(), this._size.constantMaxSeparate.clone());
else
destSize = GradientSize.createByRandomTwoConstant(this._size.constantMin, this._size.constantMax);
break;
case 2:
if (this._size.separateAxes)
destSize = GradientSize.createByRandomTwoGradientSeparate(this._size.gradientXMin.clone(), this._size.gradientYMin.clone(), this._size.gradientZMin.clone(), this._size.gradientXMax.clone(), this._size.gradientYMax.clone(), this._size.gradientZMax.clone());
else
destSize = GradientSize.createByRandomTwoGradient(this._size.gradientMin.clone(), this._size.gradientMax.clone());
break;
}
var destSizeOverLifetime = new SizeOverLifetime(destSize);
destSizeOverLifetime.enable = this.enable;
return destSizeOverLifetime;
}
}
class StartFrame {
constructor() {
this._type = 0;
this._constant = 0;
this._constantMin = 0;
this._constantMax = 0;
}
static createByConstant(constant = 0) {
var rotationOverLifetime = new StartFrame();
rotationOverLifetime._type = 0;
rotationOverLifetime._constant = constant;
return rotationOverLifetime;
}
static createByRandomTwoConstant(constantMin = 0, constantMax = 0) {
var rotationOverLifetime = new StartFrame();
rotationOverLifetime._type = 1;
rotationOverLifetime._constantMin = constantMin;
rotationOverLifetime._constantMax = constantMax;
return rotationOverLifetime;
}
get type() {
return this._type;
}
get constant() {
return this._constant;
}
get constantMin() {
return this._constantMin;
}
get constantMax() {
return this._constantMax;
}
cloneTo(destObject) {
var destStartFrame = destObject;
destStartFrame._type = this._type;
destStartFrame._constant = this._constant;
destStartFrame._constantMin = this._constantMin;
destStartFrame._constantMax = this._constantMax;
}
clone() {
var destStartFrame = new StartFrame();
this.cloneTo(destStartFrame);
return destStartFrame;
}
}
class TextureSheetAnimation {
constructor(frame, startFrame) {
this.type = 0;
this.randomRow = false;
this.rowIndex = 0;
this.cycles = 0;
this.enableUVChannels = 0;
this.enable = false;
this.tiles = new Vector2(1, 1);
this.type = 0;
this.randomRow = true;
this.rowIndex = 0;
this.cycles = 1;
this.enableUVChannels = 1;
this._frame = frame;
this._startFrame = startFrame;
}
get frame() {
return this._frame;
}
get startFrame() {
return this._startFrame;
}
cloneTo(destObject) {
var destTextureSheetAnimation = destObject;
this.tiles.cloneTo(destTextureSheetAnimation.tiles);
destTextureSheetAnimation.type = this.type;
destTextureSheetAnimation.randomRow = this.randomRow;
destTextureSheetAnimation.rowIndex = this.rowIndex;
destTextureSheetAnimation.cycles = this.cycles;
destTextureSheetAnimation.enableUVChannels = this.enableUVChannels;
destTextureSheetAnimation.enable = this.enable;
this._frame.cloneTo(destTextureSheetAnimation._frame);
this._startFrame.cloneTo(destTextureSheetAnimation._startFrame);
}
clone() {
var destFrame;
switch (this._frame.type) {
case 0:
destFrame = FrameOverTime.createByConstant(this._frame.constant);
break;
case 1:
destFrame = FrameOverTime.createByOverTime(this._frame.frameOverTimeData.clone());
break;
case 2:
destFrame = FrameOverTime.createByRandomTwoConstant(this._frame.constantMin, this._frame.constantMax);
break;
case 3:
destFrame = FrameOverTime.createByRandomTwoOverTime(this._frame.frameOverTimeDataMin.clone(), this._frame.frameOverTimeDataMax.clone());
break;
}
var destStartFrame;
switch (this._startFrame.type) {
case 0:
destStartFrame = StartFrame.createByConstant(this._startFrame.constant);
break;
case 1:
destStartFrame = StartFrame.createByRandomTwoConstant(this._startFrame.constantMin, this._startFrame.constantMax);
break;
}
var destTextureSheetAnimation = new TextureSheetAnimation(destFrame, destStartFrame);
this.cloneTo(destTextureSheetAnimation);
return destTextureSheetAnimation;
}
}
class VelocityOverLifetime {
constructor(velocity) {
this.enable = false;
this.space = 0;
this._velocity = velocity;
}
get velocity() {
return this._velocity;
}
cloneTo(destObject) {
var destVelocityOverLifetime = destObject;
this._velocity.cloneTo(destVelocityOverLifetime._velocity);
destVelocityOverLifetime.enable = this.enable;
destVelocityOverLifetime.space = this.space;
}
clone() {
var destVelocity;
switch (this._velocity.type) {
case 0:
destVelocity = GradientVelocity.createByConstant(this._velocity.constant.clone());
break;
case 1:
destVelocity = GradientVelocity.createByGradient(this._velocity.gradientX.clone(), this._velocity.gradientY.clone(), this._velocity.gradientZ.clone());
break;
case 2:
destVelocity = GradientVelocity.createByRandomTwoConstant(this._velocity.constantMin.clone(), this._velocity.constantMax.clone());
break;
case 3:
destVelocity = GradientVelocity.createByRandomTwoGradient(this._velocity.gradientXMin.clone(), this._velocity.gradientXMax.clone(), this._velocity.gradientYMin.clone(), this._velocity.gradientYMax.clone(), this._velocity.gradientZMin.clone(), this._velocity.gradientZMax.clone());
break;
}
var destVelocityOverLifetime = new VelocityOverLifetime(destVelocity);
destVelocityOverLifetime.enable = this.enable;
destVelocityOverLifetime.space = this.space;
return destVelocityOverLifetime;
}
}
class ShuriKenParticle3DShaderDeclaration {
}
ShuriKenParticle3DShaderDeclaration.WORLDPOSITION = Shader3D.propertyNameToID("u_WorldPosition");
ShuriKenParticle3DShaderDeclaration.WORLDROTATION = Shader3D.propertyNameToID("u_WorldRotation");
ShuriKenParticle3DShaderDeclaration.POSITIONSCALE = Shader3D.propertyNameToID("u_PositionScale");
ShuriKenParticle3DShaderDeclaration.SIZESCALE = Shader3D.propertyNameToID("u_SizeScale");
ShuriKenParticle3DShaderDeclaration.SCALINGMODE = Shader3D.propertyNameToID("u_ScalingMode");
ShuriKenParticle3DShaderDeclaration.GRAVITY = Shader3D.propertyNameToID("u_Gravity");
ShuriKenParticle3DShaderDeclaration.THREEDSTARTROTATION = Shader3D.propertyNameToID("u_ThreeDStartRotation");
ShuriKenParticle3DShaderDeclaration.STRETCHEDBILLBOARDLENGTHSCALE = Shader3D.propertyNameToID("u_StretchedBillboardLengthScale");
ShuriKenParticle3DShaderDeclaration.STRETCHEDBILLBOARDSPEEDSCALE = Shader3D.propertyNameToID("u_StretchedBillboardSpeedScale");
ShuriKenParticle3DShaderDeclaration.SIMULATIONSPACE = Shader3D.propertyNameToID("u_SimulationSpace");
ShuriKenParticle3DShaderDeclaration.CURRENTTIME = Shader3D.propertyNameToID("u_CurrentTime");
ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONST = Shader3D.propertyNameToID("u_VOLVelocityConst");
ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTX = Shader3D.propertyNameToID("u_VOLVelocityGradientX");
ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTY = Shader3D.propertyNameToID("u_VOLVelocityGradientY");
ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZ = Shader3D.propertyNameToID("u_VOLVelocityGradientZ");
ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONSTMAX = Shader3D.propertyNameToID("u_VOLVelocityConstMax");
ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTXMAX = Shader3D.propertyNameToID("u_VOLVelocityGradientMaxX");
ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTYMAX = Shader3D.propertyNameToID("u_VOLVelocityGradientMaxY");
ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZMAX = Shader3D.propertyNameToID("u_VOLVelocityGradientMaxZ");
ShuriKenParticle3DShaderDeclaration.VOLSPACETYPE = Shader3D.propertyNameToID("u_VOLSpaceType");
ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS = Shader3D.propertyNameToID("u_ColorOverLifeGradientAlphas");
ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS = Shader3D.propertyNameToID("u_ColorOverLifeGradientColors");
ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTALPHAS = Shader3D.propertyNameToID("u_MaxColorOverLifeGradientAlphas");
ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTCOLORS = Shader3D.propertyNameToID("u_MaxColorOverLifeGradientColors");
ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENT = Shader3D.propertyNameToID("u_SOLSizeGradient");
ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTX = Shader3D.propertyNameToID("u_SOLSizeGradientX");
ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTY = Shader3D.propertyNameToID("u_SOLSizeGradientY");
ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZ = Shader3D.propertyNameToID("u_SOLSizeGradientZ");
ShuriKenParticle3DShaderDeclaration.SOLSizeGradientMax = Shader3D.propertyNameToID("u_SOLSizeGradientMax");
ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTXMAX = Shader3D.propertyNameToID("u_SOLSizeGradientMaxX");
ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTYMAX = Shader3D.propertyNameToID("u_SOLSizeGradientMaxY");
ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZMAX = Shader3D.propertyNameToID("u_SOLSizeGradientMaxZ");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONST = Shader3D.propertyNameToID("u_ROLAngularVelocityConst");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTSEPRARATE = Shader3D.propertyNameToID("u_ROLAngularVelocityConstSeprarate");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENT = Shader3D.propertyNameToID("u_ROLAngularVelocityGradient");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientX");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTY = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientY");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZ = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientZ");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityConstMax");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTMAXSEPRARATE = Shader3D.propertyNameToID("u_ROLAngularVelocityConstMaxSeprarate");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMax");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTXMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMaxX");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTYMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMaxY");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMaxZ");
ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTWMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMaxW");
ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONCYCLES = Shader3D.propertyNameToID("u_TSACycles");
ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONSUBUVLENGTH = Shader3D.propertyNameToID("u_TSASubUVLength");
ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTUVS = Shader3D.propertyNameToID("u_TSAGradientUVs");
ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTMAXUVS = Shader3D.propertyNameToID("u_TSAMaxGradientUVs");
class ShurikenParticleMaterial extends Material {
constructor() {
super();
this.setShaderName("PARTICLESHURIKEN");
this._shaderValues.setVector(ShurikenParticleMaterial.TINTCOLOR, new Vector4(0.5, 0.5, 0.5, 0.5));
this._shaderValues.setVector(ShurikenParticleMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0));
this.renderMode = ShurikenParticleMaterial.RENDERMODE_ALPHABLENDED;
}
static __initDefine__() {
ShurikenParticleMaterial.SHADERDEFINE_DIFFUSEMAP = Shader3D.getDefineByName("DIFFUSEMAP");
ShurikenParticleMaterial.SHADERDEFINE_TINTCOLOR = Shader3D.getDefineByName("TINTCOLOR");
ShurikenParticleMaterial.SHADERDEFINE_ADDTIVEFOG = Shader3D.getDefineByName("ADDTIVEFOG");
}
get _TintColor() {
return this.color;
}
set _TintColor(value) {
this.color = value;
}
get _TintColorR() {
return this.color.x;
}
set _TintColorR(value) {
this.color.x = value;
}
get _TintColorG() {
return this.color.y;
}
set _TintColorG(value) {
this.color.y = value;
}
get _TintColorB() {
return this.color.z;
}
set _TintColorB(value) {
this.color.z = value;
}
get _TintColorA() {
return this.color.w;
}
set _TintColorA(value) {
this.color.w = value;
}
get _MainTex_ST() {
return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET);
}
set _MainTex_ST(value) {
var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET);
tilOff.setValue(value.x, value.y, value.z, value.w);
this.tilingOffset = tilOff;
}
get _MainTex_STX() {
return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).x;
}
set _MainTex_STX(x) {
var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET);
tilOff.x = x;
this.tilingOffset = tilOff;
}
get _MainTex_STY() {
return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).y;
}
set _MainTex_STY(y) {
var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET);
tilOff.y = y;
this.tilingOffset = tilOff;
}
get _MainTex_STZ() {
return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).z;
}
set _MainTex_STZ(z) {
var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET);
tilOff.z = z;
this.tilingOffset = tilOff;
}
get _MainTex_STW() {
return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).w;
}
set _MainTex_STW(w) {
var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET);
tilOff.w = w;
this.tilingOffset = tilOff;
}
set renderMode(value) {
switch (value) {
case ShurikenParticleMaterial.RENDERMODE_ADDTIVE:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.depthWrite = false;
this.cull = RenderState.CULL_NONE;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE;
this.alphaTest = false;
this._shaderValues.addDefine(ShurikenParticleMaterial.SHADERDEFINE_ADDTIVEFOG);
break;
case ShurikenParticleMaterial.RENDERMODE_ALPHABLENDED:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.depthWrite = false;
this.cull = RenderState.CULL_NONE;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
this.alphaTest = false;
this._shaderValues.removeDefine(ShurikenParticleMaterial.SHADERDEFINE_ADDTIVEFOG);
break;
default:
throw new Error("ShurikenParticleMaterial : renderMode value error.");
}
}
get colorR() {
return this._TintColorR;
}
set colorR(value) {
this._TintColorR = value;
}
get colorG() {
return this._TintColorG;
}
set colorG(value) {
this._TintColorG = value;
}
get colorB() {
return this._TintColorB;
}
set colorB(value) {
this._TintColorB = value;
}
get colorA() {
return this._TintColorA;
}
set colorA(value) {
this._TintColorA = value;
}
get color() {
return this._shaderValues.getVector(ShurikenParticleMaterial.TINTCOLOR);
}
set color(value) {
if (value)
this._shaderValues.addDefine(ShurikenParticleMaterial.SHADERDEFINE_TINTCOLOR);
else
this._shaderValues.removeDefine(ShurikenParticleMaterial.SHADERDEFINE_TINTCOLOR);
this._shaderValues.setVector(ShurikenParticleMaterial.TINTCOLOR, value);
}
get tilingOffsetX() {
return this._MainTex_STX;
}
set tilingOffsetX(x) {
this._MainTex_STX = x;
}
get tilingOffsetY() {
return this._MainTex_STY;
}
set tilingOffsetY(y) {
this._MainTex_STY = y;
}
get tilingOffsetZ() {
return this._MainTex_STZ;
}
set tilingOffsetZ(z) {
this._MainTex_STZ = z;
}
get tilingOffsetW() {
return this._MainTex_STW;
}
set tilingOffsetW(w) {
this._MainTex_STW = w;
}
get tilingOffset() {
return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET);
}
set tilingOffset(value) {
if (value) {
this._shaderValues.setVector(ShurikenParticleMaterial.TILINGOFFSET, value);
}
else {
this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0);
}
}
get texture() {
return this._shaderValues.getTexture(ShurikenParticleMaterial.DIFFUSETEXTURE);
}
set texture(value) {
if (value)
this._shaderValues.addDefine(ShurikenParticleMaterial.SHADERDEFINE_DIFFUSEMAP);
else
this._shaderValues.removeDefine(ShurikenParticleMaterial.SHADERDEFINE_DIFFUSEMAP);
this._shaderValues.setTexture(ShurikenParticleMaterial.DIFFUSETEXTURE, value);
}
clone() {
var dest = new ShurikenParticleMaterial();
this.cloneTo(dest);
return dest;
}
}
ShurikenParticleMaterial.RENDERMODE_ALPHABLENDED = 0;
ShurikenParticleMaterial.RENDERMODE_ADDTIVE = 1;
ShurikenParticleMaterial.DIFFUSETEXTURE = Shader3D.propertyNameToID("u_texture");
ShurikenParticleMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_Tintcolor");
ShurikenParticleMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset");
class Physics3DUtils {
constructor() {
}
static setColliderCollision(collider1, collider2, collsion) {
}
static getIColliderCollision(collider1, collider2) {
return false;
}
}
Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER = 0x1;
Physics3DUtils.COLLISIONFILTERGROUP_STATICFILTER = 0x2;
Physics3DUtils.COLLISIONFILTERGROUP_KINEMATICFILTER = 0x4;
Physics3DUtils.COLLISIONFILTERGROUP_DEBRISFILTER = 0x8;
Physics3DUtils.COLLISIONFILTERGROUP_SENSORTRIGGER = 0x10;
Physics3DUtils.COLLISIONFILTERGROUP_CHARACTERFILTER = 0x20;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER1 = 0x40;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER2 = 0x80;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER3 = 0x100;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER4 = 0x200;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER5 = 0x400;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER6 = 0x800;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER7 = 0x1000;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER8 = 0x2000;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER9 = 0x4000;
Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER10 = 0x8000;
Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER = -1;
Physics3DUtils.gravity = new Vector3(0, -9.81, 0);
class ShurikenParticleRenderer extends BaseRender {
constructor(owner) {
super(owner);
this._finalGravity = new Vector3();
this._mesh = null;
this.stretchedBillboardCameraSpeedScale = 0;
this.stretchedBillboardSpeedScale = 0;
this.stretchedBillboardLengthScale = 2;
this.renderMode = 0;
this._supportOctree = false;
}
get renderMode() {
return this._renderMode;
}
set renderMode(value) {
if (this._renderMode !== value) {
var defineDatas = this._shaderValues;
switch (this._renderMode) {
case 0:
defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_BILLBOARD);
break;
case 1:
defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_STRETCHEDBILLBOARD);
break;
case 2:
defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_HORIZONTALBILLBOARD);
break;
case 3:
defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_VERTICALBILLBOARD);
break;
case 4:
defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_MESH);
break;
}
this._renderMode = value;
switch (value) {
case 0:
defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_BILLBOARD);
break;
case 1:
defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_STRETCHEDBILLBOARD);
break;
case 2:
defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_HORIZONTALBILLBOARD);
break;
case 3:
defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_VERTICALBILLBOARD);
break;
case 4:
defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_MESH);
break;
default:
throw new Error("ShurikenParticleRender: unknown renderMode Value.");
}
var parSys = this._owner.particleSystem;
(parSys) && (parSys._initBufferDatas());
}
}
get mesh() {
return this._mesh;
}
set mesh(value) {
if (this._mesh !== value) {
(this._mesh) && (this._mesh._removeReference());
this._mesh = value;
(value) && (value._addReference());
this._owner.particleSystem._initBufferDatas();
}
}
_calculateBoundingBox() {
var particleSystem = this._owner.particleSystem;
var bounds;
if (particleSystem._useCustomBounds) {
bounds = particleSystem.customBounds;
bounds._tranform(this._owner.transform.worldMatrix, this._bounds);
}
else if (particleSystem._simulationSupported()) {
particleSystem._generateBounds();
bounds = particleSystem._bounds;
bounds._tranform(this._owner.transform.worldMatrix, this._bounds);
if (particleSystem.gravityModifier != 0) {
var max = this._bounds.getMax();
var min = this._bounds.getMin();
var gravityOffset = particleSystem._gravityOffset;
max.y -= gravityOffset.x;
min.y -= gravityOffset.y;
this._bounds.setMax(max);
this._bounds.setMin(min);
}
}
else {
var min = this._bounds.getMin();
min.setValue(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
this._bounds.setMin(min);
var max = this._bounds.getMax();
max.setValue(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
this._bounds.setMax(max);
}
}
_needRender(boundFrustum, context) {
if (boundFrustum) {
if (boundFrustum.intersects(this.bounds._getBoundBox())) {
if (this._owner.particleSystem.isAlive)
return true;
else
return false;
}
else {
return false;
}
}
else {
return true;
}
}
_renderUpdate(context, transfrom) {
var particleSystem = this._owner.particleSystem;
var sv = this._shaderValues;
var transform = this._owner.transform;
switch (particleSystem.simulationSpace) {
case 0:
break;
case 1:
sv.setVector3(ShuriKenParticle3DShaderDeclaration.WORLDPOSITION, transform.position);
sv.setQuaternion(ShuriKenParticle3DShaderDeclaration.WORLDROTATION, transform.rotation);
break;
default:
throw new Error("ShurikenParticleMaterial: SimulationSpace value is invalid.");
}
switch (particleSystem.scaleMode) {
case 0:
var scale = transform.getWorldLossyScale();
sv.setVector3(ShuriKenParticle3DShaderDeclaration.POSITIONSCALE, scale);
sv.setVector3(ShuriKenParticle3DShaderDeclaration.SIZESCALE, scale);
break;
case 1:
var localScale = transform.localScale;
sv.setVector3(ShuriKenParticle3DShaderDeclaration.POSITIONSCALE, localScale);
sv.setVector3(ShuriKenParticle3DShaderDeclaration.SIZESCALE, localScale);
break;
case 2:
sv.setVector3(ShuriKenParticle3DShaderDeclaration.POSITIONSCALE, transform.getWorldLossyScale());
sv.setVector3(ShuriKenParticle3DShaderDeclaration.SIZESCALE, Vector3._ONE);
break;
}
Vector3.scale(Physics3DUtils.gravity, particleSystem.gravityModifier, this._finalGravity);
sv.setVector3(ShuriKenParticle3DShaderDeclaration.GRAVITY, this._finalGravity);
sv.setInt(ShuriKenParticle3DShaderDeclaration.SIMULATIONSPACE, particleSystem.simulationSpace);
sv.setBool(ShuriKenParticle3DShaderDeclaration.THREEDSTARTROTATION, particleSystem.threeDStartRotation);
sv.setInt(ShuriKenParticle3DShaderDeclaration.SCALINGMODE, particleSystem.scaleMode);
sv.setNumber(ShuriKenParticle3DShaderDeclaration.STRETCHEDBILLBOARDLENGTHSCALE, this.stretchedBillboardLengthScale);
sv.setNumber(ShuriKenParticle3DShaderDeclaration.STRETCHEDBILLBOARDSPEEDSCALE, this.stretchedBillboardSpeedScale);
sv.setNumber(ShuriKenParticle3DShaderDeclaration.CURRENTTIME, particleSystem._currentTime);
}
get bounds() {
if (this._boundsChange) {
this._calculateBoundingBox();
this._boundsChange = false;
}
return this._bounds;
}
_destroy() {
super._destroy();
(this._mesh) && (this._mesh._removeReference(), this._mesh = null);
}
}
class VertexShuriKenParticle {
constructor() {
}
}
VertexShuriKenParticle.PARTICLE_CORNERTEXTURECOORDINATE0 = 5;
VertexShuriKenParticle.PARTICLE_POSITION0 = 1;
VertexShuriKenParticle.PARTICLE_COLOR0 = 2;
VertexShuriKenParticle.PARTICLE_TEXTURECOORDINATE0 = 3;
VertexShuriKenParticle.PARTICLE_SHAPEPOSITIONSTARTLIFETIME = 4;
VertexShuriKenParticle.PARTICLE_DIRECTIONTIME = 0;
VertexShuriKenParticle.PARTICLE_STARTCOLOR0 = 6;
VertexShuriKenParticle.PARTICLE_ENDCOLOR0 = 7;
VertexShuriKenParticle.PARTICLE_STARTSIZE = 8;
VertexShuriKenParticle.PARTICLE_STARTROTATION = 9;
VertexShuriKenParticle.PARTICLE_STARTSPEED = 10;
VertexShuriKenParticle.PARTICLE_RANDOM0 = 11;
VertexShuriKenParticle.PARTICLE_RANDOM1 = 12;
VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDPOSTION = 13;
VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDROTATION = 14;
class VertexShurikenParticleBillboard extends VertexShuriKenParticle {
constructor(cornerTextureCoordinate, positionStartLifeTime, velocity, startColor, startSize, startRotation0, startRotation1, startRotation2, ageAddScale, time, startSpeed, randoms0, randoms1, simulationWorldPostion) {
super();
this._cornerTextureCoordinate = cornerTextureCoordinate;
this._positionStartLifeTime = positionStartLifeTime;
this._velocity = velocity;
this._startColor = startColor;
this._startSize = startSize;
this._startRotation0 = startRotation0;
this._startRotation1 = startRotation1;
this._startRotation2 = startRotation2;
this._startLifeTime = ageAddScale;
this._time = time;
this._startSpeed = startSpeed;
this._randoms0 = randoms0;
this._randoms1 = randoms1;
this._simulationWorldPostion = simulationWorldPostion;
}
static get vertexDeclaration() {
return VertexShurikenParticleBillboard._vertexDeclaration;
}
static __init__() {
VertexShurikenParticleBillboard._vertexDeclaration = new VertexDeclaration(152, [new VertexElement(0, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_CORNERTEXTURECOORDINATE0),
new VertexElement(16, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_SHAPEPOSITIONSTARTLIFETIME),
new VertexElement(32, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_DIRECTIONTIME),
new VertexElement(48, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_STARTCOLOR0),
new VertexElement(64, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_STARTSIZE),
new VertexElement(76, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_STARTROTATION),
new VertexElement(88, VertexElementFormat.Single, VertexShuriKenParticle.PARTICLE_STARTSPEED),
new VertexElement(92, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_RANDOM0),
new VertexElement(108, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_RANDOM1),
new VertexElement(124, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDPOSTION),
new VertexElement(136, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDROTATION)]);
}
get cornerTextureCoordinate() {
return this._cornerTextureCoordinate;
}
get positionStartLifeTime() {
return this._positionStartLifeTime;
}
get velocity() {
return this._velocity;
}
get startColor() {
return this._startColor;
}
get startSize() {
return this._startSize;
}
get startRotation0() {
return this._startRotation0;
}
get startRotation1() {
return this._startRotation1;
}
get startRotation2() {
return this._startRotation2;
}
get startLifeTime() {
return this._startLifeTime;
}
get time() {
return this._time;
}
get startSpeed() {
return this._startSpeed;
}
get random0() {
return this._randoms0;
}
get random1() {
return this._randoms1;
}
get simulationWorldPostion() {
return this._simulationWorldPostion;
}
}
class VertexShurikenParticleMesh extends VertexShuriKenParticle {
constructor(cornerTextureCoordinate, positionStartLifeTime, velocity, startColor, startSize, startRotation0, startRotation1, startRotation2, ageAddScale, time, startSpeed, randoms0, randoms1, simulationWorldPostion) {
super();
this._cornerTextureCoordinate = cornerTextureCoordinate;
this._positionStartLifeTime = positionStartLifeTime;
this._velocity = velocity;
this._startColor = startColor;
this._startSize = startSize;
this._startRotation0 = startRotation0;
this._startRotation1 = startRotation1;
this._startRotation2 = startRotation2;
this._startLifeTime = ageAddScale;
this._time = time;
this._startSpeed = startSpeed;
this._randoms0 = randoms0;
this._randoms1 = randoms1;
this._simulationWorldPostion = simulationWorldPostion;
}
static __init__() {
VertexShurikenParticleMesh._vertexDeclaration = new VertexDeclaration(172, [new VertexElement(0, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_POSITION0),
new VertexElement(12, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_COLOR0),
new VertexElement(28, VertexElementFormat.Vector2, VertexShuriKenParticle.PARTICLE_TEXTURECOORDINATE0),
new VertexElement(36, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_SHAPEPOSITIONSTARTLIFETIME),
new VertexElement(52, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_DIRECTIONTIME),
new VertexElement(68, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_STARTCOLOR0),
new VertexElement(84, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_STARTSIZE),
new VertexElement(96, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_STARTROTATION),
new VertexElement(108, VertexElementFormat.Single, VertexShuriKenParticle.PARTICLE_STARTSPEED),
new VertexElement(112, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_RANDOM0),
new VertexElement(128, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_RANDOM1),
new VertexElement(144, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDPOSTION),
new VertexElement(156, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDROTATION)]);
}
static get vertexDeclaration() {
return VertexShurikenParticleMesh._vertexDeclaration;
}
get cornerTextureCoordinate() {
return this._cornerTextureCoordinate;
}
get position() {
return this._positionStartLifeTime;
}
get velocity() {
return this._velocity;
}
get startColor() {
return this._startColor;
}
get startSize() {
return this._startSize;
}
get startRotation0() {
return this._startRotation0;
}
get startRotation1() {
return this._startRotation1;
}
get startRotation2() {
return this._startRotation2;
}
get startLifeTime() {
return this._startLifeTime;
}
get time() {
return this._time;
}
get startSpeed() {
return this._startSpeed;
}
get random0() {
return this._randoms0;
}
get random1() {
return this._randoms1;
}
get simulationWorldPostion() {
return this._simulationWorldPostion;
}
}
class Rand {
constructor(seed) {
this._temp = new Uint32Array(1);
this.seeds = new Uint32Array(4);
this.seeds[0] = seed;
this.seeds[1] = this.seeds[0] * 0x6C078965 + 1;
this.seeds[2] = this.seeds[1] * 0x6C078965 + 1;
this.seeds[3] = this.seeds[2] * 0x6C078965 + 1;
}
static getFloatFromInt(v) {
return (v & 0x007FFFFF) * (1.0 / 8388607.0);
}
static getByteFromInt(v) {
return (v & 0x007FFFFF) >>> 15;
}
get seed() {
return this.seeds[0];
}
set seed(seed) {
this.seeds[0] = seed;
this.seeds[1] = this.seeds[0] * 0x6C078965 + 1;
this.seeds[2] = this.seeds[1] * 0x6C078965 + 1;
this.seeds[3] = this.seeds[2] * 0x6C078965 + 1;
}
getUint() {
this._temp[0] = this.seeds[0] ^ (this.seeds[0] << 11);
this.seeds[0] = this.seeds[1];
this.seeds[1] = this.seeds[2];
this.seeds[2] = this.seeds[3];
this.seeds[3] = (this.seeds[3] ^ (this.seeds[3] >>> 19)) ^ (this._temp[0] ^ (this._temp[0] >>> 8));
return this.seeds[3];
}
getFloat() {
this.getUint();
return (this.seeds[3] & 0x007FFFFF) * (1.0 / 8388607.0);
}
getSignedFloat() {
return this.getFloat() * 2.0 - 1.0;
}
}
class Emission {
constructor() {
this._emissionRate = 10;
this._destroyed = false;
this._bursts = [];
}
set emissionRate(value) {
if (value < 0)
throw new Error("ParticleBaseShape:emissionRate value must large or equal than 0.");
this._emissionRate = value;
}
get emissionRate() {
return this._emissionRate;
}
get destroyed() {
return this._destroyed;
}
destroy() {
this._bursts = null;
this._destroyed = true;
}
getBurstsCount() {
return this._bursts.length;
}
getBurstByIndex(index) {
return this._bursts[index];
}
addBurst(burst) {
var burstsCount = this._bursts.length;
if (burstsCount > 0)
for (var i = 0; i < burstsCount; i++) {
if (this._bursts[i].time > burst.time)
this._bursts.splice(i, 0, burst);
}
this._bursts.push(burst);
}
removeBurst(burst) {
var index = this._bursts.indexOf(burst);
if (index !== -1) {
this._bursts.splice(index, 1);
}
}
removeBurstByIndex(index) {
this._bursts.splice(index, 1);
}
clearBurst() {
this._bursts.length = 0;
}
cloneTo(destObject) {
var destEmission = destObject;
var destBursts = destEmission._bursts;
destBursts.length = this._bursts.length;
for (var i = 0, n = this._bursts.length; i < n; i++) {
var destBurst = destBursts[i];
if (destBurst)
this._bursts[i].cloneTo(destBurst);
else
destBursts[i] = this._bursts[i].clone();
}
destEmission._emissionRate = this._emissionRate;
destEmission.enable = this.enable;
}
clone() {
var destEmission = new Emission();
this.cloneTo(destEmission);
return destEmission;
}
}
class ShurikenParticleData {
constructor() {
}
static _getStartLifetimeFromGradient(startLifeTimeGradient, emissionTime) {
for (var i = 1, n = startLifeTimeGradient.gradientCount; i < n; i++) {
var key = startLifeTimeGradient.getKeyByIndex(i);
if (key >= emissionTime) {
var lastKey = startLifeTimeGradient.getKeyByIndex(i - 1);
var age = (emissionTime - lastKey) / (key - lastKey);
return Laya.MathUtil.lerp(startLifeTimeGradient.getValueByIndex(i - 1), startLifeTimeGradient.getValueByIndex(i), age);
}
}
throw new Error("ShurikenParticleData: can't get value foam startLifeTimeGradient.");
}
static _randomInvertRoationArray(rotatonE, outE, randomizeRotationDirection, rand, randomSeeds) {
var randDic;
if (rand) {
rand.seed = randomSeeds[6];
randDic = rand.getFloat();
randomSeeds[6] = rand.seed;
}
else {
randDic = Math.random();
}
if (randDic < randomizeRotationDirection) {
outE.x = -rotatonE.x;
outE.y = -rotatonE.y;
outE.z = -rotatonE.z;
}
else {
outE.x = rotatonE.x;
outE.y = rotatonE.y;
outE.z = rotatonE.z;
}
}
static _randomInvertRoation(rotaton, randomizeRotationDirection, rand, randomSeeds) {
var randDic;
if (rand) {
rand.seed = randomSeeds[6];
randDic = rand.getFloat();
randomSeeds[6] = rand.seed;
}
else {
randDic = Math.random();
}
if (randDic < randomizeRotationDirection)
rotaton = -rotaton;
return rotaton;
}
static create(particleSystem, particleRender) {
var autoRandomSeed = particleSystem.autoRandomSeed;
var rand = particleSystem._rand;
var randomSeeds = particleSystem._randomSeeds;
switch (particleSystem.startColorType) {
case 0:
var constantStartColor = particleSystem.startColorConstant;
ShurikenParticleData.startColor.x = constantStartColor.x;
ShurikenParticleData.startColor.y = constantStartColor.y;
ShurikenParticleData.startColor.z = constantStartColor.z;
ShurikenParticleData.startColor.w = constantStartColor.w;
break;
case 2:
if (autoRandomSeed) {
Vector4.lerp(particleSystem.startColorConstantMin, particleSystem.startColorConstantMax, Math.random(), ShurikenParticleData.startColor);
}
else {
rand.seed = randomSeeds[3];
Vector4.lerp(particleSystem.startColorConstantMin, particleSystem.startColorConstantMax, rand.getFloat(), ShurikenParticleData.startColor);
randomSeeds[3] = rand.seed;
}
break;
}
var colorOverLifetime = particleSystem.colorOverLifetime;
if (colorOverLifetime && colorOverLifetime.enable) {
var color = colorOverLifetime.color;
switch (color.type) {
case 0:
ShurikenParticleData.startColor.x = ShurikenParticleData.startColor.x * color.constant.x;
ShurikenParticleData.startColor.y = ShurikenParticleData.startColor.y * color.constant.y;
ShurikenParticleData.startColor.z = ShurikenParticleData.startColor.z * color.constant.z;
ShurikenParticleData.startColor.w = ShurikenParticleData.startColor.w * color.constant.w;
break;
case 2:
var colorRandom;
if (autoRandomSeed) {
colorRandom = Math.random();
}
else {
rand.seed = randomSeeds[10];
colorRandom = rand.getFloat();
randomSeeds[10] = rand.seed;
}
var minConstantColor = color.constantMin;
var maxConstantColor = color.constantMax;
ShurikenParticleData.startColor.x = ShurikenParticleData.startColor.x * Laya.MathUtil.lerp(minConstantColor.x, maxConstantColor.x, colorRandom);
ShurikenParticleData.startColor.y = ShurikenParticleData.startColor.y * Laya.MathUtil.lerp(minConstantColor.y, maxConstantColor.y, colorRandom);
ShurikenParticleData.startColor.z = ShurikenParticleData.startColor.z * Laya.MathUtil.lerp(minConstantColor.z, maxConstantColor.z, colorRandom);
ShurikenParticleData.startColor.w = ShurikenParticleData.startColor.w * Laya.MathUtil.lerp(minConstantColor.w, maxConstantColor.w, colorRandom);
break;
}
}
var particleSize = ShurikenParticleData.startSize;
switch (particleSystem.startSizeType) {
case 0:
if (particleSystem.threeDStartSize) {
var startSizeConstantSeparate = particleSystem.startSizeConstantSeparate;
particleSize[0] = startSizeConstantSeparate.x;
particleSize[1] = startSizeConstantSeparate.y;
particleSize[2] = startSizeConstantSeparate.z;
}
else {
particleSize[0] = particleSize[1] = particleSize[2] = particleSystem.startSizeConstant;
}
break;
case 2:
if (particleSystem.threeDStartSize) {
var startSizeConstantMinSeparate = particleSystem.startSizeConstantMinSeparate;
var startSizeConstantMaxSeparate = particleSystem.startSizeConstantMaxSeparate;
if (autoRandomSeed) {
particleSize[0] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.x, startSizeConstantMaxSeparate.x, Math.random());
particleSize[1] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.y, startSizeConstantMaxSeparate.y, Math.random());
particleSize[2] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.z, startSizeConstantMaxSeparate.z, Math.random());
}
else {
rand.seed = randomSeeds[4];
particleSize[0] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.x, startSizeConstantMaxSeparate.x, rand.getFloat());
particleSize[1] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.y, startSizeConstantMaxSeparate.y, rand.getFloat());
particleSize[2] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.z, startSizeConstantMaxSeparate.z, rand.getFloat());
randomSeeds[4] = rand.seed;
}
}
else {
if (autoRandomSeed) {
particleSize[0] = particleSize[1] = particleSize[2] = Laya.MathUtil.lerp(particleSystem.startSizeConstantMin, particleSystem.startSizeConstantMax, Math.random());
}
else {
rand.seed = randomSeeds[4];
particleSize[0] = particleSize[1] = particleSize[2] = Laya.MathUtil.lerp(particleSystem.startSizeConstantMin, particleSystem.startSizeConstantMax, rand.getFloat());
randomSeeds[4] = rand.seed;
}
}
break;
}
var sizeOverLifetime = particleSystem.sizeOverLifetime;
if (sizeOverLifetime && sizeOverLifetime.enable && sizeOverLifetime.size.type === 1) {
var size = sizeOverLifetime.size;
if (size.separateAxes) {
if (autoRandomSeed) {
particleSize[0] = particleSize[0] * Laya.MathUtil.lerp(size.constantMinSeparate.x, size.constantMaxSeparate.x, Math.random());
particleSize[1] = particleSize[1] * Laya.MathUtil.lerp(size.constantMinSeparate.y, size.constantMaxSeparate.y, Math.random());
particleSize[2] = particleSize[2] * Laya.MathUtil.lerp(size.constantMinSeparate.z, size.constantMaxSeparate.z, Math.random());
}
else {
rand.seed = randomSeeds[11];
particleSize[0] = particleSize[0] * Laya.MathUtil.lerp(size.constantMinSeparate.x, size.constantMaxSeparate.x, rand.getFloat());
particleSize[1] = particleSize[1] * Laya.MathUtil.lerp(size.constantMinSeparate.y, size.constantMaxSeparate.y, rand.getFloat());
particleSize[2] = particleSize[2] * Laya.MathUtil.lerp(size.constantMinSeparate.z, size.constantMaxSeparate.z, rand.getFloat());
randomSeeds[11] = rand.seed;
}
}
else {
var randomSize;
if (autoRandomSeed) {
randomSize = Laya.MathUtil.lerp(size.constantMin, size.constantMax, Math.random());
}
else {
rand.seed = randomSeeds[11];
randomSize = Laya.MathUtil.lerp(size.constantMin, size.constantMax, rand.getFloat());
randomSeeds[11] = rand.seed;
}
particleSize[0] = particleSize[0] * randomSize;
particleSize[1] = particleSize[1] * randomSize;
particleSize[2] = particleSize[2] * randomSize;
}
}
var renderMode = particleRender.renderMode;
if (renderMode !== 1) {
switch (particleSystem.startRotationType) {
case 0:
if (particleSystem.threeDStartRotation) {
var startRotationConstantSeparate = particleSystem.startRotationConstantSeparate;
var randomRotationE = ShurikenParticleData._tempVector30;
ShurikenParticleData._randomInvertRoationArray(startRotationConstantSeparate, randomRotationE, particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds);
ShurikenParticleData.startRotation[0] = randomRotationE.x;
ShurikenParticleData.startRotation[1] = randomRotationE.y;
if (renderMode !== 4)
ShurikenParticleData.startRotation[2] = -randomRotationE.z;
else
ShurikenParticleData.startRotation[2] = randomRotationE.z;
}
else {
ShurikenParticleData.startRotation[0] = ShurikenParticleData._randomInvertRoation(particleSystem.startRotationConstant, particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds);
ShurikenParticleData.startRotation[1] = 0;
ShurikenParticleData.startRotation[2] = 0;
}
break;
case 2:
if (particleSystem.threeDStartRotation) {
var startRotationConstantMinSeparate = particleSystem.startRotationConstantMinSeparate;
var startRotationConstantMaxSeparate = particleSystem.startRotationConstantMaxSeparate;
var lerpRoationE = ShurikenParticleData._tempVector30;
if (autoRandomSeed) {
lerpRoationE.x = Laya.MathUtil.lerp(startRotationConstantMinSeparate.x, startRotationConstantMaxSeparate.x, Math.random());
lerpRoationE.y = Laya.MathUtil.lerp(startRotationConstantMinSeparate.y, startRotationConstantMaxSeparate.y, Math.random());
lerpRoationE.z = Laya.MathUtil.lerp(startRotationConstantMinSeparate.z, startRotationConstantMaxSeparate.z, Math.random());
}
else {
rand.seed = randomSeeds[5];
lerpRoationE.x = Laya.MathUtil.lerp(startRotationConstantMinSeparate.x, startRotationConstantMaxSeparate.x, rand.getFloat());
lerpRoationE.y = Laya.MathUtil.lerp(startRotationConstantMinSeparate.y, startRotationConstantMaxSeparate.y, rand.getFloat());
lerpRoationE.z = Laya.MathUtil.lerp(startRotationConstantMinSeparate.z, startRotationConstantMaxSeparate.z, rand.getFloat());
randomSeeds[5] = rand.seed;
}
ShurikenParticleData._randomInvertRoationArray(lerpRoationE, lerpRoationE, particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds);
ShurikenParticleData.startRotation[0] = lerpRoationE.x;
ShurikenParticleData.startRotation[1] = lerpRoationE.y;
if (renderMode !== 4)
ShurikenParticleData.startRotation[2] = -lerpRoationE.z;
else
ShurikenParticleData.startRotation[2] = lerpRoationE.z;
}
else {
if (autoRandomSeed) {
ShurikenParticleData.startRotation[0] = ShurikenParticleData._randomInvertRoation(Laya.MathUtil.lerp(particleSystem.startRotationConstantMin, particleSystem.startRotationConstantMax, Math.random()), particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds);
}
else {
rand.seed = randomSeeds[5];
ShurikenParticleData.startRotation[0] = ShurikenParticleData._randomInvertRoation(Laya.MathUtil.lerp(particleSystem.startRotationConstantMin, particleSystem.startRotationConstantMax, rand.getFloat()), particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds);
randomSeeds[5] = rand.seed;
}
}
break;
}
}
switch (particleSystem.startLifetimeType) {
case 0:
ShurikenParticleData.startLifeTime = particleSystem.startLifetimeConstant;
break;
case 1:
ShurikenParticleData.startLifeTime = ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradient, particleSystem.emissionTime);
break;
case 2:
if (autoRandomSeed) {
ShurikenParticleData.startLifeTime = Laya.MathUtil.lerp(particleSystem.startLifetimeConstantMin, particleSystem.startLifetimeConstantMax, Math.random());
}
else {
rand.seed = randomSeeds[7];
ShurikenParticleData.startLifeTime = Laya.MathUtil.lerp(particleSystem.startLifetimeConstantMin, particleSystem.startLifetimeConstantMax, rand.getFloat());
randomSeeds[7] = rand.seed;
}
break;
case 3:
var emissionTime = particleSystem.emissionTime;
if (autoRandomSeed) {
ShurikenParticleData.startLifeTime = Laya.MathUtil.lerp(ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradientMin, emissionTime), ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradientMax, emissionTime), Math.random());
}
else {
rand.seed = randomSeeds[7];
ShurikenParticleData.startLifeTime = Laya.MathUtil.lerp(ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradientMin, emissionTime), ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradientMax, emissionTime), rand.getFloat());
randomSeeds[7] = rand.seed;
}
break;
}
var textureSheetAnimation = particleSystem.textureSheetAnimation;
var enableSheetAnimation = textureSheetAnimation && textureSheetAnimation.enable;
if (enableSheetAnimation) {
var title = textureSheetAnimation.tiles;
var titleX = title.x, titleY = title.y;
var subU = 1.0 / titleX, subV = 1.0 / titleY;
var startFrameCount;
var startFrame = textureSheetAnimation.startFrame;
switch (startFrame.type) {
case 0:
startFrameCount = startFrame.constant;
break;
case 1:
if (autoRandomSeed) {
startFrameCount = Laya.MathUtil.lerp(startFrame.constantMin, startFrame.constantMax, Math.random());
}
else {
rand.seed = randomSeeds[14];
startFrameCount = Laya.MathUtil.lerp(startFrame.constantMin, startFrame.constantMax, rand.getFloat());
randomSeeds[14] = rand.seed;
}
break;
}
var frame = textureSheetAnimation.frame;
var cycles = textureSheetAnimation.cycles;
switch (frame.type) {
case 0:
startFrameCount += frame.constant * cycles;
break;
case 2:
if (autoRandomSeed) {
startFrameCount += Laya.MathUtil.lerp(frame.constantMin, frame.constantMax, Math.random()) * cycles;
}
else {
rand.seed = randomSeeds[15];
startFrameCount += Laya.MathUtil.lerp(frame.constantMin, frame.constantMax, rand.getFloat()) * cycles;
randomSeeds[15] = rand.seed;
}
break;
}
var startRow = 0;
switch (textureSheetAnimation.type) {
case 0:
startRow = Math.floor(startFrameCount / titleX);
break;
case 1:
if (textureSheetAnimation.randomRow) {
if (autoRandomSeed) {
startRow = Math.floor(Math.random() * titleY);
}
else {
rand.seed = randomSeeds[13];
startRow = Math.floor(rand.getFloat() * titleY);
randomSeeds[13] = rand.seed;
}
}
else {
startRow = textureSheetAnimation.rowIndex;
}
break;
}
var startCol = Math.floor(startFrameCount % titleX);
ShurikenParticleData.startUVInfo = ShurikenParticleData.startUVInfo;
ShurikenParticleData.startUVInfo[0] = subU;
ShurikenParticleData.startUVInfo[1] = subV;
ShurikenParticleData.startUVInfo[2] = startCol * subU;
ShurikenParticleData.startUVInfo[3] = startRow * subV;
}
else {
ShurikenParticleData.startUVInfo = ShurikenParticleData.startUVInfo;
ShurikenParticleData.startUVInfo[0] = 1.0;
ShurikenParticleData.startUVInfo[1] = 1.0;
ShurikenParticleData.startUVInfo[2] = 0.0;
ShurikenParticleData.startUVInfo[3] = 0.0;
}
}
}
ShurikenParticleData._tempVector30 = new Vector3();
ShurikenParticleData.startColor = new Vector4();
ShurikenParticleData.startSize = new Float32Array(3);
ShurikenParticleData.startRotation = new Float32Array(3);
ShurikenParticleData.startUVInfo = new Float32Array(4);
class ShurikenParticleSystem extends GeometryElement {
constructor(owner) {
super();
this._boundingSphere = null;
this._boundingBox = null;
this._boundingBoxCorners = null;
this._bounds = null;
this._gravityOffset = new Vector2();
this._customBounds = null;
this._useCustomBounds = false;
this._owner = null;
this._ownerRender = null;
this._vertices = null;
this._floatCountPerVertex = 0;
this._startLifeTimeIndex = 0;
this._timeIndex = 0;
this._simulateUpdate = false;
this._firstActiveElement = 0;
this._firstNewElement = 0;
this._firstFreeElement = 0;
this._firstRetiredElement = 0;
this._drawCounter = 0;
this._bufferMaxParticles = 0;
this._emission = null;
this._shape = null;
this._isEmitting = false;
this._isPlaying = false;
this._isPaused = false;
this._playStartDelay = 0;
this._frameRateTime = 0;
this._emissionTime = 0;
this._totalDelayTime = 0;
this._burstsIndex = 0;
this._velocityOverLifetime = null;
this._colorOverLifetime = null;
this._sizeOverLifetime = null;
this._rotationOverLifetime = null;
this._textureSheetAnimation = null;
this._startLifetimeType = 0;
this._startLifetimeConstant = 0;
this._startLifeTimeGradient = null;
this._startLifetimeConstantMin = 0;
this._startLifetimeConstantMax = 0;
this._startLifeTimeGradientMin = null;
this._startLifeTimeGradientMax = null;
this._maxStartLifetime = 0;
this._uvLength = new Vector2();
this._vertexStride = 0;
this._indexStride = 0;
this._vertexBuffer = null;
this._indexBuffer = null;
this._bufferState = new BufferState();
this._updateMask = 0;
this._currentTime = 0;
this._startUpdateLoopCount = 0;
this._rand = null;
this._randomSeeds = null;
this.duration = 0;
this.looping = false;
this.prewarm = false;
this.startDelayType = 0;
this.startDelay = 0;
this.startDelayMin = 0;
this.startDelayMax = 0;
this.startSpeedType = 0;
this.startSpeedConstant = 0;
this.startSpeedConstantMin = 0;
this.startSpeedConstantMax = 0;
this.threeDStartSize = false;
this.startSizeType = 0;
this.startSizeConstant = 0;
this.startSizeConstantSeparate = null;
this.startSizeConstantMin = 0;
this.startSizeConstantMax = 0;
this.startSizeConstantMinSeparate = null;
this.startSizeConstantMaxSeparate = null;
this.threeDStartRotation = false;
this.startRotationType = 0;
this.startRotationConstant = 0;
this.startRotationConstantSeparate = null;
this.startRotationConstantMin = 0;
this.startRotationConstantMax = 0;
this.startRotationConstantMinSeparate = null;
this.startRotationConstantMaxSeparate = null;
this.randomizeRotationDirection = 0;
this.startColorType = 0;
this.startColorConstant = new Vector4(1, 1, 1, 1);
this.startColorConstantMin = new Vector4(0, 0, 0, 0);
this.startColorConstantMax = new Vector4(1, 1, 1, 1);
this.gravityModifier = 0;
this.simulationSpace = 0;
this.simulationSpeed = 1.0;
this.scaleMode = 1;
this.playOnAwake = false;
this.randomSeed = null;
this.autoRandomSeed = false;
this.isPerformanceMode = false;
this._firstActiveElement = 0;
this._firstNewElement = 0;
this._firstFreeElement = 0;
this._firstRetiredElement = 0;
this._owner = owner;
this._ownerRender = owner.particleRenderer;
this._boundingBoxCorners = [];
this._boundingSphere = new BoundSphere(new Vector3(), Number.MAX_VALUE);
this._boundingBox = new BoundBox(new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE), new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE));
this._bounds = new Bounds(this._boundingBox.min, this._boundingBox.max);
this._useCustomBounds = false;
this._currentTime = 0;
this._isEmitting = false;
this._isPlaying = false;
this._isPaused = false;
this._burstsIndex = 0;
this._frameRateTime = 0;
this._emissionTime = 0;
this._totalDelayTime = 0;
this._simulateUpdate = false;
this._bufferMaxParticles = 1;
this.duration = 5.0;
this.looping = true;
this.prewarm = false;
this.startDelayType = 0;
this.startDelay = 0.0;
this.startDelayMin = 0.0;
this.startDelayMax = 0.0;
this._startLifetimeType = 0;
this._startLifetimeConstant = 5.0;
this._startLifeTimeGradient = new GradientDataNumber();
this._startLifetimeConstantMin = 0.0;
this._startLifetimeConstantMax = 5.0;
this._startLifeTimeGradientMin = new GradientDataNumber();
this._startLifeTimeGradientMax = new GradientDataNumber();
this._maxStartLifetime = 5.0;
this.startSpeedType = 0;
this.startSpeedConstant = 5.0;
this.startSpeedConstantMin = 0.0;
this.startSpeedConstantMax = 5.0;
this.threeDStartSize = false;
this.startSizeType = 0;
this.startSizeConstant = 1;
this.startSizeConstantSeparate = new Vector3(1, 1, 1);
this.startSizeConstantMin = 0;
this.startSizeConstantMax = 1;
this.startSizeConstantMinSeparate = new Vector3(0, 0, 0);
this.startSizeConstantMaxSeparate = new Vector3(1, 1, 1);
this.threeDStartRotation = false;
this.startRotationType = 0;
this.startRotationConstant = 0;
this.startRotationConstantSeparate = new Vector3(0, 0, 0);
this.startRotationConstantMin = 0.0;
this.startRotationConstantMax = 0.0;
this.startRotationConstantMinSeparate = new Vector3(0, 0, 0);
this.startRotationConstantMaxSeparate = new Vector3(0, 0, 0);
this.gravityModifier = 0.0;
this.simulationSpace = 1;
this.scaleMode = 1;
this.playOnAwake = true;
this._rand = new Rand(0);
this.autoRandomSeed = true;
this.randomSeed = new Uint32Array(1);
this._randomSeeds = new Uint32Array(ShurikenParticleSystem._RANDOMOFFSET.length);
this.isPerformanceMode = true;
this._emission = new Emission();
this._emission.enable = true;
}
;
get maxParticles() {
return this._bufferMaxParticles - 1;
}
set maxParticles(value) {
var newMaxParticles = value + 1;
if (newMaxParticles !== this._bufferMaxParticles) {
this._bufferMaxParticles = newMaxParticles;
this._initBufferDatas();
}
}
get emission() {
return this._emission;
}
get aliveParticleCount() {
if (this._firstNewElement >= this._firstRetiredElement)
return this._firstNewElement - this._firstRetiredElement;
else
return this._bufferMaxParticles - this._firstRetiredElement + this._firstNewElement;
}
get emissionTime() {
return this._emissionTime > this.duration ? this.duration : this._emissionTime;
}
get shape() {
return this._shape;
}
set shape(value) {
if (this._shape !== value) {
if (value && value.enable)
this._owner._render._shaderValues.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SHAPE);
else
this._owner._render._shaderValues.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SHAPE);
this._shape = value;
}
}
get isAlive() {
if (this._isPlaying || this.aliveParticleCount > 0)
return true;
return false;
}
get isEmitting() {
return this._isEmitting;
}
get isPlaying() {
return this._isPlaying;
}
get isPaused() {
return this._isPaused;
}
get startLifetimeType() {
return this._startLifetimeType;
}
set startLifetimeType(value) {
var i, n;
switch (this.startLifetimeType) {
case 0:
this._maxStartLifetime = this.startLifetimeConstant;
break;
case 1:
this._maxStartLifetime = -Number.MAX_VALUE;
var startLifeTimeGradient = startLifeTimeGradient;
for (i = 0, n = startLifeTimeGradient.gradientCount; i < n; i++)
this._maxStartLifetime = Math.max(this._maxStartLifetime, startLifeTimeGradient.getValueByIndex(i));
break;
case 2:
this._maxStartLifetime = Math.max(this.startLifetimeConstantMin, this.startLifetimeConstantMax);
break;
case 3:
this._maxStartLifetime = -Number.MAX_VALUE;
var startLifeTimeGradientMin = startLifeTimeGradientMin;
for (i = 0, n = startLifeTimeGradientMin.gradientCount; i < n; i++)
this._maxStartLifetime = Math.max(this._maxStartLifetime, startLifeTimeGradientMin.getValueByIndex(i));
var startLifeTimeGradientMax = startLifeTimeGradientMax;
for (i = 0, n = startLifeTimeGradientMax.gradientCount; i < n; i++)
this._maxStartLifetime = Math.max(this._maxStartLifetime, startLifeTimeGradientMax.getValueByIndex(i));
break;
}
this._startLifetimeType = value;
}
get startLifetimeConstant() {
return this._startLifetimeConstant;
}
set startLifetimeConstant(value) {
if (this._startLifetimeType === 0)
this._maxStartLifetime = value;
this._startLifetimeConstant = value;
}
get startLifeTimeGradient() {
return this._startLifeTimeGradient;
}
set startLifeTimeGradient(value) {
if (this._startLifetimeType === 1) {
this._maxStartLifetime = -Number.MAX_VALUE;
for (var i = 0, n = value.gradientCount; i < n; i++)
this._maxStartLifetime = Math.max(this._maxStartLifetime, value.getValueByIndex(i));
}
this._startLifeTimeGradient = value;
}
get startLifetimeConstantMin() {
return this._startLifetimeConstantMin;
}
set startLifetimeConstantMin(value) {
if (this._startLifetimeType === 2)
this._maxStartLifetime = Math.max(value, this._startLifetimeConstantMax);
this._startLifetimeConstantMin = value;
}
get startLifetimeConstantMax() {
return this._startLifetimeConstantMax;
}
set startLifetimeConstantMax(value) {
if (this._startLifetimeType === 2)
this._maxStartLifetime = Math.max(this._startLifetimeConstantMin, value);
this._startLifetimeConstantMax = value;
}
get startLifeTimeGradientMin() {
return this._startLifeTimeGradientMin;
}
set startLifeTimeGradientMin(value) {
if (this._startLifetimeType === 3) {
var i, n;
this._maxStartLifetime = -Number.MAX_VALUE;
for (i = 0, n = value.gradientCount; i < n; i++)
this._maxStartLifetime = Math.max(this._maxStartLifetime, value.getValueByIndex(i));
for (i = 0, n = this._startLifeTimeGradientMax.gradientCount; i < n; i++)
this._maxStartLifetime = Math.max(this._maxStartLifetime, this._startLifeTimeGradientMax.getValueByIndex(i));
}
this._startLifeTimeGradientMin = value;
}
get startLifeTimeGradientMax() {
return this._startLifeTimeGradientMax;
}
set startLifeTimeGradientMax(value) {
if (this._startLifetimeType === 3) {
var i, n;
this._maxStartLifetime = -Number.MAX_VALUE;
for (i = 0, n = this._startLifeTimeGradientMin.gradientCount; i < n; i++)
this._maxStartLifetime = Math.max(this._maxStartLifetime, this._startLifeTimeGradientMin.getValueByIndex(i));
for (i = 0, n = value.gradientCount; i < n; i++)
this._maxStartLifetime = Math.max(this._maxStartLifetime, value.getValueByIndex(i));
}
this._startLifeTimeGradientMax = value;
}
get velocityOverLifetime() {
return this._velocityOverLifetime;
}
set velocityOverLifetime(value) {
var shaDat = this._owner._render._shaderValues;
if (value) {
var velocity = value.velocity;
var velocityType = velocity.type;
if (value.enable) {
switch (velocityType) {
case 0:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECONSTANT);
break;
case 1:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECURVE);
break;
case 2:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCONSTANT);
break;
case 3:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCURVE);
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECONSTANT);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECURVE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCONSTANT);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCURVE);
}
switch (velocityType) {
case 0:
shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONST, velocity.constant);
break;
case 1:
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTX, velocity.gradientX._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTY, velocity.gradientY._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZ, velocity.gradientZ._elements);
break;
case 2:
shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONST, velocity.constantMin);
shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONSTMAX, velocity.constantMax);
break;
case 3:
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTX, velocity.gradientXMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTXMAX, velocity.gradientXMax._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTY, velocity.gradientYMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTYMAX, velocity.gradientYMax._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZ, velocity.gradientZMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZMAX, velocity.gradientZMax._elements);
break;
}
shaDat.setInt(ShuriKenParticle3DShaderDeclaration.VOLSPACETYPE, value.space);
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECONSTANT);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECURVE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCONSTANT);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCURVE);
}
this._velocityOverLifetime = value;
}
get colorOverLifetime() {
return this._colorOverLifetime;
}
set colorOverLifetime(value) {
var shaDat = this._owner._render._shaderValues;
if (value) {
var color = value.color;
if (value.enable) {
switch (color.type) {
case 1:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_COLOROVERLIFETIME);
break;
case 3:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RANDOMCOLOROVERLIFETIME);
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_COLOROVERLIFETIME);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RANDOMCOLOROVERLIFETIME);
}
switch (color.type) {
case 1:
var gradientColor = color.gradient;
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS, gradientColor._alphaElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS, gradientColor._rgbElements);
break;
case 3:
var minGradientColor = color.gradientMin;
var maxGradientColor = color.gradientMax;
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS, minGradientColor._alphaElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS, minGradientColor._rgbElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTALPHAS, maxGradientColor._alphaElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTCOLORS, maxGradientColor._rgbElements);
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_COLOROVERLIFETIME);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RANDOMCOLOROVERLIFETIME);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS, gradientColor._alphaElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS, gradientColor._rgbElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS, minGradientColor._alphaElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS, minGradientColor._rgbElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTALPHAS, maxGradientColor._alphaElements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTCOLORS, maxGradientColor._rgbElements);
}
this._colorOverLifetime = value;
}
get sizeOverLifetime() {
return this._sizeOverLifetime;
}
set sizeOverLifetime(value) {
var shaDat = this._owner._render._shaderValues;
if (value) {
var size = value.size;
var sizeSeparate = size.separateAxes;
var sizeType = size.type;
if (value.enable) {
switch (sizeType) {
case 0:
if (sizeSeparate)
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVESEPERATE);
else
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVE);
break;
case 2:
if (sizeSeparate)
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVESSEPERATE);
else
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVES);
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVESEPERATE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVES);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVESSEPERATE);
}
switch (sizeType) {
case 0:
if (sizeSeparate) {
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTX, size.gradientX._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTY, size.gradientY._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZ, size.gradientZ._elements);
}
else {
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENT, size.gradient._elements);
}
break;
case 2:
if (sizeSeparate) {
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTX, size.gradientXMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTXMAX, size.gradientXMax._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTY, size.gradientYMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTYMAX, size.gradientYMax._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZ, size.gradientZMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZMAX, size.gradientZMax._elements);
}
else {
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENT, size.gradientMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSizeGradientMax, size.gradientMax._elements);
}
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVESEPERATE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVES);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVESSEPERATE);
}
this._sizeOverLifetime = value;
}
get rotationOverLifetime() {
return this._rotationOverLifetime;
}
set rotationOverLifetime(value) {
var shaDat = this._owner._render._shaderValues;
if (value) {
var rotation = value.angularVelocity;
if (!rotation)
return;
var rotationSeparate = rotation.separateAxes;
var rotationType = rotation.type;
if (value.enable) {
if (rotationSeparate)
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMESEPERATE);
else
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIME);
switch (rotationType) {
case 0:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECONSTANT);
break;
case 1:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECURVE);
break;
case 2:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCONSTANTS);
break;
case 3:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCURVES);
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIME);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMESEPERATE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECONSTANT);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECURVE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCONSTANTS);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCURVES);
}
switch (rotationType) {
case 0:
if (rotationSeparate) {
shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTSEPRARATE, rotation.constantSeparate);
}
else {
shaDat.setNumber(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONST, rotation.constant);
}
break;
case 1:
if (rotationSeparate) {
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTX, rotation.gradientX._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTY, rotation.gradientY._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZ, rotation.gradientZ._elements);
}
else {
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENT, rotation.gradient._elements);
}
break;
case 2:
if (rotationSeparate) {
shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTSEPRARATE, rotation.constantMinSeparate);
shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTMAXSEPRARATE, rotation.constantMaxSeparate);
}
else {
shaDat.setNumber(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONST, rotation.constantMin);
shaDat.setNumber(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTMAX, rotation.constantMax);
}
break;
case 3:
if (rotationSeparate) {
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTX, rotation.gradientXMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTXMAX, rotation.gradientXMax._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTY, rotation.gradientYMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTYMAX, rotation.gradientYMax._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZ, rotation.gradientZMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZMAX, rotation.gradientZMax._elements);
}
else {
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENT, rotation.gradientMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTMAX, rotation.gradientMax._elements);
}
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIME);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMESEPERATE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECONSTANT);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECURVE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCONSTANTS);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCURVES);
}
this._rotationOverLifetime = value;
}
get textureSheetAnimation() {
return this._textureSheetAnimation;
}
set textureSheetAnimation(value) {
var shaDat = this._owner._render._shaderValues;
if (value) {
var frameOverTime = value.frame;
var textureAniType = frameOverTime.type;
if (value.enable) {
switch (textureAniType) {
case 1:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONCURVE);
break;
case 3:
shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONRANDOMCURVE);
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONCURVE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONRANDOMCURVE);
}
if (textureAniType === 1 || textureAniType === 3) {
shaDat.setNumber(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONCYCLES, value.cycles);
var title = value.tiles;
var _uvLengthE = this._uvLength;
_uvLengthE.x = 1.0 / title.x;
_uvLengthE.y = 1.0 / title.y;
shaDat.setVector2(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONSUBUVLENGTH, this._uvLength);
}
switch (textureAniType) {
case 1:
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTUVS, frameOverTime.frameOverTimeData._elements);
break;
case 3:
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTUVS, frameOverTime.frameOverTimeDataMin._elements);
shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTMAXUVS, frameOverTime.frameOverTimeDataMax._elements);
break;
}
}
else {
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONCURVE);
shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONRANDOMCURVE);
}
this._textureSheetAnimation = value;
}
_getVertexBuffer(index = 0) {
if (index === 0)
return this._vertexBuffer;
else
return null;
}
_getIndexBuffer() {
return this._indexBuffer;
}
_generateBoundingSphere() {
var centerE = this._boundingSphere.center;
centerE.x = 0;
centerE.y = 0;
centerE.z = 0;
this._boundingSphere.radius = Number.MAX_VALUE;
}
_generateBounds() {
var particle = this._owner;
var particleRender = particle.particleRenderer;
var boundsMin = this._bounds.getMin();
var boundsMax = this._bounds.getMax();
var time = 0;
switch (this.startLifetimeType) {
case 0:
time = this._startLifetimeConstant;
break;
case 2:
time = this._startLifetimeConstantMax;
break;
}
var speedOrigan = 0;
switch (this.startSpeedType) {
case 0:
speedOrigan = this.startSpeedConstant;
break;
case 2:
speedOrigan = this.startSpeedConstantMax;
break;
}
var maxSizeScale = 0;
if (this.threeDStartSize) {
switch (this.startSizeType) {
case 0:
maxSizeScale = Math.max(this.startSizeConstantSeparate.x, this.startSizeConstantSeparate.y, this.startSizeConstantSeparate.z);
break;
case 2:
maxSizeScale = Math.max(this.startSizeConstantMaxSeparate.x, this.startSizeConstantMaxSeparate.y, this.startSizeConstantMaxSeparate.z);
break;
}
}
else {
switch (this.startSizeType) {
case 0:
maxSizeScale = this.startSizeConstant;
break;
case 2:
maxSizeScale = this.startSizeConstantMax;
break;
}
}
var zDirectionSpeed = ShurikenParticleSystem._tempVector30;
var fDirectionSpeed = ShurikenParticleSystem._tempVector31;
var zEmisionOffsetXYZ = ShurikenParticleSystem._tempVector32;
var fEmisionOffsetXYZ = ShurikenParticleSystem._tempVector33;
zDirectionSpeed.setValue(0, 0, 1);
fDirectionSpeed.setValue(0, 0, 0);
zEmisionOffsetXYZ.setValue(0, 0, 0);
fEmisionOffsetXYZ.setValue(0, 0, 0);
if (this.shape && this.shape.enable) {
switch (this.shape.shapeType) {
case exports.ParticleSystemShapeType.Sphere:
var sphere = this.shape;
zDirectionSpeed.setValue(1, 1, 1);
fDirectionSpeed.setValue(1, 1, 1);
zEmisionOffsetXYZ.setValue(sphere.radius, sphere.radius, sphere.radius);
fEmisionOffsetXYZ.setValue(sphere.radius, sphere.radius, sphere.radius);
break;
case exports.ParticleSystemShapeType.Hemisphere:
var hemiShpere = this.shape;
zDirectionSpeed.setValue(1, 1, 1);
fDirectionSpeed.setValue(1, 1, 1);
zEmisionOffsetXYZ.setValue(hemiShpere.radius, hemiShpere.radius, hemiShpere.radius);
fEmisionOffsetXYZ.setValue(hemiShpere.radius, hemiShpere.radius, 0.0);
break;
case exports.ParticleSystemShapeType.Cone:
var cone = this.shape;
if (cone.emitType == 0 || cone.emitType == 1) {
var angle = cone.angle;
var sinAngle = Math.sin(angle);
zDirectionSpeed.setValue(sinAngle, sinAngle, 1.0);
fDirectionSpeed.setValue(sinAngle, sinAngle, 0.0);
zEmisionOffsetXYZ.setValue(cone.radius, cone.radius, 0.0);
fEmisionOffsetXYZ.setValue(cone.radius, cone.radius, 0.0);
break;
}
else if (cone.emitType == 2 || cone.emitType == 3) {
var angle = cone.angle;
var sinAngle = Math.sin(angle);
var coneLength = cone.length;
zDirectionSpeed.setValue(sinAngle, sinAngle, 1.0);
fDirectionSpeed.setValue(sinAngle, sinAngle, 0.0);
var tanAngle = Math.tan(angle);
var rPLCT = cone.radius + coneLength * tanAngle;
zEmisionOffsetXYZ.setValue(rPLCT, rPLCT, coneLength);
fEmisionOffsetXYZ.setValue(rPLCT, rPLCT, 0.0);
}
break;
case exports.ParticleSystemShapeType.Box:
var box = this.shape;
if (this.shape.randomDirection != 0) {
zDirectionSpeed.setValue(1, 1, 1);
fDirectionSpeed.setValue(1, 1, 1);
}
zEmisionOffsetXYZ.setValue(box.x / 2, box.y / 2, box.z / 2);
fEmisionOffsetXYZ.setValue(box.x / 2, box.y / 2, box.z / 2);
break;
case exports.ParticleSystemShapeType.Circle:
var circle = this.shape;
zDirectionSpeed.setValue(1, 1, 1);
fDirectionSpeed.setValue(1, 1, 1);
zEmisionOffsetXYZ.setValue(circle.radius, circle.radius, 0);
fEmisionOffsetXYZ.setValue(circle.radius, circle.radius, 0);
break;
}
}
var meshSize = 0;
var meshMode = particleRender.renderMode == 4;
switch (particleRender.renderMode) {
case 0:
case 1:
case 2:
case 3:
meshSize = ShurikenParticleSystem.halfKSqrtOf2;
break;
case 4:
var meshBounds = particleRender.mesh.bounds;
meshSize = Math.sqrt(Math.pow(meshBounds.getExtent().x, 2.0) + Math.pow(meshBounds.getExtent().y, 2.0) + Math.pow(meshBounds.getExtent().z, 2.0));
break;
}
var endSizeOffset = ShurikenParticleSystem._tempVector36;
endSizeOffset.setValue(1, 1, 1);
if (this.sizeOverLifetime && this.sizeOverLifetime.enable) {
var gradientSize = this.sizeOverLifetime.size;
var maxSize = gradientSize.getMaxSizeInGradient(meshMode);
endSizeOffset.setValue(maxSize, maxSize, maxSize);
}
var offsetSize = meshSize * maxSizeScale;
Vector3.scale(endSizeOffset, offsetSize, endSizeOffset);
var speedZOffset = ShurikenParticleSystem._tempVector34;
var speedFOffset = ShurikenParticleSystem._tempVector35;
if (speedOrigan > 0) {
Vector3.scale(zDirectionSpeed, speedOrigan, speedZOffset);
Vector3.scale(fDirectionSpeed, speedOrigan, speedFOffset);
}
else {
Vector3.scale(zDirectionSpeed, -speedOrigan, speedFOffset);
Vector3.scale(fDirectionSpeed, -speedOrigan, speedZOffset);
}
if (this.velocityOverLifetime && this.velocityOverLifetime.enable) {
var gradientVelocity = this.velocityOverLifetime.velocity;
var velocitySpeedOffset = ShurikenParticleSystem._tempVector37;
velocitySpeedOffset.setValue(0, 0, 0);
switch (gradientVelocity.type) {
case 0:
gradientVelocity.constant.cloneTo(velocitySpeedOffset);
break;
case 2:
gradientVelocity.constantMax.cloneTo(velocitySpeedOffset);
break;
case 1:
var curveX = gradientVelocity.gradientX.getAverageValue();
var curveY = gradientVelocity.gradientY.getAverageValue();
var curveZ = gradientVelocity.gradientZ.getAverageValue();
velocitySpeedOffset.setValue(curveX, curveY, curveZ);
break;
case 3:
var xMax = gradientVelocity.gradientXMax.getAverageValue();
var yMax = gradientVelocity.gradientYMax.getAverageValue();
var zMax = gradientVelocity.gradientZMax.getAverageValue();
velocitySpeedOffset.setValue(xMax, yMax, zMax);
break;
}
if (this.velocityOverLifetime.space == 1) {
Vector3.transformV3ToV3(velocitySpeedOffset, this._owner.transform.worldMatrix, velocitySpeedOffset);
}
Vector3.add(speedZOffset, velocitySpeedOffset, speedZOffset);
Vector3.subtract(speedFOffset, velocitySpeedOffset, speedFOffset);
Vector3.max(speedZOffset, Vector3._ZERO, speedZOffset);
Vector3.max(speedFOffset, Vector3._ZERO, speedFOffset);
}
Vector3.scale(speedZOffset, time, speedZOffset);
Vector3.scale(speedFOffset, time, speedFOffset);
var gravity = this.gravityModifier;
if (gravity != 0) {
var gravityOffset = 0.5 * ShurikenParticleSystem.g * gravity * time * time;
var speedZOffsetY = speedZOffset.y - gravityOffset;
var speedFOffsetY = speedFOffset.y + gravityOffset;
speedZOffsetY = speedZOffsetY > 0 ? speedZOffsetY : 0;
speedFOffsetY = speedFOffsetY > 0 ? speedFOffsetY : 0;
this._gravityOffset.setValue(speedZOffset.y - speedZOffsetY, speedFOffsetY - speedFOffset.y);
}
Vector3.add(speedZOffset, endSizeOffset, boundsMax);
Vector3.add(boundsMax, zEmisionOffsetXYZ, boundsMax);
Vector3.add(speedFOffset, endSizeOffset, boundsMin);
Vector3.add(boundsMin, fEmisionOffsetXYZ, boundsMin);
Vector3.scale(boundsMin, -1, boundsMin);
this._bounds.setMin(boundsMin);
this._bounds.setMax(boundsMax);
}
get customBounds() {
return this._customBounds;
}
set customBounds(value) {
if (value) {
this._useCustomBounds = true;
}
else {
this._useCustomBounds = false;
}
this._customBounds = value;
}
_simulationSupported() {
if (this.simulationSpace == 0) {
return false;
}
return true;
}
_updateEmission() {
if (!this.isAlive)
return;
if (this._simulateUpdate) {
this._simulateUpdate = false;
}
else {
var elapsedTime = (this._startUpdateLoopCount !== Laya.Stat.loopCount && !this._isPaused) ? this._owner._scene.timer._delta / 1000.0 : 0;
elapsedTime = Math.min(ShurikenParticleSystem._maxElapsedTime, elapsedTime * this.simulationSpeed);
this._updateParticles(elapsedTime);
}
}
_updateParticles(elapsedTime) {
if (this._ownerRender.renderMode === 4 && !this._ownerRender.mesh)
return;
this._currentTime += elapsedTime;
this._retireActiveParticles();
this._freeRetiredParticles();
this._totalDelayTime += elapsedTime;
if (this._totalDelayTime < this._playStartDelay) {
return;
}
if (this._emission.enable && this._isEmitting && !this._isPaused)
this._advanceTime(elapsedTime, this._currentTime);
}
_updateParticlesSimulationRestart(time) {
this._firstActiveElement = 0;
this._firstNewElement = 0;
this._firstFreeElement = 0;
this._firstRetiredElement = 0;
this._burstsIndex = 0;
this._frameRateTime = time;
this._emissionTime = 0;
this._totalDelayTime = 0;
this._currentTime = time;
var delayTime = time;
if (delayTime < this._playStartDelay) {
this._totalDelayTime = delayTime;
return;
}
if (this._emission.enable)
this._advanceTime(time, time);
}
_retireActiveParticles() {
const epsilon = 0.0001;
while (this._firstActiveElement != this._firstNewElement) {
var index = this._firstActiveElement * this._floatCountPerVertex * this._vertexStride;
var timeIndex = index + this._timeIndex;
var particleAge = this._currentTime - this._vertices[timeIndex];
if (particleAge + epsilon < this._vertices[index + this._startLifeTimeIndex])
break;
this._vertices[timeIndex] = this._drawCounter;
this._firstActiveElement++;
if (this._firstActiveElement >= this._bufferMaxParticles)
this._firstActiveElement = 0;
}
}
_freeRetiredParticles() {
while (this._firstRetiredElement != this._firstActiveElement) {
var age = this._drawCounter - this._vertices[this._firstRetiredElement * this._floatCountPerVertex * this._vertexStride + this._timeIndex];
this._firstRetiredElement++;
if (this._firstRetiredElement >= this._bufferMaxParticles)
this._firstRetiredElement = 0;
}
}
_burst(fromTime, toTime) {
var totalEmitCount = 0;
var bursts = this._emission._bursts;
for (var n = bursts.length; this._burstsIndex < n; this._burstsIndex++) {
var burst = bursts[this._burstsIndex];
var burstTime = burst.time;
if (fromTime <= burstTime && burstTime < toTime) {
var emitCount;
if (this.autoRandomSeed) {
emitCount = Laya.MathUtil.lerp(burst.minCount, burst.maxCount, Math.random());
}
else {
this._rand.seed = this._randomSeeds[0];
emitCount = Laya.MathUtil.lerp(burst.minCount, burst.maxCount, this._rand.getFloat());
this._randomSeeds[0] = this._rand.seed;
}
totalEmitCount += emitCount;
}
else {
break;
}
}
return totalEmitCount;
}
_advanceTime(elapsedTime, emitTime) {
var i;
var lastEmissionTime = this._emissionTime;
this._emissionTime += elapsedTime;
var totalEmitCount = 0;
if (this._emissionTime > this.duration) {
if (this.looping) {
totalEmitCount += this._burst(lastEmissionTime, this._emissionTime);
this._emissionTime -= this.duration;
this._burstsIndex = 0;
totalEmitCount += this._burst(0, this._emissionTime);
}
else {
totalEmitCount = Math.min(this.maxParticles - this.aliveParticleCount, totalEmitCount);
for (i = 0; i < totalEmitCount; i++)
this.emit(emitTime);
this._isPlaying = false;
this.stop();
return;
}
}
else {
totalEmitCount += this._burst(lastEmissionTime, this._emissionTime);
}
totalEmitCount = Math.min(this.maxParticles - this.aliveParticleCount, totalEmitCount);
for (i = 0; i < totalEmitCount; i++)
this.emit(emitTime);
var emissionRate = this.emission.emissionRate;
if (emissionRate > 0) {
var minEmissionTime = 1 / emissionRate;
this._frameRateTime += minEmissionTime;
this._frameRateTime = this._currentTime - (this._currentTime - this._frameRateTime) % this._maxStartLifetime;
while (this._frameRateTime <= emitTime) {
if (this.emit(this._frameRateTime))
this._frameRateTime += minEmissionTime;
else
break;
}
this._frameRateTime = Math.floor(emitTime / minEmissionTime) * minEmissionTime;
}
}
_initBufferDatas() {
if (this._vertexBuffer) {
var memorySize = this._vertexBuffer._byteLength + this._indexBuffer.indexCount * 2;
this._vertexBuffer.destroy();
this._indexBuffer.destroy();
Laya.Resource._addMemory(-memorySize, -memorySize);
}
var gl = Laya.LayaGL.instance;
var render = this._ownerRender;
var renderMode = render.renderMode;
if (renderMode !== -1 && this.maxParticles > 0) {
var indices, i, j, m, indexOffset, perPartOffset, vertexDeclaration;
var vbMemorySize = 0, memorySize = 0;
var mesh = render.mesh;
if (renderMode === 4) {
if (mesh) {
vertexDeclaration = VertexShurikenParticleMesh.vertexDeclaration;
this._floatCountPerVertex = vertexDeclaration.vertexStride / 4;
this._startLifeTimeIndex = 12;
this._timeIndex = 16;
this._vertexStride = mesh._vertexCount;
var totalVertexCount = this._bufferMaxParticles * this._vertexStride;
var vbCount = Math.floor(totalVertexCount / 65535) + 1;
var lastVBVertexCount = totalVertexCount % 65535;
if (vbCount > 1) {
throw new Error("ShurikenParticleSystem:the maxParticleCount multiply mesh vertexCount is large than 65535.");
}
vbMemorySize = vertexDeclaration.vertexStride * lastVBVertexCount;
this._vertexBuffer = new VertexBuffer3D(vbMemorySize, gl.DYNAMIC_DRAW);
this._vertexBuffer.vertexDeclaration = vertexDeclaration;
this._vertices = new Float32Array(this._floatCountPerVertex * lastVBVertexCount);
this._indexStride = mesh._indexBuffer.indexCount;
var indexDatas = mesh._indexBuffer.getData();
var indexCount = this._bufferMaxParticles * this._indexStride;
this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, indexCount, gl.STATIC_DRAW);
indices = new Uint16Array(indexCount);
memorySize = vbMemorySize + indexCount * 2;
indexOffset = 0;
for (i = 0; i < this._bufferMaxParticles; i++) {
var indexValueOffset = i * this._vertexStride;
for (j = 0, m = indexDatas.length; j < m; j++)
indices[indexOffset++] = indexValueOffset + indexDatas[j];
}
this._indexBuffer.setData(indices);
this._bufferState.bind();
this._bufferState.applyVertexBuffer(this._vertexBuffer);
this._bufferState.applyIndexBuffer(this._indexBuffer);
this._bufferState.unBind();
}
}
else {
vertexDeclaration = VertexShurikenParticleBillboard.vertexDeclaration;
this._floatCountPerVertex = vertexDeclaration.vertexStride / 4;
this._startLifeTimeIndex = 7;
this._timeIndex = 11;
this._vertexStride = 4;
vbMemorySize = vertexDeclaration.vertexStride * this._bufferMaxParticles * this._vertexStride;
this._vertexBuffer = new VertexBuffer3D(vbMemorySize, gl.DYNAMIC_DRAW);
this._vertexBuffer.vertexDeclaration = vertexDeclaration;
this._vertices = new Float32Array(this._floatCountPerVertex * this._bufferMaxParticles * this._vertexStride);
for (i = 0; i < this._bufferMaxParticles; i++) {
perPartOffset = i * this._floatCountPerVertex * this._vertexStride;
this._vertices[perPartOffset] = -0.5;
this._vertices[perPartOffset + 1] = -0.5;
this._vertices[perPartOffset + 2] = 0;
this._vertices[perPartOffset + 3] = 1;
perPartOffset += this._floatCountPerVertex;
this._vertices[perPartOffset] = 0.5;
this._vertices[perPartOffset + 1] = -0.5;
this._vertices[perPartOffset + 2] = 1;
this._vertices[perPartOffset + 3] = 1;
perPartOffset += this._floatCountPerVertex;
this._vertices[perPartOffset] = 0.5;
this._vertices[perPartOffset + 1] = 0.5;
this._vertices[perPartOffset + 2] = 1;
this._vertices[perPartOffset + 3] = 0;
perPartOffset += this._floatCountPerVertex;
this._vertices[perPartOffset] = -0.5;
this._vertices[perPartOffset + 1] = 0.5;
this._vertices[perPartOffset + 2] = 0;
this._vertices[perPartOffset + 3] = 0;
}
this._indexStride = 6;
this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, this._bufferMaxParticles * 6, gl.STATIC_DRAW);
indices = new Uint16Array(this._bufferMaxParticles * 6);
for (i = 0; i < this._bufferMaxParticles; i++) {
indexOffset = i * 6;
var firstVertex = i * this._vertexStride, secondVertex = firstVertex + 2;
indices[indexOffset++] = firstVertex;
indices[indexOffset++] = secondVertex;
indices[indexOffset++] = firstVertex + 1;
indices[indexOffset++] = firstVertex;
indices[indexOffset++] = firstVertex + 3;
indices[indexOffset++] = secondVertex;
}
this._indexBuffer.setData(indices);
memorySize = vbMemorySize + this._bufferMaxParticles * 6 * 2;
this._bufferState.bind();
this._bufferState.applyVertexBuffer(this._vertexBuffer);
this._bufferState.applyIndexBuffer(this._indexBuffer);
this._bufferState.unBind();
}
Laya.Resource._addMemory(memorySize, memorySize);
}
}
destroy() {
super.destroy();
if (this._vertexBuffer) {
var memorySize = this._vertexBuffer._byteLength;
Laya.Resource._addMemory(-memorySize, -memorySize);
this._vertexBuffer.destroy();
this._vertexBuffer = null;
}
if (this._indexBuffer) {
var memorySize = this._indexBuffer._byteLength;
Laya.Resource._addMemory(-memorySize, -memorySize);
this._indexBuffer.destroy();
this._indexBuffer = null;
}
this._bufferState.destroy();
this._emission.destroy();
this._boundingBox = null;
this._boundingSphere = null;
this._boundingBoxCorners = null;
this._bounds = null;
this._customBounds = null;
this._bufferState = null;
this._owner = null;
this._vertices = null;
this._indexBuffer = null;
this._emission = null;
this._shape = null;
this.startLifeTimeGradient = null;
this.startLifeTimeGradientMin = null;
this.startLifeTimeGradientMax = null;
this.startSizeConstantSeparate = null;
this.startSizeConstantMinSeparate = null;
this.startSizeConstantMaxSeparate = null;
this.startRotationConstantSeparate = null;
this.startRotationConstantMinSeparate = null;
this.startRotationConstantMaxSeparate = null;
this.startColorConstant = null;
this.startColorConstantMin = null;
this.startColorConstantMax = null;
this._velocityOverLifetime = null;
this._colorOverLifetime = null;
this._sizeOverLifetime = null;
this._rotationOverLifetime = null;
this._textureSheetAnimation = null;
}
emit(time) {
var position = ShurikenParticleSystem._tempPosition;
var direction = ShurikenParticleSystem._tempDirection;
if (this._shape && this._shape.enable) {
if (this.autoRandomSeed)
this._shape.generatePositionAndDirection(position, direction);
else
this._shape.generatePositionAndDirection(position, direction, this._rand, this._randomSeeds);
}
else {
position.x = position.y = position.z = 0;
direction.x = direction.y = 0;
direction.z = 1;
}
return this.addParticle(position, direction, time);
}
addParticle(position, direction, time) {
Vector3.normalize(direction, direction);
var nextFreeParticle = this._firstFreeElement + 1;
if (nextFreeParticle >= this._bufferMaxParticles)
nextFreeParticle = 0;
if (nextFreeParticle === this._firstRetiredElement)
return false;
var transform = this._owner.transform;
ShurikenParticleData.create(this, this._ownerRender);
var particleAge = this._currentTime - time;
if (particleAge >= ShurikenParticleData.startLifeTime)
return true;
var pos, rot;
if (this.simulationSpace == 0) {
pos = transform.position;
rot = transform.rotation;
}
var startSpeed;
switch (this.startSpeedType) {
case 0:
startSpeed = this.startSpeedConstant;
break;
case 2:
if (this.autoRandomSeed) {
startSpeed = Laya.MathUtil.lerp(this.startSpeedConstantMin, this.startSpeedConstantMax, Math.random());
}
else {
this._rand.seed = this._randomSeeds[8];
startSpeed = Laya.MathUtil.lerp(this.startSpeedConstantMin, this.startSpeedConstantMax, this._rand.getFloat());
this._randomSeeds[8] = this._rand.seed;
}
break;
}
var randomVelocityX, randomVelocityY, randomVelocityZ, randomColor, randomSize, randomRotation, randomTextureAnimation;
var needRandomVelocity = this._velocityOverLifetime && this._velocityOverLifetime.enable;
if (needRandomVelocity) {
var velocityType = this._velocityOverLifetime.velocity.type;
if (velocityType === 2 || velocityType === 3) {
if (this.autoRandomSeed) {
randomVelocityX = Math.random();
randomVelocityY = Math.random();
randomVelocityZ = Math.random();
}
else {
this._rand.seed = this._randomSeeds[9];
randomVelocityX = this._rand.getFloat();
randomVelocityY = this._rand.getFloat();
randomVelocityZ = this._rand.getFloat();
this._randomSeeds[9] = this._rand.seed;
}
}
else {
needRandomVelocity = false;
}
}
else {
needRandomVelocity = false;
}
var needRandomColor = this._colorOverLifetime && this._colorOverLifetime.enable;
if (needRandomColor) {
var colorType = this._colorOverLifetime.color.type;
if (colorType === 3) {
if (this.autoRandomSeed) {
randomColor = Math.random();
}
else {
this._rand.seed = this._randomSeeds[10];
randomColor = this._rand.getFloat();
this._randomSeeds[10] = this._rand.seed;
}
}
else {
needRandomColor = false;
}
}
else {
needRandomColor = false;
}
var needRandomSize = this._sizeOverLifetime && this._sizeOverLifetime.enable;
if (needRandomSize) {
var sizeType = this._sizeOverLifetime.size.type;
if (sizeType === 3) {
if (this.autoRandomSeed) {
randomSize = Math.random();
}
else {
this._rand.seed = this._randomSeeds[11];
randomSize = this._rand.getFloat();
this._randomSeeds[11] = this._rand.seed;
}
}
else {
needRandomSize = false;
}
}
else {
needRandomSize = false;
}
var needRandomRotation = this._rotationOverLifetime && this._rotationOverLifetime.enable;
if (needRandomRotation) {
var rotationType = this._rotationOverLifetime.angularVelocity.type;
if (rotationType === 2 || rotationType === 3) {
if (this.autoRandomSeed) {
randomRotation = Math.random();
}
else {
this._rand.seed = this._randomSeeds[12];
randomRotation = this._rand.getFloat();
this._randomSeeds[12] = this._rand.seed;
}
}
else {
needRandomRotation = false;
}
}
else {
needRandomRotation = false;
}
var needRandomTextureAnimation = this._textureSheetAnimation && this._textureSheetAnimation.enable;
if (needRandomTextureAnimation) {
var textureAnimationType = this._textureSheetAnimation.frame.type;
if (textureAnimationType === 3) {
if (this.autoRandomSeed) {
randomTextureAnimation = Math.random();
}
else {
this._rand.seed = this._randomSeeds[15];
randomTextureAnimation = this._rand.getFloat();
this._randomSeeds[15] = this._rand.seed;
}
}
else {
needRandomTextureAnimation = false;
}
}
else {
needRandomTextureAnimation = false;
}
var startIndex = this._firstFreeElement * this._floatCountPerVertex * this._vertexStride;
var subU = ShurikenParticleData.startUVInfo[0];
var subV = ShurikenParticleData.startUVInfo[1];
var startU = ShurikenParticleData.startUVInfo[2];
var startV = ShurikenParticleData.startUVInfo[3];
var meshVertices, meshVertexStride, meshPosOffset, meshCorOffset, meshUVOffset, meshVertexIndex;
var render = this._ownerRender;
if (render.renderMode === 4) {
var meshVB = render.mesh._vertexBuffer;
meshVertices = meshVB.getFloat32Data();
var meshVertexDeclaration = meshVB.vertexDeclaration;
meshPosOffset = meshVertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_POSITION0)._offset / 4;
var colorElement = meshVertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_COLOR0);
meshCorOffset = colorElement ? colorElement._offset / 4 : -1;
var uvElement = meshVertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE0);
meshUVOffset = uvElement ? uvElement._offset / 4 : -1;
meshVertexStride = meshVertexDeclaration.vertexStride / 4;
meshVertexIndex = 0;
}
else {
this._vertices[startIndex + 2] = startU;
this._vertices[startIndex + 3] = startV + subV;
var secondOffset = startIndex + this._floatCountPerVertex;
this._vertices[secondOffset + 2] = startU + subU;
this._vertices[secondOffset + 3] = startV + subV;
var thirdOffset = secondOffset + this._floatCountPerVertex;
this._vertices[thirdOffset + 2] = startU + subU;
this._vertices[thirdOffset + 3] = startV;
var fourthOffset = thirdOffset + this._floatCountPerVertex;
this._vertices[fourthOffset + 2] = startU;
this._vertices[fourthOffset + 3] = startV;
}
for (var i = startIndex, n = startIndex + this._floatCountPerVertex * this._vertexStride; i < n; i += this._floatCountPerVertex) {
var offset;
if (render.renderMode === 4) {
offset = i;
var vertexOffset = meshVertexStride * (meshVertexIndex++);
var meshOffset = vertexOffset + meshPosOffset;
this._vertices[offset++] = meshVertices[meshOffset++];
this._vertices[offset++] = meshVertices[meshOffset++];
this._vertices[offset++] = meshVertices[meshOffset];
if (meshCorOffset === -1) {
this._vertices[offset++] = 1.0;
this._vertices[offset++] = 1.0;
this._vertices[offset++] = 1.0;
this._vertices[offset++] = 1.0;
}
else {
meshOffset = vertexOffset + meshCorOffset;
this._vertices[offset++] = meshVertices[meshOffset++];
this._vertices[offset++] = meshVertices[meshOffset++];
this._vertices[offset++] = meshVertices[meshOffset++];
this._vertices[offset++] = meshVertices[meshOffset];
}
if (meshUVOffset === -1) {
this._vertices[offset++] = 0.0;
this._vertices[offset++] = 0.0;
}
else {
meshOffset = vertexOffset + meshUVOffset;
this._vertices[offset++] = startU + meshVertices[meshOffset++] * subU;
this._vertices[offset++] = startV + meshVertices[meshOffset] * subV;
}
}
else {
offset = i + 4;
}
this._vertices[offset++] = position.x;
this._vertices[offset++] = position.y;
this._vertices[offset++] = position.z;
this._vertices[offset++] = ShurikenParticleData.startLifeTime;
this._vertices[offset++] = direction.x;
this._vertices[offset++] = direction.y;
this._vertices[offset++] = direction.z;
this._vertices[offset++] = time;
this._vertices[offset++] = ShurikenParticleData.startColor.x;
this._vertices[offset++] = ShurikenParticleData.startColor.y;
this._vertices[offset++] = ShurikenParticleData.startColor.z;
this._vertices[offset++] = ShurikenParticleData.startColor.w;
this._vertices[offset++] = ShurikenParticleData.startSize[0];
this._vertices[offset++] = ShurikenParticleData.startSize[1];
this._vertices[offset++] = ShurikenParticleData.startSize[2];
this._vertices[offset++] = ShurikenParticleData.startRotation[0];
this._vertices[offset++] = ShurikenParticleData.startRotation[1];
this._vertices[offset++] = ShurikenParticleData.startRotation[2];
this._vertices[offset++] = startSpeed;
needRandomColor && (this._vertices[offset + 1] = randomColor);
needRandomSize && (this._vertices[offset + 2] = randomSize);
needRandomRotation && (this._vertices[offset + 3] = randomRotation);
needRandomTextureAnimation && (this._vertices[offset + 4] = randomTextureAnimation);
if (needRandomVelocity) {
this._vertices[offset + 5] = randomVelocityX;
this._vertices[offset + 6] = randomVelocityY;
this._vertices[offset + 7] = randomVelocityZ;
}
switch (this.simulationSpace) {
case 0:
offset += 8;
this._vertices[offset++] = pos.x;
this._vertices[offset++] = pos.y;
this._vertices[offset++] = pos.z;
this._vertices[offset++] = rot.x;
this._vertices[offset++] = rot.y;
this._vertices[offset++] = rot.z;
this._vertices[offset++] = rot.w;
break;
case 1:
break;
default:
throw new Error("ShurikenParticleMaterial: SimulationSpace value is invalid.");
}
}
this._firstFreeElement = nextFreeParticle;
return true;
}
addNewParticlesToVertexBuffer() {
var start;
var byteStride = this._vertexStride * this._floatCountPerVertex * 4;
if (this._firstNewElement < this._firstFreeElement) {
start = this._firstNewElement * byteStride;
this._vertexBuffer.setData(this._vertices.buffer, start, start, (this._firstFreeElement - this._firstNewElement) * byteStride);
}
else {
start = this._firstNewElement * byteStride;
this._vertexBuffer.setData(this._vertices.buffer, start, start, (this._bufferMaxParticles - this._firstNewElement) * byteStride);
if (this._firstFreeElement > 0) {
this._vertexBuffer.setData(this._vertices.buffer, 0, 0, this._firstFreeElement * byteStride);
}
}
this._firstNewElement = this._firstFreeElement;
}
_getType() {
return ShurikenParticleSystem._type;
}
_prepareRender(state) {
if (this._updateMask != Laya.Stat.loopCount) {
this._updateMask = Laya.Stat.loopCount;
this._updateEmission();
if (this._firstNewElement != this._firstFreeElement)
this.addNewParticlesToVertexBuffer();
this._drawCounter++;
}
if (this._firstActiveElement != this._firstFreeElement)
return true;
else
return false;
}
_render(state) {
this._bufferState.bind();
var indexCount;
var gl = Laya.LayaGL.instance;
if (this._firstActiveElement < this._firstFreeElement) {
indexCount = (this._firstFreeElement - this._firstActiveElement) * this._indexStride;
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 2 * this._firstActiveElement * this._indexStride);
Laya.Stat.trianglesFaces += indexCount / 3;
Laya.Stat.renderBatches++;
}
else {
indexCount = (this._bufferMaxParticles - this._firstActiveElement) * this._indexStride;
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 2 * this._firstActiveElement * this._indexStride);
Laya.Stat.trianglesFaces += indexCount / 3;
Laya.Stat.renderBatches++;
if (this._firstFreeElement > 0) {
indexCount = this._firstFreeElement * this._indexStride;
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0);
Laya.Stat.trianglesFaces += indexCount / 3;
Laya.Stat.renderBatches++;
}
}
}
play() {
this._burstsIndex = 0;
this._isEmitting = true;
this._isPlaying = true;
this._isPaused = false;
this._emissionTime = 0;
this._totalDelayTime = 0;
if (!this.autoRandomSeed) {
for (var i = 0, n = this._randomSeeds.length; i < n; i++)
this._randomSeeds[i] = this.randomSeed[0] + ShurikenParticleSystem._RANDOMOFFSET[i];
}
switch (this.startDelayType) {
case 0:
this._playStartDelay = this.startDelay;
break;
case 1:
if (this.autoRandomSeed) {
this._playStartDelay = Laya.MathUtil.lerp(this.startDelayMin, this.startDelayMax, Math.random());
}
else {
this._rand.seed = this._randomSeeds[2];
this._playStartDelay = Laya.MathUtil.lerp(this.startDelayMin, this.startDelayMax, this._rand.getFloat());
this._randomSeeds[2] = this._rand.seed;
}
break;
default:
throw new Error("Utils3D: startDelayType is invalid.");
}
this._frameRateTime = this._currentTime + this._playStartDelay;
this._startUpdateLoopCount = Laya.Stat.loopCount;
}
pause() {
this._isPaused = true;
}
simulate(time, restart = true) {
this._simulateUpdate = true;
if (restart) {
this._updateParticlesSimulationRestart(time);
}
else {
this._isPaused = false;
this._updateParticles(time);
}
this.pause();
}
stop() {
this._burstsIndex = 0;
this._isEmitting = false;
this._emissionTime = 0;
}
cloneTo(destObject) {
var dest = destObject;
dest._useCustomBounds = this._useCustomBounds;
(this._customBounds) && (this._customBounds.cloneTo(dest._customBounds));
dest.duration = this.duration;
dest.looping = this.looping;
dest.prewarm = this.prewarm;
dest.startDelayType = this.startDelayType;
dest.startDelay = this.startDelay;
dest.startDelayMin = this.startDelayMin;
dest.startDelayMax = this.startDelayMax;
dest._maxStartLifetime = this._maxStartLifetime;
dest.startLifetimeType = this.startLifetimeType;
dest.startLifetimeConstant = this.startLifetimeConstant;
this.startLifeTimeGradient.cloneTo(dest.startLifeTimeGradient);
dest.startLifetimeConstantMin = this.startLifetimeConstantMin;
dest.startLifetimeConstantMax = this.startLifetimeConstantMax;
this.startLifeTimeGradientMin.cloneTo(dest.startLifeTimeGradientMin);
this.startLifeTimeGradientMax.cloneTo(dest.startLifeTimeGradientMax);
dest.startSpeedType = this.startSpeedType;
dest.startSpeedConstant = this.startSpeedConstant;
dest.startSpeedConstantMin = this.startSpeedConstantMin;
dest.startSpeedConstantMax = this.startSpeedConstantMax;
dest.threeDStartSize = this.threeDStartSize;
dest.startSizeType = this.startSizeType;
dest.startSizeConstant = this.startSizeConstant;
this.startSizeConstantSeparate.cloneTo(dest.startSizeConstantSeparate);
dest.startSizeConstantMin = this.startSizeConstantMin;
dest.startSizeConstantMax = this.startSizeConstantMax;
this.startSizeConstantMinSeparate.cloneTo(dest.startSizeConstantMinSeparate);
this.startSizeConstantMaxSeparate.cloneTo(dest.startSizeConstantMaxSeparate);
dest.threeDStartRotation = this.threeDStartRotation;
dest.startRotationType = this.startRotationType;
dest.startRotationConstant = this.startRotationConstant;
this.startRotationConstantSeparate.cloneTo(dest.startRotationConstantSeparate);
dest.startRotationConstantMin = this.startRotationConstantMin;
dest.startRotationConstantMax = this.startRotationConstantMax;
this.startRotationConstantMinSeparate.cloneTo(dest.startRotationConstantMinSeparate);
this.startRotationConstantMaxSeparate.cloneTo(dest.startRotationConstantMaxSeparate);
dest.randomizeRotationDirection = this.randomizeRotationDirection;
dest.startColorType = this.startColorType;
this.startColorConstant.cloneTo(dest.startColorConstant);
this.startColorConstantMin.cloneTo(dest.startColorConstantMin);
this.startColorConstantMax.cloneTo(dest.startColorConstantMax);
dest.gravityModifier = this.gravityModifier;
dest.simulationSpace = this.simulationSpace;
dest.scaleMode = this.scaleMode;
dest.playOnAwake = this.playOnAwake;
dest.autoRandomSeed = this.autoRandomSeed;
dest.randomSeed[0] = this.randomSeed[0];
dest.maxParticles = this.maxParticles;
(this._emission) && (dest._emission = this._emission.clone());
(this.shape) && (dest.shape = this.shape.clone());
(this.velocityOverLifetime) && (dest.velocityOverLifetime = this.velocityOverLifetime.clone());
(this.colorOverLifetime) && (dest.colorOverLifetime = this.colorOverLifetime.clone());
(this.sizeOverLifetime) && (dest.sizeOverLifetime = this.sizeOverLifetime.clone());
(this.rotationOverLifetime) && (dest.rotationOverLifetime = this.rotationOverLifetime.clone());
(this.textureSheetAnimation) && (dest.textureSheetAnimation = this.textureSheetAnimation.clone());
dest.isPerformanceMode = this.isPerformanceMode;
dest._isEmitting = this._isEmitting;
dest._isPlaying = this._isPlaying;
dest._isPaused = this._isPaused;
dest._playStartDelay = this._playStartDelay;
dest._frameRateTime = this._frameRateTime;
dest._emissionTime = this._emissionTime;
dest._totalDelayTime = this._totalDelayTime;
dest._burstsIndex = this._burstsIndex;
}
clone() {
var dest = new ShurikenParticleSystem(null);
this.cloneTo(dest);
return dest;
}
}
ShurikenParticleSystem._RANDOMOFFSET = new Uint32Array([0x23571a3e, 0xc34f56fe, 0x13371337, 0x12460f3b, 0x6aed452e, 0xdec4aea1, 0x96aa4de3, 0x8d2c8431, 0xf3857f6f, 0xe0fbd834, 0x13740583, 0x591bc05c, 0x40eb95e4, 0xbc524e5f, 0xaf502044, 0xa614b381, 0x1034e524, 0xfc524e5f]);
ShurikenParticleSystem.halfKSqrtOf2 = 1.42 * 0.5;
ShurikenParticleSystem.g = 9.8;
ShurikenParticleSystem._maxElapsedTime = 1.0 / 3.0;
ShurikenParticleSystem._tempVector30 = new Vector3();
ShurikenParticleSystem._tempVector31 = new Vector3();
ShurikenParticleSystem._tempVector32 = new Vector3();
ShurikenParticleSystem._tempVector33 = new Vector3();
ShurikenParticleSystem._tempVector34 = new Vector3();
ShurikenParticleSystem._tempVector35 = new Vector3();
ShurikenParticleSystem._tempVector36 = new Vector3();
ShurikenParticleSystem._tempVector37 = new Vector3();
ShurikenParticleSystem._tempPosition = new Vector3();
ShurikenParticleSystem._tempDirection = new Vector3();
ShurikenParticleSystem._type = GeometryElement._typeCounter++;
class ShuriKenParticle3D extends RenderableSprite3D {
constructor() {
super(null);
this._render = new ShurikenParticleRenderer(this);
this._particleSystem = new ShurikenParticleSystem(this);
var elements = this._render._renderElements;
var element = elements[0] = new RenderElement();
element.setTransform(this._transform);
element.render = this._render;
element.setGeometry(this._particleSystem);
element.material = ShurikenParticleMaterial.defaultMaterial;
}
static __init__() {
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_BILLBOARD = Shader3D.getDefineByName("SPHERHBILLBOARD");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_STRETCHEDBILLBOARD = Shader3D.getDefineByName("STRETCHEDBILLBOARD");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_HORIZONTALBILLBOARD = Shader3D.getDefineByName("HORIZONTALBILLBOARD");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_VERTICALBILLBOARD = Shader3D.getDefineByName("VERTICALBILLBOARD");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_COLOROVERLIFETIME = Shader3D.getDefineByName("COLOROVERLIFETIME");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RANDOMCOLOROVERLIFETIME = Shader3D.getDefineByName("RANDOMCOLOROVERLIFETIME");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECONSTANT = Shader3D.getDefineByName("VELOCITYOVERLIFETIMECONSTANT");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECURVE = Shader3D.getDefineByName("VELOCITYOVERLIFETIMECURVE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCONSTANT = Shader3D.getDefineByName("VELOCITYOVERLIFETIMERANDOMCONSTANT");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCURVE = Shader3D.getDefineByName("VELOCITYOVERLIFETIMERANDOMCURVE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONCURVE = Shader3D.getDefineByName("TEXTURESHEETANIMATIONCURVE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONRANDOMCURVE = Shader3D.getDefineByName("TEXTURESHEETANIMATIONRANDOMCURVE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIME = Shader3D.getDefineByName("ROTATIONOVERLIFETIME");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMESEPERATE = Shader3D.getDefineByName("ROTATIONOVERLIFETIMESEPERATE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECONSTANT = Shader3D.getDefineByName("ROTATIONOVERLIFETIMECONSTANT");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECURVE = Shader3D.getDefineByName("ROTATIONOVERLIFETIMECURVE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCONSTANTS = Shader3D.getDefineByName("ROTATIONOVERLIFETIMERANDOMCONSTANTS");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCURVES = Shader3D.getDefineByName("ROTATIONOVERLIFETIMERANDOMCURVES");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVE = Shader3D.getDefineByName("SIZEOVERLIFETIMECURVE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVESEPERATE = Shader3D.getDefineByName("SIZEOVERLIFETIMECURVESEPERATE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVES = Shader3D.getDefineByName("SIZEOVERLIFETIMERANDOMCURVES");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVESSEPERATE = Shader3D.getDefineByName("SIZEOVERLIFETIMERANDOMCURVESSEPERATE");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_MESH = Shader3D.getDefineByName("RENDERMODE_MESH");
ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SHAPE = Shader3D.getDefineByName("SHAPE");
}
get particleSystem() {
return this._particleSystem;
}
get particleRenderer() {
return this._render;
}
_parseModule(module, moduleData) {
for (var t in moduleData) {
switch (t) {
case "bases":
var bases = moduleData.bases;
for (var k in bases)
module[k] = bases[k];
break;
case "vector2s":
var vector2s = moduleData.vector2s;
for (var k in vector2s) {
var vec2 = module[k];
var vec2Data = vector2s[k];
vec2.setValue(vec2Data[0], vec2Data[1]);
module[k] = vec2;
}
break;
case "vector3s":
var vector3s = moduleData.vector3s;
for (var k in vector3s) {
var vec3 = module[k];
var vec3Data = vector3s[k];
vec3.setValue(vec3Data[0], vec3Data[1], vec3Data[2]);
module[k] = vec3;
}
break;
case "vector4s":
var vector4s = moduleData.vector4s;
for (var k in vector4s) {
var vec4 = module[k];
var vec4Data = vector4s[k];
vec4.setValue(vec4Data[0], vec4Data[1], vec4Data[2], vec4Data[3]);
module[k] = vec4;
}
break;
case "gradientDataNumbers":
var gradientDataNumbers = moduleData.gradientDataNumbers;
for (var k in gradientDataNumbers) {
var gradientNumber = module[k];
var gradientNumberData = moduleData[k];
for (var i = 0, n = gradientNumberData.length; i < n; i++) {
var valueData = gradientNumberData[i];
gradientNumber.add(valueData.key, valueData.value);
}
module[k] = gradientNumber;
}
break;
case "resources":
var resources = moduleData.resources;
for (var k in resources)
module[k] = Laya.Loader.getRes(resources[k]);
break;
case "bursts":
var burstsData = moduleData.bursts;
for (var i = 0, n = burstsData.length; i < n; i++) {
var brust = burstsData[i];
module.addBurst(new Burst(brust.time, brust.min, brust.max));
}
break;
case "randomSeed":
module.randomSeed[0] = moduleData.randomSeed;
break;
case "shapeType":
case "type":
case "color":
case "size":
case "frame":
case "startFrame":
case "angularVelocity":
case "velocity":
break;
default:
throw "ShurikenParticle3D:unknown type.";
}
}
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
if (data.main) {
var particleSystem = this.particleSystem;
var particleRender = this.particleRenderer;
this._parseModule(particleRender, data.renderer);
this._parseModule(particleSystem, data.main);
this._parseModule(particleSystem.emission, data.emission);
var shapeData = data.shape;
if (shapeData) {
var shape;
switch (shapeData.shapeType) {
case 0:
shape = new SphereShape();
break;
case 1:
shape = new HemisphereShape();
break;
case 2:
shape = new ConeShape();
break;
case 3:
shape = new BoxShape();
break;
case 7:
shape = new CircleShape();
break;
default:
throw "ShuriKenParticle3D:unknown shape type.";
}
this._parseModule(shape, shapeData);
particleSystem.shape = shape;
}
var velocityOverLifetimeData = data.velocityOverLifetime;
if (velocityOverLifetimeData) {
var velocityData = velocityOverLifetimeData.velocity;
var velocity;
switch (velocityData.type) {
case 0:
var constantData = velocityData.constant;
velocity = GradientVelocity.createByConstant(constantData ? new Vector3(constantData[0], constantData[1], constantData[2]) : new Vector3(0, 0, 0));
break;
case 1:
velocity = GradientVelocity.createByGradient(this._initParticleVelocity(velocityData.gradientX), this._initParticleVelocity(velocityData.gradientY), this._initParticleVelocity(velocityData.gradientZ));
break;
case 2:
var constantMinData = velocityData.constantMin;
var constantMaxData = velocityData.constantMax;
velocity = GradientVelocity.createByRandomTwoConstant(constantMinData ? new Vector3(constantMinData[0], constantMinData[1], constantMinData[2]) : new Vector3(0, 0, 0), constantMaxData ? new Vector3(constantMaxData[0], constantMaxData[1], constantMaxData[2]) : new Vector3(0, 0, 0));
break;
case 3:
velocity = GradientVelocity.createByRandomTwoGradient(this._initParticleVelocity(velocityData.gradientXMin), this._initParticleVelocity(velocityData.gradientXMax), this._initParticleVelocity(velocityData.gradientYMin), this._initParticleVelocity(velocityData.gradientYMax), this._initParticleVelocity(velocityData.gradientZMin), this._initParticleVelocity(velocityData.gradientZMax));
break;
}
var velocityOverLifetime = new VelocityOverLifetime(velocity);
this._parseModule(velocityOverLifetime, velocityOverLifetimeData);
particleSystem.velocityOverLifetime = velocityOverLifetime;
}
var colorOverLifetimeData = data.colorOverLifetime;
if (colorOverLifetimeData) {
var colorData = colorOverLifetimeData.color;
var color;
switch (colorData.type) {
case 0:
var constColorData = colorData.constant;
color = GradientColor.createByConstant(constColorData ? new Vector4(constColorData[0], constColorData[1], constColorData[2], constColorData[3]) : new Vector4(0, 0, 0, 0));
break;
case 1:
color = GradientColor.createByGradient(this._initParticleColor(colorData.gradient));
break;
case 2:
var minConstColorData = colorData.constantMin;
var maxConstColorData = colorData.constantMax;
color = GradientColor.createByRandomTwoConstant(minConstColorData ? new Vector4(minConstColorData[0], minConstColorData[1], minConstColorData[2], minConstColorData[3]) : new Vector4(0, 0, 0, 0), minConstColorData ? new Vector4(maxConstColorData[0], maxConstColorData[1], maxConstColorData[2], maxConstColorData[3]) : new Vector4(0, 0, 0, 0));
break;
case 3:
color = GradientColor.createByRandomTwoGradient(this._initParticleColor(colorData.gradientMin), this._initParticleColor(colorData.gradientMax));
break;
}
var colorOverLifetime = new ColorOverLifetime(color);
this._parseModule(colorOverLifetime, colorOverLifetimeData);
particleSystem.colorOverLifetime = colorOverLifetime;
}
var sizeOverLifetimeData = data.sizeOverLifetime;
if (sizeOverLifetimeData) {
var sizeData = sizeOverLifetimeData.size;
var size;
switch (sizeData.type) {
case 0:
if (sizeData.separateAxes) {
size = GradientSize.createByGradientSeparate(this._initParticleSize(sizeData.gradientX), this._initParticleSize(sizeData.gradientY), this._initParticleSize(sizeData.gradientZ));
}
else {
size = GradientSize.createByGradient(this._initParticleSize(sizeData.gradient));
}
break;
case 1:
if (sizeData.separateAxes) {
var constantMinSeparateData = sizeData.constantMinSeparate;
var constantMaxSeparateData = sizeData.constantMaxSeparate;
size = GradientSize.createByRandomTwoConstantSeparate(constantMinSeparateData ? new Vector3(constantMinSeparateData[0], constantMinSeparateData[1], constantMinSeparateData[2]) : new Vector3(0, 0, 0), constantMaxSeparateData ? new Vector3(constantMaxSeparateData[0], constantMaxSeparateData[1], constantMaxSeparateData[2]) : new Vector3(0, 0, 0));
}
else {
size = GradientSize.createByRandomTwoConstant(sizeData.constantMin || 0, sizeData.constantMax || 0);
}
break;
case 2:
if (sizeData.separateAxes) {
size = GradientSize.createByRandomTwoGradientSeparate(this._initParticleSize(sizeData.gradientXMin), this._initParticleSize(sizeData.gradientYMin), this._initParticleSize(sizeData.gradientZMin), this._initParticleSize(sizeData.gradientXMax), this._initParticleSize(sizeData.gradientYMax), this._initParticleSize(sizeData.gradientZMax));
}
else {
size = GradientSize.createByRandomTwoGradient(this._initParticleSize(sizeData.gradientMin), this._initParticleSize(sizeData.gradientMax));
}
break;
}
var sizeOverLifetime = new SizeOverLifetime(size);
this._parseModule(sizeOverLifetime, sizeOverLifetimeData);
particleSystem.sizeOverLifetime = sizeOverLifetime;
}
var rotationOverLifetimeData = data.rotationOverLifetime;
if (rotationOverLifetimeData) {
var angularVelocityData = rotationOverLifetimeData.angularVelocity;
var angularVelocity;
switch (angularVelocityData.type) {
case 0:
if (angularVelocityData.separateAxes) {
var conSep = angularVelocityData.constantSeparate;
angularVelocity = GradientAngularVelocity.createByConstantSeparate(conSep ? new Vector3(conSep[0], conSep[1], conSep[2]) : new Vector3(0, 0, Math.PI / 4));
}
else {
angularVelocity = GradientAngularVelocity.createByConstant(angularVelocityData.constant || Math.PI / 4);
}
break;
case 1:
if (angularVelocityData.separateAxes) {
angularVelocity = GradientAngularVelocity.createByGradientSeparate(this._initParticleRotation(angularVelocityData.gradientX), this._initParticleRotation(angularVelocityData.gradientY), this._initParticleRotation(angularVelocityData.gradientZ));
}
else {
angularVelocity = GradientAngularVelocity.createByGradient(this._initParticleRotation(angularVelocityData.gradient));
}
break;
case 2:
if (angularVelocityData.separateAxes) {
var minSep = angularVelocityData.constantMinSeparate;
var maxSep = angularVelocityData.constantMaxSeparate;
angularVelocity = GradientAngularVelocity.createByRandomTwoConstantSeparate(minSep ? new Vector3(minSep[0], minSep[1], minSep[2]) : new Vector3(0, 0, 0), maxSep ? new Vector3(maxSep[0], maxSep[1], maxSep[2]) : new Vector3(0, 0, Math.PI / 4));
}
else {
angularVelocity = GradientAngularVelocity.createByRandomTwoConstant(angularVelocityData.constantMin || 0, angularVelocityData.constantMax || Math.PI / 4);
}
break;
case 3:
if (angularVelocityData.separateAxes) ;
else {
angularVelocity = GradientAngularVelocity.createByRandomTwoGradient(this._initParticleRotation(angularVelocityData.gradientMin), this._initParticleRotation(angularVelocityData.gradientMax));
}
break;
}
var rotationOverLifetime = new RotationOverLifetime(angularVelocity);
this._parseModule(rotationOverLifetime, rotationOverLifetimeData);
particleSystem.rotationOverLifetime = rotationOverLifetime;
}
var textureSheetAnimationData = data.textureSheetAnimation;
if (textureSheetAnimationData) {
var frameData = textureSheetAnimationData.frame;
var frameOverTime;
switch (frameData.type) {
case 0:
frameOverTime = FrameOverTime.createByConstant(frameData.constant);
break;
case 1:
frameOverTime = FrameOverTime.createByOverTime(this._initParticleFrame(frameData.overTime));
break;
case 2:
frameOverTime = FrameOverTime.createByRandomTwoConstant(frameData.constantMin, frameData.constantMax);
break;
case 3:
frameOverTime = FrameOverTime.createByRandomTwoOverTime(this._initParticleFrame(frameData.overTimeMin), this._initParticleFrame(frameData.overTimeMax));
break;
}
var startFrameData = textureSheetAnimationData.startFrame;
var startFrame;
switch (startFrameData.type) {
case 0:
startFrame = StartFrame.createByConstant(startFrameData.constant);
break;
case 1:
startFrame = StartFrame.createByRandomTwoConstant(startFrameData.constantMin, startFrameData.constantMax);
break;
}
var textureSheetAnimation = new TextureSheetAnimation(frameOverTime, startFrame);
this._parseModule(textureSheetAnimation, textureSheetAnimationData);
particleSystem.textureSheetAnimation = textureSheetAnimation;
}
}
else {
this._parseOld(data);
}
}
_activeHierarchy(activeChangeComponents) {
super._activeHierarchy(activeChangeComponents);
(this.particleSystem.playOnAwake) && (this.particleSystem.play());
}
_inActiveHierarchy(activeChangeComponents) {
super._inActiveHierarchy(activeChangeComponents);
(this.particleSystem.isAlive) && (this.particleSystem.simulate(0, true));
}
_cloneTo(destObject, srcSprite, dstSprite) {
var destShuriKenParticle3D = destObject;
var destParticleSystem = destShuriKenParticle3D._particleSystem;
this._particleSystem.cloneTo(destParticleSystem);
var destParticleRender = destShuriKenParticle3D._render;
var particleRender = this._render;
destParticleRender.sharedMaterials = particleRender.sharedMaterials;
destParticleRender.enable = particleRender.enable;
destParticleRender.renderMode = particleRender.renderMode;
destParticleRender.mesh = particleRender.mesh;
destParticleRender.stretchedBillboardCameraSpeedScale = particleRender.stretchedBillboardCameraSpeedScale;
destParticleRender.stretchedBillboardSpeedScale = particleRender.stretchedBillboardSpeedScale;
destParticleRender.stretchedBillboardLengthScale = particleRender.stretchedBillboardLengthScale;
destParticleRender.sortingFudge = particleRender.sortingFudge;
super._cloneTo(destObject, srcSprite, dstSprite);
}
destroy(destroyChild = true) {
if (this.destroyed)
return;
super.destroy(destroyChild);
this._particleSystem.destroy();
this._particleSystem = null;
}
_create() {
return new ShuriKenParticle3D();
}
_parseOld(data) {
const anglelToRad = Math.PI / 180.0;
var i, n;
var particleRender = this.particleRenderer;
var material;
var materialData = data.material;
(materialData) && (material = Laya.Loader.getRes(materialData.path));
particleRender.sharedMaterial = material;
var meshPath = data.meshPath;
(meshPath) && (particleRender.mesh = Laya.Loader.getRes(meshPath));
particleRender.renderMode = data.renderMode;
particleRender.stretchedBillboardCameraSpeedScale = data.stretchedBillboardCameraSpeedScale;
particleRender.stretchedBillboardSpeedScale = data.stretchedBillboardSpeedScale;
particleRender.stretchedBillboardLengthScale = data.stretchedBillboardLengthScale;
particleRender.sortingFudge = data.sortingFudge ? data.sortingFudge : 0.0;
var particleSystem = this.particleSystem;
particleSystem.isPerformanceMode = data.isPerformanceMode;
particleSystem.duration = data.duration;
particleSystem.looping = data.looping;
particleSystem.prewarm = data.prewarm;
particleSystem.startDelayType = data.startDelayType;
particleSystem.startDelay = data.startDelay;
particleSystem.startDelayMin = data.startDelayMin;
particleSystem.startDelayMax = data.startDelayMax;
particleSystem.startLifetimeType = data.startLifetimeType;
particleSystem.startLifetimeConstant = data.startLifetimeConstant;
particleSystem.startLifeTimeGradient = ShuriKenParticle3D._initStartLife(data.startLifetimeGradient);
particleSystem.startLifetimeConstantMin = data.startLifetimeConstantMin;
particleSystem.startLifetimeConstantMax = data.startLifetimeConstantMax;
particleSystem.startLifeTimeGradientMin = ShuriKenParticle3D._initStartLife(data.startLifetimeGradientMin);
particleSystem.startLifeTimeGradientMax = ShuriKenParticle3D._initStartLife(data.startLifetimeGradientMax);
particleSystem.startSpeedType = data.startSpeedType;
particleSystem.startSpeedConstant = data.startSpeedConstant;
particleSystem.startSpeedConstantMin = data.startSpeedConstantMin;
particleSystem.startSpeedConstantMax = data.startSpeedConstantMax;
particleSystem.threeDStartSize = data.threeDStartSize;
particleSystem.startSizeType = data.startSizeType;
particleSystem.startSizeConstant = data.startSizeConstant;
var startSizeConstantSeparateArray = data.startSizeConstantSeparate;
var startSizeConstantSeparateElement = particleSystem.startSizeConstantSeparate;
startSizeConstantSeparateElement.x = startSizeConstantSeparateArray[0];
startSizeConstantSeparateElement.y = startSizeConstantSeparateArray[1];
startSizeConstantSeparateElement.z = startSizeConstantSeparateArray[2];
particleSystem.startSizeConstantMin = data.startSizeConstantMin;
particleSystem.startSizeConstantMax = data.startSizeConstantMax;
var startSizeConstantMinSeparateArray = data.startSizeConstantMinSeparate;
var startSizeConstantMinSeparateElement = particleSystem.startSizeConstantMinSeparate;
startSizeConstantMinSeparateElement.x = startSizeConstantMinSeparateArray[0];
startSizeConstantMinSeparateElement.y = startSizeConstantMinSeparateArray[1];
startSizeConstantMinSeparateElement.z = startSizeConstantMinSeparateArray[2];
var startSizeConstantMaxSeparateArray = data.startSizeConstantMaxSeparate;
var startSizeConstantMaxSeparateElement = particleSystem.startSizeConstantMaxSeparate;
startSizeConstantMaxSeparateElement.x = startSizeConstantMaxSeparateArray[0];
startSizeConstantMaxSeparateElement.y = startSizeConstantMaxSeparateArray[1];
startSizeConstantMaxSeparateElement.z = startSizeConstantMaxSeparateArray[2];
particleSystem.threeDStartRotation = data.threeDStartRotation;
particleSystem.startRotationType = data.startRotationType;
particleSystem.startRotationConstant = data.startRotationConstant * anglelToRad;
var startRotationConstantSeparateArray = data.startRotationConstantSeparate;
var startRotationConstantSeparateElement = particleSystem.startRotationConstantSeparate;
startRotationConstantSeparateElement.x = startRotationConstantSeparateArray[0] * anglelToRad;
startRotationConstantSeparateElement.y = startRotationConstantSeparateArray[1] * anglelToRad;
startRotationConstantSeparateElement.z = startRotationConstantSeparateArray[2] * anglelToRad;
particleSystem.startRotationConstantMin = data.startRotationConstantMin * anglelToRad;
particleSystem.startRotationConstantMax = data.startRotationConstantMax * anglelToRad;
var startRotationConstantMinSeparateArray = data.startRotationConstantMinSeparate;
var startRotationConstantMinSeparateElement = particleSystem.startRotationConstantMinSeparate;
startRotationConstantMinSeparateElement.x = startRotationConstantMinSeparateArray[0] * anglelToRad;
startRotationConstantMinSeparateElement.y = startRotationConstantMinSeparateArray[1] * anglelToRad;
startRotationConstantMinSeparateElement.z = startRotationConstantMinSeparateArray[2] * anglelToRad;
var startRotationConstantMaxSeparateArray = data.startRotationConstantMaxSeparate;
var startRotationConstantMaxSeparateElement = particleSystem.startRotationConstantMaxSeparate;
startRotationConstantMaxSeparateElement.x = startRotationConstantMaxSeparateArray[0] * anglelToRad;
startRotationConstantMaxSeparateElement.y = startRotationConstantMaxSeparateArray[1] * anglelToRad;
startRotationConstantMaxSeparateElement.z = startRotationConstantMaxSeparateArray[2] * anglelToRad;
particleSystem.randomizeRotationDirection = data.randomizeRotationDirection;
particleSystem.startColorType = data.startColorType;
var startColorConstantArray = data.startColorConstant;
var startColorConstantElement = particleSystem.startColorConstant;
startColorConstantElement.x = startColorConstantArray[0];
startColorConstantElement.y = startColorConstantArray[1];
startColorConstantElement.z = startColorConstantArray[2];
startColorConstantElement.w = startColorConstantArray[3];
var startColorConstantMinArray = data.startColorConstantMin;
var startColorConstantMinElement = particleSystem.startColorConstantMin;
startColorConstantMinElement.x = startColorConstantMinArray[0];
startColorConstantMinElement.y = startColorConstantMinArray[1];
startColorConstantMinElement.z = startColorConstantMinArray[2];
startColorConstantMinElement.w = startColorConstantMinArray[3];
var startColorConstantMaxArray = data.startColorConstantMax;
var startColorConstantMaxElement = particleSystem.startColorConstantMax;
startColorConstantMaxElement.x = startColorConstantMaxArray[0];
startColorConstantMaxElement.y = startColorConstantMaxArray[1];
startColorConstantMaxElement.z = startColorConstantMaxArray[2];
startColorConstantMaxElement.w = startColorConstantMaxArray[3];
particleSystem.gravityModifier = data.gravityModifier;
particleSystem.simulationSpace = data.simulationSpace;
(data.simulationSpeed !== undefined) && (particleSystem.simulationSpeed = data.simulationSpeed);
particleSystem.scaleMode = data.scaleMode;
particleSystem.playOnAwake = data.playOnAwake;
particleSystem.maxParticles = data.maxParticles;
var autoRandomSeed = data.autoRandomSeed;
(autoRandomSeed != null) && (particleSystem.autoRandomSeed = autoRandomSeed);
var randomSeed = data.randomSeed;
(randomSeed != null) && (particleSystem.randomSeed[0] = randomSeed);
var emissionData = data.emission;
var emission = particleSystem.emission;
if (emissionData) {
emission.emissionRate = emissionData.emissionRate;
var burstsData = emissionData.bursts;
if (burstsData)
for (i = 0, n = burstsData.length; i < n; i++) {
var brust = burstsData[i];
emission.addBurst(new Burst(brust.time, brust.min, brust.max));
}
emission.enable = emissionData.enable;
}
else {
emission.enable = false;
}
var shapeData = data.shape;
if (shapeData) {
var shape;
switch (shapeData.shapeType) {
case 0:
var sphereShape;
shape = sphereShape = new SphereShape();
sphereShape.radius = shapeData.sphereRadius;
sphereShape.emitFromShell = shapeData.sphereEmitFromShell;
sphereShape.randomDirection = shapeData.sphereRandomDirection;
break;
case 1:
var hemiSphereShape;
shape = hemiSphereShape = new HemisphereShape();
hemiSphereShape.radius = shapeData.hemiSphereRadius;
hemiSphereShape.emitFromShell = shapeData.hemiSphereEmitFromShell;
hemiSphereShape.randomDirection = shapeData.hemiSphereRandomDirection;
break;
case 2:
var coneShape;
shape = coneShape = new ConeShape();
coneShape.angle = shapeData.coneAngle * anglelToRad;
coneShape.radius = shapeData.coneRadius;
coneShape.length = shapeData.coneLength;
coneShape.emitType = shapeData.coneEmitType;
coneShape.randomDirection = shapeData.coneRandomDirection;
break;
case 3:
var boxShape;
shape = boxShape = new BoxShape();
boxShape.x = shapeData.boxX;
boxShape.y = shapeData.boxY;
boxShape.z = shapeData.boxZ;
boxShape.randomDirection = shapeData.boxRandomDirection;
break;
case 7:
var circleShape;
shape = circleShape = new CircleShape();
circleShape.radius = shapeData.circleRadius;
circleShape.arc = shapeData.circleArc * anglelToRad;
circleShape.emitFromEdge = shapeData.circleEmitFromEdge;
circleShape.randomDirection = shapeData.circleRandomDirection;
break;
default:
var tempShape;
shape = tempShape = new CircleShape();
tempShape.radius = shapeData.circleRadius;
tempShape.arc = shapeData.circleArc * anglelToRad;
tempShape.emitFromEdge = shapeData.circleEmitFromEdge;
tempShape.randomDirection = shapeData.circleRandomDirection;
break;
}
shape.enable = shapeData.enable;
particleSystem.shape = shape;
}
var velocityOverLifetimeData = data.velocityOverLifetime;
if (velocityOverLifetimeData) {
var velocityData = velocityOverLifetimeData.velocity;
var velocity;
switch (velocityData.type) {
case 0:
var constantData = velocityData.constant;
velocity = GradientVelocity.createByConstant(new Vector3(constantData[0], constantData[1], constantData[2]));
break;
case 1:
velocity = GradientVelocity.createByGradient(this._initParticleVelocity(velocityData.gradientX), this._initParticleVelocity(velocityData.gradientY), this._initParticleVelocity(velocityData.gradientZ));
break;
case 2:
var constantMinData = velocityData.constantMin;
var constantMaxData = velocityData.constantMax;
velocity = GradientVelocity.createByRandomTwoConstant(new Vector3(constantMinData[0], constantMinData[1], constantMinData[2]), new Vector3(constantMaxData[0], constantMaxData[1], constantMaxData[2]));
break;
case 3:
velocity = GradientVelocity.createByRandomTwoGradient(this._initParticleVelocity(velocityData.gradientXMin), this._initParticleVelocity(velocityData.gradientXMax), this._initParticleVelocity(velocityData.gradientYMin), this._initParticleVelocity(velocityData.gradientYMax), this._initParticleVelocity(velocityData.gradientZMin), this._initParticleVelocity(velocityData.gradientZMax));
break;
}
var velocityOverLifetime = new VelocityOverLifetime(velocity);
velocityOverLifetime.space = velocityOverLifetimeData.space;
velocityOverLifetime.enable = velocityOverLifetimeData.enable;
particleSystem.velocityOverLifetime = velocityOverLifetime;
}
var colorOverLifetimeData = data.colorOverLifetime;
if (colorOverLifetimeData) {
var colorData = colorOverLifetimeData.color;
var color;
switch (colorData.type) {
case 0:
var constColorData = colorData.constant;
color = GradientColor.createByConstant(new Vector4(constColorData[0], constColorData[1], constColorData[2], constColorData[3]));
break;
case 1:
color = GradientColor.createByGradient(this._initParticleColor(colorData.gradient));
break;
case 2:
var minConstColorData = colorData.constantMin;
var maxConstColorData = colorData.constantMax;
color = GradientColor.createByRandomTwoConstant(new Vector4(minConstColorData[0], minConstColorData[1], minConstColorData[2], minConstColorData[3]), new Vector4(maxConstColorData[0], maxConstColorData[1], maxConstColorData[2], maxConstColorData[3]));
break;
case 3:
color = GradientColor.createByRandomTwoGradient(this._initParticleColor(colorData.gradientMin), this._initParticleColor(colorData.gradientMax));
break;
}
var colorOverLifetime = new ColorOverLifetime(color);
colorOverLifetime.enable = colorOverLifetimeData.enable;
particleSystem.colorOverLifetime = colorOverLifetime;
}
var sizeOverLifetimeData = data.sizeOverLifetime;
if (sizeOverLifetimeData) {
var sizeData = sizeOverLifetimeData.size;
var size;
switch (sizeData.type) {
case 0:
if (sizeData.separateAxes) {
size = GradientSize.createByGradientSeparate(this._initParticleSize(sizeData.gradientX), this._initParticleSize(sizeData.gradientY), this._initParticleSize(sizeData.gradientZ));
}
else {
size = GradientSize.createByGradient(this._initParticleSize(sizeData.gradient));
}
break;
case 1:
if (sizeData.separateAxes) {
var constantMinSeparateData = sizeData.constantMinSeparate;
var constantMaxSeparateData = sizeData.constantMaxSeparate;
size = GradientSize.createByRandomTwoConstantSeparate(new Vector3(constantMinSeparateData[0], constantMinSeparateData[1], constantMinSeparateData[2]), new Vector3(constantMaxSeparateData[0], constantMaxSeparateData[1], constantMaxSeparateData[2]));
}
else {
size = GradientSize.createByRandomTwoConstant(sizeData.constantMin, sizeData.constantMax);
}
break;
case 2:
if (sizeData.separateAxes) {
size = GradientSize.createByRandomTwoGradientSeparate(this._initParticleSize(sizeData.gradientXMin), this._initParticleSize(sizeData.gradientYMin), this._initParticleSize(sizeData.gradientZMin), this._initParticleSize(sizeData.gradientXMax), this._initParticleSize(sizeData.gradientYMax), this._initParticleSize(sizeData.gradientZMax));
}
else {
size = GradientSize.createByRandomTwoGradient(this._initParticleSize(sizeData.gradientMin), this._initParticleSize(sizeData.gradientMax));
}
break;
}
var sizeOverLifetime = new SizeOverLifetime(size);
sizeOverLifetime.enable = sizeOverLifetimeData.enable;
particleSystem.sizeOverLifetime = sizeOverLifetime;
}
var rotationOverLifetimeData = data.rotationOverLifetime;
if (rotationOverLifetimeData) {
var angularVelocityData = rotationOverLifetimeData.angularVelocity;
var angularVelocity;
switch (angularVelocityData.type) {
case 0:
if (angularVelocityData.separateAxes) {
var conSep = angularVelocityData.constantSeparate;
angularVelocity = GradientAngularVelocity.createByConstantSeparate(new Vector3(conSep[0] * anglelToRad, conSep[1] * anglelToRad, conSep[2] * anglelToRad));
}
else {
angularVelocity = GradientAngularVelocity.createByConstant(angularVelocityData.constant * anglelToRad);
}
break;
case 1:
if (angularVelocityData.separateAxes) {
angularVelocity = GradientAngularVelocity.createByGradientSeparate(this._initParticleRotation(angularVelocityData.gradientX), this._initParticleRotation(angularVelocityData.gradientY), this._initParticleRotation(angularVelocityData.gradientZ));
}
else {
angularVelocity = GradientAngularVelocity.createByGradient(this._initParticleRotation(angularVelocityData.gradient));
}
break;
case 2:
if (angularVelocityData.separateAxes) {
var minSep = angularVelocityData.constantMinSeparate;
var maxSep = angularVelocityData.constantMaxSeparate;
angularVelocity = GradientAngularVelocity.createByRandomTwoConstantSeparate(new Vector3(minSep[0] * anglelToRad, minSep[1] * anglelToRad, minSep[2] * anglelToRad), new Vector3(maxSep[0] * anglelToRad, maxSep[1] * anglelToRad, maxSep[2] * anglelToRad));
}
else {
angularVelocity = GradientAngularVelocity.createByRandomTwoConstant(angularVelocityData.constantMin * anglelToRad, angularVelocityData.constantMax * anglelToRad);
}
break;
case 3:
if (angularVelocityData.separateAxes) ;
else {
angularVelocity = GradientAngularVelocity.createByRandomTwoGradient(this._initParticleRotation(angularVelocityData.gradientMin), this._initParticleRotation(angularVelocityData.gradientMax));
}
break;
}
var rotationOverLifetime = new RotationOverLifetime(angularVelocity);
rotationOverLifetime.enable = rotationOverLifetimeData.enable;
particleSystem.rotationOverLifetime = rotationOverLifetime;
}
var textureSheetAnimationData = data.textureSheetAnimation;
if (textureSheetAnimationData) {
var frameData = textureSheetAnimationData.frame;
var frameOverTime;
switch (frameData.type) {
case 0:
frameOverTime = FrameOverTime.createByConstant(frameData.constant);
break;
case 1:
frameOverTime = FrameOverTime.createByOverTime(this._initParticleFrame(frameData.overTime));
break;
case 2:
frameOverTime = FrameOverTime.createByRandomTwoConstant(frameData.constantMin, frameData.constantMax);
break;
case 3:
frameOverTime = FrameOverTime.createByRandomTwoOverTime(this._initParticleFrame(frameData.overTimeMin), this._initParticleFrame(frameData.overTimeMax));
break;
}
var startFrameData = textureSheetAnimationData.startFrame;
var startFrame;
switch (startFrameData.type) {
case 0:
startFrame = StartFrame.createByConstant(startFrameData.constant);
break;
case 1:
startFrame = StartFrame.createByRandomTwoConstant(startFrameData.constantMin, startFrameData.constantMax);
break;
}
var textureSheetAnimation = new TextureSheetAnimation(frameOverTime, startFrame);
textureSheetAnimation.enable = textureSheetAnimationData.enable;
var tilesData = textureSheetAnimationData.tiles;
textureSheetAnimation.tiles = new Vector2(tilesData[0], tilesData[1]);
textureSheetAnimation.type = textureSheetAnimationData.type;
textureSheetAnimation.randomRow = textureSheetAnimationData.randomRow;
var rowIndex = textureSheetAnimationData.rowIndex;
(rowIndex !== undefined) && (textureSheetAnimation.rowIndex = rowIndex);
textureSheetAnimation.cycles = textureSheetAnimationData.cycles;
particleSystem.textureSheetAnimation = textureSheetAnimation;
}
}
_initParticleColor(gradientColorData) {
var gradientColor = new Gradient(4, 4);
if (!gradientColorData) {
gradientColor.addColorAlpha(0, 1);
gradientColor.addColorAlpha(1, 1);
gradientColor.addColorRGB(0, new Color(1.0, 1.0, 1.0, 1.0));
gradientColor.addColorRGB(1, new Color(1.0, 1.0, 1.0, 1.0));
}
else {
var alphasData = gradientColorData.alphas;
var i, n;
if (!alphasData) {
gradientColor.addColorAlpha(0, 1);
gradientColor.addColorAlpha(1, 1);
}
else {
for (i = 0, n = alphasData.length; i < n; i++) {
if (i == 3 && n > 4) {
i = n - 1;
console.warn("GradientDataColor warning:alpha data length is large than 4, will ignore the middle data.");
}
var alphaData = alphasData[i];
gradientColor.addColorAlpha(alphaData.key, alphaData.value);
}
}
var rgbsData = gradientColorData.rgbs;
if (!rgbsData) {
gradientColor.addColorRGB(0, new Color(1.0, 1.0, 1.0, 1.0));
gradientColor.addColorRGB(1, new Color(1.0, 1.0, 1.0, 1.0));
}
else {
for (i = 0, n = rgbsData.length; i < n; i++) {
if (i == 3 && n > 4) {
i = n - 1;
console.warn("GradientDataColor warning:rgb data length is large than 4, will ignore the middle data.");
}
var rgbData = rgbsData[i];
var rgbValue = rgbData.value;
gradientColor.addColorRGB(rgbData.key, new Color(rgbValue[0], rgbValue[1], rgbValue[2], 1.0));
}
}
}
return gradientColor;
}
_initParticleFrame(overTimeFramesData) {
var overTimeFrame = new GradientDataInt();
if (overTimeFramesData) {
var framesData = overTimeFramesData.frames;
for (var i = 0, n = framesData.length; i < n; i++) {
var frameData = framesData[i];
overTimeFrame.add(frameData.key, frameData.value);
}
}
else {
overTimeFrame.add(0, 0);
overTimeFrame.add(1, 1);
}
return overTimeFrame;
}
static _initStartLife(gradientData) {
var gradient = new GradientDataNumber();
var startLifetimesData = gradientData.startLifetimes;
for (var i = 0, n = startLifetimesData.length; i < n; i++) {
var valueData = startLifetimesData[i];
gradient.add(valueData.key, valueData.value);
}
return gradient;
}
_initParticleVelocity(gradientData) {
var gradient = new GradientDataNumber();
var velocitysData = gradientData.velocitys;
for (var i = 0, n = velocitysData.length; i < n; i++) {
var valueData = velocitysData[i];
gradient.add(valueData.key, valueData.value);
}
return gradient;
}
_initParticleSize(gradientSizeData) {
var gradientSize = new GradientDataNumber();
if (gradientSizeData) {
var sizesData = gradientSizeData.sizes;
for (var i = 0, n = sizesData.length; i < n; i++) {
var valueData = sizesData[i];
gradientSize.add(valueData.key, valueData.value);
}
}
else {
gradientSize.add(0, 0);
gradientSize.add(1, 1);
}
return gradientSize;
}
_initParticleRotation(gradientData) {
var gradient = new GradientDataNumber();
var angularVelocitysData = gradientData.angularVelocitys;
for (var i = 0, n = angularVelocitysData.length; i < n; i++) {
var valueData = angularVelocitysData[i];
gradient.add(valueData.key, valueData.value / 180.0 * Math.PI);
}
return gradient;
}
}
class SkinnedMeshSprite3DShaderDeclaration {
}
class SkinnedMeshRenderer extends MeshRenderer {
constructor(owner) {
super(owner);
this._bones = [];
this._skinnedDataLoopMarks = [];
this._localBounds = new Bounds(Vector3._ZERO, Vector3._ZERO);
this._cacheAnimationNode = [];
}
get localBounds() {
return this._localBounds;
}
set localBounds(value) {
this._localBounds = value;
}
get rootBone() {
return this._cacheRootBone;
}
set rootBone(value) {
if (this._cacheRootBone != value) {
if (this._cacheRootBone)
this._cacheRootBone.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange);
else
this._owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange);
if (value)
value.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange);
else
this._owner.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange);
this._cacheRootBone = value;
this._onWorldMatNeedChange(Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDSCALE);
}
}
get bones() {
return this._bones;
}
_computeSkinnedData() {
if (this._cacheMesh && this._cacheAvatar || this._cacheMesh && !this._cacheAvatar) {
var bindPoses = this._cacheMesh._inverseBindPoses;
var pathMarks = this._cacheMesh._skinnedMatrixCaches;
for (var i = 0, n = this._cacheMesh.subMeshCount; i < n; i++) {
var subMeshBoneIndices = this._cacheMesh.getSubMesh(i)._boneIndicesList;
var subData = this._skinnedData[i];
for (var j = 0, m = subMeshBoneIndices.length; j < m; j++) {
var boneIndices = subMeshBoneIndices[j];
this._computeSubSkinnedData(bindPoses, boneIndices, subData[j], pathMarks);
}
}
}
}
_computeSubSkinnedData(bindPoses, boneIndices, data, matrixCaches) {
for (var k = 0, q = boneIndices.length; k < q; k++) {
var index = boneIndices[k];
if (this._skinnedDataLoopMarks[index] === Laya.Stat.loopCount) {
var c = matrixCaches[index];
var preData = this._skinnedData[c.subMeshIndex][c.batchIndex];
var srcIndex = c.batchBoneIndex * 16;
var dstIndex = k * 16;
for (var d = 0; d < 16; d++)
data[dstIndex + d] = preData[srcIndex + d];
}
else {
if (!this._cacheAvatar) {
Utils3D._mulMatrixArray(this._bones[index].transform.worldMatrix.elements, bindPoses[index].elements, 0, data, k * 16);
}
else {
Utils3D._mulMatrixArray(this._cacheAnimationNode[index].transform.getWorldMatrix(), bindPoses[index].elements, 0, data, k * 16);
}
this._skinnedDataLoopMarks[index] = Laya.Stat.loopCount;
}
}
}
_onWorldMatNeedChange(flag) {
this._boundsChange = true;
if (this._octreeNode) {
if (this._cacheAvatar) {
if (this._indexInOctreeMotionList === -1)
this._octreeNode._octree.addMotionObject(this);
}
else {
flag &= Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDSCALE;
if (flag) {
if (this._indexInOctreeMotionList === -1)
this._octreeNode._octree.addMotionObject(this);
}
}
}
}
_createRenderElement() {
return new RenderElement();
}
_onMeshChange(value) {
super._onMeshChange(value);
this._cacheMesh = value;
var subMeshCount = value.subMeshCount;
this._skinnedData = [];
this._skinnedDataLoopMarks.length = value._inverseBindPoses.length;
for (var i = 0; i < subMeshCount; i++) {
var subBoneIndices = value.getSubMesh(i)._boneIndicesList;
var subCount = subBoneIndices.length;
var subData = this._skinnedData[i] = [];
for (var j = 0; j < subCount; j++)
subData[j] = new Float32Array(subBoneIndices[j].length * 16);
}
(this._cacheAvatar && value) && (this._getCacheAnimationNodes());
}
_setCacheAnimator(animator) {
this._cacheAnimator = animator;
this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_BONE);
this._setRootNode();
}
_calculateBoundingBox() {
if (!this._cacheAvatar) {
if (this._cacheRootBone)
this._localBounds._tranform(this._cacheRootBone.transform.worldMatrix, this._bounds);
else
this._localBounds._tranform(this._owner.transform.worldMatrix, this._bounds);
}
else {
if (this._cacheAnimator && this._rootBone) {
var worldMat = SkinnedMeshRenderer._tempMatrix4x4;
Utils3D.matrix4x4MultiplyMFM(this._cacheAnimator.owner.transform.worldMatrix, this._cacheRootAnimationNode.transform.getWorldMatrix(), worldMat);
this._localBounds._tranform(worldMat, this._bounds);
}
else {
super._calculateBoundingBox();
}
}
}
_renderUpdate(context, transform) {
if (this._cacheAnimator) {
this._computeSkinnedData();
if (!this._cacheAvatar) {
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, Matrix4x4.DEFAULT);
}
else {
var aniOwnerTrans = this._cacheAnimator.owner._transform;
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, aniOwnerTrans.worldMatrix);
}
}
else {
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, transform.worldMatrix);
}
if (!this._probReflection)
return;
if (this._reflectionMode == exports.ReflectionProbeMode.off) {
this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION);
this._shaderValues.setVector(RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS, ReflectionProbe.defaultTextureHDRDecodeValues);
this._shaderValues.setTexture(RenderableSprite3D.REFLECTIONTEXTURE, TextureCube.blackTexture);
}
else {
if (!this._probReflection.boxProjection) {
this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION);
}
else {
this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION);
this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEPOSITION, this._probReflection.probePosition);
this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMAX, this._probReflection.boundsMax);
this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMIN, this._probReflection.boundsMin);
}
this._shaderValues.setTexture(RenderableSprite3D.REFLECTIONTEXTURE, this._probReflection.reflectionTexture);
this._shaderValues.setVector(RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS, this._probReflection.reflectionHDRParams);
}
}
_renderUpdateWithCamera(context, transform) {
var projectionView = context.projectionViewMatrix;
if (this._cacheAnimator) {
if (!this._cacheAvatar) {
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, projectionView);
}
else {
var aniOwnerTrans = this._cacheAnimator.owner._transform;
Matrix4x4.multiply(projectionView, aniOwnerTrans.worldMatrix, this._projectionViewWorldMatrix);
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix);
}
}
else {
Matrix4x4.multiply(projectionView, transform.worldMatrix, this._projectionViewWorldMatrix);
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix);
}
}
_destroy() {
super._destroy();
if (!this._cacheAvatar) {
if (this._cacheRootBone)
(!this._cacheRootBone.destroyed) && (this._cacheRootBone.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange));
else
(this._owner && !this._owner.destroyed) && (this._owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange));
}
else {
if (this._cacheRootAnimationNode)
this._cacheRootAnimationNode.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange);
}
}
get bounds() {
if (this._boundsChange || this._cacheAvatar) {
this._calculateBoundingBox();
this._boundsChange = false;
}
return this._bounds;
}
_setRootBone(name) {
this._rootBone = name;
this._setRootNode();
}
_setRootNode() {
var rootNode;
if (this._cacheAnimator && this._rootBone && this._cacheAvatar)
rootNode = this._cacheAnimator._avatarNodeMap[this._rootBone];
else
rootNode = null;
if (this._cacheRootAnimationNode != rootNode) {
this._onWorldMatNeedChange(Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDSCALE);
this._owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange);
if (this._cacheRootAnimationNode)
this._cacheRootAnimationNode.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange);
(rootNode) && (rootNode.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange));
this._cacheRootAnimationNode = rootNode;
}
}
_getCacheAnimationNodes() {
var meshBoneNames = this._cacheMesh._boneNames;
var innerBindPoseCount = this._cacheMesh._inverseBindPoses.length;
this._cacheAnimationNode.length = innerBindPoseCount;
var nodeMap = this._cacheAnimator._avatarNodeMap;
for (var i = 0; i < innerBindPoseCount; i++) {
var node = nodeMap[meshBoneNames[i]];
this._cacheAnimationNode[i] = node;
}
}
_setCacheAvatar(value) {
if (this._cacheAvatar !== value) {
if (this._cacheMesh) {
this._cacheAvatar = value;
if (value) {
this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_BONE);
this._getCacheAnimationNodes();
}
}
else {
this._cacheAvatar = value;
}
this._setRootNode();
}
}
}
SkinnedMeshRenderer._tempMatrix4x4 = new Matrix4x4();
class SkinnedMeshSprite3D extends RenderableSprite3D {
constructor(mesh = null, name = null) {
super(name);
this._meshFilter = new MeshFilter(this);
this._render = new SkinnedMeshRenderer(this);
(mesh) && (this._meshFilter.sharedMesh = mesh);
}
static __init__() {
SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_BONE = Shader3D.getDefineByName("BONE");
SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_SIMPLEBONE = Shader3D.getDefineByName("SIMPLEBONE");
}
get meshFilter() {
return this._meshFilter;
}
get skinnedMeshRenderer() {
return this._render;
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
var render = this.skinnedMeshRenderer;
var lightmapIndex = data.lightmapIndex;
(lightmapIndex != null) && (render.lightmapIndex = lightmapIndex);
var lightmapScaleOffsetArray = data.lightmapScaleOffset;
(lightmapScaleOffsetArray) && (render.lightmapScaleOffset = new Vector4(lightmapScaleOffsetArray[0], lightmapScaleOffsetArray[1], lightmapScaleOffsetArray[2], lightmapScaleOffsetArray[3]));
(data.enableRender != undefined) && (render.enable = data.enableRender);
(data.receiveShadows != undefined) && (render.receiveShadow = data.receiveShadows);
(data.castShadow != undefined) && (render.castShadow = data.castShadow);
var meshPath;
meshPath = data.meshPath;
if (meshPath) {
var mesh = Laya.Loader.getRes(meshPath);
(mesh) && (this.meshFilter.sharedMesh = mesh);
}
var materials = data.materials;
if (materials) {
var sharedMaterials = render.sharedMaterials;
var materialCount = materials.length;
sharedMaterials.length = materialCount;
for (var i = 0; i < materialCount; i++) {
sharedMaterials[i] = Laya.Loader.getRes(materials[i].path);
}
render.sharedMaterials = sharedMaterials;
}
var boundBox = data.boundBox;
var min = boundBox.min;
var max = boundBox.max;
render.localBounds.setMin(new Vector3(min[0], min[1], min[2]));
render.localBounds.setMax(new Vector3(max[0], max[1], max[2]));
if (spriteMap) {
var rootBoneData = data.rootBone;
render.rootBone = spriteMap[rootBoneData];
var bonesData = data.bones;
var n;
for (i = 0, n = bonesData.length; i < n; i++)
render.bones.push(spriteMap[bonesData[i]]);
}
else {
(data.rootBone) && (render._setRootBone(data.rootBone));
}
}
_changeHierarchyAnimator(animator) {
super._changeHierarchyAnimator(animator);
this.skinnedMeshRenderer._setCacheAnimator(animator);
}
_changeAnimatorAvatar(avatar) {
this.skinnedMeshRenderer._setCacheAvatar(avatar);
}
_cloneTo(destObject, srcRoot, dstRoot) {
var meshSprite3D = destObject;
meshSprite3D.meshFilter.sharedMesh = this.meshFilter.sharedMesh;
var meshRender = this._render;
var destMeshRender = meshSprite3D._render;
destMeshRender.enable = meshRender.enable;
destMeshRender.sharedMaterials = meshRender.sharedMaterials;
destMeshRender.castShadow = meshRender.castShadow;
var lightmapScaleOffset = meshRender.lightmapScaleOffset;
lightmapScaleOffset && (destMeshRender.lightmapScaleOffset = lightmapScaleOffset.clone());
destMeshRender.receiveShadow = meshRender.receiveShadow;
destMeshRender.sortingFudge = meshRender.sortingFudge;
destMeshRender._rootBone = meshRender._rootBone;
var bones = meshRender.bones;
var destBones = destMeshRender.bones;
var bonesCount = bones.length;
destBones.length = bonesCount;
var rootBone = meshRender.rootBone;
if (rootBone) {
var pathes = Utils3D._getHierarchyPath(srcRoot, rootBone, SkinnedMeshSprite3D._tempArray0);
if (pathes)
destMeshRender.rootBone = Utils3D._getNodeByHierarchyPath(dstRoot, pathes);
else
destMeshRender.rootBone = rootBone;
}
for (var i = 0; i < bones.length; i++) {
pathes = Utils3D._getHierarchyPath(srcRoot, bones[i], SkinnedMeshSprite3D._tempArray0);
if (pathes)
destBones[i] = Utils3D._getNodeByHierarchyPath(dstRoot, pathes);
else
destBones[i] = bones[i];
}
var lbb = meshRender.localBounds;
(lbb) && (lbb.cloneTo(destMeshRender.localBounds));
super._cloneTo(destObject, srcRoot, dstRoot);
}
destroy(destroyChild = true) {
if (this.destroyed)
return;
super.destroy(destroyChild);
this._meshFilter.destroy();
}
_create() {
return new SkinnedMeshSprite3D();
}
}
SkinnedMeshSprite3D._tempArray0 = [];
SkinnedMeshSprite3D.BONES = Shader3D.propertyNameToID("u_Bones");
SkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURE = Shader3D.propertyNameToID("u_SimpleAnimatorTexture");
SkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORPARAMS = Shader3D.propertyNameToID("u_SimpleAnimatorParams");
SkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURESIZE = Shader3D.propertyNameToID("u_SimpleAnimatorTextureSize");
class TrailMaterial extends Material {
constructor() {
super();
this.setShaderName("Trail");
this._color = new Vector4(1.0, 1.0, 1.0, 1.0);
this._shaderValues.setVector(TrailMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0));
this._shaderValues.setVector(TrailMaterial.TINTCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0));
this.renderMode = TrailMaterial.RENDERMODE_ALPHABLENDED;
}
static __initDefine__() {
TrailMaterial.SHADERDEFINE_MAINTEXTURE = Shader3D.getDefineByName("MAINTEXTURE");
TrailMaterial.SHADERDEFINE_ADDTIVEFOG = Shader3D.getDefineByName("ADDTIVEFOG");
}
get _TintColorR() {
return this._color.x;
}
set _TintColorR(value) {
this._color.x = value;
this.color = this._color;
}
get _TintColorG() {
return this._color.y;
}
set _TintColorG(value) {
this._color.y = value;
this.color = this._color;
}
get _TintColorB() {
return this._color.z;
}
set _TintColorB(value) {
this._color.z = value;
this.color = this._color;
}
get _TintColorA() {
return this._color.w;
}
set _TintColorA(value) {
this._color.w = value;
this.color = this._color;
}
get _MainTex_STX() {
return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).x;
}
set _MainTex_STX(x) {
var tilOff = this._shaderValues.getVector(TrailMaterial.TILINGOFFSET);
tilOff.x = x;
this.tilingOffset = tilOff;
}
get _MainTex_STY() {
return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).y;
}
set _MainTex_STY(y) {
var tilOff = this._shaderValues.getVector(TrailMaterial.TILINGOFFSET);
tilOff.y = y;
this.tilingOffset = tilOff;
}
get _MainTex_STZ() {
return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).z;
}
set _MainTex_STZ(z) {
var tilOff = this._shaderValues.getVector(TrailMaterial.TILINGOFFSET);
tilOff.z = z;
this.tilingOffset = tilOff;
}
get _MainTex_STW() {
return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).w;
}
set _MainTex_STW(w) {
var tilOff = this._shaderValues.getVector(TrailMaterial.TILINGOFFSET);
tilOff.w = w;
this.tilingOffset = tilOff;
}
set renderMode(value) {
switch (value) {
case TrailMaterial.RENDERMODE_ADDTIVE:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.alphaTest = false;
this.depthWrite = false;
this.cull = RenderState.CULL_NONE;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE;
this.depthTest = RenderState.DEPTHTEST_LESS;
this._shaderValues.addDefine(TrailMaterial.SHADERDEFINE_ADDTIVEFOG);
break;
case TrailMaterial.RENDERMODE_ALPHABLENDED:
this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
this.alphaTest = false;
this.depthWrite = false;
this.cull = RenderState.CULL_NONE;
this.blend = RenderState.BLEND_ENABLE_ALL;
this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
this.depthTest = RenderState.DEPTHTEST_LESS;
this._shaderValues.removeDefine(TrailMaterial.SHADERDEFINE_ADDTIVEFOG);
break;
default:
throw new Error("TrailMaterial : renderMode value error.");
}
}
get colorR() {
return this._TintColorR;
}
set colorR(value) {
this._TintColorR = value;
}
get colorG() {
return this._TintColorG;
}
set colorG(value) {
this._TintColorG = value;
}
get colorB() {
return this._TintColorB;
}
set colorB(value) {
this._TintColorB = value;
}
get colorA() {
return this._TintColorA;
}
set colorA(value) {
this._TintColorA = value;
}
get color() {
return this._shaderValues.getVector(TrailMaterial.TINTCOLOR);
}
set color(value) {
this._shaderValues.setVector(TrailMaterial.TINTCOLOR, value);
}
get texture() {
return this._shaderValues.getTexture(TrailMaterial.MAINTEXTURE);
}
set texture(value) {
if (value)
this._shaderValues.addDefine(TrailMaterial.SHADERDEFINE_MAINTEXTURE);
else
this._shaderValues.removeDefine(TrailMaterial.SHADERDEFINE_MAINTEXTURE);
this._shaderValues.setTexture(TrailMaterial.MAINTEXTURE, value);
}
get tilingOffsetX() {
return this._MainTex_STX;
}
set tilingOffsetX(x) {
this._MainTex_STX = x;
}
get tilingOffsetY() {
return this._MainTex_STY;
}
set tilingOffsetY(y) {
this._MainTex_STY = y;
}
get tilingOffsetZ() {
return this._MainTex_STZ;
}
set tilingOffsetZ(z) {
this._MainTex_STZ = z;
}
get tilingOffsetW() {
return this._MainTex_STW;
}
set tilingOffsetW(w) {
this._MainTex_STW = w;
}
get tilingOffset() {
return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET);
}
set tilingOffset(value) {
if (value) {
this._shaderValues.setVector(TrailMaterial.TILINGOFFSET, value);
}
else {
this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0);
}
}
clone() {
var dest = new TrailMaterial();
this.cloneTo(dest);
return dest;
}
}
TrailMaterial.RENDERMODE_ALPHABLENDED = 0;
TrailMaterial.RENDERMODE_ADDTIVE = 1;
TrailMaterial.MAINTEXTURE = Shader3D.propertyNameToID("u_MainTexture");
TrailMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_MainColor");
TrailMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset");
class TextureMode {
}
TextureMode.Stretch = 0;
TextureMode.Tile = 1;
(function (TrailAlignment) {
TrailAlignment[TrailAlignment["View"] = 0] = "View";
TrailAlignment[TrailAlignment["TransformZ"] = 1] = "TransformZ";
})(exports.TrailAlignment || (exports.TrailAlignment = {}));
class VertexTrail {
static get vertexDeclaration1() {
return VertexTrail._vertexDeclaration1;
}
static get vertexDeclaration2() {
return VertexTrail._vertexDeclaration2;
}
get vertexDeclaration() {
return VertexTrail._vertexDeclaration1;
}
static __init__() {
VertexTrail._vertexDeclaration1 = new VertexDeclaration(32, [new VertexElement(0, VertexElementFormat.Vector3, VertexTrail.TRAIL_POSITION0),
new VertexElement(12, VertexElementFormat.Vector3, VertexTrail.TRAIL_OFFSETVECTOR),
new VertexElement(24, VertexElementFormat.Single, VertexTrail.TRAIL_TIME0),
new VertexElement(28, VertexElementFormat.Single, VertexTrail.TRAIL_TEXTURECOORDINATE0Y)]);
VertexTrail._vertexDeclaration2 = new VertexDeclaration(20, [new VertexElement(0, VertexElementFormat.Single, VertexTrail.TRAIL_TEXTURECOORDINATE0X),
new VertexElement(4, VertexElementFormat.Color, VertexTrail.TRAIL_COLOR)]);
}
}
VertexTrail.TRAIL_POSITION0 = 0;
VertexTrail.TRAIL_OFFSETVECTOR = 1;
VertexTrail.TRAIL_TIME0 = 2;
VertexTrail.TRAIL_TEXTURECOORDINATE0Y = 3;
VertexTrail.TRAIL_TEXTURECOORDINATE0X = 4;
VertexTrail.TRAIL_COLOR = 5;
class TrailGeometry extends GeometryElement {
constructor(owner) {
super();
this._floatCountPerVertices1 = 8;
this._floatCountPerVertices2 = 5;
this._increaseSegementCount = 16;
this._activeIndex = 0;
this._endIndex = 0;
this._needAddFirstVertex = false;
this._isTempEndVertex = false;
this._vertices1 = null;
this._vertices2 = null;
this._lastFixedVertexPosition = new Vector3();
this._bufferState = new BufferState();
this.tmpColor = new Color();
this._disappearBoundsMode = false;
this._owner = owner;
this._segementCount = this._increaseSegementCount;
this._resizeData(this._segementCount, this._bufferState);
var bounds = this._owner._owner.trailRenderer.bounds;
var sprite3dPosition = this._owner._owner.transform.position;
bounds.setMin(sprite3dPosition);
bounds.setMax(sprite3dPosition);
}
_resizeData(segementCount, bufferState) {
this._subBirthTime = new Float32Array(segementCount);
this._subDistance = new Float64Array(segementCount);
var gl = Laya.LayaGL.instance;
var vertexCount = segementCount * 2;
var vertexDeclaration1 = VertexTrail.vertexDeclaration1;
var vertexDeclaration2 = VertexTrail.vertexDeclaration2;
var vertexBuffers = [];
var vertexbuffer1Size = vertexCount * vertexDeclaration1.vertexStride;
var vertexbuffer2Size = vertexCount * vertexDeclaration2.vertexStride;
var memorySize = vertexbuffer1Size + vertexbuffer2Size;
this._vertices1 = new Float32Array(vertexCount * this._floatCountPerVertices1);
this._vertices2 = new Float32Array(vertexCount * this._floatCountPerVertices2);
this._vertexBuffer1 = new VertexBuffer3D(vertexbuffer1Size, gl.STATIC_DRAW, false);
this._vertexBuffer1.vertexDeclaration = vertexDeclaration1;
this._vertexBuffer2 = new VertexBuffer3D(vertexbuffer2Size, gl.DYNAMIC_DRAW, false);
this._vertexBuffer2.vertexDeclaration = vertexDeclaration2;
vertexBuffers.push(this._vertexBuffer1);
vertexBuffers.push(this._vertexBuffer2);
bufferState.bind();
bufferState.applyVertexBuffers(vertexBuffers);
bufferState.unBind();
Laya.Resource._addMemory(memorySize, memorySize);
}
_resetData() {
var count = this._endIndex - this._activeIndex;
var oldVertices1 = new Float32Array(this._vertices1.buffer, this._floatCountPerVertices1 * 2 * this._activeIndex * 4, this._floatCountPerVertices1 * 2 * count);
var oldVertices2 = new Float32Array(this._vertices2.buffer, this._floatCountPerVertices2 * 2 * this._activeIndex * 4, this._floatCountPerVertices2 * 2 * count);
var oldSubDistance = new Float64Array(this._subDistance.buffer, this._activeIndex * 8, count);
var oldSubBirthTime = new Float32Array(this._subBirthTime.buffer, this._activeIndex * 4, count);
if (count === this._segementCount) {
var memorySize = this._vertexBuffer1._byteLength + this._vertexBuffer2._byteLength;
Laya.Resource._addMemory(-memorySize, -memorySize);
this._vertexBuffer1.destroy();
this._vertexBuffer2.destroy();
this._segementCount += this._increaseSegementCount;
this._resizeData(this._segementCount, this._bufferState);
}
this._vertices1.set(oldVertices1, 0);
this._vertices2.set(oldVertices2, 0);
this._subDistance.set(oldSubDistance, 0);
this._subBirthTime.set(oldSubBirthTime, 0);
this._endIndex = count;
this._activeIndex = 0;
this._vertexBuffer1.setData(this._vertices1.buffer, 0, this._floatCountPerVertices1 * 2 * this._activeIndex * 4, this._floatCountPerVertices1 * 2 * count * 4);
this._vertexBuffer2.setData(this._vertices2.buffer, 0, this._floatCountPerVertices2 * 2 * this._activeIndex * 4, this._floatCountPerVertices2 * 2 * count * 4);
}
_updateTrail(camera, lastPosition, position) {
if (!Vector3.equals(lastPosition, position)) {
if ((this._endIndex - this._activeIndex) === 0)
this._addTrailByFirstPosition(camera, position);
else
this._addTrailByNextPosition(camera, position);
}
}
_addTrailByFirstPosition(camera, position) {
(this._endIndex === this._segementCount) && (this._resetData());
this._subDistance[this._endIndex] = 0;
this._subBirthTime[this._endIndex] = this._owner._curtime;
this._endIndex++;
position.cloneTo(this._lastFixedVertexPosition);
this._needAddFirstVertex = true;
}
_addTrailByNextPosition(camera, position) {
var delVector3 = TrailGeometry._tempVector30;
var pointAtoBVector3 = TrailGeometry._tempVector31;
switch (this._owner.alignment) {
case exports.TrailAlignment.View:
var cameraMatrix = camera.viewMatrix;
Vector3.transformCoordinate(position, cameraMatrix, TrailGeometry._tempVector33);
Vector3.transformCoordinate(this._lastFixedVertexPosition, cameraMatrix, TrailGeometry._tempVector34);
Vector3.subtract(TrailGeometry._tempVector33, TrailGeometry._tempVector34, delVector3);
Vector3.cross(TrailGeometry._tempVector33, delVector3, pointAtoBVector3);
break;
case exports.TrailAlignment.TransformZ:
Vector3.subtract(position, this._lastFixedVertexPosition, delVector3);
var forward = TrailGeometry._tempVector32;
this._owner._owner.transform.getForward(forward);
Vector3.cross(delVector3, forward, pointAtoBVector3);
break;
}
Vector3.normalize(pointAtoBVector3, pointAtoBVector3);
Vector3.scale(pointAtoBVector3, this._owner.widthMultiplier / 2, pointAtoBVector3);
var delLength = Vector3.scalarLength(delVector3);
var tempEndIndex;
var offset;
if (this._needAddFirstVertex) {
this._updateVerticesByPositionData(position, pointAtoBVector3, this._endIndex - 1);
this._needAddFirstVertex = false;
}
if (delLength - this._owner.minVertexDistance >= MathUtils3D.zeroTolerance) {
if (this._isTempEndVertex) {
tempEndIndex = this._endIndex - 1;
offset = delLength - this._subDistance[tempEndIndex];
this._updateVerticesByPosition(position, pointAtoBVector3, delLength, tempEndIndex);
this._owner._totalLength += offset;
}
else {
(this._endIndex === this._segementCount) && (this._resetData());
this._updateVerticesByPosition(position, pointAtoBVector3, delLength, this._endIndex);
this._owner._totalLength += delLength;
this._endIndex++;
}
position.cloneTo(this._lastFixedVertexPosition);
this._isTempEndVertex = false;
}
else {
if (this._isTempEndVertex) {
tempEndIndex = this._endIndex - 1;
offset = delLength - this._subDistance[tempEndIndex];
this._updateVerticesByPosition(position, pointAtoBVector3, delLength, tempEndIndex);
this._owner._totalLength += offset;
}
else {
(this._endIndex === this._segementCount) && (this._resetData());
this._updateVerticesByPosition(position, pointAtoBVector3, delLength, this._endIndex);
this._owner._totalLength += delLength;
this._endIndex++;
}
this._isTempEndVertex = true;
}
}
_updateVerticesByPositionData(position, pointAtoBVector3, index) {
var vertexOffset = this._floatCountPerVertices1 * 2 * index;
var curtime = this._owner._curtime;
this._vertices1[vertexOffset] = position.x;
this._vertices1[vertexOffset + 1] = position.y;
this._vertices1[vertexOffset + 2] = position.z;
this._vertices1[vertexOffset + 3] = -pointAtoBVector3.x;
this._vertices1[vertexOffset + 4] = -pointAtoBVector3.y;
this._vertices1[vertexOffset + 5] = -pointAtoBVector3.z;
this._vertices1[vertexOffset + 6] = curtime;
this._vertices1[vertexOffset + 7] = 1.0;
this._vertices1[vertexOffset + 8] = position.x;
this._vertices1[vertexOffset + 9] = position.y;
this._vertices1[vertexOffset + 10] = position.z;
this._vertices1[vertexOffset + 11] = pointAtoBVector3.x;
this._vertices1[vertexOffset + 12] = pointAtoBVector3.y;
this._vertices1[vertexOffset + 13] = pointAtoBVector3.z;
this._vertices1[vertexOffset + 14] = curtime;
this._vertices1[vertexOffset + 15] = 0.0;
var bounds = this._owner._owner.trailRenderer.bounds;
var min = bounds.getMin();
var max = bounds.getMax();
var up = TrailGeometry._tempVector35;
var down = TrailGeometry._tempVector36;
var out = TrailGeometry._tempVector32;
Vector3.add(position, pointAtoBVector3, up);
Vector3.subtract(position, pointAtoBVector3, down);
Vector3.min(down, up, out);
Vector3.min(min, out, min);
bounds.setMin(min);
Vector3.max(up, down, out);
Vector3.max(max, out, max);
bounds.setMax(max);
var floatCount = this._floatCountPerVertices1 * 2;
this._vertexBuffer1.setData(this._vertices1.buffer, vertexOffset * 4, vertexOffset * 4, floatCount * 4);
}
_updateVerticesByPosition(position, pointAtoBVector3, delDistance, index) {
this._updateVerticesByPositionData(position, pointAtoBVector3, index);
this._subDistance[index] = delDistance;
this._subBirthTime[index] = this._owner._curtime;
}
_updateVertexBufferUV() {
var bounds;
var min, max;
if (this._disappearBoundsMode) {
bounds = this._owner._owner.trailRenderer.bounds;
var sprite3dPosition = this._owner._owner.transform.position;
bounds.setMin(sprite3dPosition);
bounds.setMax(sprite3dPosition);
min = bounds.getMin();
max = bounds.getMax();
}
var vertexCount = this._endIndex;
var curLength = 0;
var gradient = this._owner.colorGradient;
var startAlphaIndex = gradient.colorAlphaKeysCount - 1;
var startColorIndex = gradient.colorRGBKeysCount - 1;
var totalLength = this._owner._totalLength;
var stride = this._floatCountPerVertices2 * 2;
for (var i = this._activeIndex; i < vertexCount; i++) {
(i !== this._activeIndex) && (curLength += this._subDistance[i]);
var uvX;
var lerpFactor;
if (this._owner.textureMode == TextureMode.Stretch) {
uvX = 1.0 - curLength / totalLength;
lerpFactor = uvX;
}
else {
lerpFactor = 1.0 - curLength / totalLength;
uvX = 1.0 - (totalLength - curLength);
}
startColorIndex = gradient.evaluateColorRGB(lerpFactor, this.tmpColor, startColorIndex, true);
startAlphaIndex = gradient.evaluateColorAlpha(lerpFactor, this.tmpColor, startAlphaIndex, true);
var index = i * stride;
this._vertices2[index + 0] = uvX;
this._vertices2[index + 1] = this.tmpColor.r;
this._vertices2[index + 2] = this.tmpColor.g;
this._vertices2[index + 3] = this.tmpColor.b;
this._vertices2[index + 4] = this.tmpColor.a;
this._vertices2[index + 5] = uvX;
this._vertices2[index + 6] = this.tmpColor.r;
this._vertices2[index + 7] = this.tmpColor.g;
this._vertices2[index + 8] = this.tmpColor.b;
this._vertices2[index + 9] = this.tmpColor.a;
if (this._disappearBoundsMode) {
var posOffset = this._floatCountPerVertices1 * 2 * i;
var pos = TrailGeometry._tempVector32;
var up = TrailGeometry._tempVector33;
var side = TrailGeometry._tempVector34;
pos.setValue(this._vertices1[posOffset + 0], this._vertices1[posOffset + 1], this._vertices1[posOffset + 2]);
up.setValue(this._vertices1[posOffset + 3], this._vertices1[posOffset + 4], this._vertices1[posOffset + 5]);
Vector3.add(pos, up, side);
Vector3.min(side, min, min);
Vector3.max(side, max, max);
Vector3.subtract(pos, up, side);
Vector3.min(side, min, min);
Vector3.max(side, max, max);
}
}
if (this._disappearBoundsMode) {
bounds.setMin(min);
bounds.setMax(max);
this._disappearBoundsMode = false;
}
var offset = this._activeIndex * stride;
this._vertexBuffer2.setData(this._vertices2.buffer, offset * 4, offset * 4, (vertexCount * stride - offset) * 4);
}
_updateDisappear() {
var count = this._endIndex;
for (var i = this._activeIndex; i < count; i++) {
if (this._owner._curtime - this._subBirthTime[i] >= this._owner.time + MathUtils3D.zeroTolerance) {
var nextIndex = i + 1;
if (nextIndex !== count)
this._owner._totalLength -= this._subDistance[nextIndex];
if (this._isTempEndVertex && (nextIndex === count - 1)) {
var fixedPos = this._lastFixedVertexPosition;
fixedPos.x = this._vertices1[0];
fixedPos.y = this._vertices1[1];
fixedPos.z = this._vertices1[2];
this._isTempEndVertex = false;
}
this._activeIndex++;
this._disappearBoundsMode = true;
}
else {
break;
}
}
}
_getType() {
return TrailGeometry._type;
}
_prepareRender(state) {
return this._endIndex - this._activeIndex > 1;
}
_render(state) {
this._bufferState.bind();
var gl = Laya.LayaGL.instance;
var start = this._activeIndex * 2;
var count = this._endIndex * 2 - start;
gl.drawArrays(gl.TRIANGLE_STRIP, start, count);
Laya.Stat.renderBatches++;
Laya.Stat.trianglesFaces += count - 2;
}
destroy() {
super.destroy();
var memorySize = this._vertexBuffer1._byteLength + this._vertexBuffer2._byteLength;
Laya.Resource._addMemory(-memorySize, -memorySize);
this._bufferState.destroy();
this._vertexBuffer1.destroy();
this._vertexBuffer2.destroy();
this._bufferState = null;
this._vertices1 = null;
this._vertexBuffer1 = null;
this._vertices2 = null;
this._vertexBuffer2 = null;
this._subBirthTime = null;
this._subDistance = null;
this._lastFixedVertexPosition = null;
this._disappearBoundsMode = false;
}
clear() {
this._activeIndex = 0;
this._endIndex = 0;
this._disappearBoundsMode = false;
this._subBirthTime.fill(0);
this._subDistance.fill(0);
this._segementCount = 0;
this._isTempEndVertex = false;
this._needAddFirstVertex = false;
this._lastFixedVertexPosition.setValue(0, 0, 0);
}
}
TrailGeometry.ALIGNMENT_VIEW = 0;
TrailGeometry.ALIGNMENT_TRANSFORM_Z = 1;
TrailGeometry._tempVector30 = new Vector3();
TrailGeometry._tempVector31 = new Vector3();
TrailGeometry._tempVector32 = new Vector3();
TrailGeometry._tempVector33 = new Vector3();
TrailGeometry._tempVector34 = new Vector3();
TrailGeometry._tempVector35 = new Vector3();
TrailGeometry._tempVector36 = new Vector3();
TrailGeometry._type = GeometryElement._typeCounter++;
class TrailFilter {
constructor(owner) {
this._totalLength = 0;
this._lastPosition = new Vector3();
this._curtime = 0;
this.alignment = TrailFilter.ALIGNMENT_VIEW;
this._owner = owner;
this._initDefaultData();
this.addRenderElement();
}
get time() {
return this._time;
}
set time(value) {
this._time = value;
this._owner._render._shaderValues.setNumber(TrailFilter.LIFETIME, value);
}
get minVertexDistance() {
return this._minVertexDistance;
}
set minVertexDistance(value) {
this._minVertexDistance = value;
}
get widthMultiplier() {
return this._widthMultiplier;
}
set widthMultiplier(value) {
this._widthMultiplier = value;
}
get widthCurve() {
return this._widthCurve;
}
set widthCurve(value) {
this._widthCurve = value;
var widthCurveFloatArray = new Float32Array(value.length * 4);
var i, j, index = 0;
for (i = 0, j = value.length; i < j; i++) {
widthCurveFloatArray[index++] = value[i].time;
widthCurveFloatArray[index++] = value[i].inTangent;
widthCurveFloatArray[index++] = value[i].outTangent;
widthCurveFloatArray[index++] = value[i].value;
}
this._owner._render._shaderValues.setBuffer(TrailFilter.WIDTHCURVE, widthCurveFloatArray);
this._owner._render._shaderValues.setInt(TrailFilter.WIDTHCURVEKEYLENGTH, value.length);
}
get colorGradient() {
return this._colorGradient;
}
set colorGradient(value) {
this._colorGradient = value;
}
get textureMode() {
return this._textureMode;
}
set textureMode(value) {
this._textureMode = value;
}
addRenderElement() {
var render = this._owner._render;
var elements = render._renderElements;
var material = render.sharedMaterials[0];
(material) || (material = TrailMaterial.defaultMaterial);
var element = new RenderElement();
element.setTransform(this._owner._transform);
element.render = render;
element.material = material;
this._trialGeometry = new TrailGeometry(this);
element.setGeometry(this._trialGeometry);
elements.push(element);
}
_update(state) {
var render = this._owner._render;
this._curtime += state.scene.timer._delta / 1000;
render._shaderValues.setNumber(TrailFilter.CURTIME, this._curtime);
var curPos = this._owner.transform.position;
var element = render._renderElements[0]._geometry;
element._updateDisappear();
element._updateTrail(state.camera, this._lastPosition, curPos);
element._updateVertexBufferUV();
curPos.cloneTo(this._lastPosition);
}
_initDefaultData() {
this.time = 5.0;
this.minVertexDistance = 0.1;
this.widthMultiplier = 1;
this.textureMode = TextureMode.Stretch;
var widthKeyFrames = [];
var widthKeyFrame1 = new FloatKeyframe();
widthKeyFrame1.time = 0;
widthKeyFrame1.inTangent = 0;
widthKeyFrame1.outTangent = 0;
widthKeyFrame1.value = 1;
widthKeyFrames.push(widthKeyFrame1);
var widthKeyFrame2 = new FloatKeyframe();
widthKeyFrame2.time = 1;
widthKeyFrame2.inTangent = 0;
widthKeyFrame2.outTangent = 0;
widthKeyFrame2.value = 1;
widthKeyFrames.push(widthKeyFrame2);
this.widthCurve = widthKeyFrames;
var gradient = new Gradient(2, 2);
gradient.mode = GradientMode.Blend;
gradient.addColorRGB(0, Color.WHITE);
gradient.addColorRGB(1, Color.WHITE);
gradient.addColorAlpha(0, 1);
gradient.addColorAlpha(1, 1);
this.colorGradient = gradient;
}
destroy() {
this._trialGeometry.destroy();
this._trialGeometry = null;
this._widthCurve = null;
this._colorGradient = null;
}
clear() {
this._trialGeometry.clear();
this._lastPosition.setValue(0, 0, 0);
this._curtime = 0;
this._totalLength = 0;
}
}
TrailFilter.CURTIME = Shader3D.propertyNameToID("u_CurTime");
TrailFilter.LIFETIME = Shader3D.propertyNameToID("u_LifeTime");
TrailFilter.WIDTHCURVE = Shader3D.propertyNameToID("u_WidthCurve");
TrailFilter.WIDTHCURVEKEYLENGTH = Shader3D.propertyNameToID("u_WidthCurveKeyLength");
TrailFilter.ALIGNMENT_VIEW = 0;
TrailFilter.ALIGNMENT_TRANSFORM_Z = 1;
class TrailRenderer extends BaseRender {
constructor(owner) {
super(owner);
this._projectionViewWorldMatrix = new Matrix4x4();
}
_calculateBoundingBox() {
}
_needRender(boundFrustum, context) {
this._owner.trailFilter._update(context);
if (boundFrustum)
return boundFrustum.intersects(this.bounds._getBoundBox());
else
return true;
}
_updateForNative(context) {
this._owner.trailFilter._update(context);
}
_renderUpdate(state, transform) {
super._renderUpdate(state, transform);
}
_renderUpdateWithCamera(context, transform) {
var projectionView = context.projectionViewMatrix;
if (transform) {
Matrix4x4.multiply(projectionView, transform.worldMatrix, this._projectionViewWorldMatrix);
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix);
}
else {
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, projectionView);
}
}
}
class TrailSprite3D extends RenderableSprite3D {
constructor(name = null) {
super(name);
this._render = new TrailRenderer(this);
this._geometryFilter = new TrailFilter(this);
}
static __init__() {
}
get trailFilter() {
return this._geometryFilter;
}
get trailRenderer() {
return this._render;
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
var render = this._render;
var filter = this._geometryFilter;
var i, j;
var materials = data.materials;
if (materials) {
var sharedMaterials = render.sharedMaterials;
var materialCount = materials.length;
sharedMaterials.length = materialCount;
for (i = 0; i < materialCount; i++)
sharedMaterials[i] = Laya.Loader.getRes(materials[i].path);
render.sharedMaterials = sharedMaterials;
}
filter.time = data.time;
filter.minVertexDistance = data.minVertexDistance;
filter.widthMultiplier = data.widthMultiplier;
filter.textureMode = data.textureMode;
(data.alignment != null) && (filter.alignment = data.alignment);
var widthCurve = [];
var widthCurveData = data.widthCurve;
for (i = 0, j = widthCurveData.length; i < j; i++) {
var trailkeyframe = new FloatKeyframe();
trailkeyframe.time = widthCurveData[i].time;
trailkeyframe.inTangent = widthCurveData[i].inTangent;
trailkeyframe.outTangent = widthCurveData[i].outTangent;
trailkeyframe.value = widthCurveData[i].value;
widthCurve.push(trailkeyframe);
}
filter.widthCurve = widthCurve;
var colorGradientData = data.colorGradient;
var colorKeys = colorGradientData.colorKeys;
var alphaKeys = colorGradientData.alphaKeys;
var colorGradient = new Gradient(colorKeys.length, alphaKeys.length);
colorGradient.mode = colorGradientData.mode;
for (i = 0, j = colorKeys.length; i < j; i++) {
var colorKey = colorKeys[i];
colorGradient.addColorRGB(colorKey.time, new Color(colorKey.value[0], colorKey.value[1], colorKey.value[2], 1.0));
}
for (i = 0, j = alphaKeys.length; i < j; i++) {
var alphaKey = alphaKeys[i];
colorGradient.addColorAlpha(alphaKey.time, alphaKey.value);
}
filter.colorGradient = colorGradient;
}
_onActive() {
super._onActive();
this._transform.position.cloneTo(this._geometryFilter._lastPosition);
}
_cloneTo(destObject, srcSprite, dstSprite) {
super._cloneTo(destObject, srcSprite, dstSprite);
var i, j;
var destTrailSprite3D = destObject;
var destTrailFilter = destTrailSprite3D.trailFilter;
destTrailFilter.time = this.trailFilter.time;
destTrailFilter.minVertexDistance = this.trailFilter.minVertexDistance;
destTrailFilter.widthMultiplier = this.trailFilter.widthMultiplier;
destTrailFilter.textureMode = this.trailFilter.textureMode;
destTrailFilter.alignment = this.trailFilter.alignment;
var widthCurveData = this.trailFilter.widthCurve;
var widthCurve = [];
for (i = 0, j = widthCurveData.length; i < j; i++) {
var keyFrame = new FloatKeyframe();
widthCurveData[i].cloneTo(keyFrame);
widthCurve.push(keyFrame);
}
destTrailFilter.widthCurve = widthCurve;
var destColorGradient = new Gradient(this.trailFilter.colorGradient.maxColorRGBKeysCount, this.trailFilter.colorGradient.maxColorAlphaKeysCount);
this.trailFilter.colorGradient.cloneTo(destColorGradient);
destTrailFilter.colorGradient = destColorGradient;
var destTrailRender = destTrailSprite3D.trailRenderer;
destTrailRender.sharedMaterial = this.trailRenderer.sharedMaterial;
}
destroy(destroyChild = true) {
if (this.destroyed)
return;
super.destroy(destroyChild);
this._geometryFilter.destroy();
this._geometryFilter = null;
}
clear() {
this._geometryFilter.clear();
}
_create() {
return new TrailSprite3D();
}
}
class VertexPositionTerrain {
constructor(position, normal, textureCoord0, textureCoord1) {
this._position = position;
this._normal = normal;
this._textureCoord0 = textureCoord0;
this._textureCoord1 = textureCoord1;
}
static __init__() {
VertexPositionTerrain._vertexDeclaration = new VertexDeclaration(40, [new VertexElement(0, VertexElementFormat.Vector3, VertexPositionTerrain.TERRAIN_POSITION0),
new VertexElement(12, VertexElementFormat.Vector3, VertexPositionTerrain.TERRAIN_NORMAL0),
new VertexElement(24, VertexElementFormat.Vector2, VertexPositionTerrain.TERRAIN_TEXTURECOORDINATE0),
new VertexElement(32, VertexElementFormat.Vector2, VertexPositionTerrain.TERRAIN_TEXTURECOORDINATE1)]);
}
static get vertexDeclaration() {
return VertexPositionTerrain._vertexDeclaration;
}
get position() {
return this._position;
}
get normal() {
return this._normal;
}
get textureCoord0() {
return this._textureCoord0;
}
get textureCoord1() {
return this._textureCoord1;
}
get vertexDeclaration() {
return VertexPositionTerrain._vertexDeclaration;
}
}
VertexPositionTerrain.TERRAIN_POSITION0 = 0;
VertexPositionTerrain.TERRAIN_NORMAL0 = 1;
VertexPositionTerrain.TERRAIN_TEXTURECOORDINATE0 = 2;
VertexPositionTerrain.TERRAIN_TEXTURECOORDINATE1 = 3;
class SubMesh extends GeometryElement {
constructor(mesh) {
super();
this._id = ++SubMesh._uniqueIDCounter;
this._mesh = mesh;
this._boneIndicesList = [];
this._subIndexBufferStart = [];
this._subIndexBufferCount = [];
}
get indexCount() {
return this._indexCount;
}
_setIndexRange(indexStart, indexCount, indexFormat = exports.IndexFormat.UInt16) {
this._indexStart = indexStart;
this._indexCount = indexCount;
if (indexFormat == exports.IndexFormat.UInt16) {
this._indices = new Uint16Array(this._indexBuffer.getData().buffer, indexStart * 2, indexCount);
}
else {
this._indices = new Uint32Array(this._indexBuffer.getData().buffer, indexStart * 4, indexCount);
}
}
_getType() {
return SubMesh._type;
}
_prepareRender(state) {
this._mesh._uploadVerticesData();
return true;
}
_render(state) {
var mesh = this._mesh;
if (mesh.indexFormat === exports.IndexFormat.UInt32 && !Laya.LayaGL.layaGPUInstance.supportElementIndexUint32()) {
console.warn("SubMesh:this device do not support IndexFormat.UInt32.");
return;
}
var gl = Laya.LayaGL.instance;
var skinnedDatas = state.renderElement ? state.renderElement.render._skinnedData : null;
var glIndexFormat;
var byteCount;
switch (mesh.indexFormat) {
case exports.IndexFormat.UInt32:
glIndexFormat = gl.UNSIGNED_INT;
byteCount = 4;
break;
case exports.IndexFormat.UInt16:
glIndexFormat = gl.UNSIGNED_SHORT;
byteCount = 2;
break;
case exports.IndexFormat.UInt8:
glIndexFormat = gl.UNSIGNED_BYTE;
byteCount = 1;
break;
}
mesh._bufferState.bind();
if (skinnedDatas) {
var subSkinnedDatas = skinnedDatas[this._indexInMesh];
for (var i = 0, n = this._boneIndicesList.length; i < n; i++) {
state.shader.uploadCustomUniform(SkinnedMeshSprite3D.BONES, subSkinnedDatas[i]);
gl.drawElements(gl.TRIANGLES, this._subIndexBufferCount[i], glIndexFormat, this._subIndexBufferStart[i] * byteCount);
}
}
else {
gl.drawElements(gl.TRIANGLES, this._indexCount, glIndexFormat, this._indexStart * byteCount);
}
Laya.Stat.trianglesFaces += this._indexCount / 3;
Laya.Stat.renderBatches++;
}
getIndices() {
if (this._mesh._isReadable)
return this._indices.slice();
else
throw "SubMesh:can't get indices on subMesh,mesh's isReadable must be true.";
}
setIndices(indices) {
this._indexBuffer.setData(indices, this._indexStart, 0, this._indexCount);
}
destroy() {
if (this._destroyed)
return;
super.destroy();
this._indexBuffer.destroy();
this._indexBuffer = null;
this._mesh = null;
this._boneIndicesList = null;
this._subIndexBufferStart = null;
this._subIndexBufferCount = null;
this._skinAnimationDatas = null;
}
}
SubMesh._uniqueIDCounter = 0;
SubMesh._type = GeometryElement._typeCounter++;
class skinnedMatrixCache {
constructor(subMeshIndex, batchIndex, batchBoneIndex) {
this.subMeshIndex = subMeshIndex;
this.batchIndex = batchIndex;
this.batchBoneIndex = batchBoneIndex;
}
}
class Mesh extends Laya.Resource {
constructor(isReadable = true) {
super();
this._tempVector30 = new Vector3();
this._tempVector31 = new Vector3();
this._tempVector32 = new Vector3();
this._minVerticesUpdate = -1;
this._maxVerticesUpdate = -1;
this._needUpdateBounds = true;
this._bounds = new Bounds(new Vector3(), new Vector3());
this._bufferState = new BufferState();
this._instanceBufferState = new BufferState();
this._instanceBufferStateType = 0;
this._vertexBuffer = null;
this._indexBuffer = null;
this._skinnedMatrixCaches = [];
this._vertexCount = 0;
this._indexFormat = exports.IndexFormat.UInt16;
this._isReadable = isReadable;
this._subMeshes = [];
}
static __init__() {
var physics3D = Physics3D._bullet;
if (physics3D) {
Mesh._nativeTempVector30 = physics3D.btVector3_create(0, 0, 0);
Mesh._nativeTempVector31 = physics3D.btVector3_create(0, 0, 0);
Mesh._nativeTempVector32 = physics3D.btVector3_create(0, 0, 0);
}
}
static load(url, complete) {
Laya.ILaya.loader.create(url, complete, null, Mesh.MESH);
}
get inverseAbsoluteBindPoses() {
return this._inverseBindPoses;
}
get vertexCount() {
return this._vertexCount;
}
get indexCount() {
return this._indexBuffer.indexCount;
}
get subMeshCount() {
return this._subMeshes.length;
}
get bounds() {
return this._bounds;
}
set bounds(value) {
if (this._bounds !== value)
value.cloneTo(this._bounds);
}
get indexFormat() {
return this._indexFormat;
}
_getPositionElement(vertexBuffer) {
var vertexElements = vertexBuffer.vertexDeclaration._vertexElements;
for (var i = 0, n = vertexElements.length; i < n; i++) {
var vertexElement = vertexElements[i];
if (vertexElement._elementFormat === VertexElementFormat.Vector3 && vertexElement._elementUsage === VertexMesh.MESH_POSITION0)
return vertexElement;
}
return null;
}
_getVerticeElementData(data, elementUsage) {
data.length = this._vertexCount;
var verDec = this._vertexBuffer.vertexDeclaration;
var element = verDec.getVertexElementByUsage(elementUsage);
if (element) {
var uint8Vertices = this._vertexBuffer.getUint8Data();
var floatVertices = this._vertexBuffer.getFloat32Data();
var uint8VerStr = verDec.vertexStride;
var floatVerStr = uint8VerStr / 4;
var uint8EleOffset = element._offset;
var floatEleOffset = uint8EleOffset / 4;
switch (elementUsage) {
case VertexMesh.MESH_TEXTURECOORDINATE0:
case VertexMesh.MESH_TEXTURECOORDINATE1:
for (var i = 0; i < this._vertexCount; i++) {
var offset = floatVerStr * i + floatEleOffset;
data[i] = new Vector2(floatVertices[offset], floatVertices[offset + 1]);
}
break;
case VertexMesh.MESH_POSITION0:
case VertexMesh.MESH_NORMAL0:
for (var i = 0; i < this._vertexCount; i++) {
var offset = floatVerStr * i + floatEleOffset;
data[i] = new Vector3(floatVertices[offset], floatVertices[offset + 1], floatVertices[offset + 2]);
}
break;
case VertexMesh.MESH_TANGENT0:
case VertexMesh.MESH_BLENDWEIGHT0:
for (var i = 0; i < this._vertexCount; i++) {
var offset = floatVerStr * i + floatEleOffset;
data[i] = new Vector4(floatVertices[offset], floatVertices[offset + 1], floatVertices[offset + 2], floatVertices[offset + 3]);
}
break;
case VertexMesh.MESH_COLOR0:
for (var i = 0; i < this._vertexCount; i++) {
var offset = floatVerStr * i + floatEleOffset;
data[i] = new Color(floatVertices[offset], floatVertices[offset + 1], floatVertices[offset + 2], floatVertices[offset + 3]);
}
break;
case VertexMesh.MESH_BLENDINDICES0:
for (var i = 0; i < this._vertexCount; i++) {
var offset = uint8VerStr * i + uint8EleOffset;
data[i] = new Vector4(uint8Vertices[offset], uint8Vertices[offset + 1], uint8Vertices[offset + 2], uint8Vertices[offset + 3]);
}
break;
default:
throw "Mesh:Unknown elementUsage.";
}
}
}
_setVerticeElementData(data, elementUsage) {
var verDec = this._vertexBuffer.vertexDeclaration;
var element = verDec.getVertexElementByUsage(elementUsage);
if (element) {
var uint8Vertices = this._vertexBuffer.getUint8Data();
var floatVertices = this._vertexBuffer.getFloat32Data();
var uint8VerStr = verDec.vertexStride;
var float8VerStr = uint8VerStr / 4;
var uint8EleOffset = element._offset;
var floatEleOffset = uint8EleOffset / 4;
switch (elementUsage) {
case VertexMesh.MESH_TEXTURECOORDINATE0:
case VertexMesh.MESH_TEXTURECOORDINATE1:
for (var i = 0, n = data.length; i < n; i++) {
var offset = float8VerStr * i + floatEleOffset;
var vec2 = data[i];
floatVertices[offset] = vec2.x;
floatVertices[offset + 1] = vec2.y;
}
break;
case VertexMesh.MESH_POSITION0:
case VertexMesh.MESH_NORMAL0:
for (var i = 0, n = data.length; i < n; i++) {
var offset = float8VerStr * i + floatEleOffset;
var vec3 = data[i];
floatVertices[offset] = vec3.x;
floatVertices[offset + 1] = vec3.y;
floatVertices[offset + 2] = vec3.z;
}
break;
case VertexMesh.MESH_TANGENT0:
case VertexMesh.MESH_BLENDWEIGHT0:
for (var i = 0, n = data.length; i < n; i++) {
var offset = float8VerStr * i + floatEleOffset;
var vec4 = data[i];
floatVertices[offset] = vec4.x;
floatVertices[offset + 1] = vec4.y;
floatVertices[offset + 2] = vec4.z;
floatVertices[offset + 3] = vec4.w;
}
break;
case VertexMesh.MESH_COLOR0:
for (var i = 0, n = data.length; i < n; i++) {
var offset = float8VerStr * i + floatEleOffset;
var cor = data[i];
floatVertices[offset] = cor.r;
floatVertices[offset + 1] = cor.g;
floatVertices[offset + 2] = cor.b;
floatVertices[offset + 3] = cor.a;
}
break;
case VertexMesh.MESH_BLENDINDICES0:
for (var i = 0, n = data.length; i < n; i++) {
var offset = uint8VerStr * i + uint8EleOffset;
var vec4 = data[i];
uint8Vertices[offset] = vec4.x;
uint8Vertices[offset + 1] = vec4.y;
uint8Vertices[offset + 2] = vec4.z;
uint8Vertices[offset + 3] = vec4.w;
}
break;
default:
throw "Mesh:Unknown elementUsage.";
}
this._minVerticesUpdate = 0;
this._maxVerticesUpdate = Number.MAX_SAFE_INTEGER;
}
else {
console.warn("Mesh: the mesh don't have this VertexElement.");
}
}
_disposeResource() {
for (var i = 0, n = this._subMeshes.length; i < n; i++)
this._subMeshes[i].destroy();
this._btTriangleMesh && Physics3D._bullet.btStridingMeshInterface_destroy(this._btTriangleMesh);
this._vertexBuffer.destroy();
this._indexBuffer.destroy();
this._bufferState.destroy();
this._instanceBufferState.destroy();
this._setCPUMemory(0);
this._setGPUMemory(0);
this._bufferState = null;
this._instanceBufferState = null;
this._vertexBuffer = null;
this._indexBuffer = null;
this._subMeshes = null;
this._btTriangleMesh = null;
this._indexBuffer = null;
this._boneNames = null;
this._inverseBindPoses = null;
}
_setSubMeshes(subMeshes) {
this._subMeshes = subMeshes;
for (var i = 0, n = subMeshes.length; i < n; i++)
subMeshes[i]._indexInMesh = i;
}
_setBuffer(vertexBuffer, indexBuffer) {
var bufferState = this._bufferState;
bufferState.bind();
bufferState.applyVertexBuffer(vertexBuffer);
bufferState.applyIndexBuffer(indexBuffer);
bufferState.unBind();
}
_setInstanceBuffer(instanceBufferStateType) {
var instanceBufferState = this._instanceBufferState;
instanceBufferState.bind();
instanceBufferState.applyVertexBuffer(this._vertexBuffer);
instanceBufferState.applyInstanceVertexBuffer(SubMeshInstanceBatch.instance.instanceWorldMatrixBuffer);
switch (instanceBufferStateType) {
case Mesh.MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR:
instanceBufferState.applyInstanceVertexBuffer(SubMeshInstanceBatch.instance.instanceSimpleAnimatorBuffer);
break;
}
instanceBufferState.applyIndexBuffer(this._indexBuffer);
instanceBufferState.unBind();
}
_getPhysicMesh() {
if (!this._btTriangleMesh) {
var bt = Physics3D._bullet;
var triangleMesh = bt.btTriangleMesh_create();
var nativePositio0 = Mesh._nativeTempVector30;
var nativePositio1 = Mesh._nativeTempVector31;
var nativePositio2 = Mesh._nativeTempVector32;
var position0 = this._tempVector30;
var position1 = this._tempVector31;
var position2 = this._tempVector32;
var vertexBuffer = this._vertexBuffer;
var positionElement = this._getPositionElement(vertexBuffer);
var verticesData = vertexBuffer.getFloat32Data();
var floatCount = vertexBuffer.vertexDeclaration.vertexStride / 4;
var posOffset = positionElement._offset / 4;
var indices = this._indexBuffer.getData();
for (var i = 0, n = indices.length; i < n; i += 3) {
var p0Index = indices[i] * floatCount + posOffset;
var p1Index = indices[i + 1] * floatCount + posOffset;
var p2Index = indices[i + 2] * floatCount + posOffset;
position0.setValue(verticesData[p0Index], verticesData[p0Index + 1], verticesData[p0Index + 2]);
position1.setValue(verticesData[p1Index], verticesData[p1Index + 1], verticesData[p1Index + 2]);
position2.setValue(verticesData[p2Index], verticesData[p2Index + 1], verticesData[p2Index + 2]);
Utils3D._convertToBulletVec3(position0, nativePositio0, true);
Utils3D._convertToBulletVec3(position1, nativePositio1, true);
Utils3D._convertToBulletVec3(position2, nativePositio2, true);
bt.btTriangleMesh_addTriangle(triangleMesh, nativePositio0, nativePositio1, nativePositio2, true);
}
this._btTriangleMesh = triangleMesh;
}
return this._btTriangleMesh;
}
_uploadVerticesData() {
var min = this._minVerticesUpdate;
var max = this._maxVerticesUpdate;
if (min !== -1 && max !== -1) {
var offset = min;
this._vertexBuffer.setData(this._vertexBuffer.getUint8Data().buffer, offset, offset, max - min);
this._minVerticesUpdate = -1;
this._maxVerticesUpdate = -1;
}
}
getSubMesh(index) {
return this._subMeshes[index];
}
getPositions(positions) {
if (this._isReadable)
this._getVerticeElementData(positions, VertexMesh.MESH_POSITION0);
else
throw "Mesh:can't get positions on mesh,isReadable must be true.";
}
setPositions(positions) {
if (this._isReadable) {
this._setVerticeElementData(positions, VertexMesh.MESH_POSITION0);
this._needUpdateBounds = true;
}
else {
throw "Mesh:setPosition() need isReadable must be true or use setVertices().";
}
}
getColors(colors) {
if (this._isReadable)
this._getVerticeElementData(colors, VertexMesh.MESH_COLOR0);
else
throw "Mesh:can't get colors on mesh,isReadable must be true.";
}
setColors(colors) {
if (this._isReadable)
this._setVerticeElementData(colors, VertexMesh.MESH_COLOR0);
else
throw "Mesh:setColors() need isReadable must be true or use setVertices().";
}
getUVs(uvs, channel = 0) {
if (this._isReadable) {
switch (channel) {
case 0:
this._getVerticeElementData(uvs, VertexMesh.MESH_TEXTURECOORDINATE0);
break;
case 1:
this._getVerticeElementData(uvs, VertexMesh.MESH_TEXTURECOORDINATE1);
break;
default:
throw "Mesh:Invalid channel.";
}
}
else {
throw "Mesh:can't get uvs on mesh,isReadable must be true.";
}
}
setUVs(uvs, channel = 0) {
if (this._isReadable) {
switch (channel) {
case 0:
this._setVerticeElementData(uvs, VertexMesh.MESH_TEXTURECOORDINATE0);
break;
case 1:
this._setVerticeElementData(uvs, VertexMesh.MESH_TEXTURECOORDINATE1);
break;
default:
throw "Mesh:Invalid channel.";
}
}
else {
throw "Mesh:setUVs() need isReadable must be true or use setVertices().";
}
}
getNormals(normals) {
if (this._isReadable)
this._getVerticeElementData(normals, VertexMesh.MESH_NORMAL0);
else
throw "Mesh:can't get colors on mesh,isReadable must be true.";
}
setNormals(normals) {
if (this._isReadable)
this._setVerticeElementData(normals, VertexMesh.MESH_NORMAL0);
else
throw "Mesh:setNormals() need must be true or use setVertices().";
}
getTangents(tangents) {
if (this._isReadable)
this._getVerticeElementData(tangents, VertexMesh.MESH_TANGENT0);
else
throw "Mesh:can't get colors on mesh,isReadable must be true.";
}
setTangents(tangents) {
if (this._isReadable)
this._setVerticeElementData(tangents, VertexMesh.MESH_TANGENT0);
else
throw "Mesh:setTangents() need isReadable must be true or use setVertices().";
}
getBoneWeights(boneWeights) {
if (this._isReadable)
this._getVerticeElementData(boneWeights, VertexMesh.MESH_BLENDWEIGHT0);
else
throw "Mesh:can't get boneWeights on mesh,isReadable must be true.";
}
setBoneWeights(boneWeights) {
if (this._isReadable)
this._setVerticeElementData(boneWeights, VertexMesh.MESH_BLENDWEIGHT0);
else
throw "Mesh:setBoneWeights() need isReadable must be true or use setVertices().";
}
getBoneIndices(boneIndices) {
if (this._isReadable)
this._getVerticeElementData(boneIndices, VertexMesh.MESH_BLENDINDICES0);
else
throw "Mesh:can't get boneIndices on mesh,isReadable must be true.";
}
setBoneIndices(boneIndices) {
if (this._isReadable)
this._setVerticeElementData(boneIndices, VertexMesh.MESH_BLENDINDICES0);
else
throw "Mesh:setBoneIndices() need isReadable must be true or use setVertices().";
}
markAsUnreadbale() {
this._uploadVerticesData();
this._vertexBuffer.markAsUnreadbale();
this._isReadable = false;
}
getVertexDeclaration() {
return this._vertexBuffer._vertexDeclaration;
}
getVertices() {
if (this._isReadable)
return this._vertexBuffer.getUint8Data().buffer.slice(0);
else
throw "Mesh:can't get vertices on mesh,isReadable must be true.";
}
setVertices(vertices) {
this._vertexBuffer.setData(vertices);
this._needUpdateBounds = true;
}
getIndices() {
if (this._isReadable)
return this._indexBuffer.getData().slice();
else
throw "Mesh:can't get indices on subMesh,mesh's isReadable must be true.";
}
setIndices(indices) {
var format;
if (indices instanceof Uint32Array)
format = exports.IndexFormat.UInt32;
else if (indices instanceof Uint16Array)
format = exports.IndexFormat.UInt16;
else if (indices instanceof Uint8Array)
format = exports.IndexFormat.UInt8;
var indexBuffer = this._indexBuffer;
if (this._indexFormat !== format || indexBuffer.indexCount !== indices.length) {
indexBuffer.destroy();
this._indexBuffer = indexBuffer = new IndexBuffer3D(format, indices.length, Laya.LayaGL.instance.STATIC_DRAW, this._isReadable);
}
indexBuffer.setData(indices);
this._indexFormat = format;
}
calculateBounds() {
if (this._isReadable) {
if (this._needUpdateBounds) {
var min = this._tempVector30;
var max = this._tempVector31;
min.x = min.y = min.z = Number.MAX_VALUE;
max.x = max.y = max.z = -Number.MAX_VALUE;
var vertexBuffer = this._vertexBuffer;
var positionElement = this._getPositionElement(vertexBuffer);
var verticesData = vertexBuffer.getFloat32Data();
var floatCount = vertexBuffer.vertexDeclaration.vertexStride / 4;
var posOffset = positionElement._offset / 4;
for (var j = 0, m = verticesData.length; j < m; j += floatCount) {
var ofset = j + posOffset;
var pX = verticesData[ofset];
var pY = verticesData[ofset + 1];
var pZ = verticesData[ofset + 2];
min.x = Math.min(min.x, pX);
min.y = Math.min(min.y, pY);
min.z = Math.min(min.z, pZ);
max.x = Math.max(max.x, pX);
max.y = Math.max(max.y, pY);
max.z = Math.max(max.z, pZ);
}
this._bounds.setMin(min);
this._bounds.setMax(max);
this._needUpdateBounds = false;
}
}
else {
throw "Mesh:can't calculate bounds on subMesh,mesh's isReadable must be true.";
}
}
cloneTo(destObject) {
var destMesh = destObject;
var vb = this._vertexBuffer;
var destVB = new VertexBuffer3D(vb._byteLength, vb.bufferUsage, vb.canRead);
destVB.vertexDeclaration = vb.vertexDeclaration;
destVB.setData(vb.getUint8Data().slice().buffer);
destMesh._vertexBuffer = destVB;
destMesh._vertexCount = this._vertexCount;
var ib = this._indexBuffer;
var destIB = new IndexBuffer3D(exports.IndexFormat.UInt16, ib.indexCount, ib.bufferUsage, ib.canRead);
destIB.setData(ib.getData().slice());
destMesh._indexBuffer = destIB;
destMesh._setBuffer(destMesh._vertexBuffer, destIB);
destMesh._setInstanceBuffer(this._instanceBufferStateType);
destMesh._setCPUMemory(this.cpuMemory);
destMesh._setGPUMemory(this.gpuMemory);
var i;
var boneNames = this._boneNames;
if (boneNames) {
var destBoneNames = destMesh._boneNames = [];
for (i = 0; i < boneNames.length; i++)
destBoneNames[i] = boneNames[i];
}
var inverseBindPoses = this._inverseBindPoses;
if (inverseBindPoses) {
var destInverseBindPoses = destMesh._inverseBindPoses = [];
for (i = 0; i < inverseBindPoses.length; i++)
destInverseBindPoses[i] = inverseBindPoses[i];
}
var cacheLength = this._skinnedMatrixCaches.length;
destMesh._skinnedMatrixCaches.length = cacheLength;
for (i = 0; i < cacheLength; i++) {
var skinnedCache = this._skinnedMatrixCaches[i];
destMesh._skinnedMatrixCaches[i] = new skinnedMatrixCache(skinnedCache.subMeshIndex, skinnedCache.batchIndex, skinnedCache.batchBoneIndex);
}
for (i = 0; i < this.subMeshCount; i++) {
var subMesh = this._subMeshes[i];
var subIndexBufferStart = subMesh._subIndexBufferStart;
var subIndexBufferCount = subMesh._subIndexBufferCount;
var boneIndicesList = subMesh._boneIndicesList;
var destSubmesh = new SubMesh(destMesh);
destSubmesh._subIndexBufferStart.length = subIndexBufferStart.length;
destSubmesh._subIndexBufferCount.length = subIndexBufferCount.length;
destSubmesh._boneIndicesList.length = boneIndicesList.length;
for (var j = 0; j < subIndexBufferStart.length; j++)
destSubmesh._subIndexBufferStart[j] = subIndexBufferStart[j];
for (j = 0; j < subIndexBufferCount.length; j++)
destSubmesh._subIndexBufferCount[j] = subIndexBufferCount[j];
for (j = 0; j < boneIndicesList.length; j++)
destSubmesh._boneIndicesList[j] = new Uint16Array(boneIndicesList[j]);
destSubmesh._indexBuffer = destIB;
destSubmesh._indexStart = subMesh._indexStart;
destSubmesh._indexCount = subMesh._indexCount;
destSubmesh._indices = new Uint16Array(destIB.getData().buffer, subMesh._indexStart * 2, subMesh._indexCount);
var vertexBuffer = destMesh._vertexBuffer;
destSubmesh._vertexBuffer = vertexBuffer;
destMesh._subMeshes.push(destSubmesh);
}
destMesh._setSubMeshes(destMesh._subMeshes);
}
clone() {
var dest = new Mesh();
this.cloneTo(dest);
return dest;
}
}
Mesh.MESH = "MESH";
Mesh.MESH_INSTANCEBUFFER_TYPE_NORMAL = 0;
Mesh.MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR = 1;
class PrimitiveMesh {
static __init__() {
}
static _createMesh(vertexDeclaration, vertices, indices) {
var gl = Laya.LayaGL.instance;
var mesh = new Mesh();
var subMesh = new SubMesh(mesh);
var vertexBuffer = new VertexBuffer3D(vertices.length * 4, gl.STATIC_DRAW, true);
vertexBuffer.vertexDeclaration = vertexDeclaration;
vertexBuffer.setData(vertices.buffer);
mesh._vertexBuffer = vertexBuffer;
mesh._vertexCount = vertexBuffer._byteLength / vertexDeclaration.vertexStride;
var indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, indices.length, gl.STATIC_DRAW, true);
indexBuffer.setData(indices);
mesh._indexBuffer = indexBuffer;
mesh._setBuffer(vertexBuffer, indexBuffer);
mesh._setInstanceBuffer(mesh._instanceBufferStateType);
subMesh._vertexBuffer = vertexBuffer;
subMesh._indexBuffer = indexBuffer;
subMesh._setIndexRange(0, indexBuffer.indexCount);
var subIndexBufferStart = subMesh._subIndexBufferStart;
var subIndexBufferCount = subMesh._subIndexBufferCount;
var boneIndicesList = subMesh._boneIndicesList;
subIndexBufferStart.length = 1;
subIndexBufferCount.length = 1;
boneIndicesList.length = 1;
subIndexBufferStart[0] = 0;
subIndexBufferCount[0] = indexBuffer.indexCount;
var subMeshes = [];
subMeshes.push(subMesh);
mesh._setSubMeshes(subMeshes);
mesh.calculateBounds();
var memorySize = vertexBuffer._byteLength + indexBuffer._byteLength;
mesh._setCPUMemory(memorySize);
mesh._setGPUMemory(memorySize);
return mesh;
}
static createBox(long = 1, height = 1, width = 1) {
var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
var halfLong = long / 2;
var halfHeight = height / 2;
var halfWidth = width / 2;
var vertices = new Float32Array([
-halfLong, halfHeight, -halfWidth, 0, 1, 0, 0, 0, halfLong, halfHeight, -halfWidth, 0, 1, 0, 1, 0, halfLong, halfHeight, halfWidth, 0, 1, 0, 1, 1, -halfLong, halfHeight, halfWidth, 0, 1, 0, 0, 1,
-halfLong, -halfHeight, -halfWidth, 0, -1, 0, 0, 1, halfLong, -halfHeight, -halfWidth, 0, -1, 0, 1, 1, halfLong, -halfHeight, halfWidth, 0, -1, 0, 1, 0, -halfLong, -halfHeight, halfWidth, 0, -1, 0, 0, 0,
-halfLong, halfHeight, -halfWidth, -1, 0, 0, 0, 0, -halfLong, halfHeight, halfWidth, -1, 0, 0, 1, 0, -halfLong, -halfHeight, halfWidth, -1, 0, 0, 1, 1, -halfLong, -halfHeight, -halfWidth, -1, 0, 0, 0, 1,
halfLong, halfHeight, -halfWidth, 1, 0, 0, 1, 0, halfLong, halfHeight, halfWidth, 1, 0, 0, 0, 0, halfLong, -halfHeight, halfWidth, 1, 0, 0, 0, 1, halfLong, -halfHeight, -halfWidth, 1, 0, 0, 1, 1,
-halfLong, halfHeight, halfWidth, 0, 0, 1, 0, 0, halfLong, halfHeight, halfWidth, 0, 0, 1, 1, 0, halfLong, -halfHeight, halfWidth, 0, 0, 1, 1, 1, -halfLong, -halfHeight, halfWidth, 0, 0, 1, 0, 1,
-halfLong, halfHeight, -halfWidth, 0, 0, -1, 1, 0, halfLong, halfHeight, -halfWidth, 0, 0, -1, 0, 0, halfLong, -halfHeight, -halfWidth, 0, 0, -1, 0, 1, -halfLong, -halfHeight, -halfWidth, 0, 0, -1, 1, 1
]);
var indices = new Uint16Array([
0, 1, 2, 2, 3, 0,
4, 7, 6, 6, 5, 4,
8, 9, 10, 10, 11, 8,
12, 15, 14, 14, 13, 12,
16, 17, 18, 18, 19, 16,
20, 23, 22, 22, 21, 20
]);
return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
}
static createCapsule(radius = 0.5, height = 2, stacks = 16, slices = 32) {
var vertexCount = (stacks + 1) * (slices + 1) * 2 + (slices + 1) * 2;
var indexCount = (3 * stacks * (slices + 1)) * 2 * 2 + 2 * slices * 3;
var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
var vertexFloatStride = vertexDeclaration.vertexStride / 4;
var vertices = new Float32Array(vertexCount * vertexFloatStride);
var indices = new Uint16Array(indexCount);
var stackAngle = (Math.PI / 2.0) / stacks;
var sliceAngle = (Math.PI * 2.0) / slices;
var hcHeight = height / 2 - radius;
var posX = 0;
var posY = 0;
var posZ = 0;
var vc = 0;
var ic = 0;
var verticeCount = 0;
var stack, slice;
for (stack = 0; stack <= stacks; stack++) {
for (slice = 0; slice <= slices; slice++) {
posX = radius * Math.cos(stack * stackAngle) * Math.cos(slice * sliceAngle + Math.PI);
posY = radius * Math.sin(stack * stackAngle);
posZ = radius * Math.cos(stack * stackAngle) * Math.sin(slice * sliceAngle + Math.PI);
vertices[vc++] = posX;
vertices[vc++] = posY + hcHeight;
vertices[vc++] = posZ;
vertices[vc++] = posX;
vertices[vc++] = posY;
vertices[vc++] = posZ;
vertices[vc++] = 1 - slice / slices;
vertices[vc++] = (1 - stack / stacks) * ((Math.PI * radius / 2) / (height + Math.PI * radius));
if (stack < stacks) {
indices[ic++] = (stack * (slices + 1)) + slice + (slices + 1);
indices[ic++] = (stack * (slices + 1)) + slice;
indices[ic++] = (stack * (slices + 1)) + slice + 1;
indices[ic++] = (stack * (slices + 1)) + slice + (slices);
indices[ic++] = (stack * (slices + 1)) + slice;
indices[ic++] = (stack * (slices + 1)) + slice + (slices + 1);
}
}
}
verticeCount += (stacks + 1) * (slices + 1);
for (stack = 0; stack <= stacks; stack++) {
for (slice = 0; slice <= slices; slice++) {
posX = radius * Math.cos(stack * stackAngle) * Math.cos(slice * sliceAngle + Math.PI);
posY = radius * Math.sin(-stack * stackAngle);
posZ = radius * Math.cos(stack * stackAngle) * Math.sin(slice * sliceAngle + Math.PI);
vertices[vc++] = posX;
vertices[vc++] = posY - hcHeight;
vertices[vc++] = posZ;
vertices[vc++] = posX;
vertices[vc++] = posY;
vertices[vc++] = posZ;
vertices[vc++] = 1 - slice / slices;
vertices[vc++] = ((stack / stacks) * (Math.PI * radius / 2) + (height + Math.PI * radius / 2)) / (height + Math.PI * radius);
if (stack < stacks) {
indices[ic++] = verticeCount + (stack * (slices + 1)) + slice;
indices[ic++] = verticeCount + (stack * (slices + 1)) + slice + (slices + 1);
indices[ic++] = verticeCount + (stack * (slices + 1)) + slice + 1;
indices[ic++] = verticeCount + (stack * (slices + 1)) + slice;
indices[ic++] = verticeCount + (stack * (slices + 1)) + slice + (slices);
indices[ic++] = verticeCount + (stack * (slices + 1)) + slice + (slices + 1);
}
}
}
verticeCount += (stacks + 1) * (slices + 1);
for (slice = 0; slice <= slices; slice++) {
posX = radius * Math.cos(slice * sliceAngle + Math.PI);
posY = hcHeight;
posZ = radius * Math.sin(slice * sliceAngle + Math.PI);
vertices[vc++] = posX;
vertices[vc + (slices + 1) * 8 - 1] = posX;
vertices[vc++] = posY;
vertices[vc + (slices + 1) * 8 - 1] = -posY;
vertices[vc++] = posZ;
vertices[vc + (slices + 1) * 8 - 1] = posZ;
vertices[vc++] = posX;
vertices[vc + (slices + 1) * 8 - 1] = posX;
vertices[vc++] = 0;
vertices[vc + (slices + 1) * 8 - 1] = 0;
vertices[vc++] = posZ;
vertices[vc + (slices + 1) * 8 - 1] = posZ;
vertices[vc++] = 1 - slice * 1 / slices;
vertices[vc + (slices + 1) * 8 - 1] = 1 - slice * 1 / slices;
vertices[vc++] = (Math.PI * radius / 2) / (height + Math.PI * radius);
vertices[vc + (slices + 1) * 8 - 1] = (Math.PI * radius / 2 + height) / (height + Math.PI * radius);
}
for (slice = 0; slice < slices; slice++) {
indices[ic++] = slice + verticeCount + (slices + 1);
indices[ic++] = slice + verticeCount + 1;
indices[ic++] = slice + verticeCount;
indices[ic++] = slice + verticeCount + (slices + 1);
indices[ic++] = slice + verticeCount + (slices + 1) + 1;
indices[ic++] = slice + verticeCount + 1;
}
verticeCount += 2 * (slices + 1);
return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
}
static createCone(radius = 0.5, height = 1, slices = 32) {
var vertexCount = (slices + 1 + 1) + (slices + 1) * 2;
var indexCount = 6 * slices + 3 * slices;
var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
var vertexFloatStride = vertexDeclaration.vertexStride / 4;
var vertices = new Float32Array(vertexCount * vertexFloatStride);
var indices = new Uint16Array(indexCount);
var sliceAngle = (Math.PI * 2.0) / slices;
var halfHeight = height / 2;
var curAngle = 0;
var verticeCount = 0;
var posX = 0;
var posY = 0;
var posZ = 0;
var normal = new Vector3();
var downV3 = new Vector3(0, -1, 0);
var upPoint = new Vector3(0, halfHeight, 0);
var downPoint = new Vector3();
var v3 = new Vector3();
var q4 = new Quaternion();
var rotateAxis = new Vector3();
var rotateRadius;
var vc = 0;
var ic = 0;
for (var rv = 0; rv <= slices; rv++) {
curAngle = rv * sliceAngle;
posX = Math.cos(curAngle + Math.PI) * radius;
posY = halfHeight;
posZ = Math.sin(curAngle + Math.PI) * radius;
vertices[vc++] = 0;
vertices[vc + (slices + 1) * 8 - 1] = posX;
vertices[vc++] = posY;
vertices[vc + (slices + 1) * 8 - 1] = -posY;
vertices[vc++] = 0;
vertices[vc + (slices + 1) * 8 - 1] = posZ;
normal.x = posX;
normal.y = 0;
normal.z = posZ;
downPoint.x = posX;
downPoint.y = -posY;
downPoint.z = posZ;
Vector3.subtract(downPoint, upPoint, v3);
Vector3.normalize(v3, v3);
rotateRadius = Math.acos(Vector3.dot(downV3, v3));
Vector3.cross(downV3, v3, rotateAxis);
Vector3.normalize(rotateAxis, rotateAxis);
Quaternion.createFromAxisAngle(rotateAxis, rotateRadius, q4);
Vector3.normalize(normal, normal);
Vector3.transformQuat(normal, q4, normal);
Vector3.normalize(normal, normal);
vertices[vc++] = normal.x;
vertices[vc + (slices + 1) * 8 - 1] = normal.x;
vertices[vc++] = normal.y;
vertices[vc + (slices + 1) * 8 - 1] = normal.y;
vertices[vc++] = normal.z;
vertices[vc + (slices + 1) * 8 - 1] = normal.z;
vertices[vc++] = 1 - rv * 1 / slices;
vertices[vc + (slices + 1) * 8 - 1] = 1 - rv * 1 / slices;
vertices[vc++] = 0;
vertices[vc + (slices + 1) * 8 - 1] = 1;
}
vc += (slices + 1) * 8;
for (var ri = 0; ri < slices; ri++) {
indices[ic++] = ri + verticeCount + (slices + 1);
indices[ic++] = ri + verticeCount + 1;
indices[ic++] = ri + verticeCount;
indices[ic++] = ri + verticeCount + (slices + 1);
indices[ic++] = ri + verticeCount + (slices + 1) + 1;
indices[ic++] = ri + verticeCount + 1;
}
verticeCount += 2 * (slices + 1);
for (var bv = 0; bv <= slices; bv++) {
if (bv === 0) {
vertices[vc++] = 0;
vertices[vc++] = -halfHeight;
vertices[vc++] = 0;
vertices[vc++] = 0;
vertices[vc++] = -1;
vertices[vc++] = 0;
vertices[vc++] = 0.5;
vertices[vc++] = 0.5;
}
curAngle = bv * sliceAngle;
posX = Math.cos(curAngle + Math.PI) * radius;
posY = -halfHeight;
posZ = Math.sin(curAngle + Math.PI) * radius;
vertices[vc++] = posX;
vertices[vc++] = posY;
vertices[vc++] = posZ;
vertices[vc++] = 0;
vertices[vc++] = -1;
vertices[vc++] = 0;
vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5;
vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5;
}
for (var bi = 0; bi < slices; bi++) {
indices[ic++] = 0 + verticeCount;
indices[ic++] = bi + 2 + verticeCount;
indices[ic++] = bi + 1 + verticeCount;
}
verticeCount += slices + 1 + 1;
return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
}
static createCylinder(radius = 0.5, height = 2, slices = 32) {
var vertexCount = (slices + 1 + 1) + (slices + 1) * 2 + (slices + 1 + 1);
var indexCount = 3 * slices + 6 * slices + 3 * slices;
var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
var vertexFloatStride = vertexDeclaration.vertexStride / 4;
var vertices = new Float32Array(vertexCount * vertexFloatStride);
var indices = new Uint16Array(indexCount);
var sliceAngle = (Math.PI * 2.0) / slices;
var halfHeight = height / 2;
var curAngle = 0;
var verticeCount = 0;
var posX = 0;
var posY = 0;
var posZ = 0;
var vc = 0;
var ic = 0;
for (var tv = 0; tv <= slices; tv++) {
if (tv === 0) {
vertices[vc++] = 0;
vertices[vc++] = halfHeight;
vertices[vc++] = 0;
vertices[vc++] = 0;
vertices[vc++] = 1;
vertices[vc++] = 0;
vertices[vc++] = 0.5;
vertices[vc++] = 0.5;
}
curAngle = tv * sliceAngle;
posX = Math.cos(curAngle) * radius;
posY = halfHeight;
posZ = Math.sin(curAngle) * radius;
vertices[vc++] = posX;
vertices[vc++] = posY;
vertices[vc++] = posZ;
vertices[vc++] = 0;
vertices[vc++] = 1;
vertices[vc++] = 0;
vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5;
vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5;
}
for (var ti = 0; ti < slices; ti++) {
indices[ic++] = 0;
indices[ic++] = ti + 1;
indices[ic++] = ti + 2;
}
verticeCount += slices + 1 + 1;
for (var rv = 0; rv <= slices; rv++) {
curAngle = rv * sliceAngle;
posX = Math.cos(curAngle + Math.PI) * radius;
posY = halfHeight;
posZ = Math.sin(curAngle + Math.PI) * radius;
vertices[vc++] = posX;
vertices[vc + (slices + 1) * 8 - 1] = posX;
vertices[vc++] = posY;
vertices[vc + (slices + 1) * 8 - 1] = -posY;
vertices[vc++] = posZ;
vertices[vc + (slices + 1) * 8 - 1] = posZ;
vertices[vc++] = posX;
vertices[vc + (slices + 1) * 8 - 1] = posX;
vertices[vc++] = 0;
vertices[vc + (slices + 1) * 8 - 1] = 0;
vertices[vc++] = posZ;
vertices[vc + (slices + 1) * 8 - 1] = posZ;
vertices[vc++] = 1 - rv * 1 / slices;
vertices[vc + (slices + 1) * 8 - 1] = 1 - rv * 1 / slices;
vertices[vc++] = 0;
vertices[vc + (slices + 1) * 8 - 1] = 1;
}
vc += (slices + 1) * 8;
for (var ri = 0; ri < slices; ri++) {
indices[ic++] = ri + verticeCount + (slices + 1);
indices[ic++] = ri + verticeCount + 1;
indices[ic++] = ri + verticeCount;
indices[ic++] = ri + verticeCount + (slices + 1);
indices[ic++] = ri + verticeCount + (slices + 1) + 1;
indices[ic++] = ri + verticeCount + 1;
}
verticeCount += 2 * (slices + 1);
for (var bv = 0; bv <= slices; bv++) {
if (bv === 0) {
vertices[vc++] = 0;
vertices[vc++] = -halfHeight;
vertices[vc++] = 0;
vertices[vc++] = 0;
vertices[vc++] = -1;
vertices[vc++] = 0;
vertices[vc++] = 0.5;
vertices[vc++] = 0.5;
}
curAngle = bv * sliceAngle;
posX = Math.cos(curAngle + Math.PI) * radius;
posY = -halfHeight;
posZ = Math.sin(curAngle + Math.PI) * radius;
vertices[vc++] = posX;
vertices[vc++] = posY;
vertices[vc++] = posZ;
vertices[vc++] = 0;
vertices[vc++] = -1;
vertices[vc++] = 0;
vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5;
vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5;
}
for (var bi = 0; bi < slices; bi++) {
indices[ic++] = 0 + verticeCount;
indices[ic++] = bi + 2 + verticeCount;
indices[ic++] = bi + 1 + verticeCount;
}
verticeCount += slices + 1 + 1;
return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
}
static createPlane(long = 10, width = 10, stacks = 10, slices = 10) {
var vertexCount = (stacks + 1) * (slices + 1);
var indexCount = stacks * slices * 2 * 3;
var indices = new Uint16Array(indexCount);
var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
var vertexFloatStride = vertexDeclaration.vertexStride / 4;
var vertices = new Float32Array(vertexCount * vertexFloatStride);
var halfLong = long / 2;
var halfWidth = width / 2;
var stacksLong = long / stacks;
var slicesWidth = width / slices;
var verticeCount = 0;
for (var i = 0; i <= slices; i++) {
for (var j = 0; j <= stacks; j++) {
vertices[verticeCount++] = j * stacksLong - halfLong;
vertices[verticeCount++] = 0;
vertices[verticeCount++] = i * slicesWidth - halfWidth;
vertices[verticeCount++] = 0;
vertices[verticeCount++] = 1;
vertices[verticeCount++] = 0;
vertices[verticeCount++] = j * 1 / stacks;
vertices[verticeCount++] = i * 1 / slices;
}
}
var indiceIndex = 0;
for (i = 0; i < slices; i++) {
for (j = 0; j < stacks; j++) {
indices[indiceIndex++] = (i + 1) * (stacks + 1) + j;
indices[indiceIndex++] = i * (stacks + 1) + j;
indices[indiceIndex++] = (i + 1) * (stacks + 1) + j + 1;
indices[indiceIndex++] = i * (stacks + 1) + j;
indices[indiceIndex++] = i * (stacks + 1) + j + 1;
indices[indiceIndex++] = (i + 1) * (stacks + 1) + j + 1;
}
}
return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
}
static createQuad(long = 1, width = 1) {
var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
var halfLong = long / 2;
var halfWidth = width / 2;
var vertices = new Float32Array([-halfLong, halfWidth, 0, 0, 0, 1, 0, 0, halfLong, halfWidth, 0, 0, 0, 1, 1, 0, -halfLong, -halfWidth, 0, 0, 0, 1, 0, 1, halfLong, -halfWidth, 0, 0, 0, 1, 1, 1]);
var indices = new Uint16Array([0, 1, 2, 3, 2, 1]);
return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
}
static createSphere(radius = 0.5, stacks = 32, slices = 32) {
var vertexCount = (stacks + 1) * (slices + 1);
var indexCount = (3 * stacks * (slices + 1)) * 2;
var indices = new Uint16Array(indexCount);
var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
var vertexFloatStride = vertexDeclaration.vertexStride / 4;
var vertices = new Float32Array(vertexCount * vertexFloatStride);
var stackAngle = Math.PI / stacks;
var sliceAngle = (Math.PI * 2.0) / slices;
var vertexIndex = 0;
vertexCount = 0;
indexCount = 0;
for (var stack = 0; stack < (stacks + 1); stack++) {
var r = Math.sin(stack * stackAngle);
var y = Math.cos(stack * stackAngle);
for (var slice = 0; slice < (slices + 1); slice++) {
var x = r * Math.sin(slice * sliceAngle + Math.PI * 1 / 2);
var z = r * Math.cos(slice * sliceAngle + Math.PI * 1 / 2);
vertices[vertexCount + 0] = x * radius;
vertices[vertexCount + 1] = y * radius;
vertices[vertexCount + 2] = z * radius;
vertices[vertexCount + 3] = x;
vertices[vertexCount + 4] = y;
vertices[vertexCount + 5] = z;
vertices[vertexCount + 6] = slice / slices;
vertices[vertexCount + 7] = stack / stacks;
vertexCount += vertexFloatStride;
if (stack != (stacks - 1)) {
indices[indexCount++] = vertexIndex + (slices + 1);
indices[indexCount++] = vertexIndex;
indices[indexCount++] = vertexIndex + 1;
indices[indexCount++] = vertexIndex + (slices);
indices[indexCount++] = vertexIndex;
indices[indexCount++] = vertexIndex + (slices + 1);
vertexIndex++;
}
}
}
return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices);
}
}
var BlitScreenPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\nuniform sampler2D u_MainTex;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\r\n\tgl_FragColor = texture2D(u_MainTex, v_Texcoord0);\r\n}\r\n\r\n";
var BlitScreenVS = "#include \"Lighting.glsl\";\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\nattribute vec4 a_PositionTexcoord;\r\nuniform vec4 u_OffsetScale;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\t\r\n\tgl_Position = vec4(u_OffsetScale.x*2.0-1.0+(a_PositionTexcoord.x+1.0)*u_OffsetScale.z,(1.0-((u_OffsetScale.y*2.0-1.0+(-a_PositionTexcoord.y+1.0)*u_OffsetScale.w)+1.0)/2.0)*2.0-1.0, 0.0, 1.0);\t\r\n\tv_Texcoord0 = a_PositionTexcoord.zw;\r\n\tgl_Position = remapGLPositionZ(gl_Position);\r\n}";
var EffectPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tvarying vec4 v_Color;\r\n#endif\r\nvarying vec2 v_Texcoord0;\r\n\r\n#ifdef MAINTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = 2.0 * u_AlbedoColor;\r\n\t#ifdef COLOR\r\n\t\tcolor *= v_Color;\r\n\t#endif\r\n\t#ifdef MAINTEXTURE\r\n\t\tcolor *= texture2D(u_AlbedoTexture, v_Texcoord0);\r\n\t#endif\r\n\t\r\n\tgl_FragColor = color;\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact = clamp((1.0 / gl_FragCoord.w - u_FogStart) / u_FogRange, 0.0, 1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.0), lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, u_FogColor, lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n}\r\n\r\n";
var EffectVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec4 a_Color;\r\nattribute vec2 a_Texcoord0;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tvarying vec4 v_Color;\r\n#endif\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * a_WorldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\t\r\n\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t\t\r\n\t#ifdef COLOR\r\n\t\tv_Color = a_Color;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}";
var extendTerrainPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)\r\n\tuniform vec3 u_CameraPos;\r\n\tvarying vec3 v_Normal;\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n#endif\r\n\r\n#include \"Shadow.glsl\"\r\n#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\nvarying float v_posViewZ;\r\n\r\nuniform vec3 u_AmbientColor;\r\n\r\nuniform sampler2D u_SplatAlphaTexture;\r\n\r\nuniform sampler2D u_DiffuseTexture1;\r\nuniform sampler2D u_DiffuseTexture2;\r\nuniform sampler2D u_DiffuseTexture3;\r\nuniform sampler2D u_DiffuseTexture4;\r\nuniform sampler2D u_DiffuseTexture5;\r\n\r\nuniform vec4 u_DiffuseScaleOffset1;\r\nuniform vec4 u_DiffuseScaleOffset2;\r\nuniform vec4 u_DiffuseScaleOffset3;\r\nuniform vec4 u_DiffuseScaleOffset4;\r\nuniform vec4 u_DiffuseScaleOffset5;\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform sampler2D u_LightMap;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 splatAlpha = vec4(1.0);\r\n\t#ifdef ExtendTerrain_DETAIL_NUM1\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r;\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM2\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * (1.0 - splatAlpha.r);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM3\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * (1.0 - splatAlpha.r - splatAlpha.g);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM4\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tvec4 color4 = texture2D(u_DiffuseTexture4, v_Texcoord0 * u_DiffuseScaleOffset4.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * splatAlpha.b + color4.xyz * (1.0 - splatAlpha.r - splatAlpha.g - splatAlpha.b);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM5\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tvec4 color4 = texture2D(u_DiffuseTexture4, v_Texcoord0 * u_DiffuseScaleOffset4.xy);\r\n\t\tvec4 color5 = texture2D(u_DiffuseTexture5, v_Texcoord0 * u_DiffuseScaleOffset5.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * splatAlpha.b + color4.xyz * splatAlpha.a + color5.xyz * (1.0 - splatAlpha.r - splatAlpha.g - splatAlpha.b - splatAlpha.a);\r\n\t#endif\r\n\t\tgl_FragColor.w = splatAlpha.a;\r\n\t\t\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tvec3 normal = v_Normal;\r\n\t\tvec3 dif, spe;\r\n\t#endif\r\n\r\n\tvec3 diffuse = vec3(0.0);\r\n\tvec3 specular= vec3(0.0);\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)\r\n\t\tvec3 toEye;\r\n\t\t#ifdef FOG\r\n\t\t\ttoEye=u_CameraPos-v_PositionWorld;\r\n\t\t\tfloat toEyeLength=length(toEye);\r\n\t\t\ttoEye/=toEyeLength;\r\n\t\t#else\r\n\t\t\ttoEye=normalize(u_CameraPos-v_PositionWorld);\r\n\t\t#endif\r\n\t#endif\r\n\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tLayaAirBlinnPhongDiectionLight(vec3(0.0),1.0,normal,vec3(1.0),toEye,u_DirectionLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,u_PointLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,u_SpotLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t{\r\n\t\t\t\tif(i >= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\tLayaAirBlinnPhongDiectionLight(vec3(0.0),1.0,normal,vec3(1.0),toEye,directionLight,dif,spe);\r\n\t\t\t\tdiffuse+=dif;\r\n\t\t\t\tspecular+=spe;\r\n\t\t\t}\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,pointLight,dif,spe);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye\t,spotLight,dif,spe);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t#endif\r\n\r\nvec3 globalDiffuse = u_AmbientColor;\r\n#ifdef LIGHTMAP\r\n\tglobalDiffuse += decodeHDR(texture2D(u_LightMap, v_LightMapUV),5.0);\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tfloat shadowValue = shadowValue = sampleShadowmap(v_ShadowCoord);\r\n\tgl_FragColor = vec4(gl_FragColor.rgb * (globalDiffuse + diffuse) * shadowValue, gl_FragColor.a);\r\n#else\r\n\tgl_FragColor = vec4(gl_FragColor.rgb * (globalDiffuse + diffuse), gl_FragColor.a);\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tgl_FragColor.rgb += specular * shadowValue;\r\n\t#else\r\n\t\tgl_FragColor.rgb += specular;\r\n\t#endif\r\n#endif\r\n\r\n#ifdef FOG\r\n\tfloat lerpFact=clamp((toEyeLength-u_FogStart)/u_FogRange,0.0,1.0);\r\n\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n#endif\r\n}\r\n\r\n\r\n\r\n\r\n\r\n";
var extendTerrainVS = "#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec2 a_Texcoord0;\r\n\r\nuniform mat4 u_MvpMatrix;\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(LIGHTMAP)\r\n\tattribute vec3 a_Normal;\r\n\tvarying vec3 v_Normal;\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)||(defined(CALCULATE_SHADOWS)&&defined(SHADOWMAP_PSSM1))\r\n\tuniform mat4 u_WorldMat;\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)//shader<65><72><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ĺ겻<C4BA><EAB2BB><EFBFBD><EFBFBD>ifdef <20><><EFBFBD><EFBFBD>ij<EFBFBD>if defined\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tgl_Position = u_MvpMatrix * a_Position;\r\n \r\n\tv_Texcoord0 = a_Texcoord0;\r\n \r\n\t#ifdef LIGHTMAP\r\n\t\tv_LightMapUV = vec2(a_Texcoord0.x, 1.0 - a_Texcoord0.y) * u_LightmapScaleOffset.xy + u_LightmapScaleOffset.zw;\r\n\t\tv_LightMapUV.y = 1.0 - v_LightMapUV.y;\r\n\t#endif\r\n \r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tv_Normal = a_Normal;\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)||(defined(CALCULATE_SHADOWS)&&defined(SHADOWMAP_PSSM1))\r\n\t\tv_PositionWorld=(u_WorldMat*a_Position).xyz;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)//shader<65><72><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ĺ겻<C4BA><EAB2BB><EFBFBD><EFBFBD>ifdef <20><><EFBFBD><EFBFBD>ij<EFBFBD>if defined\r\n\t\tv_ShadowCoord = getShadowCoord(vec4(v_PositionWorld));\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}";
var GlobalIllumination = "struct LayaGIInput\r\n{\r\n\tvec2 lightmapUV;\r\n\tvec3 worldPos;\r\n};\r\n\r\n#define LAYA_SPECCUBE_LOD_STEPS 6.0\r\n\r\nuniform vec3 u_AmbientColor;\r\n\r\n#if defined(GI_AMBIENT_SH)\r\n\tuniform vec4 u_AmbientSHAr;\r\n\tuniform vec4 u_AmbientSHAg;\r\n\tuniform vec4 u_AmbientSHAb;\r\n\tuniform vec4 u_AmbientSHBr;\r\n\tuniform vec4 u_AmbientSHBg;\r\n\tuniform vec4 u_AmbientSHBb;\r\n\tuniform vec4 u_AmbientSHC;\r\n#endif\r\n\r\nuniform samplerCube u_ReflectTexture;\r\nuniform vec4 u_ReflectCubeHDRParams;\r\n\r\n#ifdef SPECCUBE_BOX_PROJECTION\r\n\tuniform vec3 u_SpecCubeProbePosition;\r\n\tuniform vec3 u_SpecCubeBoxMax;\r\n\tuniform vec3 u_SpecCubeBoxMin;\r\n#endif\r\n\r\n\r\n#ifdef GI_AMBIENT_SH\r\n\tmediump vec3 shEvalLinearL0L1(mediump vec4 normal)\r\n\t{\r\n\t\tmediump vec3 x;\r\n\t\t// Linear (L1) + constant (L0) polynomial terms\r\n\t\tx.r = dot(u_AmbientSHAr, normal);\r\n\t\tx.g = dot(u_AmbientSHAg, normal);\r\n\t\tx.b = dot(u_AmbientSHAb, normal);\r\n\t\treturn x;\r\n\t}\r\n\r\n\tmediump vec3 shEvalLinearL2(mediump vec4 normal)\r\n\t{\r\n\t\tmediump vec3 x1,x2;\r\n\t\t// 4 of the quadratic (L2) polynomials\r\n\t\tmediump vec4 vB = normal.xyzz * normal.yzzx;\r\n\t\tx1.r = dot(u_AmbientSHBr, vB);\r\n\t\tx1.g = dot(u_AmbientSHBg, vB);\r\n\t\tx1.b = dot(u_AmbientSHBb, vB);\r\n\r\n\t\t// Final (5th) quadratic (L2) polynomial\r\n\t\tmediump float vC = normal.x*normal.x - normal.y*normal.y;\r\n\t\tx2 = u_AmbientSHC.rgb * vC;\r\n\r\n\t\treturn x1 + x2;\r\n\t}\r\n\t\r\n\tmediump vec3 shadeSHPerPixel(mediump vec3 normal)\r\n\t{\r\n\t\tmediump vec3 ambientContrib;\r\n\t\tmediump vec4 normalV4=vec4(-normal.x,normal.yz, 1.0);//Note:SH Data is left-hand,so x need inverse\r\n\t\tambientContrib = shEvalLinearL0L1(normalV4);\r\n\t\tambientContrib += shEvalLinearL2(normalV4);\r\n\t\tmediump vec3 ambient = max(vec3(0.0), ambientContrib);\r\n\t\tambient = layaLinearToGammaSpace(ambient);\r\n\t\treturn ambient;\r\n\t}\r\n#endif\r\n\r\n\r\n\r\n mediump vec3 BoxProjectedCubemapDirection(mediump vec3 worldRefl,mediump vec3 worldPos,mediump vec3 cubemapCenter,mediump vec3 boxMin,mediump vec3 boxMax){\r\n\t mediump vec3 nrdir = normalize(worldRefl);\r\n\t mediump vec3 rbmax = (boxMax - worldPos);\r\n\t mediump vec3 rbmin = (boxMin - worldPos);\r\n\t mediump vec3 select = step(vec3(0.0), worldRefl);\r\n\t mediump vec3 rbminmax = mix(rbmin, rbmax, select);\r\n\trbminmax = rbminmax / nrdir;\r\n\tmediump float scalar = min(min(rbminmax.x, rbminmax.y), rbminmax.z);\r\n\t mediump vec3 worldChangeRefl = nrdir * scalar + (worldPos - cubemapCenter);\r\n\treturn worldChangeRefl;\r\n}\r\n\r\n\r\nmediump vec3 layaDecodeDirectionalLightmap (mediump vec3 color, lowp vec4 dirTex, mediump vec3 normalWorld)\r\n{\r\n // In directional (non-specular) mode Enlighten bakes dominant light direction\r\n // in a way, that using it for half Lambert and then dividing by a \"rebalancing coefficient\"\r\n // gives a result close to plain diffuse response lightmaps, but normalmapped.\r\n\r\n // Note that dir is not unit length on purpose. Its length is \"directionality\", like\r\n // for the directional specular lightmaps.\r\n\tlowp vec3 directional=dirTex.xyz - 0.5;\r\n\tdirectional.x=-directional.x;//NOTE:because coord System\r\n mediump float halfLambert = dot(normalWorld,directional) + 0.5;\r\n\r\n return color * halfLambert / max(1e-4, dirTex.w);\r\n}\r\n\r\nvec3 layaGIBase(LayaGIInput giInput,mediump float occlusion, mediump vec3 normalWorld)\r\n{\r\n\tvec3 indirectDiffuse;\r\n\t#ifdef LIGHTMAP\t\r\n\t\tmediump vec3 bakedColor =decodeHDR(texture2D(u_LightMap, giInput.lightmapUV),5.0);\r\n\t\t#ifdef LIGHTMAP_DIRECTIONAL\r\n\t\t\tlowp vec4 bakedDirTex = texture2D (u_LightMapDirection, giInput.lightmapUV);\r\n indirectDiffuse = layaDecodeDirectionalLightmap (bakedColor, bakedDirTex, normalWorld);\r\n\t\t#else //unDirectional lightmap\r\n\t\t\tindirectDiffuse = bakedColor;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef GI_AMBIENT_SH\r\n\t\t\tindirectDiffuse = shadeSHPerPixel(normalWorld);\r\n\t\t#else\r\n\t\t\tindirectDiffuse = u_AmbientColor; //already in gamma space\r\n\t\t#endif\r\n\t#endif\r\n\r\n\tindirectDiffuse*=occlusion;\r\n\treturn indirectDiffuse;\r\n}\r\n\r\nmediump vec3 layaGlossyEnvironment(mediump vec4 glossIn)\r\n{\r\n\tmediump float perceptualRoughness = glossIn.a;\r\n\r\n\t// use approximation to solve,below is more reasonable,but maybe slow. \r\n\t// float m = perceptualRoughnessToRoughness(perceptualRoughness); // m is the real roughness parameter\r\n // const float fEps = 1.192092896e-07F; // smallest such that 1.0+FLT_EPSILON != 1.0 (+1e-4h is NOT good here. is visibly very wrong)\r\n // float n = (2.0/max(fEps, m*m))-2.0; // remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf\r\n // n /= 4; // remap from n_dot_h formulatino to n_dot_r. See section \"Pre-convolved Cube Maps vs Path Tracers\" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html\r\n // perceptualRoughness = pow( 2/(n+2), 0.25); // remap back to square root of real roughness (0.25 include both the sqrt root of the conversion and sqrt for going from roughness to perceptualRoughness)\r\n\tperceptualRoughness = perceptualRoughness * (1.7 - 0.7*perceptualRoughness);//just a approximation,but fast.\r\n \r\n\tmediump float mip = perceptualRoughness * LAYA_SPECCUBE_LOD_STEPS;\r\n\tmediump vec3 uvw = glossIn.rgb;\r\n\tuvw.x=-uvw.x;//Note:reflectCube is left-hand,so x need inverse\r\n\tmediump vec4 rgbm=textureCubeLodEXT(u_ReflectTexture,uvw,mip);\r\n\treturn decodeHDR(rgbm,u_ReflectCubeHDRParams.x);\r\n}\r\n\r\nmediump vec3 layaGIIndirectSpecular(LayaGIInput giInput,mediump float occlusion, vec4 glossIn)\r\n{\r\n\t#ifdef SPECCUBE_BOX_PROJECTION\r\n\t\tvec3 originalReflUVW = glossIn.xyz;\r\n\t\tglossIn.xyz =BoxProjectedCubemapDirection(originalReflUVW,giInput.worldPos,u_SpecCubeProbePosition,u_SpecCubeBoxMin,u_SpecCubeBoxMax);\r\n\t#endif\r\n\tmediump vec3 specular = layaGlossyEnvironment(glossIn);\r\n\treturn specular * occlusion;\r\n}\r\n\r\n\r\nLayaGI layaGlobalIllumination(LayaGIInput giInput,mediump float occlusion, mediump vec3 normalWorld,mediump vec4 uvwRoughness)\r\n{\r\n\tLayaGI gi;\r\n\tgi.diffuse = layaGIBase(giInput,occlusion, normalWorld);\r\n\tgi.specular = layaGIIndirectSpecular(giInput,occlusion, uvwRoughness);\r\n\treturn gi;\r\n}\r\n\r\n\r\n";
var LightingGLSL = "#ifdef GRAPHICS_API_GLES3\r\n\t#define INVERSE_MAT(mat) inverse(mat)\r\n#else\r\n\t#define INVERSE_MAT(mat) inverseMat(mat)\r\n#endif\r\n\r\nstruct DirectionLight {\r\n\tvec3 color;\r\n\tvec3 direction;\r\n};\r\n\r\nstruct PointLight {\r\n\tvec3 color;\r\n\tvec3 position;\r\n\tfloat range;\r\n};\r\n\r\nstruct SpotLight {\r\n\tvec3 color;\r\n\tvec3 position;\r\n\tfloat range;\r\n\tvec3 direction;\r\n\tfloat spot;\r\n};\r\n\r\nstruct LayaGI{\r\n\tvec3 diffuse;\r\n\tvec3 specular;\r\n};\r\n\r\nstruct LayaLight{\r\n\tvec3 color;\r\n\tvec3 dir;\r\n};\r\n\r\nconst int c_ClusterBufferWidth = CLUSTER_X_COUNT*CLUSTER_Y_COUNT;\r\nconst int c_ClusterBufferHeight = CLUSTER_Z_COUNT*(1+int(ceil(float(MAX_LIGHT_COUNT_PER_CLUSTER)/4.0)));\r\nconst int c_ClusterBufferFloatWidth = c_ClusterBufferWidth*4;\r\n\r\n#ifndef GRAPHICS_API_GLES3\r\n\tmat2 inverseMat(mat2 m) {\r\n\t\treturn mat2(m[1][1],-m[0][1],\r\n\t\t\t\t-m[1][0], m[0][0]) / (m[0][0]*m[1][1] - m[0][1]*m[1][0]);\r\n\t}\r\n\tmat3 inverseMat(mat3 m) {\r\n\t\tfloat a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];\r\n\t\tfloat a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];\r\n\t\tfloat a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];\r\n\r\n\t\tfloat b01 = a22 * a11 - a12 * a21;\r\n\t\tfloat b11 = -a22 * a10 + a12 * a20;\r\n\t\tfloat b21 = a21 * a10 - a11 * a20;\r\n\r\n\t\tfloat det = a00 * b01 + a01 * b11 + a02 * b21;\r\n\r\n\t\treturn mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),\r\n\t\t\t\t\tb11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),\r\n\t\t\t\t\tb21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;\r\n\t}\r\n\tmat4 inverseMat(mat4 m) {\r\n\t\tfloat\r\n\t\t\ta00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],\r\n\t\t\ta10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],\r\n\t\t\ta20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],\r\n\t\t\ta30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],\r\n\r\n\t\t\tb00 = a00 * a11 - a01 * a10,\r\n\t\t\tb01 = a00 * a12 - a02 * a10,\r\n\t\t\tb02 = a00 * a13 - a03 * a10,\r\n\t\t\tb03 = a01 * a12 - a02 * a11,\r\n\t\t\tb04 = a01 * a13 - a03 * a11,\r\n\t\t\tb05 = a02 * a13 - a03 * a12,\r\n\t\t\tb06 = a20 * a31 - a21 * a30,\r\n\t\t\tb07 = a20 * a32 - a22 * a30,\r\n\t\t\tb08 = a20 * a33 - a23 * a30,\r\n\t\t\tb09 = a21 * a32 - a22 * a31,\r\n\t\t\tb10 = a21 * a33 - a23 * a31,\r\n\t\t\tb11 = a22 * a33 - a23 * a32,\r\n\r\n\t\t\tdet = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\r\n\r\n\t\treturn mat4(\r\n\t\t\ta11 * b11 - a12 * b10 + a13 * b09,\r\n\t\t\ta02 * b10 - a01 * b11 - a03 * b09,\r\n\t\t\ta31 * b05 - a32 * b04 + a33 * b03,\r\n\t\t\ta22 * b04 - a21 * b05 - a23 * b03,\r\n\t\t\ta12 * b08 - a10 * b11 - a13 * b07,\r\n\t\t\ta00 * b11 - a02 * b08 + a03 * b07,\r\n\t\t\ta32 * b02 - a30 * b05 - a33 * b01,\r\n\t\t\ta20 * b05 - a22 * b02 + a23 * b01,\r\n\t\t\ta10 * b10 - a11 * b08 + a13 * b06,\r\n\t\t\ta01 * b08 - a00 * b10 - a03 * b06,\r\n\t\t\ta30 * b04 - a31 * b02 + a33 * b00,\r\n\t\t\ta21 * b02 - a20 * b04 - a23 * b00,\r\n\t\t\ta11 * b07 - a10 * b09 - a12 * b06,\r\n\t\t\ta00 * b09 - a01 * b07 + a02 * b06,\r\n\t\t\ta31 * b01 - a30 * b03 - a32 * b00,\r\n\t\t\ta20 * b03 - a21 * b01 + a22 * b00) / det;\r\n\t}\r\n#endif\r\n\r\n\t#ifdef THICKNESSMAP\r\n\t\tuniform sampler2D u_ThinknessTexture;\r\n\t#endif\r\n#ifdef ENABLETRANSMISSION\r\n\tuniform float u_TransmissionRate;\r\n\tuniform float u_BackDiffuse;\r\n\tuniform float u_BackScale;\r\n\tuniform vec4 u_TransmissionColor;\r\n\r\n\r\n\tvec3 SubSurfaceIBack(vec3 lightDir,vec3 viewDir,float thinknessFactor){\r\n\t\tvec3 H = normalize(lightDir);\r\n\t\tfloat VdotH = pow(clamp(dot(viewDir,H),0.0,1.0),u_BackDiffuse)*u_BackScale;\r\n\t\tvec3 I;\r\n\t\t#ifdef THICKNESSMAP\r\n\t\t\tI = u_TransmissionColor.rgb*VdotH*thinknessFactor;\r\n\t\t#else\r\n\t\t\tI = u_TransmissionColor.rgb*VdotH;\r\n\t\t#endif\r\n\t\treturn I;\r\n\t}\r\n#endif\r\n\r\nivec4 getClusterInfo(sampler2D clusterBuffer,mat4 viewMatrix,vec4 viewport,vec3 position,vec4 fragCoord,vec4 projectParams)\r\n{\r\n\tvec3 viewPos = vec3(viewMatrix*vec4(position, 1.0)); //position in viewspace\r\n\r\n\tint clusterXIndex = int(floor(fragCoord.x/ (float(viewport.z)/float(CLUSTER_X_COUNT))));\r\n int clusterYIndex = int(floor((viewport.w * (projectParams.z <0.0? 0.0 : 1.0) - fragCoord.y * projectParams.z)/ (float(viewport.w)/float(CLUSTER_Y_COUNT))));//Maybe Flipped ProjectMatrix\r\n\tfloat zSliceParam =float(CLUSTER_Z_COUNT)/log2(projectParams.y / projectParams.x);\r\n \tint clusterZIndex = int(floor(log2(-viewPos.z) * zSliceParam- log2(projectParams.x) * zSliceParam));//projectParams x:cameraNear y:cameraFar\r\n\r\n\tvec2 uv= vec2((float(clusterXIndex + clusterYIndex * CLUSTER_X_COUNT)+0.5)/float(c_ClusterBufferWidth),\r\n\t\t\t\t(float(clusterZIndex)+0.5)/float(c_ClusterBufferHeight));\r\n\tvec4 clusterPixel=texture2D(clusterBuffer, uv);\r\n\treturn ivec4(clusterPixel);//X:Point Count Y:Spot Count Z、W:Light Offset\r\n}\r\n\r\n\r\nint getLightIndex(sampler2D clusterBuffer,int offset,int index) \r\n{\r\n\tint totalOffset=offset+index;\r\n\tint row=totalOffset/c_ClusterBufferFloatWidth;\r\n\tint lastRowFloat=totalOffset-row*c_ClusterBufferFloatWidth;\r\n\tint col=lastRowFloat/4;\r\n\tvec2 uv=vec2((float(col)+0.5)/float(c_ClusterBufferWidth),\r\n\t\t\t\t(float(row)+0.5)/float(c_ClusterBufferHeight));\r\n\tvec4 texel = texture2D(clusterBuffer, uv);\r\n int pixelComponent = lastRowFloat-col*4;\r\n if (pixelComponent == 0) \r\n return int(texel.x);\r\n else if (pixelComponent == 1) \r\n return int(texel.y);\r\n else if (pixelComponent == 2) \r\n return int(texel.z);\r\n else //pixelComponent==3\r\n return int(texel.w);\r\n}\r\n\r\nDirectionLight getDirectionLight(sampler2D lightBuffer,int index) \r\n{\r\n DirectionLight light;\r\n float v = (float(index)+0.5)/ float(MAX_LIGHT_COUNT);\r\n vec4 p1 = texture2D(lightBuffer, vec2(0.125,v));\r\n vec4 p2 = texture2D(lightBuffer, vec2(0.375,v));\r\n\tlight.color=p1.rgb;\r\n light.direction = p2.rgb;\r\n return light;\r\n}\r\n\r\nPointLight getPointLight(sampler2D lightBuffer,sampler2D clusterBuffer,ivec4 clusterInfo,int index) \r\n{\r\n PointLight light;\r\n\tint pointIndex=getLightIndex(clusterBuffer,clusterInfo.z*c_ClusterBufferFloatWidth+clusterInfo.w,index);\r\n float v = (float(pointIndex)+0.5)/ float(MAX_LIGHT_COUNT);\r\n vec4 p1 = texture2D(lightBuffer, vec2(0.125,v));\r\n vec4 p2 = texture2D(lightBuffer, vec2(0.375,v));\r\n\tlight.color=p1.rgb;\r\n\tlight.range = p1.a;\r\n light.position = p2.rgb;\r\n return light;\r\n}\r\n\r\nSpotLight getSpotLight(sampler2D lightBuffer,sampler2D clusterBuffer,ivec4 clusterInfo,int index) \r\n{\r\n SpotLight light;\r\n\tint spoIndex=getLightIndex(clusterBuffer,clusterInfo.z*c_ClusterBufferFloatWidth+clusterInfo.w,clusterInfo.x+index);\r\n float v = (float(spoIndex)+0.5)/ float(MAX_LIGHT_COUNT);\r\n vec4 p1 = texture2D(lightBuffer, vec2(0.125,v));\r\n vec4 p2 = texture2D(lightBuffer, vec2(0.375,v));\r\n\tvec4 p3 = texture2D(lightBuffer, vec2(0.625,v));\r\n light.color = p1.rgb;\r\n\tlight.range=p1.a;\r\n light.position = p2.rgb;\r\n\tlight.spot = p2.a;\r\n\tlight.direction = p3.rgb;\r\n return light;\r\n}\r\n\r\n// Laya中使用衰减纹理\r\nfloat LayaAttenuation(in vec3 L,in float invLightRadius) {\r\n\tfloat fRatio = clamp(length(L) * invLightRadius,0.0,1.0);\r\n\tfRatio *= fRatio;\r\n\treturn 1.0 / (1.0 + 25.0 * fRatio)* clamp(4.0*(1.0 - fRatio),0.0,1.0); //fade to black as if 4 pixel texture\r\n}\r\n\r\n// Same as Just Cause 2 and Crysis 2 (you can read GPU Pro 1 book for more information)\r\nfloat BasicAttenuation(in vec3 L,in float invLightRadius) {\r\n\tvec3 distance = L * invLightRadius;\r\n\tfloat attenuation = clamp(1.0 - dot(distance, distance),0.0,1.0); // Equals float attenuation = saturate(1.0f - dot(L, L) / (lightRadius * lightRadius));\r\n\treturn attenuation * attenuation;\r\n}\r\n\r\n// Inspired on http://fools.slindev.com/viewtopic.php?f=11&t=21&view=unread#unread\r\nfloat NaturalAttenuation(in vec3 L,in float invLightRadius) {\r\n\tfloat attenuationFactor = 30.0;\r\n\tvec3 distance = L * invLightRadius;\r\n\tfloat attenuation = dot(distance, distance); // Equals float attenuation = dot(L, L) / (lightRadius * lightRadius);\r\n\tattenuation = 1.0 / (attenuation * attenuationFactor + 1.0);\r\n\t// Second we move down the function therewith it reaches zero at abscissa 1:\r\n\tattenuationFactor = 1.0 / (attenuationFactor + 1.0); //attenuationFactor contains now the value we have to subtract\r\n\tattenuation = max(attenuation - attenuationFactor, 0.0); // The max fixes a bug.\r\n\t// Finally we expand the equation along the y-axis so that it starts with a function value of 1 again.\r\n\tattenuation /= 1.0 - attenuationFactor;\r\n\treturn attenuation;\r\n}\r\n\r\nvoid LayaAirBlinnPhongLight (in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir,in vec3 lightColor, in vec3 lightVec,out vec3 diffuseColor,out vec3 specularColor) {\r\n\tmediump vec3 h = normalize(viewDir-lightVec);\r\n\tlowp float ln = max (0.0, dot (-lightVec,normal));\r\n\tfloat nh = max (0.0, dot (h,normal));\r\n\tdiffuseColor=lightColor * ln;\r\n\tspecularColor=lightColor *specColor*pow (nh, specColorIntensity*128.0) * gloss;\r\n}\r\n\r\nvoid LayaAirBlinnPhongDiectionLight (in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in DirectionLight light,float thinknessFactor,out vec3 diffuseColor,out vec3 specularColor,out vec3 transmisColor) {\r\n\tvec3 lightVec=normalize(light.direction);\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,lightVec,diffuseColor,specularColor);\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tdiffuseColor *= u_TransmissionRate;\r\n\t\ttransmisColor = SubSurfaceIBack(lightVec, viewDir,thinknessFactor)*light.color.rgb*(1.0-u_TransmissionRate);\r\n\t#endif\r\n}\r\n\r\n\r\nvoid LayaAirBlinnPhongDiectionLight (in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in DirectionLight light,out vec3 diffuseColor,out vec3 specularColor) {\r\n\tvec3 lightVec=normalize(light.direction);\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,lightVec,diffuseColor,specularColor);\r\n}\r\n\r\n\r\nvoid LayaAirBlinnPhongPointLight (in vec3 pos,in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in PointLight light,float thinknessFactor,out vec3 diffuseColor,out vec3 specularColor,out vec3 transmisColor) {\r\n\tvec3 lightVec = pos-light.position;\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,lightVec/length(lightVec),diffuseColor,specularColor);\r\n\tfloat attenuate = LayaAttenuation(lightVec, 1.0/light.range);\r\n\tdiffuseColor *= attenuate;\r\n\tspecularColor*= attenuate;\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tdiffuseColor *= u_TransmissionRate;\r\n\t\ttransmisColor = SubSurfaceIBack(lightVec, viewDir,thinknessFactor)*light.color.rgb*(1.0-u_TransmissionRate)*attenuate;\r\n\t#endif\r\n}\r\n\r\nvoid LayaAirBlinnPhongPointLight (in vec3 pos,in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in PointLight light,out vec3 diffuseColor,out vec3 specularColor) {\r\n\tvec3 lightVec = pos-light.position;\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,lightVec/length(lightVec),diffuseColor,specularColor);\r\n\tfloat attenuate = LayaAttenuation(lightVec, 1.0/light.range);\r\n\tdiffuseColor *= attenuate;\r\n\tspecularColor*= attenuate;\r\n}\r\n\r\nvoid LayaAirBlinnPhongSpotLight (in vec3 pos,in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in SpotLight light,float thinknessFactor,out vec3 diffuseColor,out vec3 specularColor,out vec3 transmisColor) {\r\n\tvec3 lightVec = pos-light.position;\r\n\tvec3 normalLightVec=lightVec/length(lightVec);\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,normalLightVec,diffuseColor,specularColor);\r\n\tvec2 cosAngles=cos(vec2(light.spot,light.spot*0.5)*0.5);//ConeAttenuation\r\n\tfloat dl=dot(normalize(light.direction),normalLightVec);\r\n\tdl*=smoothstep(cosAngles[0],cosAngles[1],dl);\r\n\tfloat attenuate = LayaAttenuation(lightVec, 1.0/light.range)*dl;\r\n\tdiffuseColor *=attenuate;\r\n\tspecularColor *=attenuate;\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tdiffuseColor *= u_TransmissionRate;\r\n\t\ttransmisColor = SubSurfaceIBack(lightVec, viewDir,thinknessFactor)*light.color.rgb*(1.0-u_TransmissionRate)*attenuate;\r\n\t#endif\r\n}\r\n\r\nvoid LayaAirBlinnPhongSpotLight (in vec3 pos,in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in SpotLight light,out vec3 diffuseColor,out vec3 specularColor) {\r\n\tvec3 lightVec = pos-light.position;\r\n\tvec3 normalLightVec=lightVec/length(lightVec);\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,normalLightVec,diffuseColor,specularColor);\r\n\tvec2 cosAngles=cos(vec2(light.spot,light.spot*0.5)*0.5);//ConeAttenuation\r\n\tfloat dl=dot(normalize(light.direction),normalLightVec);\r\n\tdl*=smoothstep(cosAngles[0],cosAngles[1],dl);\r\n\tfloat attenuate = LayaAttenuation(lightVec, 1.0/light.range)*dl;\r\n\tdiffuseColor *=attenuate;\r\n\tspecularColor *=attenuate;\r\n}\r\n\r\n\r\n\r\n\r\nvec3 NormalSampleToWorldSpace(vec3 normalMapSample, vec3 unitNormal, vec3 tangent,vec3 binormal) {\r\n\tvec3 normalT =vec3(2.0*normalMapSample.x - 1.0,1.0-2.0*normalMapSample.y,2.0*normalMapSample.z - 1.0);\r\n\tmediump vec3 N = unitNormal;\r\n\tmediump vec3 T = tangent;\r\n\tmediump vec3 B = binormal;\r\n\tmat3 TBN = mat3(T, B, N);\r\n\r\n\t// Transform from tangent space to world space.\r\n\tvec3 bumpedNormal =normalize(TBN*normalT);\r\n\treturn bumpedNormal;\r\n}\r\n\r\nvec3 NormalSampleToWorldSpace1(vec4 normalMapSample, vec3 tangent, vec3 binormal, vec3 unitNormal) {\r\n\tvec3 normalT;\r\n\tnormalT.x = 2.0 * normalMapSample.x - 1.0;\r\n\tnormalT.y = 1.0 - 2.0 * normalMapSample.y;\r\n\tnormalT.z = sqrt(1.0 - clamp(dot(normalT.xy, normalT.xy), 0.0, 1.0));\r\n\r\n\tvec3 T = normalize(tangent);\r\n\tvec3 B = normalize(binormal);\r\n\tvec3 N = normalize(unitNormal);\r\n\tmat3 TBN = mat3(T, B, N);\r\n\r\n\t// Transform from tangent space to world space.\r\n\tvec3 bumpedNormal = TBN * normalize(normalT);\r\n\r\n\treturn bumpedNormal;\r\n}\r\n\r\nvec3 DecodeLightmap(vec4 color) {\r\n\treturn color.rgb*color.a*5.0;\r\n}\r\n\r\nvec3 decodeHDR(vec4 color,float range) {\r\n\treturn color.rgb*color.a*range;\r\n}\r\n\r\nvec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {\r\n\tvec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);\r\n\ttransTexcoord.y+=1.0;\r\n\treturn transTexcoord;\r\n}\r\n\r\nvec4 remapGLPositionZ(vec4 position) {\r\n\tposition.z=position.z * 2.0 - position.w;\r\n\treturn position;\r\n}\r\n\r\nmediump vec3 layaLinearToGammaSpace (mediump vec3 linRGB)\r\n{\r\n linRGB = max(linRGB, vec3(0.0));\r\n // An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1\r\n return max(1.055 * pow(linRGB,vec3(0.416666667)) - 0.055, 0.0); \r\n}\r\n\r\nLayaLight layaDirectionLightToLight(in DirectionLight light,in float attenuate)\r\n{\r\n\tLayaLight relight;\r\n\trelight.color = light.color*attenuate;\r\n\trelight.dir = light.direction;\r\n\treturn relight;\r\n}\r\n\r\nLayaLight layaPointLightToLight(in vec3 pos,in vec3 normal, in PointLight light,in float attenuate)\r\n{\r\n\tLayaLight relight;\r\n\tvec3 lightVec = pos-light.position;\r\n\tattenuate *= LayaAttenuation(lightVec, 1.0/light.range);\r\n\trelight.color = light.color*attenuate;\r\n\trelight.dir = normalize(lightVec);\r\n\treturn relight;\r\n}\r\n\r\nLayaLight layaSpotLightToLight(in vec3 pos,in vec3 normal, in SpotLight light,in float attenuate)\r\n{\r\n\tLayaLight relight;\r\n\tvec3 lightVec = pos-light.position;\r\n\tvec3 normalLightVec=lightVec/length(lightVec);\r\n\tvec2 cosAngles=cos(vec2(light.spot,light.spot*0.5)*0.5);//ConeAttenuation\r\n\tfloat dl=dot(normalize(light.direction),normalLightVec);\r\n\tdl*=smoothstep(cosAngles[0],cosAngles[1],dl);\r\n\tattenuate *= LayaAttenuation(lightVec, 1.0/light.range)*dl;\r\n\trelight.dir = normalLightVec;\r\n\trelight.color = light.color*attenuate;\r\n\treturn relight;\r\n}\r\n\r\n\r\n\r\n\r\n";
var ShadowSampleTentGLSL = "// ------------------------------------------------------------------\r\n// PCF Filtering Tent Functions\r\n// ------------------------------------------------------------------\r\n\r\n// Assuming a isoceles right angled triangle of height \"triangleHeight\" (as drawn below).\r\n// This function return the area of the triangle above the first texel(in Y the first texel).\r\n//\r\n// |\\ <-- 45 degree slop isosceles right angled triangle\r\n// | \\\r\n// ---- <-- length of this side is \"triangleHeight\"\r\n// _ _ _ _ <-- texels\r\nfloat sampleShadowGetIRTriangleTexelArea(float triangleHeight)\r\n{\r\n return triangleHeight - 0.5;\r\n}\r\n\r\n// Assuming a isoceles triangle of 1.5 texels height and 3 texels wide lying on 4 texels.\r\n// This function return the area of the triangle above each of those texels.\r\n// | <-- offset from -0.5 to 0.5, 0 meaning triangle is exactly in the center\r\n// / \\ <-- 45 degree slop isosceles triangle (ie tent projected in 2D)\r\n// / \\\r\n// _ _ _ _ <-- texels\r\n// X Y Z W <-- result indices (in computedArea.xyzw and computedAreaUncut.xyzw)\r\n// Top point at (right,top) in a texel,left bottom point at (middle,middle) in a texel,right bottom point at (middle,middle) in a texel.\r\nvoid sampleShadowGetTexelAreasTent3x3(float offset, out vec4 computedArea, out vec4 computedAreaUncut)\r\n{\r\n // Compute the exterior areas,a and h is same.\r\n float a = offset + 0.5;\r\n float offsetSquaredHalved = a * a * 0.5;\r\n computedAreaUncut.x = computedArea.x = offsetSquaredHalved - offset;\r\n computedAreaUncut.w = computedArea.w = offsetSquaredHalved;\r\n\r\n // Compute the middle areas\r\n // For Y : We find the area in Y of as if the left section of the isoceles triangle would\r\n // intersect the axis between Y and Z (ie where offset = 0).\r\n computedAreaUncut.y = sampleShadowGetIRTriangleTexelArea(1.5 - offset);\r\n // This area is superior to the one we are looking for if (offset < 0) thus we need to\r\n // subtract the area of the triangle defined by (0,1.5-offset), (0,1.5+offset), (-offset,1.5).\r\n float clampedOffsetLeft = min(offset,0.0);\r\n float areaOfSmallLeftTriangle = clampedOffsetLeft * clampedOffsetLeft;\r\n computedArea.y = computedAreaUncut.y - areaOfSmallLeftTriangle;\r\n\r\n // We do the same for the Z but with the right part of the isoceles triangle\r\n computedAreaUncut.z = sampleShadowGetIRTriangleTexelArea(1.5 + offset);\r\n float clampedOffsetRight = max(offset,0.0);\r\n float areaOfSmallRightTriangle = clampedOffsetRight * clampedOffsetRight;\r\n computedArea.z = computedAreaUncut.z - areaOfSmallRightTriangle;\r\n}\r\n\r\n// Assuming a isoceles triangle of 2.5 texel height and 5 texels wide lying on 6 texels.\r\n// This function return the weight of each texels area relative to the full triangle area.\r\n// / \\\r\n// _ _ _ _ _ _ <-- texels\r\n// 0 1 2 3 4 5 <-- computed area indices (in texelsWeights[])\r\n// Top point at (right,top) in a texel,left bottom point at (middle,middle) in a texel,right bottom point at (middle,middle) in a texel.\r\nvoid sampleShadowGetTexelWeightsTent5x5(float offset, out vec3 texelsWeightsA, out vec3 texelsWeightsB)\r\n{\r\n vec4 areaFrom3texelTriangle;\r\n vec4 areaUncutFrom3texelTriangle;\r\n sampleShadowGetTexelAreasTent3x3(offset, areaFrom3texelTriangle, areaUncutFrom3texelTriangle);\r\n\r\n // Triangle slope is 45 degree thus we can almost reuse the result of the 3 texel wide computation.\r\n // the 5 texel wide triangle can be seen as the 3 texel wide one but shifted up by one unit/texel.\r\n // 0.16 is 1/(the triangle area)\r\n texelsWeightsA.x = 0.16 * (areaFrom3texelTriangle.x);\r\n texelsWeightsA.y = 0.16 * (areaUncutFrom3texelTriangle.y);\r\n texelsWeightsA.z = 0.16 * (areaFrom3texelTriangle.y + 1.0);\r\n texelsWeightsB.x = 0.16 * (areaFrom3texelTriangle.z + 1.0);\r\n texelsWeightsB.y = 0.16 * (areaUncutFrom3texelTriangle.z);\r\n texelsWeightsB.z = 0.16 * (areaFrom3texelTriangle.w);\r\n}\r\n\r\n// 5x5 Tent filter (45 degree sloped triangles in U and V)\r\nvoid sampleShadowComputeSamplesTent5x5(vec4 shadowMapTextureTexelSize, vec2 coord, out float fetchesWeights[9], out vec2 fetchesUV[9])\r\n{\r\n // tent base is 5x5 base thus covering from 25 to 36 texels, thus we need 9 bilinear PCF fetches\r\n vec2 tentCenterInTexelSpace = coord.xy * shadowMapTextureTexelSize.zw;\r\n vec2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);\r\n vec2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;\r\n\r\n // find the weight of each texel based on the area of a 45 degree slop tent above each of them.\r\n vec3 texelsWeightsUA, texelsWeightsUB;\r\n vec3 texelsWeightsVA, texelsWeightsVB;\r\n sampleShadowGetTexelWeightsTent5x5(offsetFromTentCenterToCenterOfFetches.x, texelsWeightsUA, texelsWeightsUB);\r\n sampleShadowGetTexelWeightsTent5x5(offsetFromTentCenterToCenterOfFetches.y, texelsWeightsVA, texelsWeightsVB);\r\n\r\n // each fetch will cover a group of 2x2 texels, the weight of each group is the sum of the weights of the texels\r\n vec3 fetchesWeightsU = vec3(texelsWeightsUA.xz, texelsWeightsUB.y) + vec3(texelsWeightsUA.y, texelsWeightsUB.xz);\r\n vec3 fetchesWeightsV = vec3(texelsWeightsVA.xz, texelsWeightsVB.y) + vec3(texelsWeightsVA.y, texelsWeightsVB.xz);\r\n\r\n // move the PCF bilinear fetches to respect texels weights\r\n vec3 fetchesOffsetsU = vec3(texelsWeightsUA.y, texelsWeightsUB.xz) / fetchesWeightsU.xyz + vec3(-2.5,-0.5,1.5);\r\n vec3 fetchesOffsetsV = vec3(texelsWeightsVA.y, texelsWeightsVB.xz) / fetchesWeightsV.xyz + vec3(-2.5,-0.5,1.5);\r\n fetchesOffsetsU *= shadowMapTextureTexelSize.xxx;\r\n fetchesOffsetsV *= shadowMapTextureTexelSize.yyy;\r\n\r\n vec2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTextureTexelSize.xy;\r\n fetchesUV[0] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.x);\r\n fetchesUV[1] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.x);\r\n fetchesUV[2] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.x);\r\n fetchesUV[3] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.y);\r\n fetchesUV[4] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.y);\r\n fetchesUV[5] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.y);\r\n fetchesUV[6] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.z);\r\n fetchesUV[7] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.z);\r\n fetchesUV[8] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.z);\r\n\r\n fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;\r\n fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;\r\n fetchesWeights[2] = fetchesWeightsU.z * fetchesWeightsV.x;\r\n fetchesWeights[3] = fetchesWeightsU.x * fetchesWeightsV.y;\r\n fetchesWeights[4] = fetchesWeightsU.y * fetchesWeightsV.y;\r\n fetchesWeights[5] = fetchesWeightsU.z * fetchesWeightsV.y;\r\n fetchesWeights[6] = fetchesWeightsU.x * fetchesWeightsV.z;\r\n fetchesWeights[7] = fetchesWeightsU.y * fetchesWeightsV.z;\r\n fetchesWeights[8] = fetchesWeightsU.z * fetchesWeightsV.z;\r\n}";
var LayaUtile = "\r\n\r\n//SimpleSkinnedMesh\r\n#ifdef SIMPLEBONE\r\n\t#ifdef GPU_INSTANCE\r\n\t\tattribute vec4 a_SimpleTextureParams;\r\n\t#else\r\n\t\tuniform vec4 u_SimpleAnimatorParams;\r\n\t#endif\r\n\tuniform sampler2D u_SimpleAnimatorTexture;\r\n\r\n\tuniform float u_SimpleAnimatorTextureSize; \r\n#endif\r\n\r\n\r\n#ifdef SIMPLEBONE\r\n\tmat4 loadMatFromTexture(float FramePos,int boneIndices,float offset)\r\n\t{\r\n\t\tvec2 uv;\r\n\t\tfloat PixelPos = FramePos+float(boneIndices)*4.0;\r\n\t\tfloat halfOffset = offset * 0.5;\r\n\t\tfloat uvoffset = PixelPos/u_SimpleAnimatorTextureSize;\r\n\t\tuv.y = floor(uvoffset)*offset+halfOffset;\r\n\t\tuv.x = mod(float(PixelPos),u_SimpleAnimatorTextureSize)*offset+halfOffset;\r\n\t\tvec4 mat0row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat1row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat2row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat3row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tmat4 m =mat4(mat0row.x,mat0row.y,mat0row.z,mat0row.w,\r\n\t\t\t\tmat1row.x,mat1row.y,mat1row.z,mat1row.w,\r\n\t\t\t\tmat2row.x,mat2row.y,mat2row.z,mat2row.w,\r\n\t\t\t\tmat3row.x,mat3row.y,mat3row.z,mat3row.w);\r\n\t\treturn m;\r\n\t}\r\n#endif\r\n\r\n";
var linePS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nuniform vec4 u_Color;\r\n\r\nvoid main()\r\n{\r\n gl_FragColor = v_Color * u_Color; \r\n}\r\n\r\n";
var lineVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nuniform mat4 u_MvpMatrix;\r\nuniform vec4 u_Color;\r\nattribute vec4 a_Color;\r\nvarying vec4 v_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tgl_Position = u_MvpMatrix * a_Position;\r\n\tv_Color=a_Color*u_Color;\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}";
var MeshBlinnPhongPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n\r\n#include \"Lighting.glsl\";\r\n#include \"Shadow.glsl\"\r\n\r\nuniform vec4 u_DiffuseColor;\r\nuniform float u_AlbedoIntensity;\r\n\r\n#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\n#ifdef DIFFUSEMAP\r\n\tuniform sampler2D u_DiffuseTexture;\r\n#endif\r\n\r\n\r\n#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform sampler2D u_LightMap;\r\n\t#ifdef LIGHTMAP_DIRECTIONAL\r\n\t\tuniform sampler2D u_LightMapDirection;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_Normal;\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\tvarying vec3 v_ViewDir; \r\n\r\n\tuniform vec3 u_MaterialSpecular;\r\n\tuniform float u_Shininess;\r\n\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n\r\n\t#ifdef SPECULARMAP \r\n\t\tuniform sampler2D u_SpecularTexture;\r\n\t#endif\r\n#endif\r\n\r\n#ifdef NORMALMAP \r\n\tuniform sampler2D u_NormalTexture;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n\r\n#include \"GlobalIllumination.glsl\";//\"GlobalIllumination.glsl use uniform should at front of this\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec3 normal;//light and SH maybe use normal\r\n\t#if defined(NORMALMAP)\r\n\t\tvec3 normalMapSample = texture2D(u_NormalTexture, v_Texcoord0).rgb;\r\n\t\tnormal = normalize(NormalSampleToWorldSpace(normalMapSample, v_Normal, v_Tangent,v_Binormal));\r\n\t#else\r\n\t\tnormal = normalize(v_Normal);\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tvec3 viewDir= normalize(v_ViewDir);\r\n\t#endif\r\n\r\n\tLayaGIInput giInput;\r\n\t#ifdef LIGHTMAP\t\r\n\t\tgiInput.lightmapUV=v_LightMapUV;\r\n\t#endif\r\n\tvec3 globalDiffuse=layaGIBase(giInput,1.0,normal);\r\n\t\r\n\tvec4 mainColor = u_DiffuseColor * u_AlbedoIntensity;\r\n\t#ifdef DIFFUSEMAP\r\n\t\tvec4 difTexColor=texture2D(u_DiffuseTexture, v_Texcoord0);\r\n\t\tmainColor=mainColor*difTexColor;\r\n\t#endif \r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tmainColor=mainColor*v_Color;\r\n\t#endif \r\n \r\n\t#ifdef ALPHATEST\r\n\t\tif(mainColor.a<u_AlphaTestValue)\r\n\t\t\tdiscard;\r\n\t#endif\r\n \r\n\t\r\n\tvec3 diffuse = vec3(0.0);\r\n\tvec3 specular= vec3(0.0);\r\n\tvec3 transmissionDiffuse = vec3(0.0);\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tvec3 dif,spe,transmis;\r\n\t\tfloat transmissionFactor;\r\n\t\t#ifdef SPECULARMAP\r\n\t\t\tvec3 gloss=texture2D(u_SpecularTexture, v_Texcoord0).rgb;\r\n\t\t#else\r\n\t\t\t#ifdef DIFFUSEMAP\r\n\t\t\t\tvec3 gloss=vec3(difTexColor.a);\r\n\t\t\t#else\r\n\t\t\t\tvec3 gloss=vec3(1.0);\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t\t#ifdef THICKNESSMAP\r\n\t\t\ttransmissionFactor = texture2D(u_ThinknessTexture, v_Texcoord0).r;\r\n\t\t#endif\r\n\t#endif\r\n\r\n\t\r\n\t\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tLayaAirBlinnPhongDiectionLight(u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,u_DirectionLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t#ifdef SHADOW_CASCADE\r\n\t\t\t\t\tvec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t\t\t\t#else\r\n\t\t\t\t\tvec4 shadowCoord = v_ShadowCoord;\r\n\t\t\t\t#endif\r\n\t\t\t\tfloat shadowAttenuation=sampleShadowmap(shadowCoord);\r\n\t\t\t\tdif *= shadowAttenuation;\r\n\t\t\t\tspe *= shadowAttenuation;\r\n\t\t\t\ttransmis *=shadowAttenuation;\r\n\t\t\t#endif\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,u_PointLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t#endif\r\n\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,u_SpotLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\tvec4 spotShadowcoord = v_SpotShadowCoord;\r\n\t\t\t\tfloat spotShadowAttenuation = sampleSpotShadowmap(spotShadowcoord);\r\n\t\t\t\tdif *= spotShadowAttenuation;\r\n\t\t\t\tspe *= spotShadowAttenuation;\r\n\t\t\t\ttransmis *=spotShadowAttenuation;\r\n\t\t\t#endif\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t{\r\n\t\t\t\tif(i >= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t#ifdef SHADOW_CASCADE\r\n\t\t\t\t\t\t\tvec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tvec4 shadowCoord = v_ShadowCoord;\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\tdirectionLight.color *= sampleShadowmap(shadowCoord);\r\n\t\t\t\t\t}\r\n\t\t\t\t#endif\r\n\t\t\t\tLayaAirBlinnPhongDiectionLight(u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,directionLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\tdiffuse+=dif;\r\n\t\t\t\tspecular+=spe;\r\n\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t}\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,pointLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tvec4 spotShadowcoord = v_SpotShadowCoord;\r\n\t\t\t\t\t\t\tspotLight.color *= sampleSpotShadowmap(spotShadowcoord);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,spotLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t#endif\r\n\r\n\tgl_FragColor =vec4(mainColor.rgb*(globalDiffuse + diffuse),mainColor.a);\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tgl_FragColor.rgb+=specular;\r\n\t#endif\r\n\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tgl_FragColor.rgb+= transmissionDiffuse;\r\n\t#endif\r\n\r\n\t \r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n\t#endif\r\n\r\n\t//gl_FragColor.rgb =transmissionDiffuse;\r\n}\r\n\r\n";
var MeshBlinnPhongVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\"\r\n#include \"Shadow.glsl\";\r\n\r\n\r\nattribute vec4 a_Position;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\n#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))||(defined(LIGHTMAP)&&defined(UV))\r\n\tattribute vec2 a_Texcoord0;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#if defined(LIGHTMAP)&&defined(UV1)\r\n\tattribute vec2 a_Texcoord1;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tattribute vec4 a_Color;\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nattribute vec3 a_Normal;\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\tuniform vec3 u_CameraPos;\r\n\tvarying vec3 v_ViewDir; \r\n#endif\r\n\r\n#if defined(NORMALMAP)\r\n\tattribute vec4 a_Tangent0;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\n#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nvoid main()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\r\n\r\n\t\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * worldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\tv_Normal=normalize(a_Normal*worldInvMat);\r\n\t#if defined(NORMALMAP)\r\n\t\tv_Tangent=normalize(a_Tangent0.xyz*worldInvMat);\r\n\t\tv_Binormal=cross(v_Normal,v_Tangent)*a_Tangent0.w;\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\t\tvec3 positionWS=(worldMat*position).xyz;\r\n\t\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tv_ViewDir = u_CameraPos-positionWS;\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\t\t\tv_PositionWorld = positionWS;\r\n\t\t#endif\r\n\t#endif\r\n\r\n\t#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))\r\n\t\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t#endif\r\n\r\n\t#ifdef LIGHTMAP\r\n\t\t#ifdef UV1\r\n\t\t\tv_LightMapUV=vec2(a_Texcoord1.x,1.0-a_Texcoord1.y)*u_LightmapScaleOffset.xy+u_LightmapScaleOffset.zw;\r\n\t\t#else\r\n\t\t\tv_LightMapUV=vec2(a_Texcoord0.x,1.0-a_Texcoord0.y)*u_LightmapScaleOffset.xy+u_LightmapScaleOffset.zw;\r\n\t\t#endif \r\n\t\tv_LightMapUV.y=1.0-v_LightMapUV.y;\r\n\t#endif\r\n\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tv_Color=a_Color;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\t\tv_ShadowCoord =getShadowCoord(vec4(positionWS,1.0));\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tv_SpotShadowCoord = u_SpotViewProjectMatrix*vec4(positionWS,1.0);\r\n\t#endif\r\n\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}";
var MeshBlinnPhongShadowCasterPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"ShadowCasterFS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=shadowCasterFragment();\r\n}";
var MeshBlinnPhongShadowCasterVS = "#include \"ShadowCasterVS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = shadowCasterVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}";
var ParticleShuriKenPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n precision highp float;\r\n#else\r\n precision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\nuniform sampler2D u_texture;\r\nuniform vec4 u_Tintcolor;\r\n\r\n#ifdef RENDERMODE_MESH\r\n\tvarying vec4 v_MeshColor;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\t\r\n\t#ifdef RENDERMODE_MESH\r\n\t\tgl_FragColor=v_MeshColor;\r\n\t#else\r\n\t\tgl_FragColor=vec4(1.0);\t\r\n\t#endif\r\n\t\t\r\n\t#ifdef DIFFUSEMAP\r\n\t\t#ifdef TINTCOLOR\r\n\t\t\tgl_FragColor*=texture2D(u_texture,v_TextureCoordinate)*u_Tintcolor*2.0*v_Color;\r\n\t\t#else\r\n\t\t\tgl_FragColor*=texture2D(u_texture,v_TextureCoordinate)*v_Color;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef TINTCOLOR\r\n\t\t\tgl_FragColor*=u_Tintcolor*2.0*v_Color;\r\n\t\t#else\r\n\t\t\tgl_FragColor*=v_Color;\r\n\t\t#endif\r\n\t#endif\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,vec3(0.0,0.0,0.0),lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n}";
var ParticleShuriKenVS = "// #include \"Lighting.glsl\";\r\n\r\n//修改这里剔除没有用到的光照函数,增加粒子的编译速度\r\nvec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {\r\n\tvec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);\r\n\ttransTexcoord.y+=1.0;\r\n\treturn transTexcoord;\r\n}\r\n\r\nvec4 remapGLPositionZ(vec4 position) {\r\n\tposition.z=position.z * 2.0 - position.w;\r\n\treturn position;\r\n}\r\n\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)\r\n precision highp float;\r\n#else\r\n precision mediump float;\r\n#endif\r\n\r\n#if defined(SPHERHBILLBOARD)||defined(STRETCHEDBILLBOARD)||defined(HORIZONTALBILLBOARD)||defined(VERTICALBILLBOARD)\r\n\tattribute vec4 a_CornerTextureCoordinate;\r\n#endif\r\n#ifdef RENDERMODE_MESH\r\n\tattribute vec3 a_MeshPosition;\r\n\tattribute vec4 a_MeshColor;\r\n\tattribute vec2 a_MeshTextureCoordinate;\r\n\tvarying vec4 v_MeshColor;\r\n#endif\r\n\r\nattribute vec4 a_ShapePositionStartLifeTime;\r\nattribute vec4 a_DirectionTime;\r\nattribute vec4 a_StartColor;\r\nattribute vec3 a_StartSize;\r\nattribute vec3 a_StartRotation0;\r\nattribute float a_StartSpeed;\r\n#if defined(COLOROVERLIFETIME)||defined(RANDOMCOLOROVERLIFETIME)||defined(SIZEOVERLIFETIMERANDOMCURVES)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n attribute vec4 a_Random0;\r\n#endif\r\n#if defined(TEXTURESHEETANIMATIONRANDOMCURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n attribute vec4 a_Random1;\r\n#endif\r\nattribute vec3 a_SimulationWorldPostion;\r\nattribute vec4 a_SimulationWorldRotation;\r\n\r\nvarying vec4 v_Color;\r\n#ifdef DIFFUSEMAP\r\n\tvarying vec2 v_TextureCoordinate;\r\n#endif\r\n\r\nuniform float u_CurrentTime;\r\nuniform vec3 u_Gravity;\r\n\r\nuniform vec3 u_WorldPosition;\r\nuniform vec4 u_WorldRotation;\r\nuniform bool u_ThreeDStartRotation;\r\nuniform int u_ScalingMode;\r\nuniform vec3 u_PositionScale;\r\nuniform vec3 u_SizeScale;\r\nuniform mat4 u_View;\r\nuniform mat4 u_Projection;\r\n\r\n#ifdef STRETCHEDBILLBOARD\r\n\tuniform vec3 u_CameraPos;\r\n#endif\r\nuniform vec3 u_CameraDirection;//TODO:只有几种广告牌模式需要用\r\nuniform vec3 u_CameraUp;\r\n\r\nuniform float u_StretchedBillboardLengthScale;\r\nuniform float u_StretchedBillboardSpeedScale;\r\nuniform int u_SimulationSpace;\r\n\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n uniform int u_VOLSpaceType;\r\n#endif\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)\r\n uniform vec3 u_VOLVelocityConst;\r\n#endif\r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n uniform vec2 u_VOLVelocityGradientX[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientY[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientZ[4];//x为key,y为速度\r\n#endif\r\n#ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n uniform vec3 u_VOLVelocityConstMax;\r\n#endif\r\n#ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n uniform vec2 u_VOLVelocityGradientMaxX[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientMaxY[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientMaxZ[4];//x为key,y为速度\r\n#endif\r\n\r\n#ifdef COLOROVERLIFETIME\r\n uniform vec4 u_ColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_ColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n#endif\r\n#ifdef RANDOMCOLOROVERLIFETIME\r\n uniform vec4 u_ColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_ColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n uniform vec4 u_MaxColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_MaxColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n#endif\r\n\r\n\r\n#if defined(SIZEOVERLIFETIMECURVE)||defined(SIZEOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_SOLSizeGradient[4];//x为key,y为尺寸\r\n#endif\r\n#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_SOLSizeGradientMax[4];//x为key,y为尺寸\r\n#endif\r\n#if defined(SIZEOVERLIFETIMECURVESEPERATE)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)\r\n uniform vec2 u_SOLSizeGradientX[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientY[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientZ[4];//x为key,y为尺寸\r\n#endif\r\n#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n uniform vec2 u_SOLSizeGradientMaxX[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientMaxY[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientMaxZ[4];//x为key,y为尺寸\r\n#endif\r\n\r\n\r\n#ifdef ROTATIONOVERLIFETIME\r\n #if defined(ROTATIONOVERLIFETIMECONSTANT)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)\r\n uniform float u_ROLAngularVelocityConst;\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n uniform float u_ROLAngularVelocityConstMax;\r\n #endif\r\n #if defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_ROLAngularVelocityGradient[4];//x为key,y为旋转\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_ROLAngularVelocityGradientMax[4];//x为key,y为旋转\r\n #endif\r\n#endif\r\n#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n #if defined(ROTATIONOVERLIFETIMECONSTANT)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)\r\n uniform vec3 u_ROLAngularVelocityConstSeprarate;\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n uniform vec3 u_ROLAngularVelocityConstMaxSeprarate;\r\n #endif\r\n #if defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_ROLAngularVelocityGradientX[4];\r\n uniform vec2 u_ROLAngularVelocityGradientY[4];\r\n uniform vec2 u_ROLAngularVelocityGradientZ[4];\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_ROLAngularVelocityGradientMaxX[4];\r\n uniform vec2 u_ROLAngularVelocityGradientMaxY[4];\r\n uniform vec2 u_ROLAngularVelocityGradientMaxZ[4];\r\n\tuniform vec2 u_ROLAngularVelocityGradientMaxW[4];\r\n #endif\r\n#endif\r\n\r\n#if defined(TEXTURESHEETANIMATIONCURVE)||defined(TEXTURESHEETANIMATIONRANDOMCURVE)\r\n uniform float u_TSACycles;\r\n uniform vec2 u_TSASubUVLength;\r\n uniform vec2 u_TSAGradientUVs[4];//x为key,y为frame\r\n#endif\r\n#ifdef TEXTURESHEETANIMATIONRANDOMCURVE\r\n uniform vec2 u_TSAMaxGradientUVs[4];//x为key,y为frame\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nvec3 rotationByEuler(in vec3 vector,in vec3 rot)\r\n{\r\n\tfloat halfRoll = rot.z * 0.5;\r\n float halfPitch = rot.x * 0.5;\r\n\tfloat halfYaw = rot.y * 0.5;\r\n\r\n\tfloat sinRoll = sin(halfRoll);\r\n\tfloat cosRoll = cos(halfRoll);\r\n\tfloat sinPitch = sin(halfPitch);\r\n\tfloat cosPitch = cos(halfPitch);\r\n\tfloat sinYaw = sin(halfYaw);\r\n\tfloat cosYaw = cos(halfYaw);\r\n\r\n\tfloat quaX = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);\r\n\tfloat quaY = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);\r\n\tfloat quaZ = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);\r\n\tfloat quaW = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);\r\n\t\r\n\t//vec4 q=vec4(quaX,quaY,quaZ,quaW);\r\n\t//vec3 temp = cross(q.xyz, vector) + q.w * vector;\r\n\t//return (cross(temp, -q.xyz) + dot(q.xyz,vector) * q.xyz + q.w * temp);\r\n\t\r\n\tfloat x = quaX + quaX;\r\n float y = quaY + quaY;\r\n float z = quaZ + quaZ;\r\n float wx = quaW * x;\r\n float wy = quaW * y;\r\n float wz = quaW * z;\r\n\tfloat xx = quaX * x;\r\n float xy = quaX * y;\r\n\tfloat xz = quaX * z;\r\n float yy = quaY * y;\r\n float yz = quaY * z;\r\n float zz = quaZ * z;\r\n\r\n return vec3(((vector.x * ((1.0 - yy) - zz)) + (vector.y * (xy - wz))) + (vector.z * (xz + wy)),\r\n ((vector.x * (xy + wz)) + (vector.y * ((1.0 - xx) - zz))) + (vector.z * (yz - wx)),\r\n ((vector.x * (xz - wy)) + (vector.y * (yz + wx))) + (vector.z * ((1.0 - xx) - yy)));\r\n\t\r\n}\r\n\r\n//假定axis已经归一化\r\nvec3 rotationByAxis(in vec3 vector,in vec3 axis, in float angle)\r\n{\r\n\tfloat halfAngle = angle * 0.5;\r\n\tfloat sin = sin(halfAngle);\r\n\t\r\n\tfloat quaX = axis.x * sin;\r\n\tfloat quaY = axis.y * sin;\r\n\tfloat quaZ = axis.z * sin;\r\n\tfloat quaW = cos(halfAngle);\r\n\t\r\n\t//vec4 q=vec4(quaX,quaY,quaZ,quaW);\r\n\t//vec3 temp = cross(q.xyz, vector) + q.w * vector;\r\n\t//return (cross(temp, -q.xyz) + dot(q.xyz,vector) * q.xyz + q.w * temp);\r\n\t\r\n\tfloat x = quaX + quaX;\r\n float y = quaY + quaY;\r\n float z = quaZ + quaZ;\r\n float wx = quaW * x;\r\n float wy = quaW * y;\r\n float wz = quaW * z;\r\n\tfloat xx = quaX * x;\r\n float xy = quaX * y;\r\n\tfloat xz = quaX * z;\r\n float yy = quaY * y;\r\n float yz = quaY * z;\r\n float zz = quaZ * z;\r\n\r\n return vec3(((vector.x * ((1.0 - yy) - zz)) + (vector.y * (xy - wz))) + (vector.z * (xz + wy)),\r\n ((vector.x * (xy + wz)) + (vector.y * ((1.0 - xx) - zz))) + (vector.z * (yz - wx)),\r\n ((vector.x * (xz - wy)) + (vector.y * (yz + wx))) + (vector.z * ((1.0 - xx) - yy)));\r\n\t\r\n}\r\n\r\nvec3 rotationByQuaternions(in vec3 v,in vec4 q) \r\n{\r\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\r\n}\r\n\r\n \r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)||defined(SIZEOVERLIFETIMECURVE)||defined(SIZEOVERLIFETIMECURVESEPERATE)||defined(SIZEOVERLIFETIMERANDOMCURVES)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)\r\nfloat getCurValueFromGradientFloat(in vec2 gradientNumbers[4],in float normalizedAge)\r\n{\r\n\tfloat curValue;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientNumber=gradientNumbers[i];\r\n\t\tfloat key=gradientNumber.x;\r\n\t\tif(key>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientNumber=gradientNumbers[i-1];\r\n\t\t\tfloat lastKey=lastGradientNumber.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\tcurValue=mix(lastGradientNumber.y,gradientNumber.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn curValue;\r\n}\r\n#endif\r\n\r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)||defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\nfloat getTotalValueFromGradientFloat(in vec2 gradientNumbers[4],in float normalizedAge)\r\n{\r\n\tfloat totalValue=0.0;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientNumber=gradientNumbers[i];\r\n\t\tfloat key=gradientNumber.x;\r\n\t\tvec2 lastGradientNumber=gradientNumbers[i-1];\r\n\t\tfloat lastValue=lastGradientNumber.y;\r\n\t\t\r\n\t\tif(key>=normalizedAge){\r\n\t\t\tfloat lastKey=lastGradientNumber.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\ttotalValue+=(lastValue+mix(lastValue,gradientNumber.y,age))/2.0*a_ShapePositionStartLifeTime.w*(normalizedAge-lastKey);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\telse{\r\n\t\t\ttotalValue+=(lastValue+gradientNumber.y)/2.0*a_ShapePositionStartLifeTime.w*(key-lastGradientNumber.x);\r\n\t\t}\r\n\t}\r\n\treturn totalValue;\r\n}\r\n#endif\r\n\r\n#if defined(COLOROVERLIFETIME)||defined(RANDOMCOLOROVERLIFETIME)\r\nvec4 getColorFromGradient(in vec2 gradientAlphas[4],in vec4 gradientColors[4],in float normalizedAge)\r\n{\r\n\tvec4 overTimeColor;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientAlpha=gradientAlphas[i];\r\n\t\tfloat alphaKey=gradientAlpha.x;\r\n\t\tif(alphaKey>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientAlpha=gradientAlphas[i-1];\r\n\t\t\tfloat lastAlphaKey=lastGradientAlpha.x;\r\n\t\t\tfloat age=(normalizedAge-lastAlphaKey)/(alphaKey-lastAlphaKey);\r\n\t\t\toverTimeColor.a=mix(lastGradientAlpha.y,gradientAlpha.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\t\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec4 gradientColor=gradientColors[i];\r\n\t\tfloat colorKey=gradientColor.x;\r\n\t\tif(colorKey>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec4 lastGradientColor=gradientColors[i-1];\r\n\t\t\tfloat lastColorKey=lastGradientColor.x;\r\n\t\t\tfloat age=(normalizedAge-lastColorKey)/(colorKey-lastColorKey);\r\n\t\t\toverTimeColor.rgb=mix(gradientColors[i-1].yzw,gradientColor.yzw,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn overTimeColor;\r\n}\r\n#endif\r\n\r\n\r\n#if defined(TEXTURESHEETANIMATIONCURVE)||defined(TEXTURESHEETANIMATIONRANDOMCURVE)\r\nfloat getFrameFromGradient(in vec2 gradientFrames[4],in float normalizedAge)\r\n{\r\n\tfloat overTimeFrame;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientFrame=gradientFrames[i];\r\n\t\tfloat key=gradientFrame.x;\r\n\t\tif(key>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientFrame=gradientFrames[i-1];\r\n\t\t\tfloat lastKey=lastGradientFrame.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\toverTimeFrame=mix(lastGradientFrame.y,gradientFrame.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn floor(overTimeFrame);\r\n}\r\n#endif\r\n\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\nvec3 computeParticleLifeVelocity(in float normalizedAge)\r\n{\r\n vec3 outLifeVelocity;\r\n #ifdef VELOCITYOVERLIFETIMECONSTANT\r\n\t outLifeVelocity=u_VOLVelocityConst; \r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMECURVE\r\n outLifeVelocity= vec3(getCurValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge));\r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n\t outLifeVelocity=mix(u_VOLVelocityConst,u_VOLVelocityConstMax,vec3(a_Random1.y,a_Random1.z,a_Random1.w)); \r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n outLifeVelocity=vec3(mix(getCurValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxX,normalizedAge),a_Random1.y),\r\n\t mix(getCurValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxY,normalizedAge),a_Random1.z),\r\n\t\t\t\t\t mix(getCurValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxZ,normalizedAge),a_Random1.w));\r\n #endif\r\n\t\t\t\t\t\r\n return outLifeVelocity;\r\n} \r\n#endif\r\n\r\nvec3 computeParticlePosition(in vec3 startVelocity, in vec3 lifeVelocity,in float age,in float normalizedAge,vec3 gravityVelocity,vec4 worldRotation)\r\n{\r\n vec3 startPosition;\r\n vec3 lifePosition;\r\n #if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t#ifdef VELOCITYOVERLIFETIMECONSTANT\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=lifeVelocity*age;\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMECURVE\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=vec3(getTotalValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge));\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=lifeVelocity*age;\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=vec3(mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxX,normalizedAge),a_Random1.y)\r\n\t ,mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxY,normalizedAge),a_Random1.z)\r\n\t ,mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxZ,normalizedAge),a_Random1.w));\r\n\t#endif\r\n\t\r\n\tvec3 finalPosition;\r\n\tif(u_VOLSpaceType==0){\r\n\t if(u_ScalingMode!=2)\r\n\t finalPosition =rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition+lifePosition),worldRotation);\r\n\t else\r\n\t finalPosition =rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition+lifePosition,worldRotation);\r\n\t}\r\n\telse{\r\n\t if(u_ScalingMode!=2)\r\n\t finalPosition = rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition),worldRotation)+lifePosition;\r\n\t else\r\n\t finalPosition = rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition,worldRotation)+lifePosition;\r\n\t}\r\n #else\r\n\t startPosition=startVelocity*age;\r\n\t vec3 finalPosition;\r\n\t if(u_ScalingMode!=2)\r\n\t\t\tfinalPosition = rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition),worldRotation);\r\n\t else\r\n\t \tfinalPosition = rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition,worldRotation);\r\n #endif\r\n \r\n if(u_SimulationSpace==0)\r\n finalPosition=finalPosition+a_SimulationWorldPostion;\r\n else if(u_SimulationSpace==1) \r\n finalPosition=finalPosition+u_WorldPosition;\r\n \r\n finalPosition+=0.5*gravityVelocity*age;\r\n \r\n return finalPosition;\r\n}\r\n\r\n\r\nvec4 computeParticleColor(in vec4 color,in float normalizedAge)\r\n{\r\n\t#ifdef COLOROVERLIFETIME\r\n\t color*=getColorFromGradient(u_ColorOverLifeGradientAlphas,u_ColorOverLifeGradientColors,normalizedAge);\r\n\t#endif\r\n\t\r\n\t#ifdef RANDOMCOLOROVERLIFETIME\r\n\t color*=mix(getColorFromGradient(u_ColorOverLifeGradientAlphas,u_ColorOverLifeGradientColors,normalizedAge),getColorFromGradient(u_MaxColorOverLifeGradientAlphas,u_MaxColorOverLifeGradientColors,normalizedAge),a_Random0.y);\r\n\t#endif\r\n\r\n return color;\r\n}\r\n\r\nvec2 computeParticleSizeBillbard(in vec2 size,in float normalizedAge)\r\n{\r\n\t#ifdef SIZEOVERLIFETIMECURVE\r\n\t\tsize*=getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge);\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n\t size*=mix(getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMax,normalizedAge),a_Random0.z); \r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMECURVESEPERATE\r\n\t\tsize*=vec2(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge));\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n\t size*=vec2(mix(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxX,normalizedAge),a_Random0.z)\r\n\t ,mix(getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxY,normalizedAge),a_Random0.z));\r\n\t#endif\r\n\treturn size;\r\n}\r\n\r\n#ifdef RENDERMODE_MESH\r\nvec3 computeParticleSizeMesh(in vec3 size,in float normalizedAge)\r\n{\r\n\t#ifdef SIZEOVERLIFETIMECURVE\r\n\t\tsize*=getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge);\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n\t size*=mix(getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMax,normalizedAge),a_Random0.z); \r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMECURVESEPERATE\r\n\t\tsize*=vec3(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientZ,normalizedAge));\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n\t size*=vec3(mix(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxX,normalizedAge),a_Random0.z)\r\n\t ,mix(getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxY,normalizedAge),a_Random0.z)\r\n\t\t,mix(getCurValueFromGradientFloat(u_SOLSizeGradientZ,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxZ,normalizedAge),a_Random0.z));\r\n\t#endif\r\n\treturn size;\r\n}\r\n#endif\r\n\r\nfloat computeParticleRotationFloat(in float rotation,in float age,in float normalizedAge)\r\n{ \r\n\t#ifdef ROTATIONOVERLIFETIME\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConst*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConst,u_ROLAngularVelocityConstMax,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMax,normalizedAge),a_Random0.w);\r\n\t\t#endif\r\n\t#endif\r\n\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConstSeprarate.z*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConstSeprarate.z,u_ROLAngularVelocityConstMaxSeprarate.z,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxZ,normalizedAge),a_Random0.w));\r\n\t\t#endif\r\n\t#endif\r\n\treturn rotation;\r\n}\r\n\r\n#if defined(RENDERMODE_MESH)&&(defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE))\r\nvec3 computeParticleRotationVec3(in vec3 rotation,in float age,in float normalizedAge)\r\n{ \r\n\t#ifdef ROTATIONOVERLIFETIME\r\n\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConst*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConst,u_ROLAngularVelocityConstMax,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMax,normalizedAge),a_Random0.w);\r\n\t\t#endif\r\n\t#endif\r\n\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tvec3 ageRot=u_ROLAngularVelocityConstSeprarate*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=vec3(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge));\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tvec3 ageRot=mix(u_ROLAngularVelocityConstSeprarate,u_ROLAngularVelocityConstMaxSeprarate,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=vec3(mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxX,normalizedAge),a_Random0.w)\r\n\t ,mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxY,normalizedAge),a_Random0.w)\r\n\t ,mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxZ,normalizedAge),a_Random0.w));\r\n\t\t#endif\r\n\t#endif\r\n\treturn rotation;\r\n}\r\n#endif\r\n\r\nvec2 computeParticleUV(in vec2 uv,in float normalizedAge)\r\n{ \r\n\t#ifdef TEXTURESHEETANIMATIONCURVE\r\n\t\tfloat cycleNormalizedAge=normalizedAge*u_TSACycles;\r\n\t\tfloat frame=getFrameFromGradient(u_TSAGradientUVs,cycleNormalizedAge-floor(cycleNormalizedAge));\r\n\t\tfloat totalULength=frame*u_TSASubUVLength.x;\r\n\t\tfloat floorTotalULength=floor(totalULength);\r\n\t uv.x+=totalULength-floorTotalULength;\r\n\t\tuv.y+=floorTotalULength*u_TSASubUVLength.y;\r\n #endif\r\n\t#ifdef TEXTURESHEETANIMATIONRANDOMCURVE\r\n\t\tfloat cycleNormalizedAge=normalizedAge*u_TSACycles;\r\n\t\tfloat uvNormalizedAge=cycleNormalizedAge-floor(cycleNormalizedAge);\r\n\t float frame=floor(mix(getFrameFromGradient(u_TSAGradientUVs,uvNormalizedAge),getFrameFromGradient(u_TSAMaxGradientUVs,uvNormalizedAge),a_Random1.x));\r\n\t\tfloat totalULength=frame*u_TSASubUVLength.x;\r\n\t\tfloat floorTotalULength=floor(totalULength);\r\n\t uv.x+=totalULength-floorTotalULength;\r\n\t\tuv.y+=floorTotalULength*u_TSASubUVLength.y;\r\n #endif\r\n\treturn uv;\r\n}\r\n\r\nvoid main()\r\n{\r\n\tfloat age = u_CurrentTime - a_DirectionTime.w;\r\n\tfloat normalizedAge = age/a_ShapePositionStartLifeTime.w;\r\n\tvec3 lifeVelocity;\r\n\tif(normalizedAge<1.0)\r\n\t{ \r\n\t\tvec3 startVelocity=a_DirectionTime.xyz*a_StartSpeed;\r\n\t\t#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t\t\tlifeVelocity= computeParticleLifeVelocity(normalizedAge);//计算粒子生命周期速度\r\n\t\t#endif \r\n\t\tvec3 gravityVelocity=u_Gravity*age;\r\n\t\t\r\n\t\tvec4 worldRotation;\r\n\t\tif(u_SimulationSpace==0)\r\n\t\t\tworldRotation=a_SimulationWorldRotation;\r\n\t\telse\r\n\t\t\tworldRotation=u_WorldRotation;\r\n\t\t\r\n\t\tvec3 center=computeParticlePosition(startVelocity, lifeVelocity, age, normalizedAge,gravityVelocity,worldRotation);//计算粒子位置\r\n\t\r\n\t\r\n\t\t#ifdef SPHERHBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tvec3 cameraUpVector =normalize(u_CameraUp);//TODO:是否外面归一化\r\n\t\t\tvec3 sideVector = normalize(cross(u_CameraDirection,cameraUpVector));\r\n\t\t\tvec3 upVector = normalize(cross(sideVector,u_CameraDirection));\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\t#if defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE)\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tvec3 rotation=vec3(a_StartRotation0.xy,computeParticleRotationFloat(a_StartRotation0.z,age,normalizedAge));\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*rotationByEuler(corner.x*sideVector+corner.y*upVector,rotation);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\t\t\tfloat c = cos(rot);\r\n\t\t\t\t\tfloat s = sin(rot);\r\n\t\t\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\t\t\tcorner=rotation*corner;\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*(corner.x*sideVector+corner.y*upVector);\r\n\t\t\t\t}\r\n\t\t\t#else\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*rotationByEuler(corner.x*sideVector+corner.y*upVector,a_StartRotation0);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tfloat c = cos(a_StartRotation0.x);\r\n\t\t\t\t\tfloat s = sin(a_StartRotation0.x);\r\n\t\t\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\t\t\tcorner=rotation*corner;\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*(corner.x*sideVector+corner.y*upVector);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef STRETCHEDBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tvec3 velocity;\r\n\t\t\t#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t\t\t\tif(u_VOLSpaceType==0)\r\n\t\t\t\tvelocity=rotationByQuaternions(u_SizeScale*(startVelocity+lifeVelocity),worldRotation)+gravityVelocity;\r\n\t\t\t\telse\r\n\t\t\t\tvelocity=rotationByQuaternions(u_SizeScale*startVelocity,worldRotation)+lifeVelocity+gravityVelocity;\r\n\t\t\t#else\r\n\t\t\t\tvelocity= rotationByQuaternions(u_SizeScale*startVelocity,worldRotation)+gravityVelocity;\r\n\t\t\t#endif\t\r\n\t\t\tvec3 cameraUpVector = normalize(velocity);\r\n\t\t\tvec3 direction = normalize(center-u_CameraPos);\r\n\t\t\tvec3 sideVector = normalize(cross(direction,normalize(velocity)));\r\n\t\t\t\r\n\t\t\tsideVector=u_SizeScale.xzy*sideVector;\r\n\t\t\tcameraUpVector=length(vec3(u_SizeScale.x,0.0,0.0))*cameraUpVector;\r\n\t\t\t\r\n\t\t\tvec2 size=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\t\r\n\t\t\tconst mat2 rotaionZHalfPI=mat2(0.0, -1.0, 1.0, 0.0);\r\n\t\t\tcorner=rotaionZHalfPI*corner;\r\n\t\t\tcorner.y=corner.y-abs(corner.y);\r\n\t\t\t\r\n\t\t\tfloat speed=length(velocity);//TODO:\r\n\t\t\tcenter +=sign(u_SizeScale.x)*(sign(u_StretchedBillboardLengthScale)*size.x*corner.x*sideVector+(speed*u_StretchedBillboardSpeedScale+size.y*u_StretchedBillboardLengthScale)*corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef HORIZONTALBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tconst vec3 cameraUpVector=vec3(0.0,0.0,1.0);\r\n\t\t\tconst vec3 sideVector = vec3(-1.0,0.0,0.0);\r\n\t\t\t\r\n\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\tfloat c = cos(rot);\r\n\t\t\tfloat s = sin(rot);\r\n\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\tcorner=rotation*corner*cos(0.78539816339744830961566084581988);//TODO:临时缩小cos45,不确定U3D原因\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\tcenter +=u_SizeScale.xzy*(corner.x*sideVector+ corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef VERTICALBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tconst vec3 cameraUpVector =vec3(0.0,1.0,0.0);\r\n\t\t\tvec3 sideVector = normalize(cross(u_CameraDirection,cameraUpVector));\r\n\t\t\t\r\n\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\tfloat c = cos(rot);\r\n\t\t\tfloat s = sin(rot);\r\n\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\tcorner=rotation*corner*cos(0.78539816339744830961566084581988);//TODO:临时缩小cos45,不确定U3D原因\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\tcenter +=u_SizeScale.xzy*(corner.x*sideVector+ corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef RENDERMODE_MESH\r\n\t\t\tvec3 size=computeParticleSizeMesh(a_StartSize,normalizedAge);\r\n\t\t\t#if defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE)\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tvec3 rotation=vec3(a_StartRotation0.xy,computeParticleRotationFloat(a_StartRotation0.z, age,normalizedAge));\r\n\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByEuler(a_MeshPosition*size,rotation),worldRotation);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\t#ifdef ROTATIONOVERLIFETIME\r\n\t\t\t\t\t\tfloat angle=computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\t\t\t\tif(a_ShapePositionStartLifeTime.x!=0.0||a_ShapePositionStartLifeTime.y!=0.0){\r\n\t\t\t\t\t\t\tcenter+= (rotationByQuaternions(rotationByAxis(u_SizeScale*a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),angle),worldRotation));//已验证\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\t#ifdef SHAPE\r\n\t\t\t\t\t\t\t\tcenter+= u_SizeScale.xzy*(rotationByQuaternions(rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),angle),worldRotation));\r\n\t\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\t\tcenter+=rotationByAxis(u_SizeScale*a_MeshPosition*size,vec3(0.0,0.0,-1.0),angle);//已验证\r\n\t\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\t\tcenter+=rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,0.0,-1.0),angle),worldRotation);//已验证\r\n\t\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t\t\t\t\t//TODO:是否应合并if(u_ThreeDStartRotation)分支代码,待测试\r\n\t\t\t\t\t\tvec3 angle=computeParticleRotationVec3(vec3(0.0,0.0,-a_StartRotation0.x), age,normalizedAge);\r\n\t\t\t\t\t\tcenter+= (rotationByQuaternions(rotationByEuler(u_SizeScale*a_MeshPosition*size,vec3(angle.x,angle.y,angle.z)),worldRotation));//已验证\r\n\t\t\t\t\t#endif\t\t\r\n\t\t\t\t}\r\n\t\t\t#else\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByEuler(a_MeshPosition*size,a_StartRotation0),worldRotation);//已验证\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tif(a_ShapePositionStartLifeTime.x!=0.0||a_ShapePositionStartLifeTime.y!=0.0){\r\n\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\tcenter+= rotationByAxis(u_SizeScale*a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),a_StartRotation0.x);\r\n\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\tcenter+= (rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),a_StartRotation0.x),worldRotation));//已验证\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse{\r\n\t\t\t\t\t\t#ifdef SHAPE\r\n\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\tcenter+= u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),a_StartRotation0.x);\r\n\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),a_StartRotation0.x),worldRotation);\t\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByAxis(u_SizeScale*a_MeshPosition*size,vec3(0.0,0.0,-1.0),a_StartRotation0.x);\r\n\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,0.0,-1.0),a_StartRotation0.x),worldRotation);//已验证\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\tv_MeshColor=a_MeshColor;\r\n\t\t#endif\r\n\t\r\n\t\tgl_Position=u_Projection*u_View*vec4(center,1.0);\r\n\t\tv_Color = computeParticleColor(a_StartColor, normalizedAge);\r\n\t\t#ifdef DIFFUSEMAP\r\n\t\t\t#if defined(SPHERHBILLBOARD)||defined(STRETCHEDBILLBOARD)||defined(HORIZONTALBILLBOARD)||defined(VERTICALBILLBOARD)\r\n\t\t\t\tv_TextureCoordinate =computeParticleUV(a_CornerTextureCoordinate.zw, normalizedAge);\r\n\t\t\t#endif\r\n\t\t\t#ifdef RENDERMODE_MESH\r\n\t\t\t\tv_TextureCoordinate =computeParticleUV(a_MeshTextureCoordinate, normalizedAge);\r\n\t\t\t#endif\r\n\t\t\t\r\n\t\t\tv_TextureCoordinate=TransformUV(v_TextureCoordinate,u_TilingOffset);\r\n\t\t#endif\r\n \t}\r\n \telse\r\n\t{\r\n\t\tgl_Position=vec4(2.0,2.0,2.0,1.0);//Discard use out of X(-1,1),Y(-1,1),Z(0,1)\r\n\t}\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n\r\n";
var LayaPBRBRDF = "// allow to explicitly override LAYA_BRDF_GI and LAYA_BRDF_LIGHT in custom shader,default is layaBRDFHighGI and layaBRDFHighLight\r\n#if !defined (LAYA_BRDF_GI) \r\n\t#if defined(LAYA_PBR_BRDF_LOW)\r\n\t\t#define LAYA_BRDF_GI layaBRDFLowGI\r\n\t#elif defined(LAYA_PBR_BRDF_HIGH)\r\n\t\t#define LAYA_BRDF_GI layaBRDFHighGI\r\n\t#endif\r\n#endif\r\n#if !defined (LAYA_BRDF_LIGHT)\r\n\t#if defined(LAYA_PBR_BRDF_LOW)\r\n\t\t#define LAYA_BRDF_LIGHT layaBRDFLowLight\r\n\t#elif defined(LAYA_PBR_BRDF_HIGH)\r\n\t\t#define LAYA_BRDF_LIGHT layaBRDFHighLight\r\n\t#endif\r\n#endif\r\n\r\n#define PI 3.14159265359\r\n#define INV_PI 0.31830988618\r\n\r\nmediump float pow4(mediump float x)\r\n{\r\n\treturn x * x * x * x;\r\n}\r\n\r\nmediump float pow5(mediump float x)\r\n{\r\n\treturn x * x * x * x * x;\r\n}\r\n\r\nmediump vec3 fresnelLerp(mediump vec3 F0,mediump vec3 F90,mediump float cosA)\r\n{\r\n\tfloat t = pow5(1.0 - cosA); // ala Schlick interpoliation\r\n\treturn mix(F0, F90, t);\r\n}\r\n\r\nmediump vec3 fresnelTerm(mediump vec3 F0,mediump float cosA)\r\n{\r\n\tfloat t = pow5(1.0 - cosA); // ala Schlick interpoliation\r\n\treturn F0 + (vec3(1.0) - F0) * t;\r\n}\r\n\r\n// approximage Schlick with ^4 instead of ^5\r\nmediump vec3 fresnelLerpFast (mediump vec3 F0, mediump vec3 F90,mediump float cosA)\r\n{\r\n mediump float t = pow4 (1.0 - cosA);\r\n return mix (F0, F90, t);\r\n}\r\n\r\nfloat smoothnessToPerceptualRoughness(float smoothness)\r\n{\r\n return 1.0 - smoothness;\r\n}\r\n\r\nfloat perceptualRoughnessToRoughness(float perceptualRoughness)\r\n{\r\n return perceptualRoughness * perceptualRoughness;\r\n}\r\n\r\nvec3 safeNormalize(vec3 inVec)\r\n{\r\n\tfloat dp3 = max(0.001,dot(inVec,inVec));\r\n\treturn inVec * inversesqrt(dp3);\r\n}\r\n\r\n// Note: Disney diffuse must be multiply by diffuseAlbedo / PI. This is done outside of this function.\r\nmediump float disneyDiffuse(mediump float NdotV,mediump float NdotL,mediump float LdotH,mediump float perceptualRoughness)\r\n{\r\n\t//https://www.cnblogs.com/herenzhiming/articles/5790389.html\r\n\tmediump float fd90 = 0.5 + 2.0 * LdotH * LdotH * perceptualRoughness;\r\n\t// Two schlick fresnel term\r\n\tmediump float lightScatter = (1.0 + (fd90 - 1.0) * pow5(1.0 - NdotL));\r\n\tmediump float viewScatter = (1.0 + (fd90 - 1.0) * pow5(1.0 - NdotV));\r\n\r\n\treturn lightScatter * viewScatter;\r\n}\r\n\r\n// Ref: http://jcgt.org/published/0003/02/03/paper.pdf\r\nfloat smithJointGGXVisibilityTerm(float NdotL, float NdotV, float roughness)\r\n{\r\n\t// Original formulation:\r\n // lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;\r\n // lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;\r\n // G = 1 / (1 + lambda_v + lambda_l);\r\n\r\n\t// scientific code implement:\r\n\t// Reorder code to be more optimal\r\n // half a = roughness;\r\n // half a2 = a * a;\r\n\r\n // half lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);\r\n // half lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);\r\n\r\n // Simplify visibility term: (2.0f * NdotL * NdotV) / ((4.0f * NdotL * NdotV) * (lambda_v + lambda_l + 1e-5f));\r\n // return 0.5f / (lambdaV + lambdaL + 1e-5f); \r\n\t// This function is not intended to be running on Mobile,therefore epsilon is smaller than can be represented by half\r\n\r\n\t// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)\r\n\tfloat a = roughness;\r\n\tfloat lambdaV = NdotL * (NdotV * (1.0 - a) + a);\r\n\tfloat lambdaL = NdotV * (NdotL * (1.0 - a) + a);\r\n\treturn 0.5 / (lambdaV + lambdaL + 1e-5);\r\n}\r\n\r\nfloat ggxTerm(float NdotH, float roughness)\r\n{\r\n\tfloat a2 = roughness * roughness;\r\n\tfloat d = (NdotH * a2 - NdotH) * NdotH + 1.0; // 2 mad\r\n\treturn INV_PI * a2 / (d * d + 1e-7); // This function is not intended to be running on Mobile,therefore epsilon is smaller than what can be represented by half//返回值小用half来返回\r\n}\r\n\r\n// BRDF1-------------------------------------------------------------------------------------\r\n\r\n// Note: BRDF entry points use smoothness and oneMinusReflectivity for optimization purposes,\r\n// mostly for DX9 SM2.0 level. Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.\r\n\r\n// Main Physically Based BRDF\r\n// Derived from Disney work and based on Torrance-Sparrow micro-facet model\r\n//\r\n// BRDF = kD / pi + kS * (D * V * F) / 4\r\n// I = BRDF * NdotL\r\n//\r\n// *NDF GGX:\r\n// *Smith for Visiblity term\r\n// *Schlick approximation for Fresnel\r\nmediump vec4 layaBRDFHighLight(mediump vec3 diffColor, mediump vec3 specColor, mediump float oneMinusReflectivity, float perceptualRoughness,float roughness,mediump float nv,vec3 normal, vec3 viewDir,LayaLight light)\r\n{\r\n\tvec3 halfDir = safeNormalize(viewDir-light.dir);\r\n\r\n\tfloat nl = clamp(dot(normal, -light.dir),0.0,1.0);\r\n\tfloat nh = clamp(dot(normal, halfDir),0.0,1.0);\r\n\tmediump float lv = clamp(dot(light.dir, viewDir),0.0,1.0);\r\n\tmediump float lh = clamp(dot(light.dir, -halfDir),0.0,1.0);\r\n\r\n\t// Diffuse term\r\n\tmediump float diffuseTerm = disneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;\r\n\r\n\t// Specular term\r\n // HACK: theoretically we should divide diffuseTerm by Pi and not multiply specularTerm!\r\n // BUT that will make shader look significantly darker than Legacy ones\r\n\r\n\t// GGX with roughtness to 0 would mean no specular at all, using max(roughness, 0.002) here to match HDrenderloop roughtness remapping.\r\n\troughness = max(roughness, 0.002);\r\n\tfloat V = smithJointGGXVisibilityTerm(nl, nv, roughness);\r\n\tfloat D = ggxTerm(nh, roughness);\r\n\r\n\tfloat specularTerm = V * D * PI; // Torrance-Sparrow model, Fresnel is applied later\r\n\r\n\t//#ifdef LAYA_COLORSPACE_GAMMA\r\n\tspecularTerm = sqrt(max(1e-4, specularTerm));\r\n\t//#endif\r\n\tspecularTerm = max(0.0, specularTerm * nl);\r\n\t\t\r\n\tmediump vec3 color = diffColor * light.color * diffuseTerm + specularTerm * light.color * fresnelTerm(specColor, lh);\r\n\treturn vec4(color, 1.0);\r\n}\r\n\r\nvec4 layaBRDFHighGI(mediump vec3 diffColor,mediump vec3 specColor,mediump float oneMinusReflectivity,float smoothness ,float perceptualRoughness,float roughness,mediump float nv,vec3 normal, vec3 viewDir,LayaGI gi)\r\n{\r\n\t// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(roughness^2+1)\r\n\tfloat surfaceReduction;\r\n\tsurfaceReduction = 1.0 - 0.28*roughness*perceptualRoughness;// 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]\r\n\tfloat grazingTerm = clamp(smoothness + (1.0 - oneMinusReflectivity),0.0,1.0);\r\n\tmediump vec3 color =diffColor * gi.diffuse + surfaceReduction * gi.specular * fresnelLerp(specColor,vec3(grazingTerm), nv);\r\n\treturn vec4(color,1.0);\r\n}\r\n// BRDF1-------------------------------------------------------------------------------------\r\n\r\n\r\n// BRDF2-------------------------------------------------------------------------------------\r\n// Based on Minimalist CookTorrance BRDF\r\n// Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255\r\n//\r\n// *NDF [Modified] GGX:\r\n// *Modified Kelemen and Szirmay-Kalos for Visibility term\r\n// *Fresnel approximated with 1/LdotH\r\nmediump vec4 layaBRDFLowLight (mediump vec3 diffColor, mediump vec3 specColor,mediump float oneMinusReflectivity,float perceptualRoughness,float roughness,mediump float nv,vec3 normal,vec3 viewDir,LayaLight light)\r\n{\r\n vec3 halfDir = safeNormalize (viewDir-light.dir);\r\n mediump float nl = clamp(dot(normal, -light.dir),0.0,1.0);\r\n float nh = clamp(dot(normal, halfDir),0.0,1.0);\r\n float lh = clamp(dot(-light.dir, halfDir),0.0,1.0);\r\n\r\n // GGX Distribution multiplied by combined approximation of Visibility and Fresnel\r\n // See \"Optimizing PBR for Mobile\" from Siggraph 2015 moving mobile graphics course\r\n // https://community.arm.com/events/1155\r\n mediump float a = roughness;\r\n float a2 = a*a;\r\n\r\n float d = nh * nh * (a2 - 1.0) + 1.00001;\r\n\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\t// Tighter approximation for Gamma only rendering mode!\r\n\t\t// DVF = sqrt(DVF);\r\n\t\t// DVF = (a * sqrt(.25)) / (max(sqrt(0.1), lh)*sqrt(roughness + .5) * d);\r\n\t\tfloat specularTerm = a / (max(0.32, lh) * (1.5 + roughness) * d);\r\n\t// #else\r\n\t// \tfloat specularTerm = a2 / (max(0.1f, lh*lh) * (roughness + 0.5f) * (d * d) * 4);\r\n\t// #endif\r\n\r\n // on mobiles (where half actually means something) denominator have risk of overflow\r\n // clamp below was added specifically to \"fix\" that, but dx compiler (we convert bytecode to metal/gles)\r\n // sees that specularTerm have only non-negative terms, so it skips max(0,..) in clamp (leaving only min(100,...))\r\n\r\n\t//#if defined (SHADER_API_MOBILE)\r\n specularTerm = specularTerm - 1e-4;\r\n\t//#endif\r\n\r\n\t// #else\r\n\t\t// // Legacy\r\n\t\t// half specularPower = PerceptualRoughnessToSpecPower(perceptualRoughness);\r\n\t\t// // Modified with approximate Visibility function that takes roughness into account\r\n\t\t// // Original ((n+1)*N.H^n) / (8*Pi * L.H^3) didn't take into account roughness\r\n\t\t// // and produced extremely bright specular at grazing angles\r\n\r\n\t\t// half invV = lh * lh * smoothness + perceptualRoughness * perceptualRoughness; // approx ModifiedKelemenVisibilityTerm(lh, perceptualRoughness);\r\n\t\t// half invF = lh;\r\n\r\n\t\t// half specularTerm = ((specularPower + 1) * pow (nh, specularPower)) / (8 * invV * invF + 1e-4h);\r\n\r\n\t\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\t// \tspecularTerm = sqrt(max(1e-4f, specularTerm));\r\n\t\t// #endif\r\n\t// #endif\r\n\r\n\t// #if defined (SHADER_API_MOBILE)\r\n\t\tspecularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles\r\n\t// #endif\r\n \r\n mediump vec3 color = (diffColor + specularTerm * specColor) * light.color * nl;\r\n\r\n return vec4(color, 1.0);\r\n}\r\n\r\nmediump vec4 layaBRDFLowGI (mediump vec3 diffColor, mediump vec3 specColor,mediump float oneMinusReflectivity,mediump float smoothness,float perceptualRoughness,float roughness,mediump float nv,vec3 normal,vec3 viewDir,LayaGI gi)\r\n{\r\n\t// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(realRoughness^2+1)\r\n\r\n // 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]\r\n // 1-x^3*(0.6-0.08*x) approximation for 1/(x^4+1)\r\n\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\tmediump float surfaceReduction = 0.28;\r\n\t// #else\r\n\t\t// mediump float surfaceReduction = (0.6-0.08*perceptualRoughness);\r\n\t// #endif\r\n\r\n surfaceReduction = 1.0 - roughness*perceptualRoughness*surfaceReduction;\r\n\r\n\tmediump float grazingTerm = clamp(smoothness + (1.0-oneMinusReflectivity),0.0,1.0);\r\n\tmediump vec3 color =gi.diffuse * diffColor+ surfaceReduction * gi.specular * fresnelLerpFast (specColor, vec3(grazingTerm), nv);\r\n\r\n return vec4(color, 1.0);\r\n}\r\n// BRDF2-------------------------------------------------------------------------------------";
var PBRCore = "struct FragmentCommonData{\r\n\tvec3 diffColor;\r\n\tvec3 specColor;\r\n\tfloat oneMinusReflectivity;\r\n\tfloat smoothness;\r\n\t//vec3 eyeVec;TODO:maybe can remove\r\n\t//float alpha;\r\n\t//vec3 reflUVW;\r\n};\r\n\r\n#if !defined(SETUP_BRDF_INPUT)//shader内部的宏需要将改成#ifdef改成#if类型 不然会被Laya的shader分析器优化掉\r\n #define SETUP_BRDF_INPUT metallicSetup//default is metallicSetup,also can be other. \r\n#endif\r\n\r\nconst mediump vec4 dielectricSpecularColor = vec4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301);\r\n\r\nmediump vec3 diffuseAndSpecularFromMetallic(mediump vec3 albedo,mediump float metallic, out mediump vec3 specColor, out mediump float oneMinusReflectivity)\r\n{\r\n\tspecColor = mix(dielectricSpecularColor.rgb, albedo, metallic);\r\n\toneMinusReflectivity= dielectricSpecularColor.a*(1.0-metallic);//diffuse proportion\r\n\treturn albedo * oneMinusReflectivity;\r\n}\r\n\r\nmediump float specularStrength(mediump vec3 specular)\r\n{\r\n return max (max (specular.r, specular.g), specular.b);\r\n}\r\n\r\n// Diffuse/Spec Energy conservation\r\nmediump vec3 energyConservationBetweenDiffuseAndSpecular (mediump vec3 albedo, mediump vec3 specColor, out mediump float oneMinusReflectivity)\r\n{\r\n\toneMinusReflectivity = 1.0 - specularStrength(specColor);\r\n return albedo * (vec3(1.0) - specColor);\r\n}\r\n\r\n#ifdef TRANSPARENTBLEND\r\n\tmediump vec3 preMultiplyAlpha (mediump vec3 diffColor, mediump float alpha, mediump float oneMinusReflectivity,out mediump float modifiedAlpha)\r\n\t{\r\n\t\t// Transparency 'removes' from Diffuse component\r\n\t\tdiffColor *= alpha;\r\n\t\t// Reflectivity 'removes' from the rest of components, including Transparency\r\n\t\t// modifiedAlpha = 1.0-(1.0-alpha)*(1.0-reflectivity) = 1.0-(oneMinusReflectivity - alpha*oneMinusReflectivity) = 1.0-oneMinusReflectivity + alpha*oneMinusReflectivity\r\n\t\tmodifiedAlpha = 1.0 - oneMinusReflectivity + alpha*oneMinusReflectivity;\r\n\t\treturn diffColor;\r\n\t}\r\n#endif\r\n\r\nFragmentCommonData metallicSetup(vec2 uv)\r\n{\r\n\tmediump vec2 metallicGloss = getMetallicGloss(uv);\r\n\tmediump float metallic = metallicGloss.x;\r\n\tmediump float smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.\r\n\tmediump float oneMinusReflectivity;\r\n\tmediump vec3 specColor;\r\n\tmediump vec3 diffColor = diffuseAndSpecularFromMetallic(albedo(uv), metallic,/*out*/specColor,/*out*/oneMinusReflectivity);\r\n\r\n\tFragmentCommonData o;\r\n\to.diffColor = diffColor;\r\n\to.specColor = specColor;\r\n\to.oneMinusReflectivity = oneMinusReflectivity;\r\n\to.smoothness = smoothness;\r\n\treturn o;\r\n}\r\n\r\nFragmentCommonData specularSetup(vec2 uv)\r\n{\r\n mediump vec4 specGloss = specularGloss(uv);\r\n mediump vec3 specColor = specGloss.rgb;\r\n mediump float smoothness = specGloss.a;\r\n\r\n mediump float oneMinusReflectivity;\r\n mediump vec3 diffColor = energyConservationBetweenDiffuseAndSpecular (albedo(uv), specColor, /*out*/ oneMinusReflectivity);\r\n\r\n FragmentCommonData o;\r\n o.diffColor = diffColor;\r\n o.specColor = specColor;\r\n o.oneMinusReflectivity = oneMinusReflectivity;\r\n o.smoothness = smoothness;\r\n return o;\r\n}\r\n\r\nLayaGI fragmentGI(float smoothness,vec3 eyeVec,mediump float occlusion,mediump vec2 lightmapUV,vec3 worldnormal,vec3 worldPos)\r\n{\r\n\tLayaGIInput giInput;\r\n\t#ifdef LIGHTMAP\r\n\t\tgiInput.lightmapUV=lightmapUV;\r\n\t#endif\r\n\tgiInput.worldPos = worldPos;\r\n\r\n\tvec3 worldViewDir = -eyeVec;\r\n\tmediump vec4 uvwRoughness;\r\n\tuvwRoughness.rgb = reflect(worldViewDir, worldnormal);//reflectUVW\r\n\tuvwRoughness.a= smoothnessToPerceptualRoughness(smoothness);//perceptualRoughness\r\n\r\n\treturn layaGlobalIllumination(giInput,occlusion, worldnormal, uvwRoughness);\r\n}\r\n\r\n\r\nvec3 perPixelWorldNormal(vec2 uv,vec3 normal,vec3 binormal,vec3 tangent)\r\n{\r\n\t#ifdef NORMALTEXTURE\r\n\t\tmediump vec3 normalTangent=normalInTangentSpace(uv);\r\n\t\tvec3 normalWorld = normalize(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z);\r\n\t#else\r\n\t\tvec3 normalWorld = normalize(normal);\r\n\t#endif\r\n\t\treturn normalWorld;\r\n}\r\n\r\nvoid fragmentForward()\r\n{\r\n\tvec2 uv;\r\n\t#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\t\t#ifdef PARALLAXTEXTURE\r\n\t\t\tuv = parallax(v_Texcoord0,normalize(v_ViewDirForParallax));\r\n\t\t#else\r\n\t\t\tuv = v_Texcoord0;\r\n\t\t#endif\r\n\t#endif\r\n\r\n\tmediump float alpha = getAlpha(uv);\r\n\t#ifdef ALPHATEST\r\n\t\tif(alpha<u_AlphaTestValue)\r\n\t\t\tdiscard;\r\n\t#endif\r\n\r\n\tFragmentCommonData o = SETUP_BRDF_INPUT(uv);\r\n\t\r\n\tvec3 binormal;\r\n\tvec3 tangent;\r\n\t#ifdef NORMALTEXTURE\r\n\t\ttangent = v_Tangent;\r\n\t\tbinormal = v_Binormal;\r\n\t#endif\r\n\r\n\tvec3 normal = v_Normal;\r\n\tvec3 normalWorld = perPixelWorldNormal(uv,normal,binormal,tangent);//In FS if the normal use mediump before normalize will cause precision prolem in mobile device.\r\n\tvec3 eyeVec = normalize(v_EyeVec);\r\n\tvec3 posworld = v_PositionWorld;\r\n\r\n\t#ifdef TRANSPARENTBLEND\r\n\t\to.diffColor=preMultiplyAlpha(o.diffColor,alpha,o.oneMinusReflectivity,/*out*/alpha);// shader relies on pre-multiply alpha-blend (srcBlend = One, dstBlend = OneMinusSrcAlpha)\r\n\t#endif\r\n\r\n\tmediump float occlusion = getOcclusion(uv);\r\n\tmediump vec2 lightMapUV;\r\n\t#ifdef LIGHTMAP\r\n\t\tlightMapUV=v_LightMapUV;\r\n\t#endif\r\n\tfloat perceptualRoughness = smoothnessToPerceptualRoughness(o.smoothness);\r\n\tfloat roughness = perceptualRoughnessToRoughness(perceptualRoughness);\r\n\tfloat nv = abs(dot(normalWorld, eyeVec));\r\n\tLayaGI gi =fragmentGI(o.smoothness,eyeVec,occlusion,lightMapUV,normalWorld,posworld);\r\n\tvec4 color = LAYA_BRDF_GI(o.diffColor,o.specColor,o.oneMinusReflectivity,o.smoothness,perceptualRoughness,roughness,nv,normalWorld,eyeVec,gi);\r\n\t\r\n\tfloat shadowAttenuation = 1.0;\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t#ifdef SHADOW_CASCADE\r\n\t\t\t\t\tvec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t\t\t\t#else\r\n\t\t\t\t\tvec4 shadowCoord = v_ShadowCoord;\r\n\t\t\t\t#endif\r\n\t\t\t\tshadowAttenuation=sampleShadowmap(shadowCoord);\r\n\t\t\t#endif\r\n\t\t\tLayaLight dirLight = layaDirectionLightToLight(u_DirectionLight,shadowAttenuation);\r\n\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tshadowAttenuation = 1.0;\r\n\t\t\tLayaLight poiLight = layaPointLightToLight(posworld,normalWorld,u_PointLight,shadowAttenuation);\r\n\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,poiLight);\r\n\t\t#endif\r\n\t\t\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tshadowAttenuation = 1.0;\r\n\t\t\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\tvec4 spotShadowcoord = v_SpotShadowCoord;\r\n\t\t\t\tshadowAttenuation = sampleSpotShadowmap(spotShadowcoord);\r\n\t\t\t#endif\r\n\t\t LayaLight spoLight = layaSpotLightToLight(posworld,normalWorld,u_SpotLight,shadowAttenuation);\r\n\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,spoLight);\r\n\t\t#endif\r\n\t#else\r\n\t \t#ifdef DIRECTIONLIGHT\r\n\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t{\r\n\t\t\t\tshadowAttenuation = 1.0;\r\n\t\t\t\tif(i >= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t#ifdef SHADOW_CASCADE\r\n\t\t\t\t\t\t\tvec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tvec4 shadowCoord = v_ShadowCoord;\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\tshadowAttenuation *= sampleShadowmap(shadowCoord);\r\n\t\t\t\t\t}\r\n\t\t\t\t#endif\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\tLayaLight dirLight = layaDirectionLightToLight(directionLight,shadowAttenuation);\r\n\t\t\t \tcolor+=LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);\r\n\t\t\t}\r\n\t \t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tshadowAttenuation = 1.0;\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaLight poiLight = layaPointLightToLight(posworld,normalWorld,pointLight,shadowAttenuation);\r\n\t\t\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,poiLight);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tshadowAttenuation = 1.0;\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tvec4 spotShadowcoord = v_SpotShadowCoord;\r\n\t\t\t\t\t\t\tshadowAttenuation= sampleSpotShadowmap(spotShadowcoord);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaLight spoLight = layaSpotLightToLight(posworld,normalWorld,spotLight,shadowAttenuation);\r\n\t\t\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,spoLight);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t #endif\r\n\r\n\t#ifdef EMISSION\r\n\t\tcolor.rgb += emission(uv);\r\n\t#endif\r\n\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\tcolor.rgb=mix(color.rgb,u_FogColor,lerpFact);\r\n\t#endif\r\n\t\r\n\tgl_FragColor=vec4(color.rgb,alpha);\r\n}\r\n\r\n\r\n\r\n";
var PBRVSInput = "attribute vec4 a_Position;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nattribute vec3 a_Normal;\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(NORMALTEXTURE)||defined(PARALLAXTEXTURE)\r\n\tattribute vec4 a_Tangent0;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n #ifdef PARALLAXTEXTURE\r\n\t varying vec3 v_ViewDirForParallax;\r\n #endif\r\n#endif\r\n\r\n#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)||(defined(LIGHTMAP)&&defined(UV))\r\n\tattribute vec2 a_Texcoord0;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#if defined(LIGHTMAP)&&defined(UV1)\r\n\tattribute vec2 a_Texcoord1;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\nuniform vec3 u_CameraPos;\r\nvarying vec3 v_EyeVec;\r\nvarying vec3 v_PositionWorld;\r\nvarying float v_posViewZ;\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n";
var PBRFSInput = "#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef NORMALTEXTURE\r\n\tuniform sampler2D u_NormalTexture;\r\n\tuniform float u_NormalScale;\r\n#endif\r\n\r\n#ifdef ALBEDOTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n#endif\r\n\r\n#ifdef METALLICGLOSSTEXTURE\r\n\tuniform sampler2D u_MetallicGlossTexture;\r\n#endif\r\nuniform float u_Metallic;\r\n\r\n#ifdef SPECULARGLOSSTEXTURE\r\n\tuniform sampler2D u_SpecGlossTexture;\r\n#endif\r\nuniform vec3 u_SpecularColor;\r\n\r\nuniform float u_Smoothness;\r\nuniform float u_SmoothnessScale;\r\n\r\n#ifdef PARALLAXTEXTURE\r\n\tuniform sampler2D u_ParallaxTexture;\r\n\tuniform float u_ParallaxScale;\r\n\tvarying vec3 v_ViewDirForParallax;\r\n#endif\r\n\r\n#ifdef OCCLUSIONTEXTURE\r\n\tuniform sampler2D u_OcclusionTexture;\r\n\tuniform float u_occlusionStrength;\r\n#endif\r\n\r\n#ifdef EMISSION \r\n\t#ifdef EMISSIONTEXTURE\r\n\t\tuniform sampler2D u_EmissionTexture;\r\n\t#endif\r\n\tuniform vec4 u_EmissionColor;\r\n#endif\r\n\r\n#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform sampler2D u_LightMap;\r\n\t#ifdef LIGHTMAP_DIRECTIONAL\r\n\t\tuniform sampler2D u_LightMapDirection;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_EyeVec;\r\n\r\n#ifdef NORMALTEXTURE\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n\r\n//后面考虑宏TODO\r\nvarying vec3 v_PositionWorld;\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nmediump float lerpOneTo(mediump float b, mediump float t)\r\n{\r\n mediump float oneMinusT = 1.0 - t;\r\n return oneMinusT + b * t;\r\n}\r\n\r\n#ifdef EMISSION \r\n\tvec3 emission(vec2 uv)\r\n\t{\r\n\t\t#ifdef EMISSIONTEXTURE\r\n\t\t\treturn texture2D(u_EmissionTexture, uv).rgb * u_EmissionColor.rgb;\r\n\t\t#else\r\n\t\t\treturn u_EmissionColor.rgb;\r\n\t\t#endif\r\n\t}\r\n#endif\r\n\r\nmediump float getAlpha(vec2 uv)\r\n{\r\n\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\treturn u_AlbedoColor.a;\r\n\t#else\r\n\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\treturn texture2D(u_AlbedoTexture, uv).a * u_AlbedoColor.a;\r\n\t\t#else\r\n\t\t\treturn u_AlbedoColor.a;\r\n\t\t#endif\r\n\t#endif\r\n}\r\n\r\nmediump float getOcclusion(vec2 uv)\r\n{\r\n\t#ifdef OCCLUSIONTEXTURE\r\n\t\tmediump float occ = texture2D(u_OcclusionTexture, uv).g;\r\n\t\treturn lerpOneTo(occ, u_occlusionStrength);\r\n\t#else\r\n\t\treturn 1.0;\r\n\t#endif\r\n}\r\n\r\nmediump vec3 albedo(vec2 uv)\r\n{\r\n\t#ifdef ALBEDOTEXTURE\r\n\t\treturn u_AlbedoColor.rgb * texture2D(u_AlbedoTexture, uv).rgb;\r\n\t#else\r\n\t\treturn u_AlbedoColor.rgb;\r\n\t#endif\r\n\t//TODO:Detail Texture\r\n}\r\n\r\nmediump vec2 getMetallicGloss(vec2 uv)\r\n{\r\n\tmediump vec2 ms;//x is metallic,y is smoothness\r\n\t#ifdef METALLICGLOSSTEXTURE\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\tms.x = texture2D(u_MetallicGlossTexture, uv).r;\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tms.y = texture2D(u_AlbedoTexture, uv).a*u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tms.y = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tms = texture2D(u_MetallicGlossTexture, uv).ra;\r\n\t\t\tms.y *= u_SmoothnessScale;\r\n\t\t#endif\r\n\t#else\r\n\t\tms.x = u_Metallic;\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tms.y = texture2D(u_AlbedoTexture, uv).a * u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tms.y = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tms.y = u_Smoothness;\r\n\t\t#endif\r\n\t#endif\r\n\treturn ms;\r\n}\r\n\r\nmediump vec4 specularGloss(vec2 uv)\r\n{\r\n\tmediump vec4 sg;\r\n\t#ifdef SPECULARGLOSSTEXTURE\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\tsg.rgb = texture2D(u_SpecGlossTexture, uv).rgb;\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tsg.a = texture2D(u_AlbedoTexture, uv).a*u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tsg.a = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tsg = texture2D(u_SpecGlossTexture, uv);\r\n\t\t\tsg.a *= u_SmoothnessScale;\r\n\t\t#endif\r\n\t#else\r\n\t\tsg.rgb = u_SpecularColor.rgb;\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tsg.a = texture2D(u_AlbedoTexture, uv).a * u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tsg.a = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tsg.a = u_Smoothness;\r\n\t\t#endif\r\n\t#endif\r\n\t\treturn sg;\r\n}\r\n\r\n\r\n#ifdef NORMALTEXTURE\r\n\tmediump vec3 unpackScaleNormal(mediump vec3 packednormal, mediump float bumpScale)\r\n\t{\r\n\t\tmediump vec3 normal = packednormal.xyz * 2.0 - 1.0;\r\n\t\tnormal.y=-normal.y;//NOTE:because unity to LayaAir coordSystem.\r\n\t\tnormal.xy *= bumpScale;\r\n\t\treturn normal;\r\n\t}\r\n\t\r\n\tmediump vec3 normalInTangentSpace(vec2 texcoords)\r\n\t{\r\n\t\tmediump vec3 normalTangent = unpackScaleNormal(texture2D(u_NormalTexture, texcoords).rgb,u_NormalScale);\r\n\t\treturn normalTangent;\r\n\t}\r\n#endif\r\n\r\n#ifdef PARALLAXTEXTURE\r\n\tmediump vec2 parallaxOffset1Step(mediump float h, mediump float height, mediump vec3 viewDir)\r\n\t{\r\n\t\th = h * height - height / 2.0;\r\n\t\tviewDir.z += 0.42;\r\n\t\treturn h * (viewDir.xy / viewDir.z);\r\n\t}\r\n\r\n\tvec2 parallax(vec2 texcoords, mediump vec3 viewDir)\r\n\t{\r\n\t\tmediump float h = texture2D(u_ParallaxTexture, texcoords.xy).g;\r\n\t\tvec2 offset = parallaxOffset1Step(h, u_ParallaxScale, viewDir);\r\n\t\treturn texcoords+offset;\r\n\t}\r\n#endif\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n";
var PBRVertex = "vec2 transformLightMapUV(in vec2 texcoord,in vec4 lightmapScaleOffset)\r\n{\r\n\tvec2 lightMapUV=vec2(texcoord.x,1.0-texcoord.y)*lightmapScaleOffset.xy+lightmapScaleOffset.zw;\r\n\tlightMapUV.y=1.0-lightMapUV.y;\r\n\treturn lightMapUV; \r\n}\r\n\r\nvoid vertexForward()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * worldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\t\r\n\r\n\tv_PositionWorld=(worldMat*position).xyz;\r\n\r\n\t#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\t\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t#endif\r\n\r\n\tv_EyeVec =u_CameraPos-v_PositionWorld;//will normalize per-pixel\r\n\r\n\t#ifdef LIGHTMAP\r\n\t\tvec2 texcoord;\r\n\t\t#ifdef UV1\r\n\t\t\ttexcoord=a_Texcoord1;\r\n\t\t#else\r\n\t\t\ttexcoord=a_Texcoord0;\r\n\t\t#endif\r\n\t\tv_LightMapUV=transformLightMapUV(texcoord,u_LightmapScaleOffset);\r\n\t#endif\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif\r\n\r\n\tv_Normal=normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem.\r\n\r\n\t#ifdef NORMALTEXTURE\r\n\t\tv_Tangent=normalize(a_Tangent0.xyz*worldInvMat);\r\n\t\tv_Binormal=cross(v_Normal,v_Tangent)*a_Tangent0.w;\r\n\t#endif\r\n\r\n\t#ifdef PARALLAXTEXTURE\r\n\t\tvec3 binormal = cross(a_Normal, a_Tangent0.xyz)*a_Tangent0.w;\r\n\t\tmat3 objectTBN = mat3(a_Tangent0.xyz, binormal, a_Normal);\r\n\t\tv_ViewDirForParallax =(u_CameraPos*worldInvMat-position.xyz)*objectTBN;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\t\tv_ShadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tv_SpotShadowCoord = u_SpotViewProjectMatrix*vec4(v_PositionWorld,1.0);\r\n\t#endif\r\n}";
var BloomVS = "#include \"Lighting.glsl\";\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\nattribute vec4 a_PositionTexcoord;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\r\n\tgl_Position = vec4(a_PositionTexcoord.xy, 0.0, 1.0);\r\n\tv_Texcoord0 = a_PositionTexcoord.zw;\r\n\tgl_Position = remapGLPositionZ(gl_Position);\r\n}";
var BloomDownsample13PS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\n\r\nvoid fragDownsample13() {\r\n\tmediump vec4 color = downsampleBox13Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = color;\r\n}\r\n\r\nvoid main() {\r\n\tfragDownsample13();\r\n}";
var BloomDownsample4PS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\n\r\nvoid fragDownsample4() {\r\n\tmediump vec4 color = downsampleBox4Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = color;\r\n}\r\n\r\nvoid main() {\r\n\tfragDownsample4();\r\n}";
var BloomPrefilter13PS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform vec4 u_Threshold; // x: threshold value (linear), y: threshold - knee, z: knee * 2, w: 0.25 / knee\r\nuniform vec4 u_Params; // x: clamp, yzw: unused\r\n\r\nmediump vec4 prefilter(mediump vec4 color, vec2 uv) {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, uv).r;\r\n\tcolor *= autoExposure;\r\n\tcolor = min(vec4(u_Params.x), color); // clamp to max\r\n\tcolor = quadraticThreshold(color, u_Threshold.x, u_Threshold.yzw);\r\n\treturn color;\r\n}\r\n\r\nvoid fragPrefilter13() {\r\n\tmediump vec4 color = downsampleBox13Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = prefilter(safeHDR(color), v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragPrefilter13();\r\n}";
var BloomPrefilter4PS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform vec4 u_Threshold; // x: threshold value (linear), y: threshold - knee, z: knee * 2, w: 0.25 / knee\r\nuniform vec4 u_Params; // x: clamp, yzw: unused\r\n\r\nmediump vec4 prefilter(mediump vec4 color, vec2 uv) {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, uv).r;\r\n\tcolor *= autoExposure;\r\n\tcolor = min(vec4(u_Params.x), color); // clamp to max\r\n\tcolor = quadraticThreshold(color, u_Threshold.x, u_Threshold.yzw);\r\n\treturn color;\r\n}\r\n\r\nvoid fragPrefilter4() {\r\n\tmediump vec4 color = downsampleBox4Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = prefilter(safeHDR(color), v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragPrefilter4();\r\n}";
var BloomUpsampleBoxPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform float u_SampleScale;\r\n\r\nmediump vec4 combine(mediump vec4 bloom, vec2 uv) {\r\n\tmediump vec4 color = texture2D(u_BloomTex, uv);\r\n\treturn bloom + color;\r\n}\r\n\r\nvoid fragUpsampleBox() {\r\n\tmediump vec4 bloom = upsampleBox(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy, vec4(u_SampleScale));\r\n\tgl_FragColor = combine(bloom, v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragUpsampleBox();\r\n}";
var BloomUpsampleTentPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform float u_SampleScale;\r\n\r\nmediump vec4 combine(mediump vec4 bloom, vec2 uv) {\r\n\tmediump vec4 color = texture2D(u_BloomTex, uv);\r\n\treturn bloom + color;\r\n}\r\n\r\nvoid fragUpsampleTent() {\r\n\tmediump vec4 bloom = upsampleTent(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy, vec4(u_SampleScale));\r\n\tgl_FragColor = combine(bloom, v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragUpsampleTent();\r\n}";
var ColorsGLSL = "#include \"StdLib.glsl\";\r\n\r\n#define EPSILON 1.0e-4\r\n\r\n// Quadratic color thresholding\r\n// curve = (threshold - knee, knee * 2, 0.25 / knee)\r\nmediump vec4 quadraticThreshold(mediump vec4 color, mediump float threshold, mediump vec3 curve) {\r\n\t// Pixel brightness\r\n\tmediump float br = max3(color.r, color.g, color.b);\r\n\r\n\t// Under-threshold part: quadratic curve\r\n\tmediump float rq = clamp(br - curve.x, 0.0, curve.y);\r\n\trq = curve.z * rq * rq;\r\n\r\n\t// Combine and apply the brightness response curve.\r\n\tcolor *= max(rq, br - threshold) / max(br, EPSILON);\r\n\r\n\treturn color;\r\n}\r\n\r\n\r\n\r\n//\r\n// sRGB transfer functions\r\n// Fast path ref: http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1\r\n//\r\nmediump vec3 sRGBToLinear(mediump vec3 c) {\r\n\t#ifdef USE_VERY_FAST_SRGB\r\n\t\treturn c * c;\r\n\t#elif defined(USE_FAST_SRGB)\r\n\t\treturn c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);\r\n\t#else\r\n\t\tmediump vec3 linearRGBLo = c / 12.92;\r\n\t\tmediump vec3 power=vec3(2.4, 2.4, 2.4);\r\n\t\tmediump vec3 linearRGBHi = positivePow((c + 0.055) / 1.055, power);\r\n\t\tmediump vec3 linearRGB =vec3((c.r<=0.04045) ? linearRGBLo.r : linearRGBHi.r,(c.g<=0.04045) ? linearRGBLo.g : linearRGBHi.g,(c.b<=0.04045) ? linearRGBLo.b : linearRGBHi.b);\r\n\t\treturn linearRGB;\r\n\t#endif\r\n}\r\n\r\nmediump vec4 sRGBToLinear(mediump vec4 c){\r\n return vec4(sRGBToLinear(c.rgb), c.a);\r\n}\r\n\r\n\r\n\r\nmediump vec3 linearToSRGB(mediump vec3 c) {\r\n\t#ifdef USE_VERY_FAST_SRGB\r\n\t\treturn sqrt(c);\r\n\t#elif defined(USE_FAST_SRGB)\r\n\t\treturn max(1.055 * PositivePow(c, 0.416666667) - 0.055, 0.0);\r\n\t#else\r\n\t\tmediump vec3 sRGBLo = c * 12.92;\r\n\t\tmediump vec3 power=vec3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4);\r\n\t\tmediump vec3 sRGBHi = (positivePow(c, power) * 1.055) - 0.055;\r\n\t\tmediump vec3 sRGB =vec3((c.r<=0.0031308) ? sRGBLo.r : sRGBHi.r,(c.g<=0.0031308) ? sRGBLo.g : sRGBHi.g,(c.b<=0.0031308) ? sRGBLo.b : sRGBHi.b);\r\n\t\treturn sRGB;\r\n\t#endif\r\n}\r\n\r\nmediump vec4 linearToSRGB(mediump vec4 c){\r\n return vec4(linearToSRGB(c.rgb), c.a);\r\n}";
var CompositePS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform sampler2D u_Bloom_DirtTex;\r\nuniform vec4 u_BloomTex_TexelSize;\r\nuniform vec4 u_Bloom_DirtTileOffset; // xy: tiling, zw: offset\r\nuniform mediump vec3 u_Bloom_Settings;// x: sampleScale, y: intensity, z: dirt intensity\r\nuniform mediump vec3 u_Bloom_Color;\r\n\r\nvoid main() {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, v_Texcoord0).r;\r\n\tmediump vec4 color=vec4(0.0);\r\n\tcolor = texture2D(u_MainTex, v_Texcoord0);\r\n\t\r\n\tcolor = sRGBToLinear(color);\r\n\tcolor.rgb *= autoExposure;\r\n\t\r\n\t#if defined(BLOOM)||defined(BLOOM_LOW)\r\n\t\t#ifdef BLOOM\r\n\t\t\tmediump vec4 bloom = upsampleTent(u_BloomTex, v_Texcoord0, u_BloomTex_TexelSize.xy, vec4(u_Bloom_Settings.x));\r\n\t\t#else\r\n\t\t\tmediump vec4 bloom = upsampleBox(u_BloomTex, v_Texcoord0, u_BloomTex_TexelSize.xy, vec4(u_Bloom_Settings.x));\r\n\t\t#endif\r\n\r\n\t\t// UVs should be Distort(uv * u_Bloom_DirtTileOffset.xy + u_Bloom_DirtTileOffset.zw)\r\n\t\t// but considering we use a cover-style scale on the dirt texture the difference\r\n\t\t// isn't massive so we chose to save a few ALUs here instead in case lens distortion\r\n\t\t// is active\r\n\t\tmediump vec4 dirt =vec4(texture2D(u_Bloom_DirtTex, v_Texcoord0 * u_Bloom_DirtTileOffset.xy + u_Bloom_DirtTileOffset.zw).rgb, 0.0);\r\n\r\n\t\t// Additive bloom (artist friendly)\r\n\t\tbloom *= u_Bloom_Settings.y;\r\n\t\tdirt *= u_Bloom_Settings.z;\r\n\t\tmediump vec4 bloomColor=vec4(u_Bloom_Color, 1.0);\r\n\t\tcolor += bloom * bloomColor;\r\n\t\tcolor += dirt * bloom;\r\n\t#endif\r\n\t\r\n\tmediump vec4 finalColor = color;\r\n\tfinalColor = linearToSRGB(finalColor);\r\n\t//finalColor.rgb = Dither(finalColor.rgb, v_Texcoord0);//TODO:抖动\r\n\tgl_FragColor = finalColor;\r\n}";
var CompositeVS = "#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_PositionTexcoord;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\r\n\tgl_Position = vec4(a_PositionTexcoord.xy, 0.0, 1.0);\r\n\tv_Texcoord0 = a_PositionTexcoord.zw;\r\n\tgl_Position = remapGLPositionZ(gl_Position);\r\n}";
var SamplingGLSL = "// Better, temporally stable box filtering\r\n// [Jimenez14] http://goo.gl/eomGso\r\n// . . . . . . .\r\n// . A . B . C .\r\n// . . D . E . .\r\n// . F . G . H .\r\n// . . I . J . .\r\n// . K . L . M .\r\n// . . . . . . .\r\nmediump vec4 downsampleBox13Tap(sampler2D tex, vec2 uv, vec2 texelSize)\r\n{\r\n mediump vec4 A = texture2D(tex, uv + texelSize * vec2(-1.0, -1.0));\r\n mediump vec4 B = texture2D(tex, uv + texelSize * vec2( 0.0, -1.0));\r\n mediump vec4 C = texture2D(tex, uv + texelSize * vec2( 1.0, -1.0));\r\n mediump vec4 D = texture2D(tex, uv + texelSize * vec2(-0.5, -0.5));\r\n mediump vec4 E = texture2D(tex, uv + texelSize * vec2( 0.5, -0.5));\r\n mediump vec4 F = texture2D(tex, uv + texelSize * vec2(-1.0, 0.0));\r\n mediump vec4 G = texture2D(tex, uv);\r\n mediump vec4 H = texture2D(tex, uv + texelSize * vec2( 1.0, 0.0));\r\n mediump vec4 I = texture2D(tex, uv + texelSize * vec2(-0.5, 0.5));\r\n mediump vec4 J = texture2D(tex, uv + texelSize * vec2( 0.5, 0.5));\r\n mediump vec4 K = texture2D(tex, uv + texelSize * vec2(-1.0, 1.0));\r\n mediump vec4 L = texture2D(tex, uv + texelSize * vec2( 0.0, 1.0));\r\n mediump vec4 M = texture2D(tex, uv + texelSize * vec2( 1.0, 1.0));\r\n\r\n\tmediump vec2 scale= vec2(0.5, 0.125);\r\n mediump vec2 div = (1.0 / 4.0) * scale;\r\n\r\n mediump vec4 o = (D + E + I + J) * div.x;\r\n o += (A + B + G + F) * div.y;\r\n o += (B + C + H + G) * div.y;\r\n o += (F + G + L + K) * div.y;\r\n o += (G + H + M + L) * div.y;\r\n\r\n return o;\r\n}\r\n\r\n// Standard box filtering\r\nmediump vec4 downsampleBox4Tap(sampler2D tex, vec2 uv, vec2 texelSize)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(-1.0, -1.0, 1.0, 1.0);\r\n\r\n mediump vec4 s = texture2D(tex, uv + d.xy);\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.xw);\r\n s += texture2D(tex, uv + d.zw);\r\n\r\n return s * (1.0 / 4.0);\r\n}\r\n\r\n// 9-tap bilinear upsampler (tent filter)\r\n// . . . . . . .\r\n// . 1 . 2 . 1 .\r\n// . . . . . . .\r\n// . 2 . 4 . 2 .\r\n// . . . . . . .\r\n// . 1 . 2 . 1 .\r\n// . . . . . . .\r\nmediump vec4 upsampleTent(sampler2D tex, vec2 uv, vec2 texelSize, vec4 sampleScale)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(1.0, 1.0, -1.0, 0.0) * sampleScale;\r\n\r\n mediump vec4 s = texture2D(tex, uv - d.xy);\r\n s += texture2D(tex, uv - d.wy) * 2.0;\r\n s += texture2D(tex, uv - d.zy);\r\n\r\n s += texture2D(tex, uv + d.zw) * 2.0;\r\n s += texture2D(tex, uv) * 4.0;\r\n s += texture2D(tex,\tuv + d.xw) * 2.0;\r\n\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.wy) * 2.0;\r\n s += texture2D(tex, uv + d.xy);\r\n\r\n return s * (1.0 / 16.0);\r\n}\r\n\r\n// Standard box filtering\r\nmediump vec4 upsampleBox(sampler2D tex, vec2 uv, vec2 texelSize, vec4 sampleScale)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(-1.0, -1.0, 1.0, 1.0) * 0.5 * sampleScale;\r\n\r\n mediump vec4 s = texture2D(tex, uv + d.xy);\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.xw);\r\n s += texture2D(tex, uv + d.zw);\r\n\r\n return s * (1.0 / 4.0);\r\n}";
var StdLibGLSL = "#define HALF_MAX 65504.0 // (2 - 2^-10) * 2^15\r\n\r\n#define FLT_EPSILON 1.192092896e-07 // Smallest positive number, such that 1.0 + FLT_EPSILON != 1.0\r\n\r\nmediump vec4 safeHDR(mediump vec4 c)\r\n{\r\n return min(c, HALF_MAX);\r\n}\r\n\r\nfloat max3(float a, float b, float c)\r\n{\r\n return max(max(a, b), c);\r\n}\r\n\r\nvec3 positivePow(vec3 base, vec3 power)\r\n{\r\n return pow(max(abs(base), vec3(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON)), power);\r\n}";
var ShadowGLSL = "#ifndef GRAPHICS_API_GLES3\r\n\t#define NO_NATIVE_SHADOWMAP\r\n#endif\r\n\r\n#if defined(NO_NATIVE_SHADOWMAP)\r\n\t#define TEXTURE2D_SHADOW(textureName) uniform mediump sampler2D textureName\r\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, coord3) (texture2D(textureName,coord3.xy).r<coord3.z?0.0:1.0)\r\n\t#define TEXTURE2D_SHADOW_PARAM(shadowMap) mediump sampler2D shadowMap\r\n#else\r\n\t#define TEXTURE2D_SHADOW(textureName) uniform mediump sampler2DShadow textureName\r\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, coord3) textureLod(textureName,coord3,0.0)\r\n\t#define TEXTURE2D_SHADOW_PARAM(shadowMap) mediump sampler2DShadow shadowMap\r\n#endif\r\n\r\n#if defined(RECEIVESHADOW)&&defined(SHADOW)\r\n #define CALCULATE_SHADOWS\r\n#endif\r\n\r\n#if defined(RECEIVESHADOW)&&defined(SHADOW_SPOT)\r\n\t#define CALCULATE_SPOTSHADOWS\r\n#endif\r\n\r\nuniform vec4 u_ShadowBias; // x: depth bias, y: normal bias\r\n\r\n#if defined(CALCULATE_SHADOWS)||defined(CALCULATE_SPOTSHADOWS)\r\n\t#include \"ShadowSampleTent.glsl\"\r\n\tuniform vec4 u_ShadowMapSize;\r\n\tuniform vec4 u_SpotShadowMapSize;\r\n\tuniform vec4 u_ShadowParams; // x: shadowStrength y: ShadowSpotLightStrength\r\n\t\r\n\tfloat sampleShdowMapFiltered4(TEXTURE2D_SHADOW_PARAM(shadowMap),vec3 shadowCoord,vec4 shadowMapSize)\r\n\t{\r\n\t\tfloat attenuation;\r\n\t\tvec4 attenuation4;\r\n\t\tvec2 offset=shadowMapSize.xy/2.0;\r\n\t\tvec3 shadowCoord0=shadowCoord + vec3(-offset,0.0);\r\n\t\tvec3 shadowCoord1=shadowCoord + vec3(offset.x,-offset.y,0.0);\r\n\t\tvec3 shadowCoord2=shadowCoord + vec3(-offset.x,offset.y,0.0);\r\n\t\tvec3 shadowCoord3=shadowCoord + vec3(offset,0.0);\r\n\t\tattenuation4.x = SAMPLE_TEXTURE2D_SHADOW(shadowMap, shadowCoord0);\r\n\t\tattenuation4.y = SAMPLE_TEXTURE2D_SHADOW(shadowMap, shadowCoord1);\r\n\t\tattenuation4.z = SAMPLE_TEXTURE2D_SHADOW(shadowMap, shadowCoord2);\r\n\t\tattenuation4.w = SAMPLE_TEXTURE2D_SHADOW(shadowMap, shadowCoord3);\r\n\t\tattenuation = dot(attenuation4, vec4(0.25));\r\n\t\treturn attenuation;\r\n\t}\r\n\r\n\tfloat sampleShdowMapFiltered9(TEXTURE2D_SHADOW_PARAM(shadowMap),vec3 shadowCoord,vec4 shadowmapSize)\r\n\t{\r\n\t\tfloat attenuation;\r\n\t\tfloat fetchesWeights[9];\r\n\t\tvec2 fetchesUV[9];\r\n\t\tsampleShadowComputeSamplesTent5x5(shadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);\r\n\t\tattenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[0].xy, shadowCoord.z));\r\n\t\tattenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[1].xy, shadowCoord.z));\r\n\t\tattenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[2].xy, shadowCoord.z));\r\n\t\tattenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[3].xy, shadowCoord.z));\r\n\t\tattenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[4].xy, shadowCoord.z));\r\n\t\tattenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[5].xy, shadowCoord.z));\r\n\t\tattenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[6].xy, shadowCoord.z));\r\n\t\tattenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[7].xy, shadowCoord.z));\r\n\t\tattenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(shadowMap, vec3(fetchesUV[8].xy, shadowCoord.z));\r\n\t\treturn attenuation;\r\n\t}\r\n\r\n#endif\r\n\r\n\r\n\r\n\r\n#if defined(CALCULATE_SHADOWS)\r\n\r\n\tTEXTURE2D_SHADOW(u_ShadowMap);\r\n\r\n\tuniform mat4 u_ShadowMatrices[4];\r\n\tuniform vec4 u_ShadowSplitSpheres[4];// max cascade is 4\r\n\r\n\tmediump int computeCascadeIndex(vec3 positionWS)\r\n\t{\r\n\t\tvec3 fromCenter0 = positionWS - u_ShadowSplitSpheres[0].xyz;\r\n\t\tvec3 fromCenter1 = positionWS - u_ShadowSplitSpheres[1].xyz;\r\n\t\tvec3 fromCenter2 = positionWS - u_ShadowSplitSpheres[2].xyz;\r\n\t\tvec3 fromCenter3 = positionWS - u_ShadowSplitSpheres[3].xyz;\r\n\r\n\t\tmediump vec4 comparison = vec4(\r\n\t\t\tdot(fromCenter0, fromCenter0)<u_ShadowSplitSpheres[0].w,\r\n\t\t\tdot(fromCenter1, fromCenter1)<u_ShadowSplitSpheres[1].w,\r\n\t\t\tdot(fromCenter2, fromCenter2)<u_ShadowSplitSpheres[2].w,\r\n\t\t\tdot(fromCenter3, fromCenter3)<u_ShadowSplitSpheres[3].w);\r\n\t\tcomparison.yzw = clamp(comparison.yzw - comparison.xyz,0.0,1.0);//keep the nearest\r\n\t\tmediump vec4 indexCoefficient = vec4(4.0,3.0,2.0,1.0);\r\n\t\tmediump int index = 4 - int(dot(comparison, indexCoefficient));\r\n\t\treturn index;\r\n\t}\r\n\r\n\tvec4 getShadowCoord(vec4 positionWS)\r\n\t{\r\n\t\t#ifdef SHADOW_CASCADE\r\n\t\t\tmediump int cascadeIndex = computeCascadeIndex(positionWS.xyz);\r\n\t\t\tif(cascadeIndex > 3)// out of shadow range cascadeIndex is 4.\r\n\t\t\t\treturn vec4(0.0);\r\n\t\t\t\r\n\t\t\t#ifdef GRAPHICS_API_GLES3\r\n\t\t\t\treturn u_ShadowMatrices[cascadeIndex] * positionWS;\r\n\t\t\t#else\r\n\t\t\t\tmat4 shadowMat;\r\n\t\t\t\tif(cascadeIndex == 0)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[0];\r\n\t\t\t\telse if(cascadeIndex == 1)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[1];\r\n\t\t\t\telse if(cascadeIndex == 2)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[2];\r\n\t\t\t\telse\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[3];\r\n\t\t\t\treturn shadowMat * positionWS;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\treturn u_ShadowMatrices[0] * positionWS;\r\n\t\t#endif\r\n\t}\r\n\r\n\tfloat sampleShadowmap(vec4 shadowCoord)\r\n\t{\r\n\t\tshadowCoord.xyz /= shadowCoord.w;\r\n\t\tfloat attenuation = 1.0;\r\n\t\tif(shadowCoord.z > 0.0 && shadowCoord.z < 1.0)\r\n\t\t{\r\n\t\t\t#if defined(SHADOW_SOFT_SHADOW_HIGH)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered9(u_ShadowMap,shadowCoord.xyz,u_ShadowMapSize);\r\n\t\t\t#elif defined(SHADOW_SOFT_SHADOW_LOW)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered4(u_ShadowMap,shadowCoord.xyz,u_ShadowMapSize);\r\n\t\t\t#else\r\n\t\t\t\tattenuation = SAMPLE_TEXTURE2D_SHADOW(u_ShadowMap,shadowCoord.xyz);\r\n\t\t\t#endif\r\n\t\t\tattenuation = mix(1.0,attenuation,u_ShadowParams.x);//shadowParams.x:shadow strength\r\n\t\t}\r\n\t\treturn attenuation;\r\n\t}\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader<65><72><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ĺ겻<C4BA><EAB2BB><EFBFBD><EFBFBD>ifdef <20><><EFBFBD><EFBFBD>ij<EFBFBD>if defined\r\n\tTEXTURE2D_SHADOW(u_SpotShadowMap);\r\n\tuniform mat4 u_SpotViewProjectMatrix;\r\n\tfloat sampleSpotShadowmap(vec4 shadowCoord)\r\n\t{\r\n\t\tshadowCoord.xyz /= shadowCoord.w;\r\n\t\tfloat attenuation = 1.0;\r\n\t\tshadowCoord.xy +=1.0;\r\n\t\tshadowCoord.xy/=2.0; \r\n\t\tif(shadowCoord.z > 0.0 && shadowCoord.z < 1.0)\r\n\t\t{\r\n\t\t\t#if defined(SHADOW_SPOT_SOFT_SHADOW_HIGH)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered9(u_SpotShadowMap,shadowCoord.xyz,u_SpotShadowMapSize);\r\n\t\t\t#elif defined(SHADOW_SPOT_SOFT_SHADOW_LOW)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered4(u_SpotShadowMap,shadowCoord.xyz,u_SpotShadowMapSize);\r\n\t\t\t#else\r\n\t\t\t\tattenuation = SAMPLE_TEXTURE2D_SHADOW(u_SpotShadowMap,shadowCoord.xyz);\r\n\t\t\t#endif\r\n\t\t\tattenuation = mix(1.0,attenuation,u_ShadowParams.y);//shadowParams.y:shadow strength\r\n\t\t}\r\n\t\treturn attenuation;\r\n\t}\r\n#endif\r\n\r\nvec3 applyShadowBias(vec3 positionWS, vec3 normalWS, vec3 lightDirection)\r\n{\r\n float invNdotL = 1.0 - clamp(dot(-lightDirection, normalWS),0.0,1.0);\r\n float scale = invNdotL * u_ShadowBias.y;\r\n\r\n // normal bias is negative since we want to apply an inset normal offset\r\n positionWS += -lightDirection * u_ShadowBias.xxx;\r\n positionWS += normalWS * vec3(scale);\r\n return positionWS;\r\n}\r\n";
var ShadowCasterVSGLSL = "#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\"\r\n#include \"Shadow.glsl\"\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\nuniform mat4 u_ViewProjection;\r\n\r\n#ifdef SHADOW\r\n\tuniform vec3 u_ShadowLightDirection;\r\n#endif\r\n\r\n\r\nvec4 shadowCasterVertex()\r\n{\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\t\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tworldMat = worldMat * skinTransform;\r\n\t#endif\r\n\r\n\tvec4 positionWS = worldMat * a_Position;\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\r\n\tvec3 normalWS = normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem\r\n\tvec4 positionCS = u_ViewProjection * positionWS;\r\n\t#ifdef SHADOW\r\n\t\tpositionWS.xyz = applyShadowBias(positionWS.xyz,normalWS,u_ShadowLightDirection);\r\n\t\tpositionCS.z = max(positionCS.z, 0.0);//min ndc z is 0.0\r\n\t#endif\r\n\r\n\t\r\n\t#ifdef SHADOW_SPOT\r\n\t\tpositionCS.z = positionCS.z-u_ShadowBias.x/positionCS.w;\r\n\t\tpositionCS.z = max(positionCS.z, 0.0);//min ndc z is 0.0\r\n\t#endif\r\n\t\r\n\t\r\n\t// //TODO没考虑UV动画呢\r\n\t// #if defined(DIFFUSEMAP)&&defined(ALPHATEST)\r\n\t// \tv_Texcoord0=a_Texcoord0;\r\n\t// #endif\r\n return positionCS;\r\n}\r\n";
var ShadowCasterFSGLSL = "vec4 shadowCasterFragment()\r\n{\r\n return vec4(0.0);\r\n}\r\n";
var SkyBoxPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec3 v_Texcoord;\r\n\r\nuniform samplerCube u_CubeTexture;\r\nuniform float u_Exposure;\r\nuniform vec4 u_TintColor;\r\n\r\n\r\nvoid main()\r\n{\t\r\n\tvec3 color=textureCube(u_CubeTexture, v_Texcoord).rgb*u_TintColor.rgb*u_Exposure*2.0;\r\n\tgl_FragColor=vec4(color,1.0);\r\n}\r\n\r\n";
var SkyBoxVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nuniform mat4 u_ViewProjection;\r\nuniform float u_Rotation;\r\nvarying vec3 v_Texcoord;\r\n\r\n\r\nvec4 rotateAroundYInDegrees (vec4 vertex, float degrees)\r\n{\r\n\tfloat angle = degrees * 3.141593 / 180.0;\r\n\tfloat sina=sin(angle);\r\n\tfloat cosa=cos(angle);\r\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\r\n\treturn vec4(m*vertex.xz, vertex.yw).xzyw;\r\n}\r\n\t\t\r\nvoid main()\r\n{\r\n\tvec4 position=rotateAroundYInDegrees(a_Position,u_Rotation);\r\n\tgl_Position = u_ViewProjection*position;\r\n\tv_Texcoord=vec3(-a_Position.x,a_Position.yz);//转换坐标系\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n";
var SkyBoxProceduralPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\nconst float MIE_G = -0.990;\r\nconst float MIE_G2 = 0.9801;\r\nconst float SKY_GROUND_THRESHOLD = 0.02;\r\n\r\nuniform float u_SunSize;\r\nuniform float u_SunSizeConvergence;\r\nuniform DirectionLight u_SunLight;\r\n\r\n\r\nvarying vec3 v_GroundColor;\r\nvarying vec3 v_SkyColor;\r\n\r\n\r\n#ifdef SUN_HIGH_QUALITY\r\n\tvarying vec3 v_Vertex;\r\n#elif defined(SUN_SIMPLE)\r\n\tvarying vec3 v_RayDir;\r\n#else\r\n\tvarying float v_SkyGroundFactor;\r\n#endif\r\n\r\n#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\tvarying vec3 v_SunColor;\r\n#endif\r\n\r\n// Calculates the Mie phase function\r\nfloat getMiePhase(float eyeCos, float eyeCos2) {\r\n\tfloat temp = 1.0 + MIE_G2 - 2.0 * MIE_G * eyeCos;\r\n\ttemp = pow(temp, pow(u_SunSize,0.65) * 10.0);\r\n\ttemp = max(temp,1.0e-4); // prevent division by zero, esp. in half precision\r\n\ttemp = 1.5 * ((1.0 - MIE_G2) / (2.0 + MIE_G2)) * (1.0 + eyeCos2) / temp;\r\n\treturn temp;\r\n}\r\n\r\n// Calculates the sun shape\r\nfloat calcSunAttenuation(vec3 lightPos, vec3 ray) {\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tfloat focusedEyeCos = pow(clamp(dot(lightPos, ray),0.0,1.0), u_SunSizeConvergence);\r\n\t\treturn getMiePhase(-focusedEyeCos, focusedEyeCos * focusedEyeCos);\r\n\t#else //SUN_SIMPLE\r\n\t\tvec3 delta = lightPos - ray;\r\n\t\tfloat dist = length(delta);\r\n\t\tfloat spot = 1.0 - smoothstep(0.0, u_SunSize, dist);\r\n\t\treturn spot * spot;\r\n\t#endif\r\n}\r\n\r\nvoid main() {\r\n\t// if y > 1 [eyeRay.y < -SKY_GROUND_THRESHOLD] - ground\r\n\t// if y >= 0 and < 1 [eyeRay.y <= 0 and > -SKY_GROUND_THRESHOLD] - horizon\r\n\t// if y < 0 [eyeRay.y > 0] - sky\r\n\tvec3 col = vec3(0.0, 0.0, 0.0);\r\n\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tvec3 ray = normalize(v_Vertex);\r\n\t\tfloat y = ray.y / SKY_GROUND_THRESHOLD;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tvec3 ray = v_RayDir;\r\n\t\tfloat y = ray.y / SKY_GROUND_THRESHOLD;\t\r\n\t#else\r\n\t\tfloat y = v_SkyGroundFactor;\r\n\t#endif\r\n\r\n\t// if we did precalculate color in vprog: just do lerp between them\r\n\tcol = mix(v_SkyColor, v_GroundColor, clamp(y,0.0,1.0));\r\n\r\n\t#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\t\tif (y < 0.0)\r\n\t\t\tcol += v_SunColor * calcSunAttenuation(-u_SunLight.direction, -ray);\r\n\t#endif\r\n\r\n\tcol = sqrt(col);//linear space convert to gamma space\r\n\tgl_FragColor=vec4(col,1.0);\r\n}\r\n\r\n";
var SkyBoxProceduralVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\n#define OUTER_RADIUS 1.025\r\n#define RAYLEIGH (mix(0.0, 0.0025, pow(u_AtmosphereThickness,2.5)))// Rayleigh constant Rayleigh为夜空光和极光亮度单位\r\n#define MIE 0.0010 // Mie constant 米氏散射\r\n#define SUN_BRIGHTNESS 20.0 // Sun brightness\r\n#define MAX_SCATTER 50.0 // Maximum scattering value, to prevent math overflows on Adrenos\r\n\r\nconst float SKY_GROUND_THRESHOLD = 0.02;\r\nconst float outerRadius = OUTER_RADIUS;\r\nconst float outerRadius2 = OUTER_RADIUS*OUTER_RADIUS;\r\nconst float innerRadius = 1.0;\r\nconst float innerRadius2 = 1.0;\r\nconst float cameraHeight = 0.0001;\r\n\r\nconst float HDSundiskIntensityFactor = 15.0;\r\nconst float simpleSundiskIntensityFactor = 27.0;\r\n\r\nconst float sunScale = 400.0 * SUN_BRIGHTNESS;\r\nconst float kmESun = MIE * SUN_BRIGHTNESS;\r\nconst float km4PI = MIE * 4.0 * 3.14159265;\r\nconst float scale = 1.0 / (OUTER_RADIUS - 1.0);\r\nconst float scaleDepth = 0.25;\r\nconst float scaleOverScaleDepth = (1.0 / (OUTER_RADIUS - 1.0)) / 0.25;\r\nconst float samples = 2.0; // THIS IS UNROLLED MANUALLY, DON'T TOUCH\r\n\r\n// RGB wavelengths .35 (.62=158), .43 (.68=174), .525 (.75=190)\r\nconst vec3 c_DefaultScatteringWavelength = vec3(0.65, 0.57, 0.475);//默认散射波长\r\nconst vec3 c_VariableRangeForScatteringWavelength = vec3(0.15, 0.15, 0.15);//散射播放的可变范围\r\n\r\nattribute vec4 a_Position;\r\n\r\nuniform mat4 u_ViewProjection;\r\nuniform vec3 u_SkyTint;\r\nuniform vec3 u_GroundTint;\r\nuniform float u_Exposure;\r\nuniform float u_AtmosphereThickness;\r\nuniform DirectionLight u_SunLight;\r\n\r\nvarying vec3 v_GroundColor;\r\nvarying vec3 v_SkyColor;\r\n\r\n#ifdef SUN_HIGH_QUALITY\r\n\tvarying vec3 v_Vertex;\r\n#elif defined(SUN_SIMPLE)\r\n\tvarying vec3 v_RayDir;\r\n#else\r\n\tvarying float v_SkyGroundFactor;\r\n#endif\r\n\r\n#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\tvarying vec3 v_SunColor;\r\n#endif\r\n\r\n// Calculates the Rayleigh phase function\r\nfloat getRayleighPhase(vec3 light, vec3 ray) \r\n{\r\n\tfloat eyeCos = dot(light, ray);\r\n\treturn 0.75 + 0.75*eyeCos*eyeCos;\r\n}\r\n\r\nfloat scaleAngle(float inCos)\r\n{\r\n\tfloat x = 1.0 - inCos;\r\n\treturn 0.25 * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\r\n}\r\n\r\n\r\nvoid main () {\r\n\tgl_Position = u_ViewProjection*a_Position;\r\n\r\n\tvec3 skyTintInGammaSpace = u_SkyTint;//支持非GAMMA空间后要调整\r\n\tvec3 scatteringWavelength = mix(c_DefaultScatteringWavelength-c_VariableRangeForScatteringWavelength,c_DefaultScatteringWavelength+c_VariableRangeForScatteringWavelength,vec3(1.0) - skyTintInGammaSpace); // using Tint in sRGB+ gamma allows for more visually linear interpolation and to keep (0.5) at (128, gray in sRGB) point\r\n\tvec3 invWavelength = 1.0 / pow(scatteringWavelength, vec3(4.0));\r\n\r\n\tfloat krESun = RAYLEIGH * SUN_BRIGHTNESS;\r\n\tfloat kr4PI = RAYLEIGH * 4.0 * 3.14159265;\r\n\r\n\tvec3 cameraPos = vec3(0.0,innerRadius + cameraHeight,0.0); // The camera's current position\r\n\r\n\t// Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)\r\n\tvec3 eyeRay = normalize(a_Position.xyz);\r\n\r\n\tfloat far = 0.0;\r\n\tvec3 cIn, cOut;\r\n\tif (eyeRay.y >= 0.0) {// Sky\r\n\t\t// Calculate the length of the \"atmosphere\"\r\n\t\tfar = sqrt(outerRadius2 + innerRadius2 * eyeRay.y * eyeRay.y - innerRadius2) - innerRadius * eyeRay.y;\r\n\r\n\t\t// Calculate the ray's starting position, then calculate its scattering offset\r\n\t\tfloat height = innerRadius + cameraHeight;\r\n\t\tfloat depth = exp(scaleOverScaleDepth * -cameraHeight);\r\n\t\tfloat startAngle = dot(eyeRay, cameraPos) / height;\r\n\t\tfloat startOffset = depth*scaleAngle(startAngle);\r\n\r\n\t\t// Initialize the scattering loop variables\r\n\t\tfloat sampleLength = far / samples;\r\n\t\tfloat scaledLength = sampleLength * scale;\r\n\t\tvec3 sampleRay = eyeRay * sampleLength;\r\n\t\tvec3 samplePoint = cameraPos + sampleRay * 0.5;\r\n\r\n\t\tvec3 frontColor = vec3(0.0);\r\n\t\t//unrolling this manually to avoid some platform for loop slow\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat lightAngle = dot(-u_SunLight.direction, samplePoint) / height;\r\n\t\t\tfloat cameraAngle = dot(eyeRay, samplePoint) / height;\r\n\t\t\tfloat scatter = (startOffset + depth*(scaleAngle(lightAngle) - scaleAngle(cameraAngle)));\r\n\t\t\tvec3 attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat lightAngle = dot(-u_SunLight.direction, samplePoint) / height;\r\n\t\t\tfloat cameraAngle = dot(eyeRay, samplePoint) / height;\r\n\t\t\tfloat scatter = (startOffset + depth*(scaleAngle(lightAngle) - scaleAngle(cameraAngle)));\r\n\t\t\tvec3 attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\r\n\t\t// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader\r\n\t\tcIn = frontColor * (invWavelength * krESun);\r\n\t\tcOut = frontColor * kmESun;\r\n\t} else {// Ground\r\n\t\tfar = (-cameraHeight) / (min(-0.001, eyeRay.y));\r\n\t\tvec3 pos = cameraPos + far * eyeRay;\r\n\r\n\t\t// Calculate the ray's starting position, then calculate its scattering offset\r\n\t\tfloat depth = exp((-cameraHeight) * (1.0/scaleDepth));\r\n\t\tfloat cameraAngle = dot(-eyeRay, pos);\r\n\t\tfloat lightAngle = dot(-u_SunLight.direction, pos);\r\n\t\tfloat cameraScale = scaleAngle(cameraAngle);\r\n\t\tfloat lightScale = scaleAngle(lightAngle);\r\n\t\tfloat cameraOffset = depth*cameraScale;\r\n\t\tfloat temp = lightScale + cameraScale;\r\n\r\n\t\t// Initialize the scattering loop variables\r\n\t\tfloat sampleLength = far / samples;\r\n\t\tfloat scaledLength = sampleLength * scale;\r\n\t\tvec3 sampleRay = eyeRay * sampleLength;\r\n\t\tvec3 samplePoint = cameraPos + sampleRay * 0.5;\r\n\r\n\t\t// Now loop through the sample rays\r\n\t\tvec3 frontColor = vec3(0.0, 0.0, 0.0);\r\n\t\tvec3 attenuate;\r\n\r\n\t\t// Loop removed because we kept hitting SM2.0 temp variable limits. Doesn't affect the image too much.\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat scatter = depth*temp - cameraOffset;\r\n\t\t\tattenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\r\n\t\tcIn = frontColor * (invWavelength * krESun + kmESun);\r\n\t\tcOut = clamp(attenuate, 0.0, 1.0);\r\n\t}\r\n\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tv_Vertex = -a_Position.xyz;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tv_RayDir = -eyeRay;\r\n\t#else\r\n\t\tv_SkyGroundFactor = -eyeRay.y / SKY_GROUND_THRESHOLD;\r\n\t#endif\r\n\r\n\t// if we want to calculate color in vprog:\r\n\t// in case of linear: multiply by _Exposure in here (even in case of lerp it will be common multiplier, so we can skip mul in fshader)\r\n\tv_GroundColor = u_Exposure * (cIn + u_GroundTint*u_GroundTint * cOut);//u_GroundColor*u_GroundColor is gamma space convert to linear space\r\n\tv_SkyColor = u_Exposure * (cIn * getRayleighPhase(-u_SunLight.direction, -eyeRay));\r\n\r\n\t\r\n\t// The sun should have a stable intensity in its course in the sky. Moreover it should match the highlight of a purely specular material.\r\n\t// This matching was done using the Unity3D standard shader BRDF1 on the 5/31/2017\r\n\t// Finally we want the sun to be always bright even in LDR thus the normalization of the lightColor for low intensity.\r\n\tfloat lightColorIntensity = clamp(length(u_SunLight.color), 0.25, 1.0);\r\n\r\n\t#ifdef SUN_HIGH_QUALITY \r\n\t\tv_SunColor = HDSundiskIntensityFactor * clamp(cOut,0.0,1.0) * u_SunLight.color / lightColorIntensity;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tv_SunColor = simpleSundiskIntensityFactor * clamp(cOut * sunScale,0.0,1.0) * u_SunLight.color / lightColorIntensity;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n";
var TrailPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\nuniform sampler2D u_MainTexture;\r\nuniform vec4 u_MainColor;\r\n\r\nvarying vec2 v_Texcoord0;\r\nvarying vec4 v_Color;\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = 2.0 * u_MainColor * v_Color;\r\n\t#ifdef MAINTEXTURE\r\n\t\tvec4 mainTextureColor = texture2D(u_MainTexture, v_Texcoord0);\r\n\t\tcolor *= mainTextureColor;\r\n\t#endif\r\n\tgl_FragColor = color;\r\n}\r\n\r\n ";
var TrailVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n\r\nattribute vec3 a_Position;\r\nattribute vec3 a_OffsetVector;\r\nattribute vec4 a_Color;\r\nattribute float a_Texcoord0X;\r\nattribute float a_Texcoord0Y;\r\nattribute float a_BirthTime;\r\n\r\nuniform mat4 u_View;\r\nuniform mat4 u_Projection;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nuniform float u_CurTime;\r\nuniform float u_LifeTime;\r\nuniform vec4 u_WidthCurve[10];\r\nuniform int u_WidthCurveKeyLength;\r\n\r\nvarying vec2 v_Texcoord0;\r\nvarying vec4 v_Color;\r\n\r\nfloat hermiteInterpolate(float t, float outTangent, float inTangent, float duration, float value1, float value2)\r\n{\r\n\tfloat t2 = t * t;\r\n\tfloat t3 = t2 * t;\r\n\tfloat a = 2.0 * t3 - 3.0 * t2 + 1.0;\r\n\tfloat b = t3 - 2.0 * t2 + t;\r\n\tfloat c = t3 - t2;\r\n\tfloat d = -2.0 * t3 + 3.0 * t2;\r\n\treturn a * value1 + b * outTangent * duration + c * inTangent * duration + d * value2;\r\n}\r\n\r\nfloat getCurWidth(in float normalizeTime)\r\n{\r\n\tfloat width;\r\n\tif(normalizeTime == 0.0){\r\n\t\twidth=u_WidthCurve[0].w;\r\n\t}\r\n\telse if(normalizeTime >= 1.0){\r\n\t\twidth=u_WidthCurve[u_WidthCurveKeyLength - 1].w;\r\n\t}\r\n\telse{\r\n\t\tfor(int i = 0; i < 10; i ++ )\r\n\t\t{\r\n\t\t\tif(normalizeTime == u_WidthCurve[i].x){\r\n\t\t\t\twidth=u_WidthCurve[i].w;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tvec4 lastFrame = u_WidthCurve[i];\r\n\t\t\tvec4 nextFrame = u_WidthCurve[i + 1];\r\n\t\t\tif(normalizeTime > lastFrame.x && normalizeTime < nextFrame.x)\r\n\t\t\t{\r\n\t\t\t\tfloat duration = nextFrame.x - lastFrame.x;\r\n\t\t\t\tfloat t = (normalizeTime - lastFrame.x) / duration;\r\n\t\t\t\tfloat outTangent = lastFrame.z;\r\n\t\t\t\tfloat inTangent = nextFrame.y;\r\n\t\t\t\tfloat value1 = lastFrame.w;\r\n\t\t\t\tfloat value2 = nextFrame.w;\r\n\t\t\t\twidth=hermiteInterpolate(t, outTangent, inTangent, duration, value1, value2);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn width;\r\n}\t\r\n\r\nvoid main()\r\n{\r\n\tfloat normalizeTime = (u_CurTime - a_BirthTime) / u_LifeTime;\r\n\t\r\n\tv_Texcoord0 = vec2(a_Texcoord0X, 1.0 - a_Texcoord0Y) * u_TilingOffset.xy + u_TilingOffset.zw;\r\n\t\r\n\tv_Color = a_Color;\r\n\t\r\n\tvec3 cameraPos = (u_View*vec4(a_Position,1.0)).rgb;\r\n\tgl_Position = u_Projection * vec4(cameraPos+a_OffsetVector * getCurWidth(normalizeTime),1.0);\r\n\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n";
var UnlitPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef ALBEDOTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = u_AlbedoColor;\r\n\t#ifdef ALBEDOTEXTURE\r\n\t\tcolor *= texture2D(u_AlbedoTexture, v_Texcoord0);\r\n\t#endif\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tcolor *= v_Color;\r\n\t#endif\r\n\t\r\n\t#ifdef ALPHATEST\r\n\t\tif(color.a < u_AlphaTestValue)\r\n\t\t\tdiscard;\r\n\t#endif\r\n\t\r\n\tgl_FragColor = color;\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact = clamp((1.0 / gl_FragCoord.w - u_FogStart) / u_FogRange, 0.0, 1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.0), lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, u_FogColor, lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n\t\r\n}\r\n\r\n";
var UnlitVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\";\r\n\r\nattribute vec4 a_Position;\r\n\r\nattribute vec2 a_Texcoord0;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\nattribute vec4 a_Color;\r\nvarying vec4 v_Color;\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nvoid main() {\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position =u_ViewProjection * a_WorldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tv_Color = a_Color;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}";
var WaterPrimaryPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#ifdef MAINTEXTURE\r\n\tuniform sampler2D u_MainTexture;\r\n#endif\r\n\r\n#ifdef NORMALTEXTURE\r\n\tuniform sampler2D u_NormalTexture;\r\n#endif\r\n\r\nuniform vec4 u_HorizonColor;\r\n\r\nvarying vec3 v_Normal;\r\nvarying vec3 v_Tangent;\r\nvarying vec3 v_Binormal;\r\nvarying vec3 v_ViewDir;\r\nvarying vec2 v_Texcoord0;\r\nvarying vec2 v_Texcoord1;\r\n\r\n\r\n#include \"Lighting.glsl\"\r\n\r\n\r\n\r\nvec3 NormalSampleToWorldSpace(vec4 normalMapSample) {\r\n\tvec3 normalT;\r\n\tnormalT.x = 2.0 * normalMapSample.x - 1.0;\r\n\tnormalT.y = 1.0 - 2.0 * normalMapSample.y;\r\n\tnormalT.z = sqrt(1.0 - clamp(dot(normalT.xy, normalT.xy), 0.0, 1.0));\r\n\r\n\tvec3 bumpedNormal = normalize(normalT);\r\n\r\n\treturn bumpedNormal;\r\n}\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 bumpColor1 = texture2D(u_NormalTexture, v_Texcoord0);\r\n\tvec4 bumpColor2 = texture2D(u_NormalTexture, v_Texcoord1);\r\n\r\n\tvec3 normal1 = NormalSampleToWorldSpace(bumpColor1);\r\n\tvec3 normal2 = NormalSampleToWorldSpace(bumpColor2);\r\n\t\r\n\tvec3 normal = normalize((normal1 + normal2) * 0.5);\r\n\tvec3 viewDir = normalize(v_ViewDir);\r\n\tfloat fresnel = dot(viewDir, normal);\r\n\t\r\n\tvec4 waterColor = texture2D(u_MainTexture, vec2(fresnel, fresnel));\r\n\t\r\n\tvec4 color;\r\n\tcolor.rgb = mix(waterColor.rgb, u_HorizonColor.rgb, vec3(waterColor.a));\r\n\tcolor.a = u_HorizonColor.a;\r\n\t\r\n\tgl_FragColor = color;\r\n}\r\n\r\n\r\n";
var WaterPrimaryVS = "#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\nattribute vec4 a_Tangent0;\r\n\r\nuniform mat4 u_MvpMatrix;\r\nuniform mat4 u_WorldMat;\r\nuniform vec3 u_CameraPos;\r\nuniform float u_WaveScale;\r\nuniform vec4 u_WaveSpeed;\r\nuniform float u_Time;\r\n\r\nvarying vec3 v_Normal;\r\nvarying vec3 v_Tangent;\r\nvarying vec3 v_Binormal;\r\nvarying vec3 v_ViewDir;\r\nvarying vec2 v_Texcoord0;\r\nvarying vec2 v_Texcoord1;\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionWorld = u_WorldMat * a_Position;\r\n\tvec4 position = u_MvpMatrix * a_Position;\r\n\t\r\n\tvec4 temp = vec4(positionWorld.x, positionWorld.z, positionWorld.x, positionWorld.z) * u_WaveScale + u_WaveSpeed * u_WaveScale * u_Time;\r\n\t\r\n\tv_Texcoord0 = temp.xy * vec2(0.4, 0.45);\r\n\tv_Texcoord1 = temp.wz;\r\n\t\r\n\tmat3 worldMat = mat3(u_WorldMat);\r\n\tv_Normal = worldMat * a_Normal;\r\n\tv_Tangent = worldMat * a_Tangent0.xyz;\r\n\tv_Binormal = cross(v_Normal, v_Tangent) * a_Tangent0.w;\r\n\t\r\n\tv_ViewDir = u_CameraPos - positionWorld.xyz;\r\n\tgl_Position = position;\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}";
var DepthNormalUtil = "#define SAMPLE_DEPTH_TEXTURE(textureName,coord2) (texture2D(textureName,coord2).r)\r\n//此方法库用来压缩解析深度贴图,法线深度贴图\r\n\r\n/*camera 传入的Texture以及*/\r\nuniform sampler2D u_CameraDepthTexture;\r\nuniform vec4 u_ZBufferParams;\r\nuniform sampler2D u_CameraDepthNormalsTexture;\r\n\r\n// Encoding/decoding view space normals into 2D 0..1 vector\r\nvec2 EncodeViewNormalStereo( vec3 n )\r\n{\r\n n.z = abs(n.z);\r\n float kScale = 1.7777;\r\n vec2 enc;\r\n enc = n.xy / (n.z+1.0);\r\n enc /= kScale;\r\n enc = enc*0.5+0.5;\r\n return enc;\r\n}\r\n\r\nvec3 DecodeViewNormalStereo( vec4 enc4 )\r\n{\r\n float kScale = 1.7777;\r\n vec3 nn = enc4.xyz*vec3(2.0*kScale,2.0*kScale,0.0) + vec3(-kScale,-kScale,1.0);\r\n float g = 2.0 / dot(nn.xyz,nn.xyz);\r\n vec3 n;\r\n n.xy = g*nn.xy;\r\n n.z = g-1.0;\r\n return n;\r\n}\r\n\r\n\r\n// Encoding/decoding [0..1) floats into 8 bit/channel RG. Note that 1.0 will not be encoded properly.\r\nvec2 EncodeFloatRG( float v )\r\n{\r\n vec2 kEncodeMul = vec2(1.0, 255.0);\r\n float kEncodeBit = 1.0/255.0;\r\n vec2 enc = kEncodeMul * v;\r\n enc = fract(enc);\r\n enc.x -= enc.y * kEncodeBit;\r\n return enc;\r\n}\r\n\r\n\r\n\r\nfloat DecodeFloatRG( vec2 enc )\r\n{\r\n vec2 kDecodeDot = vec2(1.0, 1.0/255.0);\r\n return dot( enc, kDecodeDot );\r\n}\r\n\r\nvec4 EncodeDepthNormal(float depth,vec3 normals){\r\n\tvec4 encode;\r\n\tencode.xy = EncodeViewNormalStereo(normals);\r\n\tencode.zw = EncodeFloatRG(depth);\r\n return encode;\r\n}\r\n\r\nvoid DecodeDepthNormal( vec4 enc, out float depth, out vec3 normal )\r\n{\r\n depth = DecodeFloatRG (enc.zw);\r\n normal = DecodeViewNormalStereo (enc);\r\n}\r\n\r\n\r\n\r\nvec4 depthNormalsFragment(vec4 depthNormal)\r\n{\r\n return EncodeDepthNormal(depthNormal.w,depthNormal.xyz);\r\n}\r\n\r\n\r\n// Z buffer to linear 0..1 depth\r\nfloat Linear01Depth(float z,vec4 zbufferParams)\r\n{\r\n return 1.0 / (zbufferParams.x * z + zbufferParams.y);\r\n}\r\n// Z buffer to linear depth\r\nfloat LinearEyeDepth(float z,vec4 zbufferParams)\r\n{\r\n return 1.0 / (zbufferParams.z * z + zbufferParams.w);\r\n}\r\n";
class ShaderInit3D {
constructor() {
}
static __init__() {
Shader3D.SHADERDEFINE_LEGACYSINGALLIGHTING = Shader3D.getDefineByName("LEGACYSINGLELIGHTING");
Shader3D.SHADERDEFINE_GRAPHICS_API_GLES2 = Shader3D.getDefineByName("GRAPHICS_API_GLES2");
Shader3D.SHADERDEFINE_GRAPHICS_API_GLES3 = Shader3D.getDefineByName("GRAPHICS_API_GLES3");
Shader3D.addInclude("Lighting.glsl", LightingGLSL);
Shader3D.addInclude("ShadowSampleTent.glsl", ShadowSampleTentGLSL);
Shader3D.addInclude("GlobalIllumination.glsl", GlobalIllumination);
Shader3D.addInclude("Shadow.glsl", ShadowGLSL);
Shader3D.addInclude("ShadowCasterVS.glsl", ShadowCasterVSGLSL);
Shader3D.addInclude("ShadowCasterFS.glsl", ShadowCasterFSGLSL);
Shader3D.addInclude("Colors.glsl", ColorsGLSL);
Shader3D.addInclude("Sampling.glsl", SamplingGLSL);
Shader3D.addInclude("StdLib.glsl", StdLibGLSL);
Shader3D.addInclude("PBRVSInput.glsl", PBRVSInput);
Shader3D.addInclude("PBRFSInput.glsl", PBRFSInput);
Shader3D.addInclude("LayaPBRBRDF.glsl", LayaPBRBRDF);
Shader3D.addInclude("PBRCore.glsl", PBRCore);
Shader3D.addInclude("PBRVertex.glsl", PBRVertex);
Shader3D.addInclude("LayaUtile.glsl", LayaUtile);
Shader3D.addInclude("DepthNormalUtil.glsl", DepthNormalUtil);
var attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0,
'a_Color': VertexMesh.MESH_COLOR0,
'a_Normal': VertexMesh.MESH_NORMAL0,
'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0,
'a_Texcoord1': VertexMesh.MESH_TEXTURECOORDINATE1,
'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0,
'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0,
'a_Tangent0': VertexMesh.MESH_TANGENT0,
'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0,
'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR
};
var uniformMap = {
'u_Bones': Shader3D.PERIOD_CUSTOM,
'u_DiffuseTexture': Shader3D.PERIOD_MATERIAL,
'u_SpecularTexture': Shader3D.PERIOD_MATERIAL,
'u_NormalTexture': Shader3D.PERIOD_MATERIAL,
'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL,
'u_DiffuseColor': Shader3D.PERIOD_MATERIAL,
'u_AlbedoIntensity': Shader3D.PERIOD_MATERIAL,
'u_MaterialSpecular': Shader3D.PERIOD_MATERIAL,
'u_Shininess': Shader3D.PERIOD_MATERIAL,
'u_TilingOffset': Shader3D.PERIOD_MATERIAL,
'u_TransmissionRate': Shader3D.PERIOD_MATERIAL,
'u_BackDiffuse': Shader3D.PERIOD_MATERIAL,
'u_BackScale': Shader3D.PERIOD_MATERIAL,
'u_ThinknessTexture': Shader3D.PERIOD_MATERIAL,
'u_TransmissionColor': Shader3D.PERIOD_MATERIAL,
'u_WorldMat': Shader3D.PERIOD_SPRITE,
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE,
'u_LightMap': Shader3D.PERIOD_SPRITE,
'u_LightMapDirection': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE,
'u_CameraPos': Shader3D.PERIOD_CAMERA,
'u_Viewport': Shader3D.PERIOD_CAMERA,
'u_ProjectionParams': Shader3D.PERIOD_CAMERA,
'u_View': Shader3D.PERIOD_CAMERA,
'u_ViewProjection': Shader3D.PERIOD_CAMERA,
'u_ReflectTexture': Shader3D.PERIOD_SCENE,
'u_FogStart': Shader3D.PERIOD_SCENE,
'u_FogRange': Shader3D.PERIOD_SCENE,
'u_FogColor': Shader3D.PERIOD_SCENE,
'u_DirationLightCount': Shader3D.PERIOD_SCENE,
'u_LightBuffer': Shader3D.PERIOD_SCENE,
'u_LightClusterBuffer': Shader3D.PERIOD_SCENE,
'u_AmbientColor': Shader3D.PERIOD_SCENE,
'u_ShadowBias': Shader3D.PERIOD_SCENE,
'u_ShadowLightDirection': Shader3D.PERIOD_SCENE,
'u_ShadowMap': Shader3D.PERIOD_SCENE,
'u_ShadowParams': Shader3D.PERIOD_SCENE,
'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE,
'u_ShadowMatrices': Shader3D.PERIOD_SCENE,
'u_ShadowMapSize': Shader3D.PERIOD_SCENE,
'u_SpotShadowMap': Shader3D.PERIOD_SCENE,
'u_SpotViewProjectMatrix': Shader3D.PERIOD_SCENE,
'u_ShadowLightPosition': Shader3D.PERIOD_SCENE,
'u_AmbientSHAr': Shader3D.PERIOD_SCENE,
'u_AmbientSHAg': Shader3D.PERIOD_SCENE,
'u_AmbientSHAb': Shader3D.PERIOD_SCENE,
'u_AmbientSHBr': Shader3D.PERIOD_SCENE,
'u_AmbientSHBg': Shader3D.PERIOD_SCENE,
'u_AmbientSHBb': Shader3D.PERIOD_SCENE,
'u_AmbientSHC': Shader3D.PERIOD_SCENE,
'u_DirectionLight.color': Shader3D.PERIOD_SCENE,
'u_DirectionLight.direction': Shader3D.PERIOD_SCENE,
'u_PointLight.position': Shader3D.PERIOD_SCENE,
'u_PointLight.range': Shader3D.PERIOD_SCENE,
'u_PointLight.color': Shader3D.PERIOD_SCENE,
'u_SpotLight.position': Shader3D.PERIOD_SCENE,
'u_SpotLight.direction': Shader3D.PERIOD_SCENE,
'u_SpotLight.range': Shader3D.PERIOD_SCENE,
'u_SpotLight.spot': Shader3D.PERIOD_SCENE,
'u_SpotLight.color': Shader3D.PERIOD_SCENE
};
var stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
var shader = Shader3D.add("BLINNPHONG", null, null, true);
var subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(MeshBlinnPhongVS, MeshBlinnPhongPS, stateMap, "Forward");
var shaderPass = subShader.addShaderPass(MeshBlinnPhongShadowCasterVS, MeshBlinnPhongShadowCasterPS, stateMap, "ShadowCaster");
shaderPass = subShader.addShaderPass(DepthNormalsTextureVS, DepthNormalsTextureFS, stateMap, "DepthNormal");
attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0,
'a_Color': VertexMesh.MESH_COLOR0
};
uniformMap = {
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_Color': Shader3D.PERIOD_MATERIAL
};
stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
shader = Shader3D.add("LineShader");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(lineVS, linePS, stateMap);
attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0,
'a_Color': VertexMesh.MESH_COLOR0,
'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0,
'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0,
'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0,
'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0,
'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR
};
uniformMap = {
'u_Bones': Shader3D.PERIOD_CUSTOM,
'u_AlbedoTexture': Shader3D.PERIOD_MATERIAL,
'u_AlbedoColor': Shader3D.PERIOD_MATERIAL,
'u_TilingOffset': Shader3D.PERIOD_MATERIAL,
'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL,
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_ViewProjection': Shader3D.PERIOD_CAMERA,
'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE,
'u_FogStart': Shader3D.PERIOD_SCENE,
'u_FogRange': Shader3D.PERIOD_SCENE,
'u_FogColor': Shader3D.PERIOD_SCENE
};
stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
shader = Shader3D.add("Unlit", null, null, true);
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(UnlitVS, UnlitPS, stateMap);
attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0,
'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0,
'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0,
'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0,
'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0,
'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR
};
uniformMap = {
'u_Bones': Shader3D.PERIOD_CUSTOM,
'u_AlbedoTexture': Shader3D.PERIOD_MATERIAL,
'u_AlbedoColor': Shader3D.PERIOD_MATERIAL,
'u_TilingOffset': Shader3D.PERIOD_MATERIAL,
'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL,
'u_ViewProjection': Shader3D.PERIOD_CAMERA,
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE,
'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE,
'u_FogStart': Shader3D.PERIOD_SCENE,
'u_FogRange': Shader3D.PERIOD_SCENE,
'u_FogColor': Shader3D.PERIOD_SCENE
};
stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
shader = Shader3D.add("Effect", null, null, true);
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(EffectVS, EffectPS, stateMap);
attributeMap = {
'a_CornerTextureCoordinate': VertexShuriKenParticle.PARTICLE_CORNERTEXTURECOORDINATE0,
'a_MeshPosition': VertexShuriKenParticle.PARTICLE_POSITION0,
'a_MeshColor': VertexShuriKenParticle.PARTICLE_COLOR0,
'a_MeshTextureCoordinate': VertexShuriKenParticle.PARTICLE_TEXTURECOORDINATE0,
'a_ShapePositionStartLifeTime': VertexShuriKenParticle.PARTICLE_SHAPEPOSITIONSTARTLIFETIME,
'a_DirectionTime': VertexShuriKenParticle.PARTICLE_DIRECTIONTIME,
'a_StartColor': VertexShuriKenParticle.PARTICLE_STARTCOLOR0,
'a_EndColor': VertexShuriKenParticle.PARTICLE_ENDCOLOR0,
'a_StartSize': VertexShuriKenParticle.PARTICLE_STARTSIZE,
'a_StartRotation0': VertexShuriKenParticle.PARTICLE_STARTROTATION,
'a_StartSpeed': VertexShuriKenParticle.PARTICLE_STARTSPEED,
'a_Random0': VertexShuriKenParticle.PARTICLE_RANDOM0,
'a_Random1': VertexShuriKenParticle.PARTICLE_RANDOM1,
'a_SimulationWorldPostion': VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDPOSTION,
'a_SimulationWorldRotation': VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDROTATION
};
uniformMap = {
'u_Tintcolor': Shader3D.PERIOD_MATERIAL,
'u_TilingOffset': Shader3D.PERIOD_MATERIAL,
'u_texture': Shader3D.PERIOD_MATERIAL,
'u_WorldPosition': Shader3D.PERIOD_SPRITE,
'u_WorldRotation': Shader3D.PERIOD_SPRITE,
'u_PositionScale': Shader3D.PERIOD_SPRITE,
'u_SizeScale': Shader3D.PERIOD_SPRITE,
'u_ScalingMode': Shader3D.PERIOD_SPRITE,
'u_Gravity': Shader3D.PERIOD_SPRITE,
'u_ThreeDStartRotation': Shader3D.PERIOD_SPRITE,
'u_StretchedBillboardLengthScale': Shader3D.PERIOD_SPRITE,
'u_StretchedBillboardSpeedScale': Shader3D.PERIOD_SPRITE,
'u_SimulationSpace': Shader3D.PERIOD_SPRITE,
'u_CurrentTime': Shader3D.PERIOD_SPRITE,
'u_ColorOverLifeGradientAlphas': Shader3D.PERIOD_SPRITE,
'u_ColorOverLifeGradientColors': Shader3D.PERIOD_SPRITE,
'u_MaxColorOverLifeGradientAlphas': Shader3D.PERIOD_SPRITE,
'u_MaxColorOverLifeGradientColors': Shader3D.PERIOD_SPRITE,
'u_VOLVelocityConst': Shader3D.PERIOD_SPRITE,
'u_VOLVelocityGradientX': Shader3D.PERIOD_SPRITE,
'u_VOLVelocityGradientY': Shader3D.PERIOD_SPRITE,
'u_VOLVelocityGradientZ': Shader3D.PERIOD_SPRITE,
'u_VOLVelocityConstMax': Shader3D.PERIOD_SPRITE,
'u_VOLVelocityGradientMaxX': Shader3D.PERIOD_SPRITE,
'u_VOLVelocityGradientMaxY': Shader3D.PERIOD_SPRITE,
'u_VOLVelocityGradientMaxZ': Shader3D.PERIOD_SPRITE,
'u_VOLSpaceType': Shader3D.PERIOD_SPRITE,
'u_SOLSizeGradient': Shader3D.PERIOD_SPRITE,
'u_SOLSizeGradientX': Shader3D.PERIOD_SPRITE,
'u_SOLSizeGradientY': Shader3D.PERIOD_SPRITE,
'u_SOLSizeGradientZ': Shader3D.PERIOD_SPRITE,
'u_SOLSizeGradientMax': Shader3D.PERIOD_SPRITE,
'u_SOLSizeGradientMaxX': Shader3D.PERIOD_SPRITE,
'u_SOLSizeGradientMaxY': Shader3D.PERIOD_SPRITE,
'u_SOLSizeGradientMaxZ': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityConst': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityConstSeprarate': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradient': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradientX': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradientY': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradientZ': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityConstMax': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityConstMaxSeprarate': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradientMax': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradientMaxX': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradientMaxY': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradientMaxZ': Shader3D.PERIOD_SPRITE,
'u_ROLAngularVelocityGradientMaxW': Shader3D.PERIOD_SPRITE,
'u_TSACycles': Shader3D.PERIOD_SPRITE,
'u_TSASubUVLength': Shader3D.PERIOD_SPRITE,
'u_TSAGradientUVs': Shader3D.PERIOD_SPRITE,
'u_TSAMaxGradientUVs': Shader3D.PERIOD_SPRITE,
'u_CameraPos': Shader3D.PERIOD_CAMERA,
'u_CameraDirection': Shader3D.PERIOD_CAMERA,
'u_CameraUp': Shader3D.PERIOD_CAMERA,
'u_View': Shader3D.PERIOD_CAMERA,
'u_Projection': Shader3D.PERIOD_CAMERA,
'u_FogStart': Shader3D.PERIOD_SCENE,
'u_FogRange': Shader3D.PERIOD_SCENE,
'u_FogColor': Shader3D.PERIOD_SCENE
};
stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
shader = Shader3D.add("PARTICLESHURIKEN");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(ParticleShuriKenVS, ParticleShuriKenPS, stateMap);
attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0
};
uniformMap = {
'u_TintColor': Shader3D.PERIOD_MATERIAL,
'u_Exposure': Shader3D.PERIOD_MATERIAL,
'u_Rotation': Shader3D.PERIOD_MATERIAL,
'u_CubeTexture': Shader3D.PERIOD_MATERIAL,
'u_ViewProjection': Shader3D.PERIOD_CAMERA
};
shader = Shader3D.add("SkyBox");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(SkyBoxVS, SkyBoxPS);
attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0
};
uniformMap = {
'u_SunSize': Shader3D.PERIOD_MATERIAL,
'u_SunSizeConvergence': Shader3D.PERIOD_MATERIAL,
'u_AtmosphereThickness': Shader3D.PERIOD_MATERIAL,
'u_SkyTint': Shader3D.PERIOD_MATERIAL,
'u_GroundTint': Shader3D.PERIOD_MATERIAL,
'u_Exposure': Shader3D.PERIOD_MATERIAL,
'u_ViewProjection': Shader3D.PERIOD_CAMERA,
'u_SunLight.direction': Shader3D.PERIOD_SCENE,
'u_SunLight.color': Shader3D.PERIOD_SCENE,
};
shader = Shader3D.add("SkyBoxProcedural");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(SkyBoxProceduralVS, SkyBoxProceduralPS);
attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0,
'a_Normal': VertexMesh.MESH_NORMAL0,
'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0
};
uniformMap = {
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_WorldMat': Shader3D.PERIOD_SPRITE,
'u_CameraPos': Shader3D.PERIOD_CAMERA,
'u_Viewport': Shader3D.PERIOD_CAMERA,
'u_ProjectionParams': Shader3D.PERIOD_CAMERA,
'u_View': Shader3D.PERIOD_CAMERA,
'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE,
'u_LightMap': Shader3D.PERIOD_SPRITE,
'u_SplatAlphaTexture': Shader3D.PERIOD_MATERIAL,
'u_DiffuseTexture1': Shader3D.PERIOD_MATERIAL,
'u_DiffuseTexture2': Shader3D.PERIOD_MATERIAL,
'u_DiffuseTexture3': Shader3D.PERIOD_MATERIAL,
'u_DiffuseTexture4': Shader3D.PERIOD_MATERIAL,
'u_DiffuseTexture5': Shader3D.PERIOD_MATERIAL,
'u_DiffuseScaleOffset1': Shader3D.PERIOD_MATERIAL,
'u_DiffuseScaleOffset2': Shader3D.PERIOD_MATERIAL,
'u_DiffuseScaleOffset3': Shader3D.PERIOD_MATERIAL,
'u_DiffuseScaleOffset4': Shader3D.PERIOD_MATERIAL,
'u_DiffuseScaleOffset5': Shader3D.PERIOD_MATERIAL,
'u_FogStart': Shader3D.PERIOD_SCENE,
'u_FogRange': Shader3D.PERIOD_SCENE,
'u_FogColor': Shader3D.PERIOD_SCENE,
'u_DirationLightCount': Shader3D.PERIOD_SCENE,
'u_LightBuffer': Shader3D.PERIOD_SCENE,
'u_LightClusterBuffer': Shader3D.PERIOD_SCENE,
'u_AmbientColor': Shader3D.PERIOD_SCENE,
'u_ShadowMap': Shader3D.PERIOD_SCENE,
'u_shadowMap2': Shader3D.PERIOD_SCENE,
'u_shadowMap3': Shader3D.PERIOD_SCENE,
'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE,
'u_ShadowMatrices': Shader3D.PERIOD_SCENE,
'u_ShadowMapSize': Shader3D.PERIOD_SCENE,
'u_DirectionLight.color': Shader3D.PERIOD_SCENE,
'u_DirectionLight.direction': Shader3D.PERIOD_SCENE,
'u_PointLight.position': Shader3D.PERIOD_SCENE,
'u_PointLight.range': Shader3D.PERIOD_SCENE,
'u_PointLight.color': Shader3D.PERIOD_SCENE,
'u_SpotLight.position': Shader3D.PERIOD_SCENE,
'u_SpotLight.direction': Shader3D.PERIOD_SCENE,
'u_SpotLight.range': Shader3D.PERIOD_SCENE,
'u_SpotLight.spot': Shader3D.PERIOD_SCENE,
'u_SpotLight.color': Shader3D.PERIOD_SCENE
};
stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
shader = Shader3D.add("ExtendTerrain");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(extendTerrainVS, extendTerrainPS, stateMap);
attributeMap = {
'a_Position': VertexTrail.TRAIL_POSITION0,
'a_OffsetVector': VertexTrail.TRAIL_OFFSETVECTOR,
'a_Texcoord0X': VertexTrail.TRAIL_TEXTURECOORDINATE0X,
'a_Texcoord0Y': VertexTrail.TRAIL_TEXTURECOORDINATE0Y,
'a_BirthTime': VertexTrail.TRAIL_TIME0,
'a_Color': VertexTrail.TRAIL_COLOR
};
uniformMap = {
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_View': Shader3D.PERIOD_CAMERA,
'u_Projection': Shader3D.PERIOD_CAMERA,
'u_TilingOffset': Shader3D.PERIOD_MATERIAL,
'u_MainTexture': Shader3D.PERIOD_MATERIAL,
'u_MainColor': Shader3D.PERIOD_MATERIAL,
'u_CurTime': Shader3D.PERIOD_SPRITE,
'u_LifeTime': Shader3D.PERIOD_SPRITE,
'u_WidthCurve': Shader3D.PERIOD_SPRITE,
'u_WidthCurveKeyLength': Shader3D.PERIOD_SPRITE,
'u_GradientColorkey': Shader3D.PERIOD_SPRITE,
'u_GradientAlphakey': Shader3D.PERIOD_SPRITE
};
stateMap = {
's_Cull': Shader3D.RENDER_STATE_CULL,
's_Blend': Shader3D.RENDER_STATE_BLEND,
's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
};
shader = Shader3D.add("Trail");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(TrailVS, TrailPS, stateMap);
attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0,
'a_Normal': VertexMesh.MESH_NORMAL0,
'a_Tangent0': VertexMesh.MESH_TANGENT0
};
uniformMap = {
'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
'u_WorldMat': Shader3D.PERIOD_SPRITE,
'u_CameraPos': Shader3D.PERIOD_CAMERA,
'u_Time': Shader3D.PERIOD_SCENE,
'u_MainTexture': Shader3D.PERIOD_MATERIAL,
'u_NormalTexture': Shader3D.PERIOD_MATERIAL,
'u_HorizonColor': Shader3D.PERIOD_MATERIAL,
'u_WaveScale': Shader3D.PERIOD_MATERIAL,
'u_WaveSpeed': Shader3D.PERIOD_MATERIAL
};
shader = Shader3D.add("WaterPrimary");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(WaterPrimaryVS, WaterPrimaryPS);
attributeMap = {
'a_PositionTexcoord': VertexMesh.MESH_POSITION0
};
uniformMap = {
'u_MainTex': Shader3D.PERIOD_MATERIAL,
'u_OffsetScale': Shader3D.PERIOD_MATERIAL
};
shader = Shader3D.add("BlitScreen");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
var shaderPass = subShader.addShaderPass(BlitScreenVS, BlitScreenPS);
var renderState = shaderPass.renderState;
renderState.depthTest = RenderState.DEPTHTEST_ALWAYS;
renderState.depthWrite = false;
renderState.cull = RenderState.CULL_NONE;
renderState.blend = RenderState.BLEND_DISABLE;
attributeMap = {
'a_PositionTexcoord': VertexMesh.MESH_POSITION0
};
uniformMap = {
'u_MainTex': Shader3D.PERIOD_MATERIAL,
'u_BloomTex': Shader3D.PERIOD_MATERIAL,
'u_AutoExposureTex': Shader3D.PERIOD_MATERIAL,
'u_MainTex_TexelSize': Shader3D.PERIOD_MATERIAL,
'u_SampleScale': Shader3D.PERIOD_MATERIAL,
'u_Threshold': Shader3D.PERIOD_MATERIAL,
'u_Params': Shader3D.PERIOD_MATERIAL
};
shader = Shader3D.add("PostProcessBloom");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
shaderPass = subShader.addShaderPass(BloomVS, BloomPrefilter13PS);
renderState = shaderPass.renderState;
renderState.depthTest = RenderState.DEPTHTEST_ALWAYS;
renderState.depthWrite = false;
renderState.cull = RenderState.CULL_NONE;
renderState.blend = RenderState.BLEND_DISABLE;
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
shaderPass = subShader.addShaderPass(BloomVS, BloomPrefilter4PS);
renderState = shaderPass.renderState;
renderState.depthTest = RenderState.DEPTHTEST_ALWAYS;
renderState.depthWrite = false;
renderState.cull = RenderState.CULL_NONE;
renderState.blend = RenderState.BLEND_DISABLE;
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
shaderPass = subShader.addShaderPass(BloomVS, BloomDownsample13PS);
renderState = shaderPass.renderState;
renderState.depthTest = RenderState.DEPTHTEST_ALWAYS;
renderState.depthWrite = false;
renderState.cull = RenderState.CULL_NONE;
renderState.blend = RenderState.BLEND_DISABLE;
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
shaderPass = subShader.addShaderPass(BloomVS, BloomDownsample4PS);
renderState = shaderPass.renderState;
renderState.depthTest = RenderState.DEPTHTEST_ALWAYS;
renderState.depthWrite = false;
renderState.cull = RenderState.CULL_NONE;
renderState.blend = RenderState.BLEND_DISABLE;
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
shaderPass = subShader.addShaderPass(BloomVS, BloomUpsampleTentPS);
renderState = shaderPass.renderState;
renderState.depthTest = RenderState.DEPTHTEST_ALWAYS;
renderState.depthWrite = false;
renderState.cull = RenderState.CULL_NONE;
renderState.blend = RenderState.BLEND_DISABLE;
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
shaderPass = subShader.addShaderPass(BloomVS, BloomUpsampleBoxPS);
renderState = shaderPass.renderState;
renderState.depthTest = RenderState.DEPTHTEST_ALWAYS;
renderState.depthWrite = false;
renderState.cull = RenderState.CULL_NONE;
renderState.blend = RenderState.BLEND_DISABLE;
attributeMap = {
'a_PositionTexcoord': VertexMesh.MESH_POSITION0
};
uniformMap = {
'u_MainTex': Shader3D.PERIOD_MATERIAL,
'u_BloomTex': Shader3D.PERIOD_MATERIAL,
'u_AutoExposureTex': Shader3D.PERIOD_MATERIAL,
'u_Bloom_DirtTileOffset': Shader3D.PERIOD_MATERIAL,
'u_Bloom_DirtTex': Shader3D.PERIOD_MATERIAL,
'u_BloomTex_TexelSize': Shader3D.PERIOD_MATERIAL,
'u_Bloom_Settings': Shader3D.PERIOD_MATERIAL,
'u_Bloom_Color': Shader3D.PERIOD_MATERIAL
};
shader = Shader3D.add("PostProcessComposite");
subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
shaderPass = subShader.addShaderPass(CompositeVS, CompositePS);
renderState = shaderPass.renderState;
renderState.depthTest = RenderState.DEPTHTEST_ALWAYS;
renderState.depthWrite = false;
renderState.cull = RenderState.CULL_NONE;
renderState.blend = RenderState.BLEND_DISABLE;
}
}
class DirectionLight extends LightSprite {
constructor() {
super();
this._direction = new Vector3();
this._shadowCascadesMode = exports.ShadowCascadesMode.NoCascades;
this._shadowTwoCascadeSplits = 1.0 / 3.0;
this._shadowFourCascadeSplits = new Vector3(1.0 / 15, 3.0 / 15.0, 7.0 / 15.0);
this._lightType = exports.LightType.Directional;
}
get shadowCascadesMode() {
return this._shadowCascadesMode;
}
set shadowCascadesMode(value) {
this._shadowCascadesMode = value;
}
get shadowTwoCascadeSplits() {
return this._shadowTwoCascadeSplits;
}
set shadowTwoCascadeSplits(value) {
this._shadowTwoCascadeSplits = value;
}
get shadowFourCascadeSplits() {
return this._shadowFourCascadeSplits;
}
set shadowFourCascadeSplits(value) {
if (value.x > value.y || value.y > value.z || value.z > 1.0)
throw "DiretionLight:Invalid value.";
value.cloneTo(this._shadowFourCascadeSplits);
}
_addToLightQueue() {
this._scene._directionLights.add(this);
}
_removeFromLightQueue() {
this._scene._directionLights.remove(this);
}
_create() {
return new DirectionLight();
}
}
class PointLight extends LightSprite {
constructor() {
super();
this._range = 6.0;
this._lightType = exports.LightType.Point;
}
get range() {
return this._range;
}
set range(value) {
this._range = value;
}
_addToLightQueue() {
this._scene._pointLights.add(this);
}
_removeFromLightQueue() {
this._scene._pointLights.remove(this);
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
this.range = data.range;
}
_cloneTo(destObject, rootSprite, dstSprite) {
super._cloneTo(destObject, rootSprite, dstSprite);
var pointlight = destObject;
pointlight.range = this.range;
pointlight._lightType = exports.LightType.Point;
}
_create() {
return new PointLight();
}
}
class SpotLight extends LightSprite {
constructor() {
super();
this._spotAngle = 30.0;
this._range = 10.0;
this._direction = new Vector3();
this._lightType = exports.LightType.Spot;
}
get spotAngle() {
return this._spotAngle;
}
set spotAngle(value) {
this._spotAngle = Math.max(Math.min(value, 179), 0);
}
get range() {
return this._range;
}
set range(value) {
this._range = value;
}
_addToLightQueue() {
this._scene._spotLights.add(this);
}
_removeFromLightQueue() {
this._scene._spotLights.remove(this);
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
this.range = data.range;
this.spotAngle = data.spotAngle;
}
_cloneTo(destObject, rootSprite, dstSprite) {
super._cloneTo(destObject, rootSprite, dstSprite);
var spotLight = destObject;
spotLight.range = this.range;
spotLight.spotAngle = this.spotAngle;
}
_create() {
return new SpotLight();
}
}
class SimpleSkinnedMeshRenderer extends SkinnedMeshRenderer {
constructor(owner) {
super(owner);
this._simpleAnimatorParams = new Vector4();
this._simpleAnimatorOffset = new Vector2();
this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_SIMPLEBONE);
this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_BONE);
}
get simpleAnimatorTexture() {
return this._simpleAnimatorTexture;
}
set simpleAnimatorTexture(value) {
this._simpleAnimatorTexture = value;
this._simpleAnimatorTextureSize = value.width;
this._shaderValues.setTexture(SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORTEXTURE, value);
value._addReference();
this._shaderValues.setNumber(SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORTEXTURESIZE, this._simpleAnimatorTextureSize);
}
get simpleAnimatorOffset() {
return this._simpleAnimatorOffset;
}
set simpleAnimatorOffset(value) {
value.cloneTo(this._simpleAnimatorOffset);
}
_computeAnimatorParamsData() {
if (this._cacheMesh) {
this._simpleAnimatorParams.x = this._simpleAnimatorOffset.x;
this._simpleAnimatorParams.y = Math.round(this._simpleAnimatorOffset.y) * this._bonesNums * 4;
}
}
_createRenderElement() {
return new SubMeshRenderElement();
}
_setCacheAnimator(animator) {
this._cacheAnimator = animator;
this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_SIMPLEBONE);
}
_onMeshChange(value) {
super._onMeshChange(value);
this._cacheMesh = value;
}
_renderUpdate(context, transform) {
var element = context.renderElement;
switch (element.renderType) {
case RenderElement.RENDERTYPE_NORMAL:
if (this._cacheAnimator) {
var worldMat = this._cacheAnimator.owner.transform.worldMatrix;
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, worldMat);
}
else {
this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, transform.worldMatrix);
}
this._computeAnimatorParamsData();
this._shaderValues.setVector(SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORPARAMS, this._simpleAnimatorParams);
break;
case RenderElement.RENDERTYPE_INSTANCEBATCH:
var worldMatrixData = SubMeshInstanceBatch.instance.instanceWorldMatrixData;
var insBatches = element.instanceBatchElementList;
var elements = insBatches.elements;
var count = insBatches.length;
if (this._cacheAnimator) {
for (var i = 0; i < count; i++) {
var mat = (elements[i].render)._cacheAnimator.owner._transform.worldMatrix;
worldMatrixData.set(mat.elements, i * 16);
}
}
else {
for (var i = 0; i < count; i++)
worldMatrixData.set(elements[i]._transform.worldMatrix.elements, i * 16);
}
var worldBuffer = SubMeshInstanceBatch.instance.instanceWorldMatrixBuffer;
worldBuffer.orphanStorage();
worldBuffer.setData(worldMatrixData.buffer, 0, 0, count * 16 * 4);
this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE);
var simpleAnimatorData = SubMeshInstanceBatch.instance.instanceSimpleAnimatorData;
if (this._cacheAnimator) {
for (var i = 0; i < count; i++) {
var render = (elements[i].render);
render._computeAnimatorParamsData();
var simpleAnimatorParams = render._simpleAnimatorParams;
var offset = i * 4;
simpleAnimatorData[offset] = simpleAnimatorParams.x;
simpleAnimatorData[offset + 1] = simpleAnimatorParams.y;
}
}
else {
for (var i = 0; i < count; i++) {
simpleAnimatorData[offset] = 0;
simpleAnimatorData[offset + 1] = 0;
}
}
var simpleAnimatorBuffer = SubMeshInstanceBatch.instance.instanceSimpleAnimatorBuffer;
simpleAnimatorBuffer.orphanStorage();
simpleAnimatorBuffer.setData(simpleAnimatorData.buffer, 0, 0, count * 4 * 4);
break;
}
}
_renderUpdateWithCamera(context, transform) {
var projectionView = context.projectionViewMatrix;
if (projectionView) {
var element = context.renderElement;
switch (element.renderType) {
case RenderElement.RENDERTYPE_NORMAL:
if (this._cacheAnimator) {
var mat = this._cacheAnimator.owner._transform.worldMatrix;
Matrix4x4.multiply(projectionView, mat, this._projectionViewWorldMatrix);
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix);
}
else {
Matrix4x4.multiply(projectionView, transform.worldMatrix, this._projectionViewWorldMatrix);
this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix);
}
break;
}
}
}
_destroy() {
if (this._cacheRootBone)
(!this._cacheRootBone.destroyed) && (this._cacheRootBone.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange));
(this._simpleAnimatorTexture) && this._simpleAnimatorTexture._removeReference();
this._simpleAnimatorTexture = null;
}
}
class SimpleSkinnedMeshSprite3D extends RenderableSprite3D {
constructor(mesh = null, name = null) {
super(name);
this._meshFilter = new MeshFilter(this);
this._render = new SimpleSkinnedMeshRenderer(this);
(mesh) && (this._meshFilter.sharedMesh = mesh);
}
static __init__() {
SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORPARAMS = SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORPARAMS;
SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORTEXTURE = SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURE;
SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORTEXTURESIZE = SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURESIZE;
}
get meshFilter() {
return this._meshFilter;
}
get simpleSkinnedMeshRenderer() {
return this._render;
}
_parse(data, spriteMap) {
super._parse(data, spriteMap);
var render = this.simpleSkinnedMeshRenderer;
var lightmapIndex = data.lightmapIndex;
(lightmapIndex != null) && (render.lightmapIndex = lightmapIndex);
var lightmapScaleOffsetArray = data.lightmapScaleOffset;
(lightmapScaleOffsetArray) && (render.lightmapScaleOffset = new Vector4(lightmapScaleOffsetArray[0], lightmapScaleOffsetArray[1], lightmapScaleOffsetArray[2], lightmapScaleOffsetArray[3]));
(data.enableRender != undefined) && (render.enable = data.enableRender);
(data.receiveShadows != undefined) && (render.receiveShadow = data.receiveShadows);
(data.castShadow != undefined) && (render.castShadow = data.castShadow);
var meshPath;
meshPath = data.meshPath;
if (meshPath) {
var mesh = Laya.Loader.getRes(meshPath);
(mesh) && (this.meshFilter.sharedMesh = mesh);
}
var materials = data.materials;
if (materials) {
var sharedMaterials = render.sharedMaterials;
var materialCount = materials.length;
sharedMaterials.length = materialCount;
for (var i = 0; i < materialCount; i++) {
sharedMaterials[i] = Laya.Loader.getRes(materials[i].path);
}
render.sharedMaterials = sharedMaterials;
}
var boundBox = data.boundBox;
var min = boundBox.min;
var max = boundBox.max;
render.localBounds.setMin(new Vector3(min[0], min[1], min[2]));
render.localBounds.setMax(new Vector3(max[0], max[1], max[2]));
if (spriteMap) {
var rootBoneData = data.rootBone;
render.rootBone = spriteMap[rootBoneData];
var bonesData = data.bones;
var n;
for (i = 0, n = bonesData.length; i < n; i++)
render.bones.push(spriteMap[bonesData[i]]);
render._bonesNums = data.bonesNums ? data.bonesNums : render.bones.length;
}
else {
(data.rootBone) && (render._setRootBone(data.rootBone));
}
var animatorTexture = data.animatorTexture;
if (animatorTexture) {
var animatortexture = Laya.Loader.getRes(animatorTexture);
render.simpleAnimatorTexture = animatortexture;
}
}
_changeHierarchyAnimator(animator) {
super._changeHierarchyAnimator(animator);
this.simpleSkinnedMeshRenderer._setCacheAnimator(animator);
}
_cloneTo(destObject, srcRoot, dstRoot) {
var meshSprite3D = destObject;
meshSprite3D.meshFilter.sharedMesh = this.meshFilter.sharedMesh;
var meshRender = this._render;
var destMeshRender = meshSprite3D._render;
destMeshRender.enable = meshRender.enable;
destMeshRender.sharedMaterials = meshRender.sharedMaterials;
destMeshRender.castShadow = meshRender.castShadow;
var lightmapScaleOffset = meshRender.lightmapScaleOffset;
lightmapScaleOffset && (destMeshRender.lightmapScaleOffset = lightmapScaleOffset.clone());
destMeshRender.receiveShadow = meshRender.receiveShadow;
destMeshRender.sortingFudge = meshRender.sortingFudge;
destMeshRender._rootBone = meshRender._rootBone;
var bones = meshRender.bones;
var destBones = destMeshRender.bones;
var bonesCount = bones.length;
destBones.length = bonesCount;
var rootBone = meshRender.rootBone;
if (rootBone) {
var pathes = Utils3D._getHierarchyPath(srcRoot, rootBone, SimpleSkinnedMeshSprite3D._tempArray0);
if (pathes)
destMeshRender.rootBone = Utils3D._getNodeByHierarchyPath(dstRoot, pathes);
else
destMeshRender.rootBone = rootBone;
}
for (var i = 0; i < bones.length; i++) {
pathes = Utils3D._getHierarchyPath(srcRoot, bones[i], SimpleSkinnedMeshSprite3D._tempArray0);
if (pathes)
destBones[i] = Utils3D._getNodeByHierarchyPath(dstRoot, pathes);
else
destBones[i] = bones[i];
}
var lbb = meshRender.localBounds;
(lbb) && (lbb.cloneTo(destMeshRender.localBounds));
destMeshRender.simpleAnimatorOffset = meshRender.simpleAnimatorOffset;
destMeshRender.simpleAnimatorTexture = meshRender.simpleAnimatorTexture;
destMeshRender._bonesNums = meshRender._bonesNums;
super._cloneTo(destObject, srcRoot, dstRoot);
}
destroy(destroyChild = true) {
if (this.destroyed)
return;
super.destroy(destroyChild);
this._meshFilter.destroy();
}
_create() {
return new SimpleSkinnedMeshSprite3D();
}
}
SimpleSkinnedMeshSprite3D._tempArray0 = [];
SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURE = Shader3D.propertyNameToID("u_SimpleAnimatorTexture");
SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORPARAMS = Shader3D.propertyNameToID("u_SimpleAnimatorParams");
SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURESIZE = Shader3D.propertyNameToID("u_SimpleAnimatorTextureSize");
class Scene3DUtils {
static _createSprite3DInstance(nodeData, spriteMap, outBatchSprites) {
var node;
switch (nodeData.type) {
case "Scene3D":
node = new Scene3D();
break;
case "Sprite3D":
node = new Sprite3D();
break;
case "MeshSprite3D":
node = new MeshSprite3D();
(outBatchSprites && nodeData.props.isStatic) && (outBatchSprites.push(node));
break;
case "SkinnedMeshSprite3D":
node = new SkinnedMeshSprite3D();
break;
case "SimpleSkinnedMeshSprite3D":
node = new SimpleSkinnedMeshSprite3D();
break;
case "ShuriKenParticle3D":
node = new ShuriKenParticle3D();
break;
case "Camera":
node = new Camera();
break;
case "DirectionLight":
node = new DirectionLight();
break;
case "PointLight":
node = new PointLight();
break;
case "SpotLight":
node = new SpotLight();
break;
case "TrailSprite3D":
node = new TrailSprite3D();
break;
case "ReflectionProbe":
node = new ReflectionProbe();
break;
default:
throw new Error("Utils3D:unidentified class type in (.lh) file.");
}
var childData = nodeData.child;
if (childData) {
for (var i = 0, n = childData.length; i < n; i++) {
var child = Scene3DUtils._createSprite3DInstance(childData[i], spriteMap, outBatchSprites);
node.addChild(child);
}
}
spriteMap[nodeData.instanceID] = node;
return node;
}
static _createComponentInstance(nodeData, spriteMap, interactMap) {
var node = spriteMap[nodeData.instanceID];
node._parse(nodeData.props, spriteMap);
var childData = nodeData.child;
if (childData) {
for (var i = 0, n = childData.length; i < n; i++)
Scene3DUtils._createComponentInstance(childData[i], spriteMap, interactMap);
}
var componentsData = nodeData.components;
if (componentsData) {
for (var j = 0, m = componentsData.length; j < m; j++) {
var data = componentsData[j];
var clas = Laya.ClassUtils.getRegClass(data.type);
if (clas) {
var component = node.addComponent(clas);
component._parse(data, interactMap);
}
else {
console.warn("Unkown component type.");
}
}
}
}
static _createNodeByJson02(nodeData, outBatchSprites) {
var spriteMap = {};
var interactMap = { component: [], data: [] };
var node = Scene3DUtils._createSprite3DInstance(nodeData, spriteMap, outBatchSprites);
Scene3DUtils._createComponentInstance(nodeData, spriteMap, interactMap);
Scene3DUtils._createInteractInstance(interactMap, spriteMap);
return node;
}
static _createInteractInstance(interatMap, spriteMap) {
var components = interatMap.component;
var data = interatMap.data;
for (var i = 0, n = components.length; i < n; i++) {
components[i]._parseInteractive(data[i], spriteMap);
}
}
static _parse(data, propertyParams = null, constructParams = null) {
var json = data.data;
var outBatchSprits = [];
var sprite;
switch (data.version) {
case "LAYAHIERARCHY:02":
sprite = Scene3DUtils._createNodeByJson02(json, outBatchSprits);
break;
default:
sprite = Scene3DUtils._createNodeByJson(json, outBatchSprits);
}
StaticBatchManager.combine(sprite, outBatchSprits);
return sprite;
}
static _parseScene(data, propertyParams = null, constructParams = null) {
var json = data.data;
var outBatchSprits = [];
var scene;
switch (data.version) {
case "LAYASCENE3D:02":
scene = Scene3DUtils._createNodeByJson02(json, outBatchSprits);
break;
default:
scene = Scene3DUtils._createNodeByJson(json, outBatchSprits);
}
StaticBatchManager.combine(null, outBatchSprits);
return scene;
}
static _createNodeByJson(nodeData, outBatchSprites) {
var node;
switch (nodeData.type) {
case "Scene3D":
node = new Scene3D();
break;
case "Sprite3D":
node = new Sprite3D();
break;
case "MeshSprite3D":
node = new MeshSprite3D();
(outBatchSprites && nodeData.props.isStatic) && (outBatchSprites.push(node));
break;
case "SkinnedMeshSprite3D":
node = new SkinnedMeshSprite3D();
break;
case "ShuriKenParticle3D":
node = new ShuriKenParticle3D();
break;
case "Camera":
node = new Camera();
break;
case "DirectionLight":
node = new DirectionLight();
break;
case "PointLight":
node = new PointLight();
break;
case "SpotLight":
node = new SpotLight();
break;
case "TrailSprite3D":
node = new TrailSprite3D();
break;
default:
throw new Error("Utils3D:unidentified class type in (.lh) file.");
}
var childData = nodeData.child;
if (childData) {
for (var i = 0, n = childData.length; i < n; i++) {
var child = Scene3DUtils._createNodeByJson(childData[i], outBatchSprites);
node.addChild(child);
}
}
var componentsData = nodeData.components;
if (componentsData) {
for (var j = 0, m = componentsData.length; j < m; j++) {
var data = componentsData[j];
var clas = Laya.ClassUtils.getRegClass(data.type);
if (clas) {
var component = node.addComponent(clas);
component._parse(data);
}
else {
console.warn("Unkown component type.");
}
}
}
node._parse(nodeData.props, null);
return node;
}
}
class LoadModelV04 {
static parse(readData, version, mesh, subMeshes) {
LoadModelV04._mesh = mesh;
LoadModelV04._subMeshes = subMeshes;
LoadModelV04._version = version;
LoadModelV04._readData = readData;
LoadModelV04.READ_DATA();
LoadModelV04.READ_BLOCK();
LoadModelV04.READ_STRINGS();
for (var i = 0, n = LoadModelV04._BLOCK.count; i < n; i++) {
LoadModelV04._readData.pos = LoadModelV04._BLOCK.blockStarts[i];
var index = LoadModelV04._readData.getUint16();
var blockName = LoadModelV04._strings[index];
var fn = LoadModelV04["READ_" + blockName];
if (fn == null)
throw new Error("model file err,no this function:" + index + " " + blockName);
else
fn.call(null);
}
LoadModelV04._strings.length = 0;
LoadModelV04._readData = null;
LoadModelV04._version = null;
LoadModelV04._mesh = null;
LoadModelV04._subMeshes = null;
}
static _readString() {
return LoadModelV04._strings[LoadModelV04._readData.getUint16()];
}
static READ_DATA() {
LoadModelV04._DATA.offset = LoadModelV04._readData.getUint32();
LoadModelV04._DATA.size = LoadModelV04._readData.getUint32();
}
static READ_BLOCK() {
var count = LoadModelV04._BLOCK.count = LoadModelV04._readData.getUint16();
var blockStarts = LoadModelV04._BLOCK.blockStarts = [];
var blockLengths = LoadModelV04._BLOCK.blockLengths = [];
for (var i = 0; i < count; i++) {
blockStarts.push(LoadModelV04._readData.getUint32());
blockLengths.push(LoadModelV04._readData.getUint32());
}
}
static READ_STRINGS() {
var offset = LoadModelV04._readData.getUint32();
var count = LoadModelV04._readData.getUint16();
var prePos = LoadModelV04._readData.pos;
LoadModelV04._readData.pos = offset + LoadModelV04._DATA.offset;
for (var i = 0; i < count; i++)
LoadModelV04._strings[i] = LoadModelV04._readData.readUTFString();
LoadModelV04._readData.pos = prePos;
}
static READ_MESH() {
var gl = Laya.LayaGL.instance;
var name = LoadModelV04._readString();
var arrayBuffer = LoadModelV04._readData.__getBuffer();
var i;
var memorySize = 0;
var vertexBufferCount = LoadModelV04._readData.getInt16();
var offset = LoadModelV04._DATA.offset;
for (i = 0; i < vertexBufferCount; i++) {
var vbStart = offset + LoadModelV04._readData.getUint32();
var vbLength = LoadModelV04._readData.getUint32();
var vbArrayBuffer = arrayBuffer.slice(vbStart, vbStart + vbLength);
var vbDatas = new Float32Array(vbArrayBuffer);
var bufferAttribute = LoadModelV04._readString();
var vertexDeclaration;
switch (LoadModelV04._version) {
case "LAYAMODEL:0301":
case "LAYAMODEL:0400":
vertexDeclaration = VertexMesh.getVertexDeclaration(bufferAttribute);
break;
case "LAYAMODEL:0401":
vertexDeclaration = VertexMesh.getVertexDeclaration(bufferAttribute, false);
break;
default:
throw new Error("LoadModelV03: unknown version.");
}
if (!vertexDeclaration)
throw new Error("LoadModelV03: unknown vertexDeclaration.");
var vertexBuffer = new VertexBuffer3D(vbDatas.length * 4, gl.STATIC_DRAW, true);
vertexBuffer.vertexDeclaration = vertexDeclaration;
vertexBuffer.setData(vbDatas.buffer);
LoadModelV04._mesh._vertexBuffer = vertexBuffer;
LoadModelV04._mesh._vertexCount += vertexBuffer._byteLength / vertexDeclaration.vertexStride;
memorySize += vbDatas.length * 4;
}
var ibStart = offset + LoadModelV04._readData.getUint32();
var ibLength = LoadModelV04._readData.getUint32();
var ibDatas = new Uint16Array(arrayBuffer.slice(ibStart, ibStart + ibLength));
var indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, ibLength / 2, gl.STATIC_DRAW, true);
indexBuffer.setData(ibDatas);
LoadModelV04._mesh._indexBuffer = indexBuffer;
memorySize += indexBuffer.indexCount * 2;
LoadModelV04._mesh._setBuffer(LoadModelV04._mesh._vertexBuffer, indexBuffer);
LoadModelV04._mesh._setCPUMemory(memorySize);
LoadModelV04._mesh._setGPUMemory(memorySize);
var boneNames = LoadModelV04._mesh._boneNames = [];
var boneCount = LoadModelV04._readData.getUint16();
boneNames.length = boneCount;
for (i = 0; i < boneCount; i++)
boneNames[i] = LoadModelV04._strings[LoadModelV04._readData.getUint16()];
LoadModelV04._readData.pos += 8;
var bindPoseDataStart = LoadModelV04._readData.getUint32();
var bindPoseDataLength = LoadModelV04._readData.getUint32();
var bindPoseDatas = new Float32Array(arrayBuffer.slice(offset + bindPoseDataStart, offset + bindPoseDataStart + bindPoseDataLength));
var bindPoseFloatCount = bindPoseDatas.length;
var bindPoseBuffer = LoadModelV04._mesh._inverseBindPosesBuffer = new ArrayBuffer(bindPoseFloatCount * 4);
LoadModelV04._mesh._inverseBindPoses = [];
if (bindPoseFloatCount != 0)
LoadModelV04._mesh._instanceBufferStateType = Mesh.MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR;
else
LoadModelV04._mesh._instanceBufferStateType = Mesh.MESH_INSTANCEBUFFER_TYPE_NORMAL;
LoadModelV04._mesh._setInstanceBuffer(LoadModelV04._mesh._instanceBufferStateType);
for (i = 0; i < bindPoseFloatCount; i += 16) {
var inverseGlobalBindPose = new Matrix4x4(bindPoseDatas[i + 0], bindPoseDatas[i + 1], bindPoseDatas[i + 2], bindPoseDatas[i + 3], bindPoseDatas[i + 4], bindPoseDatas[i + 5], bindPoseDatas[i + 6], bindPoseDatas[i + 7], bindPoseDatas[i + 8], bindPoseDatas[i + 9], bindPoseDatas[i + 10], bindPoseDatas[i + 11], bindPoseDatas[i + 12], bindPoseDatas[i + 13], bindPoseDatas[i + 14], bindPoseDatas[i + 15], new Float32Array(bindPoseBuffer, i * 4, 16));
LoadModelV04._mesh._inverseBindPoses[i / 16] = inverseGlobalBindPose;
}
return true;
}
static READ_SUBMESH() {
var arrayBuffer = LoadModelV04._readData.__getBuffer();
var subMesh = new SubMesh(LoadModelV04._mesh);
LoadModelV04._readData.getInt16();
LoadModelV04._readData.getUint32();
LoadModelV04._readData.getUint32();
var ibStart = LoadModelV04._readData.getUint32();
var ibCount = LoadModelV04._readData.getUint32();
var indexBuffer = LoadModelV04._mesh._indexBuffer;
subMesh._indexBuffer = indexBuffer;
subMesh._setIndexRange(ibStart, ibCount);
var vertexBuffer = LoadModelV04._mesh._vertexBuffer;
subMesh._vertexBuffer = vertexBuffer;
var offset = LoadModelV04._DATA.offset;
var subIndexBufferStart = subMesh._subIndexBufferStart;
var subIndexBufferCount = subMesh._subIndexBufferCount;
var boneIndicesList = subMesh._boneIndicesList;
var drawCount = LoadModelV04._readData.getUint16();
subIndexBufferStart.length = drawCount;
subIndexBufferCount.length = drawCount;
boneIndicesList.length = drawCount;
var skinnedCache = LoadModelV04._mesh._skinnedMatrixCaches;
var subMeshIndex = LoadModelV04._subMeshes.length;
skinnedCache.length = LoadModelV04._mesh._inverseBindPoses.length;
for (var i = 0; i < drawCount; i++) {
subIndexBufferStart[i] = LoadModelV04._readData.getUint32();
subIndexBufferCount[i] = LoadModelV04._readData.getUint32();
var boneDicofs = LoadModelV04._readData.getUint32();
var boneDicCount = LoadModelV04._readData.getUint32();
var boneIndices = boneIndicesList[i] = new Uint16Array(arrayBuffer.slice(offset + boneDicofs, offset + boneDicofs + boneDicCount));
var boneIndexCount = boneIndices.length;
for (var j = 0; j < boneIndexCount; j++) {
var index = boneIndices[j];
skinnedCache[index] || (skinnedCache[index] = new skinnedMatrixCache(subMeshIndex, i, j));
}
}
LoadModelV04._subMeshes.push(subMesh);
return true;
}
}
LoadModelV04._BLOCK = { count: 0 };
LoadModelV04._DATA = { offset: 0, size: 0 };
LoadModelV04._strings = [];
class LoadModelV05 {
static parse(readData, version, mesh, subMeshes) {
LoadModelV05._mesh = mesh;
LoadModelV05._subMeshes = subMeshes;
LoadModelV05._version = version;
LoadModelV05._readData = readData;
LoadModelV05.READ_DATA();
LoadModelV05.READ_BLOCK();
LoadModelV05.READ_STRINGS();
for (var i = 0, n = LoadModelV05._BLOCK.count; i < n; i++) {
LoadModelV05._readData.pos = LoadModelV05._BLOCK.blockStarts[i];
var index = LoadModelV05._readData.getUint16();
var blockName = LoadModelV05._strings[index];
var fn = LoadModelV05["READ_" + blockName];
if (fn == null)
throw new Error("model file err,no this function:" + index + " " + blockName);
else
fn.call(null);
}
LoadModelV05._strings.length = 0;
LoadModelV05._readData = null;
LoadModelV05._version = null;
LoadModelV05._mesh = null;
LoadModelV05._subMeshes = null;
}
static _readString() {
return LoadModelV05._strings[LoadModelV05._readData.getUint16()];
}
static READ_DATA() {
LoadModelV05._DATA.offset = LoadModelV05._readData.getUint32();
LoadModelV05._DATA.size = LoadModelV05._readData.getUint32();
}
static READ_BLOCK() {
var count = LoadModelV05._BLOCK.count = LoadModelV05._readData.getUint16();
var blockStarts = LoadModelV05._BLOCK.blockStarts = [];
var blockLengths = LoadModelV05._BLOCK.blockLengths = [];
for (var i = 0; i < count; i++) {
blockStarts.push(LoadModelV05._readData.getUint32());
blockLengths.push(LoadModelV05._readData.getUint32());
}
}
static READ_STRINGS() {
var offset = LoadModelV05._readData.getUint32();
var count = LoadModelV05._readData.getUint16();
var prePos = LoadModelV05._readData.pos;
LoadModelV05._readData.pos = offset + LoadModelV05._DATA.offset;
for (var i = 0; i < count; i++)
LoadModelV05._strings[i] = LoadModelV05._readData.readUTFString();
LoadModelV05._readData.pos = prePos;
}
static READ_MESH() {
var gl = Laya.LayaGL.instance;
var i;
var memorySize = 0;
var name = LoadModelV05._readString();
var reader = LoadModelV05._readData;
var arrayBuffer = reader.__getBuffer();
var vertexBufferCount = reader.getInt16();
var offset = LoadModelV05._DATA.offset;
for (i = 0; i < vertexBufferCount; i++) {
var vbStart = offset + reader.getUint32();
var vertexCount = reader.getUint32();
var vertexFlag = LoadModelV05._readString();
var vertexDeclaration = VertexMesh.getVertexDeclaration(vertexFlag, false);
var vertexStride = vertexDeclaration.vertexStride;
var vertexData;
var floatData;
var uint8Data;
var subVertexFlags = vertexFlag.split(",");
var subVertexCount = subVertexFlags.length;
var mesh = LoadModelV05._mesh;
switch (LoadModelV05._version) {
case "LAYAMODEL:05":
case "LAYAMODEL:0501":
vertexData = arrayBuffer.slice(vbStart, vbStart + vertexCount * vertexStride);
floatData = new Float32Array(vertexData);
uint8Data = new Uint8Array(vertexData);
break;
case "LAYAMODEL:COMPRESSION_05":
case "LAYAMODEL:COMPRESSION_0501":
vertexData = new ArrayBuffer(vertexStride * vertexCount);
floatData = new Float32Array(vertexData);
uint8Data = new Uint8Array(vertexData);
var lastPosition = reader.pos;
reader.pos = vbStart;
for (var j = 0; j < vertexCount; j++) {
var subOffset;
var verOffset = j * vertexStride;
for (var k = 0; k < subVertexCount; k++) {
switch (subVertexFlags[k]) {
case "POSITION":
subOffset = verOffset / 4;
floatData[subOffset] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
floatData[subOffset + 1] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
floatData[subOffset + 2] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
verOffset += 12;
break;
case "NORMAL":
subOffset = verOffset / 4;
floatData[subOffset] = reader.getUint8() / 127.5 - 1;
floatData[subOffset + 1] = reader.getUint8() / 127.5 - 1;
floatData[subOffset + 2] = reader.getUint8() / 127.5 - 1;
verOffset += 12;
break;
case "COLOR":
subOffset = verOffset / 4;
floatData[subOffset] = reader.getUint8() / 255;
floatData[subOffset + 1] = reader.getUint8() / 255;
floatData[subOffset + 2] = reader.getUint8() / 255;
floatData[subOffset + 3] = reader.getUint8() / 255;
verOffset += 16;
break;
case "UV":
subOffset = verOffset / 4;
floatData[subOffset] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
floatData[subOffset + 1] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
verOffset += 8;
break;
case "UV1":
subOffset = verOffset / 4;
floatData[subOffset] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
floatData[subOffset + 1] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16());
verOffset += 8;
break;
case "BLENDWEIGHT":
subOffset = verOffset / 4;
floatData[subOffset] = reader.getUint8() / 255;
floatData[subOffset + 1] = reader.getUint8() / 255;
floatData[subOffset + 2] = reader.getUint8() / 255;
floatData[subOffset + 3] = reader.getUint8() / 255;
verOffset += 16;
break;
case "BLENDINDICES":
uint8Data[verOffset] = reader.getUint8();
uint8Data[verOffset + 1] = reader.getUint8();
uint8Data[verOffset + 2] = reader.getUint8();
uint8Data[verOffset + 3] = reader.getUint8();
verOffset += 4;
break;
case "TANGENT":
subOffset = verOffset / 4;
floatData[subOffset] = reader.getUint8() / 127.5 - 1;
floatData[subOffset + 1] = reader.getUint8() / 127.5 - 1;
floatData[subOffset + 2] = reader.getUint8() / 127.5 - 1;
floatData[subOffset + 3] = reader.getUint8() / 127.5 - 1;
verOffset += 16;
break;
}
}
}
reader.pos = lastPosition;
break;
}
var vertexBuffer = new VertexBuffer3D(vertexData.byteLength, gl.STATIC_DRAW, true);
vertexBuffer.vertexDeclaration = vertexDeclaration;
vertexBuffer.setData(vertexData);
var vertexCount = vertexBuffer._byteLength / vertexDeclaration.vertexStride;
if (vertexCount > 65535)
mesh._indexFormat = exports.IndexFormat.UInt32;
else
mesh._indexFormat = exports.IndexFormat.UInt16;
mesh._vertexBuffer = vertexBuffer;
mesh._vertexCount += vertexCount;
memorySize += floatData.length * 4;
}
var ibStart = offset + reader.getUint32();
var ibLength = reader.getUint32();
var ibDatas;
if (mesh.indexFormat == exports.IndexFormat.UInt32)
ibDatas = new Uint32Array(arrayBuffer.slice(ibStart, ibStart + ibLength));
else
ibDatas = new Uint16Array(arrayBuffer.slice(ibStart, ibStart + ibLength));
var indexBuffer = new IndexBuffer3D(mesh.indexFormat, ibDatas.length, gl.STATIC_DRAW, true);
indexBuffer.setData(ibDatas);
mesh._indexBuffer = indexBuffer;
mesh._setBuffer(mesh._vertexBuffer, indexBuffer);
memorySize += indexBuffer.indexCount * 2;
mesh._setCPUMemory(memorySize);
mesh._setGPUMemory(memorySize);
if (LoadModelV05._version == "LAYAMODEL:0501" || LoadModelV05._version == "LAYAMODEL:COMPRESSION_0501") {
var bounds = mesh.bounds;
var min = bounds.getMin();
var max = bounds.getMax();
min.setValue(reader.getFloat32(), reader.getFloat32(), reader.getFloat32());
max.setValue(reader.getFloat32(), reader.getFloat32(), reader.getFloat32());
bounds.setMin(min);
bounds.setMax(max);
mesh.bounds = bounds;
}
var boneNames = mesh._boneNames = [];
var boneCount = reader.getUint16();
boneNames.length = boneCount;
for (i = 0; i < boneCount; i++)
boneNames[i] = LoadModelV05._strings[reader.getUint16()];
var bindPoseDataStart = reader.getUint32();
var bindPoseDataLength = reader.getUint32();
var bindPoseDatas = new Float32Array(arrayBuffer.slice(offset + bindPoseDataStart, offset + bindPoseDataStart + bindPoseDataLength));
var bindPoseFloatCount = bindPoseDatas.length;
var bindPoseBuffer = mesh._inverseBindPosesBuffer = new ArrayBuffer(bindPoseFloatCount * 4);
mesh._inverseBindPoses = [];
if (bindPoseFloatCount != 0)
mesh._instanceBufferStateType = Mesh.MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR;
else
mesh._instanceBufferStateType = Mesh.MESH_INSTANCEBUFFER_TYPE_NORMAL;
mesh._setInstanceBuffer(mesh._instanceBufferStateType);
for (i = 0; i < bindPoseFloatCount; i += 16) {
var inverseGlobalBindPose = new Matrix4x4(bindPoseDatas[i + 0], bindPoseDatas[i + 1], bindPoseDatas[i + 2], bindPoseDatas[i + 3], bindPoseDatas[i + 4], bindPoseDatas[i + 5], bindPoseDatas[i + 6], bindPoseDatas[i + 7], bindPoseDatas[i + 8], bindPoseDatas[i + 9], bindPoseDatas[i + 10], bindPoseDatas[i + 11], bindPoseDatas[i + 12], bindPoseDatas[i + 13], bindPoseDatas[i + 14], bindPoseDatas[i + 15], new Float32Array(bindPoseBuffer, i * 4, 16));
mesh._inverseBindPoses[i / 16] = inverseGlobalBindPose;
}
return true;
}
static READ_SUBMESH() {
var reader = LoadModelV05._readData;
var arrayBuffer = reader.__getBuffer();
var subMesh = new SubMesh(LoadModelV05._mesh);
reader.getInt16();
var ibStart = reader.getUint32();
var ibCount = reader.getUint32();
var indexBuffer = LoadModelV05._mesh._indexBuffer;
subMesh._indexBuffer = indexBuffer;
subMesh._setIndexRange(ibStart, ibCount);
var vertexBuffer = LoadModelV05._mesh._vertexBuffer;
subMesh._vertexBuffer = vertexBuffer;
var offset = LoadModelV05._DATA.offset;
var subIndexBufferStart = subMesh._subIndexBufferStart;
var subIndexBufferCount = subMesh._subIndexBufferCount;
var boneIndicesList = subMesh._boneIndicesList;
var drawCount = reader.getUint16();
subIndexBufferStart.length = drawCount;
subIndexBufferCount.length = drawCount;
boneIndicesList.length = drawCount;
var skinnedCache = LoadModelV05._mesh._skinnedMatrixCaches;
var subMeshIndex = LoadModelV05._subMeshes.length;
skinnedCache.length = LoadModelV05._mesh._inverseBindPoses.length;
for (var i = 0; i < drawCount; i++) {
subIndexBufferStart[i] = reader.getUint32();
subIndexBufferCount[i] = reader.getUint32();
var boneDicofs = reader.getUint32();
var boneDicCount = reader.getUint32();
var boneIndices = boneIndicesList[i] = new Uint16Array(arrayBuffer.slice(offset + boneDicofs, offset + boneDicofs + boneDicCount));
for (var j = 0, m = boneIndices.length; j < m; j++) {
var index = boneIndices[j];
skinnedCache[index] || (skinnedCache[index] = new skinnedMatrixCache(subMeshIndex, i, j));
}
}
LoadModelV05._subMeshes.push(subMesh);
return true;
}
}
LoadModelV05._BLOCK = { count: 0 };
LoadModelV05._DATA = { offset: 0, size: 0 };
LoadModelV05._strings = [];
class MeshReader {
static _parse(data, propertyParams = null, constructParams = null) {
var mesh = new Mesh();
MeshReader.read(data, mesh, mesh._subMeshes);
return mesh;
}
static read(data, mesh, subMeshes) {
var readData = new Laya.Byte(data);
readData.pos = 0;
var version = readData.readUTFString();
switch (version) {
case "LAYAMODEL:0301":
case "LAYAMODEL:0400":
case "LAYAMODEL:0401":
LoadModelV04.parse(readData, version, mesh, subMeshes);
break;
case "LAYAMODEL:05":
case "LAYAMODEL:COMPRESSION_05":
case "LAYAMODEL:0501":
case "LAYAMODEL:COMPRESSION_0501":
LoadModelV05.parse(readData, version, mesh, subMeshes);
break;
default:
throw new Error("MeshReader: unknown mesh version.");
}
mesh._setSubMeshes(subMeshes);
if (version != "LAYAMODEL:0501" && version != "LAYAMODEL:COMPRESSION_0501")
mesh.calculateBounds();
}
}
var SkyPanoramicFS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理而我们的解析是不认内置宏的导致被删掉所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#define PI 3.14159265359\r\n#include \"Lighting.glsl\";\r\n\r\nuniform sampler2D u_Texture;\r\nuniform vec4 u_TextureHDRParams;\r\nuniform vec4 u_TintColor;\r\n\r\nvarying vec3 v_Texcoord;\r\nvarying vec2 v_Image180ScaleAndCutoff;\r\nvarying vec4 v_Layout3DScaleAndOffset;\r\n\r\nvec2 ToRadialCoords(vec3 coords)\r\n{\r\n\tvec3 normalizedCoords = normalize(coords);\r\n\tfloat latitude = acos(normalizedCoords.y);\r\n\tfloat longitude = atan(normalizedCoords.z,normalizedCoords.x);\r\n\tvec2 sphereCoords = vec2(longitude, latitude) * vec2(0.5/PI, 1.0/PI);\r\n\treturn vec2(0.5,1.0) - sphereCoords;\r\n}\r\n\r\n\r\nvoid main()\r\n{\t\r\n\tvec2 tc = ToRadialCoords(v_Texcoord);\r\n\tif (tc.x > v_Image180ScaleAndCutoff.y)\r\n\t\tgl_FragColor=vec4(0,0,0,1);\r\n\ttc.x = mod(tc.x*v_Image180ScaleAndCutoff.x, 1.0);\r\n\ttc = (tc + v_Layout3DScaleAndOffset.xy) * v_Layout3DScaleAndOffset.zw;\r\n\r\n\tmediump vec4 tex = texture2D (u_Texture, tc);\r\n\tmediump vec3 c = decodeHDR (tex, u_TextureHDRParams.x);\r\n\tc = c * u_TintColor.rgb * 2.0;//Gamma Space is 2.0,linear space is 4.59479380\r\n\tgl_FragColor=vec4(c, 1.0);\r\n}\r\n\r\n";
var SkyPanoramicVS = "#include \"Lighting.glsl\";\r\n\r\n#define PI 3.14159265359\r\n\r\nattribute vec4 a_Position;\r\n\r\nuniform mat4 u_ViewProjection;\r\nuniform float u_Rotation;\r\n\r\nvarying vec3 v_Texcoord;\r\nvarying vec2 v_Image180ScaleAndCutoff;\r\nvarying vec4 v_Layout3DScaleAndOffset;\r\n\r\nvec4 rotateAroundYInDegrees (vec4 vertex, float degrees)\r\n{\r\n\tfloat angle = degrees * PI / 180.0;\r\n\tfloat sina=sin(angle);\r\n\tfloat cosa=cos(angle);\r\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\r\n\treturn vec4(m*vertex.xz, vertex.yw).xzyw;\r\n}\r\n\r\n\t\t\r\nvoid main()\r\n{\r\n\tvec4 position = rotateAroundYInDegrees(a_Position, u_Rotation);\r\n\tgl_Position = u_ViewProjection*position;\r\n\r\n\tv_Texcoord=vec3(-a_Position.x,-a_Position.y,a_Position.z);// NOTE: -a_Position.x convert coords system\r\n\r\n\t// Calculate constant horizontal scale and cutoff for 180 (vs 360) image type\r\n\tv_Image180ScaleAndCutoff = vec2(1.0, 1.0);// 360 degree mode\r\n\r\n\t// Calculate constant scale and offset for 3D layouts\r\n\tv_Layout3DScaleAndOffset = vec4(0,0,1,1);\r\n}\r\n";
class SkyPanoramicMaterial extends Material {
constructor() {
super();
this._exposure = 1.0;
this._textureDecodeFormat = Laya.TextureDecodeFormat.Normal;
this._textureHDRParams = new Vector4(1.0, 0.0, 0.0, 1.0);
this.setShaderName("SkyPanoramic");
var shaderValues = this._shaderValues;
shaderValues.setVector(SkyPanoramicMaterial.TINTCOLOR, new Vector4(0.5, 0.5, 0.5, 0.5));
shaderValues.setNumber(SkyPanoramicMaterial.ROTATION, 0.0);
shaderValues.setVector(SkyPanoramicMaterial.TEXTURE_HDR_PARAMS, this._textureHDRParams);
}
static __init__() {
var attributeMap = {
'a_Position': VertexMesh.MESH_POSITION0
};
var uniformMap = {
'u_TintColor': Shader3D.PERIOD_MATERIAL,
'u_TextureHDRParams': Shader3D.PERIOD_MATERIAL,
'u_Rotation': Shader3D.PERIOD_MATERIAL,
'u_Texture': Shader3D.PERIOD_MATERIAL,
'u_ViewProjection': Shader3D.PERIOD_CAMERA
};
var shader = Shader3D.add("SkyPanoramic");
var subShader = new SubShader(attributeMap, uniformMap);
shader.addSubShader(subShader);
subShader.addShaderPass(SkyPanoramicVS, SkyPanoramicFS);
}
get tintColor() {
return this._shaderValues.getVector(SkyPanoramicMaterial.TINTCOLOR);
}
set tintColor(value) {
this._shaderValues.setVector(SkyPanoramicMaterial.TINTCOLOR, value);
}
get exposure() {
return this._exposure;
}
set exposure(value) {
if (this._exposure !== value) {
this._exposure = value;
if (this._textureDecodeFormat == Laya.TextureDecodeFormat.RGBM)
this._textureHDRParams.x = value * Laya.BaseTexture._rgbmRange;
else
this._textureHDRParams.x = value;
}
}
get rotation() {
return this._shaderValues.getNumber(SkyPanoramicMaterial.ROTATION);
}
set rotation(value) {
this._shaderValues.setNumber(SkyPanoramicMaterial.ROTATION, value);
}
get panoramicTexture() {
return this._shaderValues.getTexture(SkyPanoramicMaterial.TEXTURE);
}
set panoramicTexture(value) {
this._shaderValues.setTexture(SkyPanoramicMaterial.TEXTURE, value);
}
get panoramicTextureDecodeFormat() {
return this._textureDecodeFormat;
}
set panoramicTextureDecodeFormat(value) {
if (this._textureDecodeFormat !== value) {
this._textureDecodeFormat = value;
if (value == Laya.TextureDecodeFormat.RGBM)
this._textureHDRParams.x = this._exposure * Laya.BaseTexture._rgbmRange;
else
this._textureHDRParams.x = this._exposure;
}
}
}
SkyPanoramicMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_TintColor");
SkyPanoramicMaterial.EXPOSURE = Shader3D.propertyNameToID("u_Exposure");
SkyPanoramicMaterial.ROTATION = Shader3D.propertyNameToID("u_Rotation");
SkyPanoramicMaterial.TEXTURE = Shader3D.propertyNameToID("u_Texture");
SkyPanoramicMaterial.TEXTURE_HDR_PARAMS = Shader3D.propertyNameToID("u_TextureHDRParams");
class Laya3D {
constructor() {
}
static get enablePhysics() {
return Physics3D._enablePhysics;
}
static _cancelLoadByUrl(url) {
Laya.Laya.loader.cancelLoadByUrl(url);
Laya3D._innerFirstLevelLoaderManager.cancelLoadByUrl(url);
Laya3D._innerSecondLevelLoaderManager.cancelLoadByUrl(url);
Laya3D._innerThirdLevelLoaderManager.cancelLoadByUrl(url);
Laya3D._innerFourthLevelLoaderManager.cancelLoadByUrl(url);
}
static _changeWebGLSize(width, height) {
Laya.WebGL.onStageResize(width, height);
RenderContext3D.clientWidth = width;
RenderContext3D.clientHeight = height;
}
static __init__(width, height, config) {
Laya.Config.isAntialias = config.isAntialias;
Laya.Config.isAlpha = config.isAlpha;
Laya.Config.premultipliedAlpha = config.premultipliedAlpha;
Laya.Config.isStencil = config.isStencil;
if (!Laya.WebGL.enable()) {
alert("Laya3D init error,must support webGL!");
return;
}
Laya.RunDriver.changeWebGLSize = Laya3D._changeWebGLSize;
Laya.Render.is3DMode = true;
Laya.Laya.init(width, height);
if (!Laya.Render.supportWebGLPlusRendering) {
Laya.LayaGL.instance = Laya.WebGLContext.mainContext;
Laya.LayaGL.instance.createCommandEncoder = function (reserveSize = 128, adjustSize = 64, isSyncToRenderThread = false) {
return new Laya.CommandEncoder(this, reserveSize, adjustSize, isSyncToRenderThread);
};
}
config._multiLighting = config.enableMultiLight && Laya.SystemUtils.supportTextureFormat(Laya.TextureFormat.R32G32B32A32);
ILaya3D.Shader3D = Shader3D;
ILaya3D.Scene3D = Scene3D;
ILaya3D.MeshRenderStaticBatchManager = MeshRenderStaticBatchManager;
ILaya3D.MeshRenderDynamicBatchManager = MeshRenderDynamicBatchManager;
ILaya3D.SubMeshDynamicBatch = SubMeshDynamicBatch;
ILaya3D.Laya3D = Laya3D;
ILaya3D.Matrix4x4 = Matrix4x4;
ILaya3D.Physics3D = Physics3D;
ILaya3D.ShadowLightType = exports.ShadowLightType;
ILaya3D.Camera = Camera;
ILaya3D.CommandBuffer = CommandBuffer;
ILaya3D.RenderElement = RenderElement;
ILaya3D.SubMeshRenderElement = SubMeshRenderElement;
Laya3D.enableNative3D();
if (config.isUseCannonPhysicsEngine)
Physics3D.__cannoninit__();
Physics3D.__bulletinit__();
VertexElementFormat.__init__();
VertexMesh.__init__();
VertexShurikenParticleBillboard.__init__();
VertexShurikenParticleMesh.__init__();
VertexPositionTexture0.__init__();
VertexTrail.__init__();
VertexPositionTerrain.__init__();
PixelLineVertex.__init__();
SubMeshInstanceBatch.__init__();
SubMeshDynamicBatch.__init__();
ShaderInit3D.__init__();
ShadowUtils.init();
PBRMaterial.__init__();
PBRStandardMaterial.__init__();
PBRSpecularMaterial.__init__();
SkyPanoramicMaterial.__init__();
Mesh.__init__();
PrimitiveMesh.__init__();
Sprite3D.__init__();
RenderableSprite3D.__init__();
MeshSprite3D.__init__();
SkinnedMeshSprite3D.__init__();
SimpleSkinnedMeshSprite3D.__init__();
ShuriKenParticle3D.__init__();
TrailSprite3D.__init__();
PostProcess.__init__();
Scene3D.__init__();
MeshRenderStaticBatchManager.__init__();
Material.__initDefine__();
BaseMaterial.__initDefine__();
BlinnPhongMaterial.__initDefine__();
SkyProceduralMaterial.__initDefine__();
UnlitMaterial.__initDefine__();
TrailMaterial.__initDefine__();
EffectMaterial.__initDefine__();
WaterPrimaryMaterial.__initDefine__();
ShurikenParticleMaterial.__initDefine__();
ExtendTerrainMaterial.__initDefine__();
PixelLineMaterial.__initDefine__();
SkyBoxMaterial.__initDefine__();
Command.__init__();
Laya.ClassUtils.regClass("Laya.SkyPanoramicMaterial", SkyPanoramicMaterial);
Laya.ClassUtils.regClass("Laya.EffectMaterial", EffectMaterial);
Laya.ClassUtils.regClass("Laya.UnlitMaterial", UnlitMaterial);
Laya.ClassUtils.regClass("Laya.BlinnPhongMaterial", BlinnPhongMaterial);
Laya.ClassUtils.regClass("Laya.SkyProceduralMaterial", SkyProceduralMaterial);
Laya.ClassUtils.regClass("Laya.PBRStandardMaterial", PBRStandardMaterial);
Laya.ClassUtils.regClass("Laya.PBRSpecularMaterial", PBRSpecularMaterial);
Laya.ClassUtils.regClass("Laya.SkyBoxMaterial", SkyBoxMaterial);
Laya.ClassUtils.regClass("Laya.WaterPrimaryMaterial", WaterPrimaryMaterial);
Laya.ClassUtils.regClass("Laya.ExtendTerrainMaterial", ExtendTerrainMaterial);
Laya.ClassUtils.regClass("Laya.ShurikenParticleMaterial", ShurikenParticleMaterial);
Laya.ClassUtils.regClass("Laya.TrailMaterial", TrailMaterial);
Laya.ClassUtils.regClass("Laya.PhysicsCollider", Laya.PhysicsCollider);
Laya.ClassUtils.regClass("Laya.Rigidbody3D", Laya.Rigidbody3D);
Laya.ClassUtils.regClass("Laya.CharacterController", Laya.CharacterController);
Laya.ClassUtils.regClass("Laya.Animator", Animator);
Laya.ClassUtils.regClass("PhysicsCollider", Laya.PhysicsCollider);
Laya.ClassUtils.regClass("CharacterController", Laya.CharacterController);
Laya.ClassUtils.regClass("Animator", Animator);
Laya.ClassUtils.regClass("Rigidbody3D", Laya.Rigidbody3D);
Laya.ClassUtils.regClass("FixedConstraint", Laya.FixedConstraint);
Laya.ClassUtils.regClass("ConfigurableConstraint", Laya.ConfigurableConstraint);
PixelLineMaterial.defaultMaterial = new PixelLineMaterial();
BlinnPhongMaterial.defaultMaterial = new BlinnPhongMaterial();
EffectMaterial.defaultMaterial = new EffectMaterial();
UnlitMaterial.defaultMaterial = new UnlitMaterial();
ShurikenParticleMaterial.defaultMaterial = new ShurikenParticleMaterial();
TrailMaterial.defaultMaterial = new TrailMaterial();
SkyProceduralMaterial.defaultMaterial = new SkyProceduralMaterial();
SkyBoxMaterial.defaultMaterial = new SkyBoxMaterial();
WaterPrimaryMaterial.defaultMaterial = new WaterPrimaryMaterial();
PixelLineMaterial.defaultMaterial.lock = true;
BlinnPhongMaterial.defaultMaterial.lock = true;
EffectMaterial.defaultMaterial.lock = true;
UnlitMaterial.defaultMaterial.lock = true;
ShurikenParticleMaterial.defaultMaterial.lock = true;
TrailMaterial.defaultMaterial.lock = true;
SkyProceduralMaterial.defaultMaterial.lock = true;
SkyBoxMaterial.defaultMaterial.lock = true;
WaterPrimaryMaterial.defaultMaterial.lock = true;
Laya.Texture2D.__init__();
TextureCube.__init__();
SkyBox.__init__();
SkyDome.__init__();
ScreenQuad.__init__();
ScreenTriangle.__init__();
FrustumCulling.__init__();
Laya.HalfFloatUtils.__init__();
var createMap = Laya.LoaderManager.createMap;
createMap["lh"] = [Laya3D.HIERARCHY, Scene3DUtils._parse];
createMap["ls"] = [Laya3D.HIERARCHY, Scene3DUtils._parseScene];
createMap["lm"] = [Laya3D.MESH, MeshReader._parse];
createMap["lmat"] = [Laya3D.MATERIAL, Material._parse];
createMap["jpg"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse];
createMap["jpeg"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse];
createMap["bmp"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse];
createMap["gif"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse];
createMap["png"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse];
createMap["dds"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse];
createMap["ktx"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse];
createMap["pvr"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse];
createMap["lani"] = [Laya3D.ANIMATIONCLIP, AnimationClip._parse];
createMap["lav"] = [Laya3D.AVATAR, Avatar._parse];
createMap["ltc"] = [Laya3D.TEXTURECUBE, TextureCube._parse];
createMap["ltcb"] = [Laya3D.TEXTURECUBEBIN, TextureCube._parseBin];
createMap["ltcb.ls"] = [Laya3D.TEXTURECUBEBIN, TextureCube._parseBin];
createMap["lanit.ls"] = [Laya3D.TEXTURE2D, Laya.Texture2D._SimpleAnimatorTextureParse];
var parserMap = Laya.Loader.parserMap;
parserMap[Laya3D.HIERARCHY] = Laya3D._loadHierarchy;
parserMap[Laya3D.MESH] = Laya3D._loadMesh;
parserMap[Laya3D.MATERIAL] = Laya3D._loadMaterial;
parserMap[Laya3D.TEXTURECUBE] = Laya3D._loadTextureCube;
parserMap[Laya3D.TEXTURECUBEBIN] = Laya3D._loadTextureCubeBin;
parserMap[Laya3D.TEXTURE2D] = Laya3D._loadTexture2D;
parserMap[Laya3D.ANIMATIONCLIP] = Laya3D._loadAnimationClip;
parserMap[Laya3D.AVATAR] = Laya3D._loadAvatar;
parserMap[Laya3D.SIMPLEANIMATORBIN] = Laya3D._loadSimpleAnimator;
Laya3D._innerFirstLevelLoaderManager.on(Laya.Event.ERROR, null, Laya3D._eventLoadManagerError);
Laya3D._innerSecondLevelLoaderManager.on(Laya.Event.ERROR, null, Laya3D._eventLoadManagerError);
Laya3D._innerThirdLevelLoaderManager.on(Laya.Event.ERROR, null, Laya3D._eventLoadManagerError);
Laya3D._innerFourthLevelLoaderManager.on(Laya.Event.ERROR, null, Laya3D._eventLoadManagerError);
}
static enableNative3D() {
var shaderData = ShaderData;
var shader3D = ShaderInstance;
if (Laya.Render.supportWebGLPlusRendering) {
shaderData.prototype._initData = shaderData.prototype._initDataForNative;
shaderData.prototype.setBool = shaderData.prototype.setBoolForNative;
shaderData.prototype.getBool = shaderData.prototype.getBoolForNative;
shaderData.prototype.setInt = shaderData.prototype.setIntForNative;
shaderData.prototype.getInt = shaderData.prototype.getIntForNative;
shaderData.prototype.setNumber = shaderData.prototype.setNumberForNative;
shaderData.prototype.getNumber = shaderData.prototype.getNumberForNative;
shaderData.prototype.setVector = shaderData.prototype.setVectorForNative;
shaderData.prototype.getVector = shaderData.prototype.getVectorForNative;
shaderData.prototype.setVector2 = shaderData.prototype.setVector2ForNative;
shaderData.prototype.getVector2 = shaderData.prototype.getVector2ForNative;
shaderData.prototype.setVector3 = shaderData.prototype.setVector3ForNative;
shaderData.prototype.getVector3 = shaderData.prototype.getVector3ForNative;
shaderData.prototype.setQuaternion = shaderData.prototype.setQuaternionForNative;
shaderData.prototype.getQuaternion = shaderData.prototype.getQuaternionForNative;
shaderData.prototype.setMatrix4x4 = shaderData.prototype.setMatrix4x4ForNative;
shaderData.prototype.getMatrix4x4 = shaderData.prototype.getMatrix4x4ForNative;
shaderData.prototype.setBuffer = shaderData.prototype.setBufferForNative;
shaderData.prototype.getBuffer = shaderData.prototype.getBufferForNative;
shaderData.prototype.setTexture = shaderData.prototype.setTextureForNative;
shaderData.prototype.getTexture = shaderData.prototype.getTextureForNative;
shaderData.prototype.setAttribute = shaderData.prototype.setAttributeForNative;
shaderData.prototype.getAttribute = shaderData.prototype.getAttributeForNative;
shaderData.prototype.cloneTo = shaderData.prototype.cloneToForNative;
shaderData.prototype.getData = shaderData.prototype.getDataForNative;
shader3D.prototype._uniformMatrix2fv = shader3D.prototype._uniformMatrix2fvForNative;
shader3D.prototype._uniformMatrix3fv = shader3D.prototype._uniformMatrix3fvForNative;
shader3D.prototype._uniformMatrix4fv = shader3D.prototype._uniformMatrix4fvForNative;
Laya.LayaGLRunner.uploadShaderUniforms = Laya.LayaGLRunner.uploadShaderUniformsForNative;
}
}
static formatRelativePath(base, value) {
var path;
path = base + value;
var char1 = value.charAt(0);
if (char1 === ".") {
var parts = path.split("/");
for (var i = 0, len = parts.length; i < len; i++) {
if (parts[i] == '..') {
var index = i - 1;
if (index > 0 && parts[index] !== '..') {
parts.splice(index, 2);
i -= 2;
}
}
}
path = parts.join('/');
}
return path;
}
static _endLoad(loader, content = null, subResous = null) {
if (subResous) {
for (var i = 0, n = subResous.length; i < n; i++) {
var resou = Laya.Loader.getRes(subResous[i]);
(resou) && (resou._removeReference());
}
}
loader.endLoad(content);
}
static _eventLoadManagerError(msg) {
Laya.Laya.loader.event(Laya.Event.ERROR, msg);
}
static _addHierarchyInnerUrls(urls, urlMap, urlVersion, hierarchyBasePath, path, type, constructParams = null, propertyParams = null) {
var formatUrl = Laya3D.formatRelativePath(hierarchyBasePath, path);
(urlVersion) && (formatUrl = formatUrl + urlVersion);
urls.push({ url: formatUrl, type: type, constructParams: constructParams, propertyParams: propertyParams });
urlMap.push(formatUrl);
return formatUrl;
}
static _getSprite3DHierarchyInnerUrls(node, firstLevelUrls, secondLevelUrls, thirdLevelUrls, fourthLelUrls, subUrls, urlVersion, hierarchyBasePath) {
var i, n;
var props = node.props;
switch (node.type) {
case "Scene3D":
var lightmaps = props.lightmaps;
for (i = 0, n = lightmaps.length; i < n; i++) {
var lightMap = lightmaps[i];
if (lightMap.path) {
lightMap.path = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, lightMap.path, Laya3D.TEXTURE2D, lightMap.constructParams, lightMap.propertyParams);
}
else {
var lightmapColorData = lightMap.color;
lightmapColorData.path = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, lightmapColorData.path, Laya3D.TEXTURE2D, lightmapColorData.constructParams, lightmapColorData.propertyParams);
var lightmapDirectionData = lightMap.direction;
if (lightmapDirectionData)
lightmapDirectionData.path = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, lightmapDirectionData.path, Laya3D.TEXTURE2D, lightmapDirectionData.constructParams, lightmapDirectionData.propertyParams);
}
}
var reflectionTextureData = props.reflectionTexture;
(reflectionTextureData) && (props.reflection = Laya3D._addHierarchyInnerUrls(thirdLevelUrls, subUrls, urlVersion, hierarchyBasePath, reflectionTextureData, Laya3D.TEXTURECUBE));
var reflectionData = props.reflection;
(reflectionData) && (props.reflection = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, reflectionData, Laya3D.TEXTURECUBEBIN));
if (props.sky) {
var skyboxMaterial = props.sky.material;
(skyboxMaterial) && (skyboxMaterial.path = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, skyboxMaterial.path, Laya3D.MATERIAL));
}
break;
case "Camera":
var skyboxMatData = props.skyboxMaterial;
(skyboxMatData) && (skyboxMatData.path = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, skyboxMatData.path, Laya3D.MATERIAL));
break;
case "TrailSprite3D":
case "MeshSprite3D":
case "SkinnedMeshSprite3D":
case "SimpleSkinnedMeshSprite3D":
var meshPath = props.meshPath;
(meshPath) && (props.meshPath = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, meshPath, Laya3D.MESH));
var materials = props.materials;
if (materials)
for (i = 0, n = materials.length; i < n; i++)
materials[i].path = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, materials[i].path, Laya3D.MATERIAL);
if (node.type == "SimpleSkinnedMeshSprite3D")
if (props.animatorTexture)
props.animatorTexture = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, props.animatorTexture, Laya3D.SIMPLEANIMATORBIN);
break;
case "ShuriKenParticle3D":
if (props.main) {
var resources = props.renderer.resources;
var mesh = resources.mesh;
var material = resources.material;
(mesh) && (resources.mesh = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, mesh, Laya3D.MESH));
(material) && (resources.material = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, material, Laya3D.MATERIAL));
}
else {
var parMeshPath = props.meshPath;
(parMeshPath) && (props.meshPath = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, parMeshPath, Laya3D.MESH));
props.material.path = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, props.material.path, Laya3D.MATERIAL);
}
break;
case "Terrain":
Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, props.dataPath, Laya3D.TERRAINRES);
break;
case "ReflectionProbe":
var reflection = props.reflection;
(reflection) && (props.reflection = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, reflection, Laya3D.TEXTURECUBEBIN));
break;
}
var components = node.components;
if (components) {
for (var k = 0, p = components.length; k < p; k++) {
var component = components[k];
switch (component.type) {
case "Animator":
var avatarPath = component.avatarPath;
var avatarData = component.avatar;
(avatarData) && (avatarData.path = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, avatarData.path, Laya3D.AVATAR));
var clipPaths = component.clipPaths;
if (!clipPaths) {
var layersData = component.layers;
for (i = 0; i < layersData.length; i++) {
var states = layersData[i].states;
for (var j = 0, m = states.length; j < m; j++) {
var clipPath = states[j].clipPath;
(clipPath) && (states[j].clipPath = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, clipPath, Laya3D.ANIMATIONCLIP));
}
}
}
else {
for (i = 0, n = clipPaths.length; i < n; i++)
clipPaths[i] = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, clipPaths[i], Laya3D.ANIMATIONCLIP);
}
break;
case "PhysicsCollider":
case "Rigidbody3D":
case "CharacterController":
var shapes = component.shapes;
for (i = 0; i < shapes.length; i++) {
var shape = shapes[i];
if (shape.type === "MeshColliderShape") {
var mesh = shape.mesh;
(mesh) && (shape.mesh = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, mesh, Laya3D.MESH));
}
}
break;
}
}
}
var children = node.child;
for (i = 0, n = children.length; i < n; i++)
Laya3D._getSprite3DHierarchyInnerUrls(children[i], firstLevelUrls, secondLevelUrls, thirdLevelUrls, fourthLelUrls, subUrls, urlVersion, hierarchyBasePath);
}
static _loadHierarchy(loader) {
loader._originType = loader.type;
loader.on(Laya.Event.LOADED, null, Laya3D._onHierarchylhLoaded, [loader]);
loader.load(loader.url, Laya.Loader.JSON, false, null, true);
}
static _onHierarchylhLoaded(loader, lhData) {
var url = loader.url;
var urlVersion = Utils3D.getURLVerion(url);
var hierarchyBasePath = Laya.URL.getPath(url);
var firstLevUrls = [];
var secondLevUrls = [];
var thirdLevUrls = [];
var forthLevUrls = [];
var subUrls = [];
Laya3D._getSprite3DHierarchyInnerUrls(lhData.data, firstLevUrls, secondLevUrls, thirdLevUrls, forthLevUrls, subUrls, urlVersion, hierarchyBasePath);
var urlCount = firstLevUrls.length + secondLevUrls.length + forthLevUrls.length;
var totalProcessCount = urlCount + 1;
var weight = 1 / totalProcessCount;
Laya3D._onProcessChange(loader, 0, weight, 1.0);
if (forthLevUrls.length > 0) {
var processCeil = urlCount / totalProcessCount;
var processHandler = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, weight, processCeil], false);
Laya3D._innerFourthLevelLoaderManager._create(forthLevUrls, false, Laya.Handler.create(null, Laya3D._onHierarchyInnerForthLevResouLoaded, [loader, processHandler, lhData, subUrls, firstLevUrls, secondLevUrls, thirdLevUrls, weight + processCeil * forthLevUrls.length, processCeil]), processHandler, null, null, null, 1, true);
}
else {
Laya3D._onHierarchyInnerForthLevResouLoaded(loader, null, lhData, subUrls, firstLevUrls, secondLevUrls, thirdLevUrls, weight, processCeil);
}
}
static _onHierarchyInnerForthLevResouLoaded(loader, processHandler, lhData, subUrls, firstLevUrls, secondLevUrls, thirdLevUrls, processOffset, processCeil) {
(processHandler) && (processHandler.recover());
if (thirdLevUrls.length > 0) {
var process = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, processOffset, processCeil], false);
Laya3D._innerThirdLevelLoaderManager._create(thirdLevUrls, false, Laya.Handler.create(null, Laya3D._onHierarchyInnerThirdLevResouLoaded, [loader, process, lhData, subUrls, firstLevUrls, secondLevUrls, processOffset + processCeil * secondLevUrls.length, processCeil]), processHandler, null, null, null, 1, true);
}
else {
Laya3D._onHierarchyInnerThirdLevResouLoaded(loader, null, lhData, subUrls, firstLevUrls, secondLevUrls, processOffset, processCeil);
}
}
static _onHierarchyInnerThirdLevResouLoaded(loader, processHandler, lhData, subUrls, firstLevUrls, secondLevUrls, processOffset, processCeil) {
(processHandler) && (processHandler.recover());
if (secondLevUrls.length > 0) {
var process = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, processOffset, processCeil], false);
Laya3D._innerSecondLevelLoaderManager._create(secondLevUrls, false, Laya.Handler.create(null, Laya3D._onHierarchyInnerSecondLevResouLoaded, [loader, process, lhData, subUrls, firstLevUrls, processOffset + processCeil * secondLevUrls.length, processCeil]), processHandler, null, null, null, 1, true);
}
else {
Laya3D._onHierarchyInnerSecondLevResouLoaded(loader, null, lhData, subUrls, firstLevUrls, processOffset, processCeil);
}
}
static _onHierarchyInnerSecondLevResouLoaded(loader, processHandler, lhData, subUrls, firstLevUrls, processOffset, processCeil) {
(processHandler) && (processHandler.recover());
if (firstLevUrls.length > 0) {
var process = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, processOffset, processCeil], false);
Laya3D._innerFirstLevelLoaderManager._create(firstLevUrls, false, Laya.Handler.create(null, Laya3D._onHierarchyInnerFirstLevResouLoaded, [loader, process, lhData, subUrls]), processHandler, null, null, null, 1, true);
}
else {
Laya3D._onHierarchyInnerFirstLevResouLoaded(loader, null, lhData, subUrls);
}
}
static _onHierarchyInnerFirstLevResouLoaded(loader, processHandler, lhData, subUrls) {
(processHandler) && (processHandler.recover());
loader._cache = loader._createCache;
var item = lhData.data.type === "Scene3D" ? Scene3DUtils._parseScene(lhData, loader._propertyParams, loader._constructParams) : Scene3DUtils._parse(lhData, loader._propertyParams, loader._constructParams);
Laya3D._endLoad(loader, item, subUrls);
}
static _loadMesh(loader) {
loader.on(Laya.Event.LOADED, null, Laya3D._onMeshLmLoaded, [loader]);
loader.load(loader.url, Laya.Loader.BUFFER, false, null, true);
}
static _onMeshLmLoaded(loader, lmData) {
loader._cache = loader._createCache;
var mesh = MeshReader._parse(lmData, loader._propertyParams, loader._constructParams);
Laya3D._endLoad(loader, mesh);
}
static _loadMaterial(loader) {
loader.on(Laya.Event.LOADED, null, Laya3D._onMaterilLmatLoaded, [loader]);
loader.load(loader.url, Laya.Loader.JSON, false, null, true);
}
static _onMaterilLmatLoaded(loader, lmatData) {
var url = loader.url;
var urlVersion = Utils3D.getURLVerion(url);
var materialBasePath = Laya.URL.getPath(url);
var urls = [];
var subUrls = [];
var customProps = lmatData.customProps;
var formatSubUrl;
var version = lmatData.version;
switch (version) {
case "LAYAMATERIAL:01":
case "LAYAMATERIAL:02":
case "LAYAMATERIAL:03":
var i, n;
var textures = lmatData.props.textures;
if (textures) {
for (i = 0, n = textures.length; i < n; i++) {
var tex2D = textures[i];
var tex2DPath = tex2D.path;
if (tex2DPath) {
formatSubUrl = Laya3D.formatRelativePath(materialBasePath, tex2DPath);
(urlVersion) && (formatSubUrl = formatSubUrl + urlVersion);
urls.push({ url: formatSubUrl, constructParams: tex2D.constructParams, propertyParams: tex2D.propertyParams });
subUrls.push(formatSubUrl);
tex2D.path = formatSubUrl;
}
}
}
break;
default:
throw new Error("Laya3D:unkonwn version.");
}
var urlCount = urls.length;
var totalProcessCount = urlCount + 1;
var lmatWeight = 1 / totalProcessCount;
Laya3D._onProcessChange(loader, 0, lmatWeight, 1.0);
if (urlCount > 0) {
var processHandler = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, lmatWeight, urlCount / totalProcessCount], false);
Laya3D._innerFourthLevelLoaderManager._create(urls, false, Laya.Handler.create(null, Laya3D._onMateialTexturesLoaded, [loader, processHandler, lmatData, subUrls]), processHandler, null, null, null, 1, true);
}
else {
Laya3D._onMateialTexturesLoaded(loader, null, lmatData, null);
}
}
static _onMateialTexturesLoaded(loader, processHandler, lmatData, subUrls) {
loader._cache = loader._createCache;
var mat = Material._parse(lmatData, loader._propertyParams, loader._constructParams);
Laya3D._endLoad(loader, mat, subUrls);
(processHandler) && (processHandler.recover());
}
static _loadAvatar(loader) {
loader.on(Laya.Event.LOADED, null, function (data) {
loader._cache = loader._createCache;
var avatar = Avatar._parse(data, loader._propertyParams, loader._constructParams);
Laya3D._endLoad(loader, avatar);
});
loader.load(loader.url, Laya.Loader.JSON, false, null, true);
}
static _loadSimpleAnimator(loader) {
loader.on(Laya.Event.LOADED, null, function (data) {
loader._cache = loader._createCache;
var texture = Laya.Texture2D._SimpleAnimatorTextureParse(data, loader._propertyParams, loader._constructParams);
Laya3D._endLoad(loader, texture);
});
loader.load(loader.url, Laya.Loader.BUFFER, false, null, true);
}
static _loadAnimationClip(loader) {
loader.on(Laya.Event.LOADED, null, function (data) {
loader._cache = loader._createCache;
var clip = AnimationClip._parse(data);
Laya3D._endLoad(loader, clip);
});
loader.load(loader.url, Laya.Loader.BUFFER, false, null, true);
}
static _loadTexture2D(loader) {
var url = loader.url;
var index = url.lastIndexOf('.') + 1;
var verIndex = url.indexOf('?');
var endIndex = verIndex == -1 ? url.length : verIndex;
var ext = url.substr(index, endIndex - index);
var type;
switch (ext) {
case "jpg":
case "jpeg":
case "bmp":
case "gif":
case "png":
type = "nativeimage";
break;
case "dds":
type = Laya.Loader.BUFFER;
break;
case "ktx":
type = Laya.Loader.BUFFER;
(!loader._constructParams) && (loader._constructParams = []);
loader._constructParams[2] = Laya.TextureFormat.KTXTEXTURE;
break;
case "pvr":
type = Laya.Loader.BUFFER;
(!loader._constructParams) && (loader._constructParams = []);
loader._propertyParams[2] = Laya.TextureFormat.PVRTEXTURE;
break;
}
loader.on(Laya.Event.LOADED, null, function (image) {
loader._cache = loader._createCache;
var tex = Laya.Texture2D._parse(image, loader._propertyParams, loader._constructParams);
Laya3D._endLoad(loader, tex);
});
loader.load(loader.url, type, false, null, true);
}
static _loadTextureCube(loader) {
loader.on(Laya.Event.LOADED, null, Laya3D._onTextureCubeLtcLoaded, [loader]);
loader.load(loader.url, Laya.Loader.JSON, false, null, true);
}
static _loadTextureCubeBin(loader) {
loader.on(Laya.Event.LOADED, null, (data) => {
loader._cache = loader._createCache;
var byte = new Laya.Byte(data);
var version = byte.readUTFString();
if (version !== "LAYATEXTURECUBE:0000")
throw "Laya3D:unknow version.";
var format = byte.readUint8();
var mipCount = byte.getUint8();
var size = byte.readUint16();
var filterMode = byte.getUint8();
var warpModeU = byte.getUint8();
var warpModev = byte.getUint8();
var anisoLevel = byte.getUint8();
var cubemap = new TextureCube(size, format, mipCount > 1 ? true : false);
cubemap.filterMode = filterMode;
cubemap.wrapModeU = warpModeU;
cubemap.wrapModeV = warpModev;
cubemap.anisoLevel = anisoLevel;
var pos = byte.pos;
var mipSize = size;
for (var i = 0; i < mipCount; i++) {
var uint8Arrays = new Array(6);
var mipPixelLength = mipSize * mipSize * cubemap._getFormatByteCount();
for (var j = 0; j < 6; j++) {
uint8Arrays[j] = new Uint8Array(data, pos, mipPixelLength);
pos += mipPixelLength;
}
cubemap.setSixSidePixels(uint8Arrays, i);
mipSize /= 2;
}
Laya3D._endLoad(loader, cubemap);
});
loader.load(loader.url, Laya.Loader.BUFFER, false, null, true);
}
static _onTextureCubeLtcLoaded(loader, ltcData) {
var ltcBasePath = Laya.URL.getPath(loader.url);
var urls = [Laya3D.formatRelativePath(ltcBasePath, ltcData.front), Laya3D.formatRelativePath(ltcBasePath, ltcData.back), Laya3D.formatRelativePath(ltcBasePath, ltcData.left), Laya3D.formatRelativePath(ltcBasePath, ltcData.right), Laya3D.formatRelativePath(ltcBasePath, ltcData.up), Laya3D.formatRelativePath(ltcBasePath, ltcData.down)];
var ltcWeight = 1.0 / 7.0;
Laya3D._onProcessChange(loader, 0, ltcWeight, 1.0);
var processHandler = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, ltcWeight, 6 / 7], false);
Laya3D._innerFourthLevelLoaderManager.load(urls, Laya.Handler.create(null, Laya3D._onTextureCubeImagesLoaded, [loader, urls, processHandler]), processHandler, "nativeimage");
}
static _onTextureCubeImagesLoaded(loader, urls, processHandler) {
var images = new Array(6);
for (var i = 0; i < 6; i++)
images[i] = Laya.Loader.getRes(urls[i]);
loader._cache = loader._createCache;
var tex = TextureCube._parse(images, loader._propertyParams, loader._constructParams);
processHandler.recover();
for (i = 0; i < 6; i++)
Laya.Loader.clearRes(urls[i]);
Laya3D._endLoad(loader, tex);
}
static _onProcessChange(loader, offset, weight, process) {
process = offset + process * weight;
(process < 1.0) && (loader.event(Laya.Event.PROGRESS, process * 2 / 3 + 1 / 3));
}
static init(width, height, config = null, compolete = null) {
if (Laya3D._isInit) {
compolete && compolete.run();
return;
}
Laya3D._isInit = true;
(config) && (config.cloneTo(Config3D._config));
config = Config3D._config;
FrustumCulling.debugFrustumCulling = config.debugFrustumCulling;
Laya3D._editerEnvironment = config._editerEnvironment;
Scene3D.octreeCulling = config.octreeCulling;
Scene3D.octreeInitialSize = config.octreeInitialSize;
Scene3D.octreeInitialCenter = config.octreeInitialCenter;
Scene3D.octreeMinNodeSize = config.octreeMinNodeSize;
Scene3D.octreeLooseness = config.octreeLooseness;
var physics3D = window.Physics3D;
if (physics3D == null || config.isUseCannonPhysicsEngine) {
Physics3D._enablePhysics = false;
Laya3D.__init__(width, height, config);
compolete && compolete.run();
}
else {
Physics3D._enablePhysics = true;
physics3D(config.defaultPhysicsMemory * 16, Laya.BulletInteractive._interactive).then(function () {
Laya3D.__init__(width, height, config);
compolete && compolete.run();
});
}
}
}
Laya3D.HIERARCHY = "HIERARCHY";
Laya3D.MESH = "MESH";
Laya3D.MATERIAL = "MATERIAL";
Laya3D.TEXTURE2D = "TEXTURE2D";
Laya3D.TEXTURECUBE = "TEXTURECUBE";
Laya3D.TEXTURECUBEBIN = "TEXTURECUBEBIN";
Laya3D.ANIMATIONCLIP = "ANIMATIONCLIP";
Laya3D.AVATAR = "AVATAR";
Laya3D.TERRAINHEIGHTDATA = "TERRAINHEIGHTDATA";
Laya3D.TERRAINRES = "TERRAIN";
Laya3D.SIMPLEANIMATORBIN = "SIMPLEANIMATOR";
Laya3D._innerFirstLevelLoaderManager = new Laya.LoaderManager();
Laya3D._innerSecondLevelLoaderManager = new Laya.LoaderManager();
Laya3D._innerThirdLevelLoaderManager = new Laya.LoaderManager();
Laya3D._innerFourthLevelLoaderManager = new Laya.LoaderManager();
Laya3D._isInit = false;
Laya3D._editerEnvironment = false;
window.Laya3D = Laya3D;
class CastShadowList extends SingletonList {
constructor() {
super();
}
add(element) {
var index = element._indexInCastShadowList;
if (index !== -1)
throw "CastShadowList:element has in CastShadowList.";
this._add(element);
element._indexInCastShadowList = this.length++;
}
remove(element) {
var index = element._indexInCastShadowList;
this.length--;
if (index !== this.length) {
var end = this.elements[this.length];
this.elements[index] = end;
end._indexInCastShadowList = index;
}
element._indexInCastShadowList = -1;
}
}
class AnimatorStateScript {
constructor() {
}
onStateEnter() {
}
onStateUpdate() {
}
onStateExit() {
}
}
class Script3D extends Laya.Component {
constructor() {
super(...arguments);
this._indexInPool = -1;
this._enableState = false;
}
get isSingleton() {
return false;
}
_checkProcessTriggers() {
var prototype = Script3D.prototype;
if (this.onTriggerEnter !== prototype.onTriggerEnter)
return true;
if (this.onTriggerStay !== prototype.onTriggerStay)
return true;
if (this.onTriggerExit !== prototype.onTriggerExit)
return true;
return false;
}
_checkProcessCollisions() {
var prototype = Script3D.prototype;
if (this.onCollisionEnter !== prototype.onCollisionEnter)
return true;
if (this.onCollisionStay !== prototype.onCollisionStay)
return true;
if (this.onCollisionExit !== prototype.onCollisionExit)
return true;
return false;
}
_onAwake() {
this.onAwake();
if (this.onStart !== Script3D.prototype.onStart)
Laya.Laya.startTimer.callLater(this, this.onStart);
}
_onEnable() {
if (this._enableState)
return;
this.owner._scene._addScript(this);
this._enableState = true;
this.onEnable();
}
_onDisable() {
if (!this._enableState || this._indexInPool == -1)
return;
this.owner._scene._removeScript(this);
this.owner.offAllCaller(this);
this._enableState = false;
this.onDisable();
}
_onDestroy() {
var scripts = this.owner._scripts;
scripts.splice(scripts.indexOf(this), 1);
var sprite = this.owner;
sprite._needProcessTriggers = false;
for (var i = 0, n = scripts.length; i < n; i++) {
if (scripts[i]._checkProcessTriggers()) {
sprite._needProcessTriggers = true;
break;
}
}
sprite._needProcessCollisions = false;
for (i = 0, n = scripts.length; i < n; i++) {
if (scripts[i]._checkProcessCollisions()) {
sprite._needProcessCollisions = true;
break;
}
}
this.onDestroy();
}
_isScript() {
return true;
}
_onAdded() {
var sprite = this.owner;
var scripts = sprite._scripts;
scripts || (sprite._scripts = scripts = []);
scripts.push(this);
if (!sprite._needProcessCollisions)
sprite._needProcessCollisions = this._checkProcessCollisions();
if (!sprite._needProcessTriggers)
sprite._needProcessTriggers = this._checkProcessTriggers();
}
onAwake() {
}
onEnable() {
}
onStart() {
}
onTriggerEnter(other) {
}
onTriggerStay(other) {
}
onTriggerExit(other) {
}
onCollisionEnter(collision) {
}
onCollisionStay(collision) {
}
onCollisionExit(collision) {
}
onJointBreak() {
}
onMouseDown() {
}
onMouseDrag() {
}
onMouseClick() {
}
onMouseUp() {
}
onMouseEnter() {
}
onMouseOver() {
}
onMouseOut() {
}
onUpdate() {
}
onLateUpdate() {
}
onPreRender() {
}
onPostRender() {
}
onDisable() {
}
onDestroy() {
}
}
class HeightMap {
constructor(width, height, minHeight, maxHeight) {
this._datas = [];
this._w = width;
this._h = height;
this._minHeight = minHeight;
this._maxHeight = maxHeight;
}
static creatFromMesh(mesh, width, height, outCellSize) {
var vertices = [];
var indexs = [];
var submesheCount = mesh.subMeshCount;
for (var i = 0; i < submesheCount; i++) {
var subMesh = mesh.getSubMesh(i);
var vertexBuffer = subMesh._vertexBuffer;
var verts = vertexBuffer.getFloat32Data();
var subMeshVertices = [];
for (var j = 0; j < verts.length; j += vertexBuffer.vertexDeclaration.vertexStride / 4) {
var position = new Vector3(verts[j + 0], verts[j + 1], verts[j + 2]);
subMeshVertices.push(position);
}
vertices.push(subMeshVertices);
var ib = subMesh._indexBuffer;
indexs.push(ib.getData());
}
var bounds = mesh.bounds;
var minX = bounds.getMin().x;
var minZ = bounds.getMin().z;
var maxX = bounds.getMax().x;
var maxZ = bounds.getMax().z;
var minY = bounds.getMin().y;
var maxY = bounds.getMax().y;
var widthSize = maxX - minX;
var heightSize = maxZ - minZ;
var cellWidth = outCellSize.x = widthSize / (width - 1);
var cellHeight = outCellSize.y = heightSize / (height - 1);
var heightMap = new HeightMap(width, height, minY, maxY);
var ray = HeightMap._tempRay;
var rayDir = ray.direction;
rayDir.x = 0;
rayDir.y = -1;
rayDir.z = 0;
const heightOffset = 0.1;
var rayY = maxY + heightOffset;
ray.origin.y = rayY;
for (var h = 0; h < height; h++) {
var posZ = minZ + h * cellHeight;
heightMap._datas[h] = [];
for (var w = 0; w < width; w++) {
var posX = minX + w * cellWidth;
var rayOri = ray.origin;
rayOri.x = posX;
rayOri.z = posZ;
var closestIntersection = HeightMap._getPosition(ray, vertices, indexs);
heightMap._datas[h][w] = (closestIntersection === Number.MAX_VALUE) ? NaN : rayY - closestIntersection;
}
}
return heightMap;
}
static createFromImage(texture, minHeight, maxHeight) {
var textureWidth = texture.width;
var textureHeight = texture.height;
var heightMap = new HeightMap(textureWidth, textureHeight, minHeight, maxHeight);
var compressionRatio = (maxHeight - minHeight) / 254;
var pixelsInfo = texture.getPixels();
var index = 0;
for (var h = 0; h < textureHeight; h++) {
var colDatas = heightMap._datas[h] = [];
for (var w = 0; w < textureWidth; w++) {
var r = pixelsInfo[index++];
var g = pixelsInfo[index++];
var b = pixelsInfo[index++];
var a = pixelsInfo[index++];
if (r == 255 && g == 255 && b == 255 && a == 255)
colDatas[w] = NaN;
else {
colDatas[w] = (r + g + b) / 3 * compressionRatio + minHeight;
}
}
}
return heightMap;
}
static _getPosition(ray, vertices, indexs) {
var closestIntersection = Number.MAX_VALUE;
for (var i = 0; i < vertices.length; i++) {
var subMeshVertices = vertices[i];
var subMeshIndexes = indexs[i];
for (var j = 0; j < subMeshIndexes.length; j += 3) {
var vertex1 = subMeshVertices[subMeshIndexes[j + 0]];
var vertex2 = subMeshVertices[subMeshIndexes[j + 1]];
var vertex3 = subMeshVertices[subMeshIndexes[j + 2]];
var intersection = Picker.rayIntersectsTriangle(ray, vertex1, vertex2, vertex3);
if (!isNaN(intersection) && intersection < closestIntersection) {
closestIntersection = intersection;
}
}
}
return closestIntersection;
}
get width() {
return this._w;
}
get height() {
return this._h;
}
get maxHeight() {
return this._maxHeight;
}
get minHeight() {
return this._minHeight;
}
_inBounds(row, col) {
return row >= 0 && row < this._h && col >= 0 && col < this._w;
}
getHeight(row, col) {
if (this._inBounds(row, col))
return this._datas[row][col];
else
return NaN;
}
}
HeightMap._tempRay = new Ray(new Vector3(), new Vector3());
class MeshTerrainSprite3D extends MeshSprite3D {
constructor(mesh, heightMap, name = null) {
super(mesh, name);
this._heightMap = heightMap;
this._cellSize = new Vector2();
}
static createFromMesh(mesh, heightMapWidth, heightMapHeight, name = null) {
var meshTerrainSprite3D = new MeshTerrainSprite3D(mesh, null, name);
meshTerrainSprite3D._initCreateFromMesh(heightMapWidth, heightMapHeight);
return meshTerrainSprite3D;
}
static createFromMeshAndHeightMap(mesh, texture, minHeight, maxHeight, name = null) {
var meshTerrainSprite3D = new MeshTerrainSprite3D(mesh, null, name);
meshTerrainSprite3D._initCreateFromMeshHeightMap(texture, minHeight, maxHeight);
return meshTerrainSprite3D;
}
get minX() {
var worldMat = this.transform.worldMatrix;
var worldMatE = worldMat.elements;
return this._minX * this._getScaleX() + worldMatE[12];
}
get minZ() {
var worldMat = this.transform.worldMatrix;
var worldMatE = worldMat.elements;
return this._minZ * this._getScaleZ() + worldMatE[14];
}
get width() {
return (this._heightMap.width - 1) * this._cellSize.x * this._getScaleX();
}
get depth() {
return (this._heightMap.height - 1) * this._cellSize.y * this._getScaleZ();
}
_disableRotation() {
var rotation = this.transform.rotation;
rotation.x = 0;
rotation.y = 0;
rotation.z = 0;
rotation.w = 1;
this.transform.rotation = rotation;
}
_getScaleX() {
var worldMat = this.transform.worldMatrix;
var worldMatE = worldMat.elements;
var m11 = worldMatE[0];
var m12 = worldMatE[1];
var m13 = worldMatE[2];
return Math.sqrt((m11 * m11) + (m12 * m12) + (m13 * m13));
}
_getScaleZ() {
var worldMat = this.transform.worldMatrix;
var worldMatE = worldMat.elements;
var m31 = worldMatE[8];
var m32 = worldMatE[9];
var m33 = worldMatE[10];
return Math.sqrt((m31 * m31) + (m32 * m32) + (m33 * m33));
}
_initCreateFromMesh(heightMapWidth, heightMapHeight) {
this._heightMap = HeightMap.creatFromMesh(this.meshFilter.sharedMesh, heightMapWidth, heightMapHeight, this._cellSize);
var boundingBox = this.meshFilter.sharedMesh.bounds;
var min = boundingBox.getMin();
this._minX = min.x;
this._minZ = min.z;
}
_initCreateFromMeshHeightMap(texture, minHeight, maxHeight) {
var boundingBox = this.meshFilter.sharedMesh.bounds;
this._heightMap = HeightMap.createFromImage(texture, minHeight, maxHeight);
this._computeCellSize(boundingBox);
var min = boundingBox.getMin();
this._minX = min.x;
this._minZ = min.z;
}
_computeCellSize(boundingBox) {
var min = boundingBox.getMin();
var max = boundingBox.getMax();
var minX = min.x;
var minZ = min.z;
var maxX = max.x;
var maxZ = max.z;
var widthSize = maxX - minX;
var heightSize = maxZ - minZ;
this._cellSize.x = widthSize / (this._heightMap.width - 1);
this._cellSize.y = heightSize / (this._heightMap.height - 1);
}
_update(state) {
this._disableRotation();
}
getHeight(x, z) {
MeshTerrainSprite3D._tempVector3.x = x;
MeshTerrainSprite3D._tempVector3.y = 0;
MeshTerrainSprite3D._tempVector3.z = z;
this._disableRotation();
var worldMat = this.transform.worldMatrix;
worldMat.invert(MeshTerrainSprite3D._tempMatrix4x4);
Vector3.transformCoordinate(MeshTerrainSprite3D._tempVector3, MeshTerrainSprite3D._tempMatrix4x4, MeshTerrainSprite3D._tempVector3);
x = MeshTerrainSprite3D._tempVector3.x;
z = MeshTerrainSprite3D._tempVector3.z;
var c = (x - this._minX) / this._cellSize.x;
var d = (z - this._minZ) / this._cellSize.y;
var row = Math.floor(d);
var col = Math.floor(c);
var s = c - col;
var t = d - row;
var uy;
var vy;
var worldMatE = worldMat.elements;
var m21 = worldMatE[4];
var m22 = worldMatE[5];
var m23 = worldMatE[6];
var scaleY = Math.sqrt((m21 * m21) + (m22 * m22) + (m23 * m23));
var translateY = worldMatE[13];
var h01 = this._heightMap.getHeight(row, col + 1);
var h10 = this._heightMap.getHeight((row + 1), col);
if (isNaN(h01) || isNaN(h10))
return NaN;
if (s + t <= 1.0) {
var h00 = this._heightMap.getHeight(row, col);
if (isNaN(h00))
return NaN;
uy = h01 - h00;
vy = h10 - h00;
return (h00 + s * uy + t * vy) * scaleY + translateY;
}
else {
var h11 = this._heightMap.getHeight((row + 1), col + 1);
if (isNaN(h11))
return NaN;
uy = h10 - h11;
vy = h01 - h11;
return (h11 + (1.0 - s) * uy + (1.0 - t) * vy) * scaleY + translateY;
}
}
}
MeshTerrainSprite3D._tempVector3 = new Vector3();
MeshTerrainSprite3D._tempMatrix4x4 = new Matrix4x4();
class GradientDataVector2 {
constructor() {
this._currentLength = 0;
this._elements = new Float32Array(12);
}
get gradientCount() {
return this._currentLength / 3;
}
add(key, value) {
if (this._currentLength < 8) {
if ((this._currentLength === 6) && ((key !== 1))) {
key = 1;
console.log("GradientDataVector2 warning:the forth key is be force set to 1.");
}
this._elements[this._currentLength++] = key;
this._elements[this._currentLength++] = value.x;
this._elements[this._currentLength++] = value.y;
}
else {
console.log("GradientDataVector2 warning:data count must lessEqual than 4");
}
}
cloneTo(destObject) {
var destGradientDataVector2 = destObject;
destGradientDataVector2._currentLength = this._currentLength;
var destElements = destGradientDataVector2._elements;
for (var i = 0, n = this._elements.length; i < n; i++) {
destElements[i] = this._elements[i];
}
}
clone() {
var destGradientDataVector2 = new GradientDataVector2();
this.cloneTo(destGradientDataVector2);
return destGradientDataVector2;
}
}
class PixelLineData {
constructor() {
this.startPosition = new Vector3();
this.endPosition = new Vector3();
this.startColor = new Color();
this.endColor = new Color();
}
cloneTo(destObject) {
this.startPosition.cloneTo(destObject.startPosition);
this.endPosition.cloneTo(destObject.endPosition);
this.startColor.cloneTo(destObject.startColor);
this.endColor.cloneTo(destObject.endColor);
}
}
class PostProcessEffect {
constructor() {
}
render(context) {
}
}
class BloomEffect extends PostProcessEffect {
constructor() {
super();
this._shader = null;
this._shaderData = new ShaderData();
this._linearColor = new Color();
this._bloomTextureTexelSize = new Vector4();
this._shaderThreshold = new Vector4();
this._shaderParams = new Vector4();
this._pyramid = null;
this._intensity = 0.0;
this._threshold = 1.0;
this._softKnee = 0.5;
this._diffusion = 7.0;
this._anamorphicRatio = 0.0;
this._dirtIntensity = 0.0;
this._shaderSetting = new Vector4();
this._dirtTileOffset = new Vector4();
this.clamp = 65472.0;
this.color = new Color(1.0, 1.0, 1.0, 1.0);
this.fastMode = false;
this.dirtTexture = null;
this._shader = Shader3D.find("PostProcessBloom");
this._pyramid = new Array(BloomEffect.MAXPYRAMIDSIZE * 2);
}
get intensity() {
return this._intensity;
}
set intensity(value) {
this._intensity = Math.max(value, 0.0);
}
get threshold() {
return this._threshold;
}
set threshold(value) {
this._threshold = Math.max(value, 0.0);
}
get softKnee() {
return this._softKnee;
}
set softKnee(value) {
this._softKnee = Math.min(Math.max(value, 0.0), 1.0);
}
get diffusion() {
return this._diffusion;
}
set diffusion(value) {
this._diffusion = Math.min(Math.max(value, 1), 10);
}
get anamorphicRatio() {
return this._anamorphicRatio;
}
set anamorphicRatio(value) {
this._anamorphicRatio = Math.min(Math.max(value, -1.0), 1.0);
}
get dirtIntensity() {
return this._dirtIntensity;
}
set dirtIntensity(value) {
this._dirtIntensity = Math.max(value, 0.0);
}
render(context) {
var cmd = context.command;
var viewport = context.camera.viewport;
this._shaderData.setTexture(BloomEffect.SHADERVALUE_AUTOEXPOSURETEX, Laya.Texture2D.whiteTexture);
var ratio = this._anamorphicRatio;
var rw = ratio < 0 ? -ratio : 0;
var rh = ratio > 0 ? ratio : 0;
var tw = Math.floor(viewport.width / (2 - rw));
var th = Math.floor(viewport.height / (2 - rh));
var s = Math.max(tw, th);
var logs;
logs = Math.log2(s) + this._diffusion - 10;
var logsInt = Math.floor(logs);
var iterations = Math.min(Math.max(logsInt, 1), BloomEffect.MAXPYRAMIDSIZE);
var sampleScale = 0.5 + logs - logsInt;
this._shaderData.setNumber(BloomEffect.SHADERVALUE_SAMPLESCALE, sampleScale);
var lthresh = Color.gammaToLinearSpace(this.threshold);
var knee = lthresh * this._softKnee + 1e-5;
this._shaderThreshold.setValue(lthresh, lthresh - knee, knee * 2, 0.25 / knee);
this._shaderData.setVector(BloomEffect.SHADERVALUE_THRESHOLD, this._shaderThreshold);
var lclamp = Color.gammaToLinearSpace(this.clamp);
this._shaderParams.setValue(lclamp, 0, 0, 0);
this._shaderData.setVector(BloomEffect.SHADERVALUE_PARAMS, this._shaderParams);
var qualityOffset = this.fastMode ? 1 : 0;
var lastDownTexture = context.source;
for (var i = 0; i < iterations; i++) {
var downIndex = i * 2;
var upIndex = downIndex + 1;
var subShader = i == 0 ? BloomEffect.SUBSHADER_PREFILTER13 + qualityOffset : BloomEffect.SUBSHADER_DOWNSAMPLE13 + qualityOffset;
var mipDownTexture = RenderTexture.createFromPool(tw, th, Laya.RenderTextureFormat.R8G8B8, Laya.RenderTextureDepthFormat.DEPTHSTENCIL_NONE);
mipDownTexture.filterMode = Laya.FilterMode.Bilinear;
this._pyramid[downIndex] = mipDownTexture;
if (i !== iterations - 1) {
var mipUpTexture = RenderTexture.createFromPool(tw, th, Laya.RenderTextureFormat.R8G8B8, Laya.RenderTextureDepthFormat.DEPTHSTENCIL_NONE);
mipUpTexture.filterMode = Laya.FilterMode.Bilinear;
this._pyramid[upIndex] = mipUpTexture;
}
cmd.blitScreenTriangle(lastDownTexture, mipDownTexture, null, this._shader, this._shaderData, subShader);
lastDownTexture = mipDownTexture;
tw = Math.max(Math.floor(tw / 2), 1);
th = Math.max(Math.floor(th / 2), 1);
}
var lastUpTexture = this._pyramid[(iterations - 1) * 2];
for (i = iterations - 2; i >= 0; i--) {
downIndex = i * 2;
upIndex = downIndex + 1;
mipDownTexture = this._pyramid[downIndex];
mipUpTexture = this._pyramid[upIndex];
cmd.setShaderDataTexture(this._shaderData, BloomEffect.SHADERVALUE_BLOOMTEX, mipDownTexture);
cmd.blitScreenTriangle(lastUpTexture, mipUpTexture, null, this._shader, this._shaderData, BloomEffect.SUBSHADER_UPSAMPLETENT + qualityOffset);
lastUpTexture = mipUpTexture;
}
var linearColor = this._linearColor;
this.color.toLinear(linearColor);
var intensity = Math.pow(2, this._intensity / 10.0) - 1.0;
var shaderSettings = this._shaderSetting;
this._shaderSetting.setValue(sampleScale, intensity, this._dirtIntensity, iterations);
var dirtTexture = this.dirtTexture ? this.dirtTexture : Laya.Texture2D.blackTexture;
var dirtRatio = dirtTexture.width / dirtTexture.height;
var screenRatio = viewport.width / viewport.height;
var dirtTileOffset = this._dirtTileOffset;
if (dirtRatio > screenRatio)
dirtTileOffset.setValue(screenRatio / dirtRatio, 1.0, (1.0 - dirtTileOffset.x) * 0.5, 0.0);
else if (dirtRatio < screenRatio)
dirtTileOffset.setValue(1.0, dirtRatio / screenRatio, 0.0, (1.0 - dirtTileOffset.y) * 0.5);
var compositeShaderData = context.compositeShaderData;
if (this.fastMode)
compositeShaderData.addDefine(PostProcess.SHADERDEFINE_BLOOM_LOW);
else
compositeShaderData.addDefine(PostProcess.SHADERDEFINE_BLOOM);
this._bloomTextureTexelSize.setValue(1.0 / lastUpTexture.width, 1.0 / lastUpTexture.height, lastUpTexture.width, lastUpTexture.height);
compositeShaderData.setVector(PostProcess.SHADERVALUE_BLOOM_DIRTTILEOFFSET, dirtTileOffset);
compositeShaderData.setVector(PostProcess.SHADERVALUE_BLOOM_SETTINGS, shaderSettings);
compositeShaderData.setVector(PostProcess.SHADERVALUE_BLOOM_COLOR, new Vector4(linearColor.r, linearColor.g, linearColor.b, linearColor.a));
compositeShaderData.setTexture(PostProcess.SHADERVALUE_BLOOM_DIRTTEX, dirtTexture);
compositeShaderData.setTexture(PostProcess.SHADERVALUE_BLOOMTEX, lastUpTexture);
compositeShaderData.setVector(PostProcess.SHADERVALUE_BLOOMTEX_TEXELSIZE, this._bloomTextureTexelSize);
for (i = 0; i < iterations; i++) {
downIndex = i * 2;
upIndex = downIndex + 1;
RenderTexture.recoverToPool(this._pyramid[downIndex]);
(i !== 0 && i !== iterations - 1) && (RenderTexture.recoverToPool(this._pyramid[upIndex]));
}
context.deferredReleaseTextures.push(lastUpTexture);
}
}
BloomEffect.SHADERVALUE_MAINTEX = Shader3D.propertyNameToID("u_MainTex");
BloomEffect.SHADERVALUE_AUTOEXPOSURETEX = Shader3D.propertyNameToID("u_AutoExposureTex");
BloomEffect.SHADERVALUE_SAMPLESCALE = Shader3D.propertyNameToID("u_SampleScale");
BloomEffect.SHADERVALUE_THRESHOLD = Shader3D.propertyNameToID("u_Threshold");
BloomEffect.SHADERVALUE_PARAMS = Shader3D.propertyNameToID("u_Params");
BloomEffect.SHADERVALUE_BLOOMTEX = Shader3D.propertyNameToID("u_BloomTex");
BloomEffect.SUBSHADER_PREFILTER13 = 0;
BloomEffect.SUBSHADER_PREFILTER4 = 1;
BloomEffect.SUBSHADER_DOWNSAMPLE13 = 2;
BloomEffect.SUBSHADER_DOWNSAMPLE4 = 3;
BloomEffect.SUBSHADER_UPSAMPLETENT = 4;
BloomEffect.SUBSHADER_UPSAMPLEBOX = 5;
BloomEffect.MAXPYRAMIDSIZE = 16;
class MaterialInstanceProperty {
constructor() {
this._isNeedUpdate = false;
}
createInstanceVertexBuffer3D() {
var gl = Laya.LayaGL.instance;
this._instanceData = new Float32Array(DrawMeshInstancedCMD.maxInstanceCount * this._vertexStride);
this._vertexBuffer = new VertexBuffer3D(this._instanceData.length * 4, gl.DYNAMIC_DRAW);
this._vertexBuffer.vertexDeclaration = this._vertexDeclaration;
}
updateVertexBufferData(drawNums) {
if (!this._isNeedUpdate)
return;
let instanceData = this._instanceData;
let dataValue = this._value;
let datalength = this._value.length;
let data;
let stride = this._vertexStride;
let updateType = 0;
if (!(this._value instanceof Float32Array)) {
updateType = 1;
}
switch (updateType) {
case 0:
instanceData.set(dataValue, 0);
break;
case 1:
for (let i = 0; i < datalength; i++) {
data = dataValue[i];
data.toArray(instanceData, i * stride);
}
break;
}
this._vertexBuffer.orphanStorage();
this._vertexBuffer.setData(instanceData.buffer, 0, 0, drawNums * 4 * stride);
}
}
(function (InstanceLocation) {
InstanceLocation[InstanceLocation["CUSTOME0"] = 12] = "CUSTOME0";
InstanceLocation[InstanceLocation["CUSTOME1"] = 13] = "CUSTOME1";
InstanceLocation[InstanceLocation["CUSTOME2"] = 14] = "CUSTOME2";
InstanceLocation[InstanceLocation["CUSTOME3"] = 15] = "CUSTOME3";
})(exports.InstanceLocation || (exports.InstanceLocation = {}));
class MaterialInstancePropertyBlock {
constructor() {
this._type = 0;
this._propertyMap = {};
}
_checkPropertyLegal(vertexElementFormat, propertyName, attributeLocation, prob) {
var vecDec = prob._vertexDeclaration;
if (vecDec._vertexElements[0]._elementFormat !== vertexElementFormat)
throw "Data exists and format does not match";
if (prob._name !== propertyName)
throw "You cannot add a new property to an existing attributeLocation,Please use another attributeLocation";
}
_creatProperty(attributeName, arrays, vertexStride, vertexformat, attributeLocation) {
var prob = this._propertyMap[attributeLocation] = new MaterialInstanceProperty();
prob._name = attributeName;
prob._value = arrays;
prob._vertexDeclaration = new VertexDeclaration(vertexStride, [new VertexElement(0, vertexformat, attributeLocation)]);
prob._isNeedUpdate = true;
prob._vertexStride = vertexStride / 4;
prob.createInstanceVertexBuffer3D();
}
setVectorArray(attributeName, arrays, attributeLocation) {
var prob = this._propertyMap[attributeLocation];
if (prob) {
this._checkPropertyLegal(VertexElementFormat.Vector4, attributeName, attributeLocation, prob);
prob._value = arrays;
prob._isNeedUpdate = true;
}
else
this._creatProperty(attributeName, arrays, 16, VertexElementFormat.Vector4, attributeLocation);
}
setVector3Array(attributeName, arrays, attributeLocation) {
var prob = this._propertyMap[attributeLocation];
if (prob) {
this._checkPropertyLegal(VertexElementFormat.Vector3, attributeName, attributeLocation, prob);
prob._value = arrays;
prob._isNeedUpdate = true;
}
else
this._creatProperty(attributeName, arrays, 12, VertexElementFormat.Vector3, attributeLocation);
}
setVector2Array(attributeName, arrays, attributeLocation) {
var prob = this._propertyMap[attributeLocation];
if (prob) {
this._checkPropertyLegal(VertexElementFormat.Vector2, attributeName, attributeLocation, prob);
prob._value = arrays;
prob._isNeedUpdate = true;
}
else
this._creatProperty(attributeName, arrays, 8, VertexElementFormat.Vector2, attributeLocation);
}
setNumberArray(attributeName, arrays, attributeLocation) {
var prob = this._propertyMap[attributeLocation];
if (prob) {
this._checkPropertyLegal(VertexElementFormat.Single, attributeName, attributeLocation, prob);
prob._value = arrays;
prob._isNeedUpdate = true;
}
else
this._creatProperty(attributeName, arrays, 4, VertexElementFormat.Single, attributeLocation);
}
getPropertyArray(attributeLocation) {
var prob = this._propertyMap[attributeLocation];
return prob ? prob._value : null;
}
clear() {
this._propertyMap = {};
}
}
MaterialInstancePropertyBlock.INSTANCETYPE_ATTRIBUTE = 0;
MaterialInstancePropertyBlock.INSTANCETYPE_UNIFORMBUFFER = 1;
class ConchVector4 {
constructor(x = 0, y = 0, z = 0, w = 0) {
var v = this.elements = new Float32Array(4);
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
}
get x() {
return this.elements[0];
}
set x(value) {
this.elements[0] = value;
}
get y() {
return this.elements[1];
}
set y(value) {
this.elements[1] = value;
}
get z() {
return this.elements[2];
}
set z(value) {
this.elements[2] = value;
}
get w() {
return this.elements[3];
}
set w(value) {
this.elements[3] = value;
}
fromArray(array, offset = 0) {
this.elements[0] = array[offset + 0];
this.elements[1] = array[offset + 1];
this.elements[2] = array[offset + 2];
this.elements[3] = array[offset + 3];
}
cloneTo(destObject) {
var destVector4 = destObject;
var destE = destVector4.elements;
var s = this.elements;
destE[0] = s[0];
destE[1] = s[1];
destE[2] = s[2];
destE[3] = s[3];
}
clone() {
var destVector4 = new ConchVector4();
this.cloneTo(destVector4);
return destVector4;
}
static lerp(a, b, t, out) {
var e = out.elements;
var f = a.elements;
var g = b.elements;
var ax = f[0], ay = f[1], az = f[2], aw = f[3];
e[0] = ax + t * (g[0] - ax);
e[1] = ay + t * (g[1] - ay);
e[2] = az + t * (g[2] - az);
e[3] = aw + t * (g[3] - aw);
}
static transformByM4x4(vector4, m4x4, out) {
var ve = vector4.elements;
var vx = ve[0];
var vy = ve[1];
var vz = ve[2];
var vw = ve[3];
var me = m4x4.elements;
var oe = out.elements;
oe[0] = vx * me[0] + vy * me[4] + vz * me[8] + vw * me[12];
oe[1] = vx * me[1] + vy * me[5] + vz * me[9] + vw * me[13];
oe[2] = vx * me[2] + vy * me[6] + vz * me[10] + vw * me[14];
oe[3] = vx * me[3] + vy * me[7] + vz * me[11] + vw * me[15];
}
static equals(a, b) {
var ae = a.elements;
var be = b.elements;
return MathUtils3D.nearEqual(Math.abs(ae[0]), Math.abs(be[0])) && MathUtils3D.nearEqual(Math.abs(ae[1]), Math.abs(be[1])) && MathUtils3D.nearEqual(Math.abs(ae[2]), Math.abs(be[2])) && MathUtils3D.nearEqual(Math.abs(ae[3]), Math.abs(be[3]));
}
length() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
}
lengthSquared() {
return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
}
static normalize(s, out) {
var se = s.elements;
var oe = out.elements;
var len = s.length();
if (len > 0) {
oe[0] = se[0] * len;
oe[1] = se[1] * len;
oe[2] = se[2] * len;
oe[3] = se[3] * len;
}
}
static add(a, b, out) {
var oe = out.elements;
var ae = a.elements;
var be = b.elements;
oe[0] = ae[0] + be[0];
oe[1] = ae[1] + be[1];
oe[2] = ae[2] + be[2];
oe[3] = ae[3] + be[3];
}
static subtract(a, b, out) {
var oe = out.elements;
var ae = a.elements;
var be = b.elements;
oe[0] = ae[0] - be[0];
oe[1] = ae[1] - be[1];
oe[2] = ae[2] - be[2];
oe[3] = ae[3] - be[3];
}
static multiply(a, b, out) {
var oe = out.elements;
var ae = a.elements;
var be = b.elements;
oe[0] = ae[0] * be[0];
oe[1] = ae[1] * be[1];
oe[2] = ae[2] * be[2];
oe[3] = ae[3] * be[3];
}
static scale(a, b, out) {
var oe = out.elements;
var ae = a.elements;
oe[0] = ae[0] * b;
oe[1] = ae[1] * b;
oe[2] = ae[2] * b;
oe[3] = ae[3] * b;
}
static Clamp(value, min, max, out) {
var valuee = value.elements;
var x = valuee[0];
var y = valuee[1];
var z = valuee[2];
var w = valuee[3];
var mine = min.elements;
var mineX = mine[0];
var mineY = mine[1];
var mineZ = mine[2];
var mineW = mine[3];
var maxe = max.elements;
var maxeX = maxe[0];
var maxeY = maxe[1];
var maxeZ = maxe[2];
var maxeW = maxe[3];
var oute = out.elements;
x = (x > maxeX) ? maxeX : x;
x = (x < mineX) ? mineX : x;
y = (y > maxeY) ? maxeY : y;
y = (y < mineY) ? mineY : y;
z = (z > maxeZ) ? maxeZ : z;
z = (z < mineZ) ? mineZ : z;
w = (w > maxeW) ? maxeW : w;
w = (w < mineW) ? mineW : w;
oute[0] = x;
oute[1] = y;
oute[2] = z;
oute[3] = w;
}
static distanceSquared(value1, value2) {
var value1e = value1.elements;
var value2e = value2.elements;
var x = value1e[0] - value2e[0];
var y = value1e[1] - value2e[1];
var z = value1e[2] - value2e[2];
var w = value1e[3] - value2e[3];
return (x * x) + (y * y) + (z * z) + (w * w);
}
static distance(value1, value2) {
var value1e = value1.elements;
var value2e = value2.elements;
var x = value1e[0] - value2e[0];
var y = value1e[1] - value2e[1];
var z = value1e[2] - value2e[2];
var w = value1e[3] - value2e[3];
return Math.sqrt((x * x) + (y * y) + (z * z) + (w * w));
}
static dot(a, b) {
var ae = a.elements;
var be = b.elements;
var r = (ae[0] * be[0]) + (ae[1] * be[1]) + (ae[2] * be[2]) + (ae[3] * be[3]);
return r;
}
static min(a, b, out) {
var e = out.elements;
var f = a.elements;
var g = b.elements;
e[0] = Math.min(f[0], g[0]);
e[1] = Math.min(f[1], g[1]);
e[2] = Math.min(f[2], g[2]);
e[3] = Math.min(f[3], g[3]);
}
static max(a, b, out) {
var e = out.elements;
var f = a.elements;
var g = b.elements;
e[0] = Math.max(f[0], g[0]);
e[1] = Math.max(f[1], g[1]);
e[2] = Math.max(f[2], g[2]);
e[3] = Math.max(f[3], g[3]);
}
}
ConchVector4.ZERO = new ConchVector4();
ConchVector4.ONE = new ConchVector4(1.0, 1.0, 1.0, 1.0);
ConchVector4.UnitX = new ConchVector4(1.0, 0.0, 0.0, 0.0);
ConchVector4.UnitY = new ConchVector4(0.0, 1.0, 0.0, 0.0);
ConchVector4.UnitZ = new ConchVector4(0.0, 0.0, 1.0, 0.0);
ConchVector4.UnitW = new ConchVector4(0.0, 0.0, 0.0, 1.0);
class ConchVector3 {
constructor(x = 0, y = 0, z = 0, nativeElements = null) {
var v;
if (nativeElements) {
v = nativeElements;
}
else {
v = new Float32Array(3);
}
this.elements = v;
v[0] = x;
v[1] = y;
v[2] = z;
}
static distanceSquared(value1, value2) {
var value1e = value1.elements;
var value2e = value2.elements;
var x = value1e[0] - value2e[0];
var y = value1e[1] - value2e[1];
var z = value1e[2] - value2e[2];
return (x * x) + (y * y) + (z * z);
}
static distance(value1, value2) {
var value1e = value1.elements;
var value2e = value2.elements;
var x = value1e[0] - value2e[0];
var y = value1e[1] - value2e[1];
var z = value1e[2] - value2e[2];
return Math.sqrt((x * x) + (y * y) + (z * z));
}
static min(a, b, out) {
var e = out.elements;
var f = a.elements;
var g = b.elements;
e[0] = Math.min(f[0], g[0]);
e[1] = Math.min(f[1], g[1]);
e[2] = Math.min(f[2], g[2]);
}
static max(a, b, out) {
var e = out.elements;
var f = a.elements;
var g = b.elements;
e[0] = Math.max(f[0], g[0]);
e[1] = Math.max(f[1], g[1]);
e[2] = Math.max(f[2], g[2]);
}
static transformQuat(source, rotation, out) {
var destination = out.elements;
var se = source.elements;
var re = rotation.elements;
var x = se[0], y = se[1], z = se[2], qx = re[0], qy = re[1], qz = re[2], qw = re[3], ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z;
destination[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
destination[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
destination[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
}
static scalarLength(a) {
var f = a.elements;
var x = f[0], y = f[1], z = f[2];
return Math.sqrt(x * x + y * y + z * z);
}
static scalarLengthSquared(a) {
var f = a.elements;
var x = f[0], y = f[1], z = f[2];
return x * x + y * y + z * z;
}
static normalize(s, out) {
var se = s.elements;
var oe = out.elements;
var x = se[0], y = se[1], z = se[2];
var len = x * x + y * y + z * z;
if (len > 0) {
len = 1 / Math.sqrt(len);
oe[0] = se[0] * len;
oe[1] = se[1] * len;
oe[2] = se[2] * len;
}
}
static multiply(a, b, out) {
var e = out.elements;
var f = a.elements;
var g = b.elements;
e[0] = f[0] * g[0];
e[1] = f[1] * g[1];
e[2] = f[2] * g[2];
}
static scale(a, b, out) {
var e = out.elements;
var f = a.elements;
e[0] = f[0] * b;
e[1] = f[1] * b;
e[2] = f[2] * b;
}
static lerp(a, b, t, out) {
var e = out.elements;
var f = a.elements;
var g = b.elements;
var ax = f[0], ay = f[1], az = f[2];
e[0] = ax + t * (g[0] - ax);
e[1] = ay + t * (g[1] - ay);
e[2] = az + t * (g[2] - az);
}
static transformV3ToV3(vector, transform, result) {
var intermediate = ConchVector3._tempVector4;
ConchVector3.transformV3ToV4(vector, transform, intermediate);
var intermediateElem = intermediate.elements;
var resultElem = result.elements;
resultElem[0] = intermediateElem[0];
resultElem[1] = intermediateElem[1];
resultElem[2] = intermediateElem[2];
}
static transformV3ToV4(vector, transform, result) {
var vectorElem = vector.elements;
var vectorX = vectorElem[0];
var vectorY = vectorElem[1];
var vectorZ = vectorElem[2];
var transformElem = transform.elements;
var resultElem = result.elements;
resultElem[0] = (vectorX * transformElem[0]) + (vectorY * transformElem[4]) + (vectorZ * transformElem[8]) + transformElem[12];
resultElem[1] = (vectorX * transformElem[1]) + (vectorY * transformElem[5]) + (vectorZ * transformElem[9]) + transformElem[13];
resultElem[2] = (vectorX * transformElem[2]) + (vectorY * transformElem[6]) + (vectorZ * transformElem[10]) + transformElem[14];
resultElem[3] = (vectorX * transformElem[3]) + (vectorY * transformElem[7]) + (vectorZ * transformElem[11]) + transformElem[15];
}
static TransformNormal(normal, transform, result) {
var normalElem = normal.elements;
var normalX = normalElem[0];
var normalY = normalElem[1];
var normalZ = normalElem[2];
var transformElem = transform.elements;
var resultElem = result.elements;
resultElem[0] = (normalX * transformElem[0]) + (normalY * transformElem[4]) + (normalZ * transformElem[8]);
resultElem[1] = (normalX * transformElem[1]) + (normalY * transformElem[5]) + (normalZ * transformElem[9]);
resultElem[2] = (normalX * transformElem[2]) + (normalY * transformElem[6]) + (normalZ * transformElem[10]);
}
static transformCoordinate(coordinate, transform, result) {
var coordinateElem = coordinate.elements;
var coordinateX = coordinateElem[0];
var coordinateY = coordinateElem[1];
var coordinateZ = coordinateElem[2];
var transformElem = transform.elements;
var w = ((coordinateX * transformElem[3]) + (coordinateY * transformElem[7]) + (coordinateZ * transformElem[11]) + transformElem[15]);
var resultElem = result.elements;
resultElem[0] = (coordinateX * transformElem[0]) + (coordinateY * transformElem[4]) + (coordinateZ * transformElem[8]) + transformElem[12] / w;
resultElem[1] = (coordinateX * transformElem[1]) + (coordinateY * transformElem[5]) + (coordinateZ * transformElem[9]) + transformElem[13] / w;
resultElem[2] = (coordinateX * transformElem[2]) + (coordinateY * transformElem[6]) + (coordinateZ * transformElem[10]) + transformElem[14] / w;
}
static Clamp(value, min, max, out) {
var valuee = value.elements;
var x = valuee[0];
var y = valuee[1];
var z = valuee[2];
var mine = min.elements;
var mineX = mine[0];
var mineY = mine[1];
var mineZ = mine[2];
var maxe = max.elements;
var maxeX = maxe[0];
var maxeY = maxe[1];
var maxeZ = maxe[2];
var oute = out.elements;
x = (x > maxeX) ? maxeX : x;
x = (x < mineX) ? mineX : x;
y = (y > maxeY) ? maxeY : y;
y = (y < mineY) ? mineY : y;
z = (z > maxeZ) ? maxeZ : z;
z = (z < mineZ) ? mineZ : z;
oute[0] = x;
oute[1] = y;
oute[2] = z;
}
static add(a, b, out) {
var e = out.elements;
var f = a.elements;
var g = b.elements;
e[0] = f[0] + g[0];
e[1] = f[1] + g[1];
e[2] = f[2] + g[2];
}
static subtract(a, b, o) {
var oe = o.elements;
var ae = a.elements;
var be = b.elements;
oe[0] = ae[0] - be[0];
oe[1] = ae[1] - be[1];
oe[2] = ae[2] - be[2];
}
static cross(a, b, o) {
var ae = a.elements;
var be = b.elements;
var oe = o.elements;
var ax = ae[0], ay = ae[1], az = ae[2], bx = be[0], by = be[1], bz = be[2];
oe[0] = ay * bz - az * by;
oe[1] = az * bx - ax * bz;
oe[2] = ax * by - ay * bx;
}
static dot(a, b) {
var ae = a.elements;
var be = b.elements;
var r = (ae[0] * be[0]) + (ae[1] * be[1]) + (ae[2] * be[2]);
return r;
}
static equals(a, b) {
var ae = a.elements;
var be = b.elements;
return MathUtils3D.nearEqual(ae[0], be[0]) && MathUtils3D.nearEqual(ae[1], be[1]) && MathUtils3D.nearEqual(ae[2], be[2]);
}
get x() {
return this.elements[0];
}
set x(value) {
this.elements[0] = value;
}
get y() {
return this.elements[1];
}
set y(value) {
this.elements[1] = value;
}
get z() {
return this.elements[2];
}
set z(value) {
this.elements[2] = value;
}
setValue(x, y, z) {
this.elements[0] = x;
this.elements[1] = y;
this.elements[2] = z;
}
fromArray(array, offset = 0) {
this.elements[0] = array[offset + 0];
this.elements[1] = array[offset + 1];
this.elements[2] = array[offset + 2];
}
cloneTo(destObject) {
var destVector3 = destObject;
var destE = destVector3.elements;
var s = this.elements;
destE[0] = s[0];
destE[1] = s[1];
destE[2] = s[2];
}
clone() {
var destVector3 = new ConchVector3();
this.cloneTo(destVector3);
return destVector3;
}
toDefault() {
this.elements[0] = 0;
this.elements[1] = 0;
this.elements[2] = 0;
}
}
ConchVector3._tempVector4 = new ConchVector4();
ConchVector3.ZERO = new ConchVector3(0.0, 0.0, 0.0);
ConchVector3.ONE = new ConchVector3(1.0, 1.0, 1.0);
ConchVector3.NegativeUnitX = new ConchVector3(-1, 0, 0);
ConchVector3.UnitX = new ConchVector3(1, 0, 0);
ConchVector3.UnitY = new ConchVector3(0, 1, 0);
ConchVector3.UnitZ = new ConchVector3(0, 0, 1);
ConchVector3.ForwardRH = new ConchVector3(0, 0, -1);
ConchVector3.ForwardLH = new ConchVector3(0, 0, 1);
ConchVector3.Up = new ConchVector3(0, 1, 0);
ConchVector3.NAN = new ConchVector3(NaN, NaN, NaN);
class ConchQuaternion {
constructor(x = 0, y = 0, z = 0, w = 1, nativeElements = null) {
var v;
if (nativeElements) {
v = nativeElements;
}
else {
v = new Float32Array(4);
}
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
this.elements = v;
}
static _dotArray(l, r) {
return l[0] * r[0] + l[1] * r[1] + l[2] * r[2] + l[3] * r[3];
}
static _normalizeArray(f, o) {
var x = f[0], y = f[1], z = f[2], w = f[3];
var len = x * x + y * y + z * z + w * w;
if (len > 0) {
len = 1 / Math.sqrt(len);
o[0] = x * len;
o[1] = y * len;
o[2] = z * len;
o[3] = w * len;
}
}
static _lerpArray(l, r, amount, o) {
var inverse = 1.0 - amount;
if (ConchQuaternion._dotArray(l, r) >= 0) {
o[0] = (inverse * l[0]) + (amount * r[0]);
o[1] = (inverse * l[1]) + (amount * r[1]);
o[2] = (inverse * l[2]) + (amount * r[2]);
o[3] = (inverse * l[3]) + (amount * r[3]);
}
else {
o[0] = (inverse * l[0]) - (amount * r[0]);
o[1] = (inverse * l[1]) - (amount * r[1]);
o[2] = (inverse * l[2]) - (amount * r[2]);
o[3] = (inverse * l[3]) - (amount * r[3]);
}
ConchQuaternion._normalizeArray(o, o);
}
static createFromYawPitchRoll(yaw, pitch, roll, out) {
var halfRoll = roll * 0.5;
var halfPitch = pitch * 0.5;
var halfYaw = yaw * 0.5;
var sinRoll = Math.sin(halfRoll);
var cosRoll = Math.cos(halfRoll);
var sinPitch = Math.sin(halfPitch);
var cosPitch = Math.cos(halfPitch);
var sinYaw = Math.sin(halfYaw);
var cosYaw = Math.cos(halfYaw);
var oe = out.elements;
oe[0] = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);
oe[1] = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);
oe[2] = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);
oe[3] = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);
}
static multiply(left, right, out) {
var le = left.elements;
var re = right.elements;
var oe = out.elements;
var lx = le[0];
var ly = le[1];
var lz = le[2];
var lw = le[3];
var rx = re[0];
var ry = re[1];
var rz = re[2];
var rw = re[3];
var a = (ly * rz - lz * ry);
var b = (lz * rx - lx * rz);
var c = (lx * ry - ly * rx);
var d = (lx * rx + ly * ry + lz * rz);
oe[0] = (lx * rw + rx * lw) + a;
oe[1] = (ly * rw + ry * lw) + b;
oe[2] = (lz * rw + rz * lw) + c;
oe[3] = lw * rw - d;
}
static arcTanAngle(x, y) {
if (x == 0) {
if (y == 1)
return Math.PI / 2;
return -Math.PI / 2;
}
if (x > 0)
return Math.atan(y / x);
if (x < 0) {
if (y > 0)
return Math.atan(y / x) + Math.PI;
return Math.atan(y / x) - Math.PI;
}
return 0;
}
static angleTo(from, location, angle) {
ConchVector3.subtract(location, from, ConchQuaternion.TEMPVector30);
ConchVector3.normalize(ConchQuaternion.TEMPVector30, ConchQuaternion.TEMPVector30);
angle.elements[0] = Math.asin(ConchQuaternion.TEMPVector30.y);
angle.elements[1] = ConchQuaternion.arcTanAngle(-ConchQuaternion.TEMPVector30.z, -ConchQuaternion.TEMPVector30.x);
}
static createFromAxisAngle(axis, rad, out) {
var e = out.elements;
var f = axis.elements;
rad = rad * 0.5;
var s = Math.sin(rad);
e[0] = s * f[0];
e[1] = s * f[1];
e[2] = s * f[2];
e[3] = Math.cos(rad);
}
static createFromMatrix3x3(sou, out) {
var e = out.elements;
var f = sou.elements;
var fTrace = f[0] + f[4] + f[8];
var fRoot;
if (fTrace > 0.0) {
fRoot = Math.sqrt(fTrace + 1.0);
e[3] = 0.5 * fRoot;
fRoot = 0.5 / fRoot;
e[0] = (f[5] - f[7]) * fRoot;
e[1] = (f[6] - f[2]) * fRoot;
e[2] = (f[1] - f[3]) * fRoot;
}
else {
var i = 0;
if (f[4] > f[0])
i = 1;
if (f[8] > f[i * 3 + i])
i = 2;
var j = (i + 1) % 3;
var k = (i + 2) % 3;
fRoot = Math.sqrt(f[i * 3 + i] - f[j * 3 + j] - f[k * 3 + k] + 1.0);
e[i] = 0.5 * fRoot;
fRoot = 0.5 / fRoot;
e[3] = (f[j * 3 + k] - f[k * 3 + j]) * fRoot;
e[j] = (f[j * 3 + i] + f[i * 3 + j]) * fRoot;
e[k] = (f[k * 3 + i] + f[i * 3 + k]) * fRoot;
}
return;
}
static createFromMatrix4x4(mat, out) {
var me = mat.elements;
var oe = out.elements;
var sqrt;
var half;
var scale = me[0] + me[5] + me[10];
if (scale > 0.0) {
sqrt = Math.sqrt(scale + 1.0);
oe[3] = sqrt * 0.5;
sqrt = 0.5 / sqrt;
oe[0] = (me[6] - me[9]) * sqrt;
oe[1] = (me[8] - me[2]) * sqrt;
oe[2] = (me[1] - me[4]) * sqrt;
}
else if ((me[0] >= me[5]) && (me[0] >= me[10])) {
sqrt = Math.sqrt(1.0 + me[0] - me[5] - me[10]);
half = 0.5 / sqrt;
oe[0] = 0.5 * sqrt;
oe[1] = (me[1] + me[4]) * half;
oe[2] = (me[2] + me[8]) * half;
oe[3] = (me[6] - me[9]) * half;
}
else if (me[5] > me[10]) {
sqrt = Math.sqrt(1.0 + me[5] - me[0] - me[10]);
half = 0.5 / sqrt;
oe[0] = (me[4] + me[1]) * half;
oe[1] = 0.5 * sqrt;
oe[2] = (me[9] + me[6]) * half;
oe[3] = (me[8] - me[2]) * half;
}
else {
sqrt = Math.sqrt(1.0 + me[10] - me[0] - me[5]);
half = 0.5 / sqrt;
oe[0] = (me[8] + me[2]) * half;
oe[1] = (me[9] + me[6]) * half;
oe[2] = 0.5 * sqrt;
oe[3] = (me[1] - me[4]) * half;
}
}
static slerp(left, right, t, out) {
var a = left.elements;
var b = right.elements;
var oe = out.elements;
var ax = a[0], ay = a[1], az = a[2], aw = a[3], bx = b[0], by = b[1], bz = b[2], bw = b[3];
var omega, cosom, sinom, scale0, scale1;
cosom = ax * bx + ay * by + az * bz + aw * bw;
if (cosom < 0.0) {
cosom = -cosom;
bx = -bx;
by = -by;
bz = -bz;
bw = -bw;
}
if ((1.0 - cosom) > 0.000001) {
omega = Math.acos(cosom);
sinom = Math.sin(omega);
scale0 = Math.sin((1.0 - t) * omega) / sinom;
scale1 = Math.sin(t * omega) / sinom;
}
else {
scale0 = 1.0 - t;
scale1 = t;
}
oe[0] = scale0 * ax + scale1 * bx;
oe[1] = scale0 * ay + scale1 * by;
oe[2] = scale0 * az + scale1 * bz;
oe[3] = scale0 * aw + scale1 * bw;
return oe;
}
static lerp(left, right, amount, out) {
ConchQuaternion._lerpArray(left.elements, right.elements, amount, out.elements);
}
static add(left, right, out) {
var e = out.elements;
var f = left.elements;
var g = right.elements;
e[0] = f[0] + g[0];
e[1] = f[1] + g[1];
e[2] = f[2] + g[2];
e[3] = f[3] + g[3];
}
static dot(left, right) {
return ConchQuaternion._dotArray(left.elements, right.elements);
}
get x() {
return this.elements[0];
}
set x(value) {
this.elements[0] = value;
}
get y() {
return this.elements[1];
}
set y(value) {
this.elements[1] = value;
}
get z() {
return this.elements[2];
}
set z(value) {
this.elements[2] = value;
}
get w() {
return this.elements[3];
}
set w(value) {
this.elements[3] = value;
}
scaling(scaling, out) {
var e = out.elements;
var f = this.elements;
e[0] = f[0] * scaling;
e[1] = f[1] * scaling;
e[2] = f[2] * scaling;
e[3] = f[3] * scaling;
}
normalize(out) {
ConchQuaternion._normalizeArray(this.elements, out.elements);
}
length() {
var f = this.elements;
var x = f[0], y = f[1], z = f[2], w = f[3];
return Math.sqrt(x * x + y * y + z * z + w * w);
}
rotateX(rad, out) {
var e = out.elements;
var f = this.elements;
rad *= 0.5;
var ax = f[0], ay = f[1], az = f[2], aw = f[3];
var bx = Math.sin(rad), bw = Math.cos(rad);
e[0] = ax * bw + aw * bx;
e[1] = ay * bw + az * bx;
e[2] = az * bw - ay * bx;
e[3] = aw * bw - ax * bx;
}
rotateY(rad, out) {
var e = out.elements;
var f = this.elements;
rad *= 0.5;
var ax = f[0], ay = f[1], az = f[2], aw = f[3], by = Math.sin(rad), bw = Math.cos(rad);
e[0] = ax * bw - az * by;
e[1] = ay * bw + aw * by;
e[2] = az * bw + ax * by;
e[3] = aw * bw - ay * by;
}
rotateZ(rad, out) {
var e = out.elements;
var f = this.elements;
rad *= 0.5;
var ax = f[0], ay = f[1], az = f[2], aw = f[3], bz = Math.sin(rad), bw = Math.cos(rad);
e[0] = ax * bw + ay * bz;
e[1] = ay * bw - ax * bz;
e[2] = az * bw + aw * bz;
e[3] = aw * bw - az * bz;
}
getYawPitchRoll(out) {
ConchVector3.transformQuat(ConchVector3.ForwardRH, this, ConchQuaternion.TEMPVector31);
ConchVector3.transformQuat(ConchVector3.Up, this, ConchQuaternion.TEMPVector32);
var upe = ConchQuaternion.TEMPVector32.elements;
ConchQuaternion.angleTo(ConchVector3.ZERO, ConchQuaternion.TEMPVector31, ConchQuaternion.TEMPVector33);
var anglee = ConchQuaternion.TEMPVector33.elements;
if (anglee[0] == Math.PI / 2) {
anglee[1] = ConchQuaternion.arcTanAngle(upe[2], upe[0]);
anglee[2] = 0;
}
else if (anglee[0] == -Math.PI / 2) {
anglee[1] = ConchQuaternion.arcTanAngle(-upe[2], -upe[0]);
anglee[2] = 0;
}
else {
Matrix4x4.createRotationY(-anglee[1], ConchQuaternion.TEMPMatrix0);
Matrix4x4.createRotationX(-anglee[0], ConchQuaternion.TEMPMatrix1);
ConchVector3.transformCoordinate(ConchQuaternion.TEMPVector32, ConchQuaternion.TEMPMatrix0, ConchQuaternion.TEMPVector32);
ConchVector3.transformCoordinate(ConchQuaternion.TEMPVector32, ConchQuaternion.TEMPMatrix1, ConchQuaternion.TEMPVector32);
anglee[2] = ConchQuaternion.arcTanAngle(upe[1], -upe[0]);
}
if (anglee[1] <= -Math.PI)
anglee[1] = Math.PI;
if (anglee[2] <= -Math.PI)
anglee[2] = Math.PI;
if (anglee[1] >= Math.PI && anglee[2] >= Math.PI) {
anglee[1] = 0;
anglee[2] = 0;
anglee[0] = Math.PI - anglee[0];
}
var oe = out.elements;
oe[0] = anglee[1];
oe[1] = anglee[0];
oe[2] = anglee[2];
}
invert(out) {
var e = out.elements;
var f = this.elements;
var a0 = f[0], a1 = f[1], a2 = f[2], a3 = f[3];
var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
var invDot = dot ? 1.0 / dot : 0;
e[0] = -a0 * invDot;
e[1] = -a1 * invDot;
e[2] = -a2 * invDot;
e[3] = a3 * invDot;
}
identity() {
var e = this.elements;
e[0] = 0;
e[1] = 0;
e[2] = 0;
e[3] = 1;
}
fromArray(array, offset = 0) {
this.elements[0] = array[offset + 0];
this.elements[1] = array[offset + 1];
this.elements[2] = array[offset + 2];
this.elements[3] = array[offset + 3];
}
cloneTo(destObject) {
var i, s, d;
s = this.elements;
d = destObject.elements;
if (s === d) {
return;
}
for (i = 0; i < 4; ++i) {
d[i] = s[i];
}
}
clone() {
var dest = new ConchQuaternion();
this.cloneTo(dest);
return dest;
}
equals(b) {
var ae = this.elements;
var be = b.elements;
return MathUtils3D.nearEqual(ae[0], be[0]) && MathUtils3D.nearEqual(ae[1], be[1]) && MathUtils3D.nearEqual(ae[2], be[2]) && MathUtils3D.nearEqual(ae[3], be[3]);
}
static rotationLookAt(forward, up, out) {
ConchQuaternion.lookAt(ConchVector3.ZERO, forward, up, out);
}
static lookAt(eye, target, up, out) {
Matrix3x3.lookAt(eye, target, up, ConchQuaternion._tempMatrix3x3);
ConchQuaternion.rotationMatrix(ConchQuaternion._tempMatrix3x3, out);
}
lengthSquared() {
var x = this.elements[0];
var y = this.elements[1];
var z = this.elements[2];
var w = this.elements[3];
return (x * x) + (y * y) + (z * z) + (w * w);
}
static invert(value, out) {
var vE = value.elements;
var oE = out.elements;
var lengthSq = value.lengthSquared();
if (!MathUtils3D.isZero(lengthSq)) {
lengthSq = 1.0 / lengthSq;
oE[0] = -vE[0] * lengthSq;
oE[1] = -vE[1] * lengthSq;
oE[2] = -vE[2] * lengthSq;
oE[3] = vE[3] * lengthSq;
}
}
static rotationMatrix(matrix3x3, out) {
var me = matrix3x3.elements;
var m11 = me[0];
var m12 = me[1];
var m13 = me[2];
var m21 = me[3];
var m22 = me[4];
var m23 = me[5];
var m31 = me[6];
var m32 = me[7];
var m33 = me[8];
var oe = out.elements;
var sqrt, half;
var scale = m11 + m22 + m33;
if (scale > 0) {
sqrt = Math.sqrt(scale + 1);
oe[3] = sqrt * 0.5;
sqrt = 0.5 / sqrt;
oe[0] = (m23 - m32) * sqrt;
oe[1] = (m31 - m13) * sqrt;
oe[2] = (m12 - m21) * sqrt;
}
else if ((m11 >= m22) && (m11 >= m33)) {
sqrt = Math.sqrt(1 + m11 - m22 - m33);
half = 0.5 / sqrt;
oe[0] = 0.5 * sqrt;
oe[1] = (m12 + m21) * half;
oe[2] = (m13 + m31) * half;
oe[3] = (m23 - m32) * half;
}
else if (m22 > m33) {
sqrt = Math.sqrt(1 + m22 - m11 - m33);
half = 0.5 / sqrt;
oe[0] = (m21 + m12) * half;
oe[1] = 0.5 * sqrt;
oe[2] = (m32 + m23) * half;
oe[3] = (m31 - m13) * half;
}
else {
sqrt = Math.sqrt(1 + m33 - m11 - m22);
half = 0.5 / sqrt;
oe[0] = (m31 + m13) * half;
oe[1] = (m32 + m23) * half;
oe[2] = 0.5 * sqrt;
oe[3] = (m12 - m21) * half;
}
}
}
ConchQuaternion.TEMPVector30 = new ConchVector3();
ConchQuaternion.TEMPVector31 = new ConchVector3();
ConchQuaternion.TEMPVector32 = new ConchVector3();
ConchQuaternion.TEMPVector33 = new ConchVector3();
ConchQuaternion.TEMPMatrix0 = new Matrix4x4();
ConchQuaternion.TEMPMatrix1 = new Matrix4x4();
ConchQuaternion._tempMatrix3x3 = new Matrix3x3();
ConchQuaternion.DEFAULT = new ConchQuaternion();
ConchQuaternion.NAN = new ConchQuaternion(NaN, NaN, NaN, NaN);
class RandX {
constructor(seed) {
if (!(seed instanceof Array) || seed.length !== 4)
throw new Error('Rand:Seed must be an array with 4 numbers');
this._state0U = seed[0] | 0;
this._state0L = seed[1] | 0;
this._state1U = seed[2] | 0;
this._state1L = seed[3] | 0;
}
randomint() {
var s1U = this._state0U, s1L = this._state0L;
var s0U = this._state1U, s0L = this._state1L;
var sumL = (s0L >>> 0) + (s1L >>> 0);
var resU = (s0U + s1U + (sumL / 2 >>> 31)) >>> 0;
var resL = sumL >>> 0;
this._state0U = s0U;
this._state0L = s0L;
var t1U = 0, t1L = 0;
var t2U = 0, t2L = 0;
var a1 = 23;
var m1 = 0xFFFFFFFF << (32 - a1);
t1U = (s1U << a1) | ((s1L & m1) >>> (32 - a1));
t1L = s1L << a1;
s1U = s1U ^ t1U;
s1L = s1L ^ t1L;
t1U = s1U ^ s0U;
t1L = s1L ^ s0L;
var a2 = 18;
var m2 = 0xFFFFFFFF >>> (32 - a2);
t2U = s1U >>> a2;
t2L = (s1L >>> a2) | ((s1U & m2) << (32 - a2));
t1U = t1U ^ t2U;
t1L = t1L ^ t2L;
var a3 = 5;
var m3 = 0xFFFFFFFF >>> (32 - a3);
t2U = s0U >>> a3;
t2L = (s0L >>> a3) | ((s0U & m3) << (32 - a3));
t1U = t1U ^ t2U;
t1L = t1L ^ t2L;
this._state1U = t1U;
this._state1L = t1L;
return [resU, resL];
}
random() {
var t2 = this.randomint();
var t2U = t2[0];
var t2L = t2[1];
var eU = 0x3FF << (52 - 32);
var eL = 0;
var a1 = 12;
var m1 = 0xFFFFFFFF >>> (32 - a1);
var sU = t2U >>> a1;
var sL = (t2L >>> a1) | ((t2U & m1) << (32 - a1));
var xU = eU | sU;
var xL = eL | sL;
RandX._CONVERTION_BUFFER.setUint32(0, xU, false);
RandX._CONVERTION_BUFFER.setUint32(4, xL, false);
var d = RandX._CONVERTION_BUFFER.getFloat64(0, false);
return d - 1;
}
}
RandX._CONVERTION_BUFFER = new DataView(new ArrayBuffer(8));
RandX.defaultRand = new RandX([0, Date.now() / 65536, 0, Date.now() % 65536]);
class TextMesh {
constructor() {
}
get text() {
return this._text;
}
set text(value) {
this._text = value;
}
get fontSize() {
return this._fontSize;
}
set fontSize(value) {
this._fontSize = value;
}
get color() {
return this._color;
}
set color(value) {
this._color = value;
}
}
class Size {
constructor(width, height) {
this._width = 0;
this._height = 0;
this._width = width;
this._height = height;
}
static get fullScreen() {
return new Size(-1, -1);
}
get width() {
if (this._width === -1)
return RenderContext3D.clientWidth;
return this._width;
}
get height() {
if (this._height === -1)
return RenderContext3D.clientHeight;
return this._height;
}
}
exports.AlternateLightQueue = AlternateLightQueue;
exports.AnimationClip = AnimationClip;
exports.AnimationClipParser03 = AnimationClipParser03;
exports.AnimationClipParser04 = AnimationClipParser04;
exports.AnimationEvent = AnimationEvent;
exports.AnimationNode = AnimationNode;
exports.AnimationTransform3D = AnimationTransform3D;
exports.Animator = Animator;
exports.AnimatorControllerLayer = AnimatorControllerLayer;
exports.AnimatorPlayState = AnimatorPlayState;
exports.AnimatorState = AnimatorState;
exports.AnimatorStateScript = AnimatorStateScript;
exports.Avatar = Avatar;
exports.AvatarMask = AvatarMask;
exports.BaseCamera = BaseCamera;
exports.BaseMaterial = BaseMaterial;
exports.BaseRender = BaseRender;
exports.BaseShape = BaseShape;
exports.BatchMark = BatchMark;
exports.BlinnPhongMaterial = BlinnPhongMaterial;
exports.BlitScreenQuadCMD = BlitScreenQuadCMD;
exports.BloomEffect = BloomEffect;
exports.BoundBox = BoundBox;
exports.BoundFrustum = BoundFrustum;
exports.BoundSphere = BoundSphere;
exports.Bounds = Bounds;
exports.BoundsOctree = BoundsOctree;
exports.BoundsOctreeNode = BoundsOctreeNode;
exports.BoxShape = BoxShape;
exports.BufferState = BufferState;
exports.Burst = Burst;
exports.Camera = Camera;
exports.CameraCullInfo = CameraCullInfo;
exports.CastShadowList = CastShadowList;
exports.CircleShape = CircleShape;
exports.ClearRenderTextureCMD = ClearRenderTextureCMD;
exports.Cluster = Cluster;
exports.CollisionUtils = CollisionUtils;
exports.Color = Color;
exports.ColorOverLifetime = ColorOverLifetime;
exports.Command = Command;
exports.CommandBuffer = CommandBuffer;
exports.ConchQuaternion = ConchQuaternion;
exports.ConchVector3 = ConchVector3;
exports.ConchVector4 = ConchVector4;
exports.ConeShape = ConeShape;
exports.Config3D = Config3D;
exports.ContainmentType = ContainmentType;
exports.DefineDatas = DefineDatas;
exports.DepthPass = DepthPass;
exports.DirectionLight = DirectionLight;
exports.DrawMeshCMD = DrawMeshCMD;
exports.DrawMeshInstancedCMD = DrawMeshInstancedCMD;
exports.DrawRenderCMD = DrawRenderCMD;
exports.DynamicBatchManager = DynamicBatchManager;
exports.EffectMaterial = EffectMaterial;
exports.Emission = Emission;
exports.ExtendTerrainMaterial = ExtendTerrainMaterial;
exports.FloatKeyframe = FloatKeyframe;
exports.FrameOverTime = FrameOverTime;
exports.FrustumCulling = FrustumCulling;
exports.GeometryElement = GeometryElement;
exports.Gradient = Gradient;
exports.GradientAngularVelocity = GradientAngularVelocity;
exports.GradientColor = GradientColor;
exports.GradientDataInt = GradientDataInt;
exports.GradientDataNumber = GradientDataNumber;
exports.GradientDataVector2 = GradientDataVector2;
exports.GradientMode = GradientMode;
exports.GradientSize = GradientSize;
exports.GradientVelocity = GradientVelocity;
exports.HeightMap = HeightMap;
exports.HemisphereShape = HemisphereShape;
exports.ILaya3D = ILaya3D;
exports.IndexBuffer3D = IndexBuffer3D;
exports.Input3D = Input3D;
exports.Keyframe = Keyframe;
exports.KeyframeNode = KeyframeNode;
exports.KeyframeNodeList = KeyframeNodeList;
exports.KeyframeNodeOwner = KeyframeNodeOwner;
exports.Laya3D = Laya3D;
exports.LightQueue = LightQueue;
exports.LightSprite = LightSprite;
exports.Lightmap = Lightmap;
exports.LoadModelV04 = LoadModelV04;
exports.LoadModelV05 = LoadModelV05;
exports.Material = Material;
exports.MaterialInstanceProperty = MaterialInstanceProperty;
exports.MaterialInstancePropertyBlock = MaterialInstancePropertyBlock;
exports.MathUtils3D = MathUtils3D;
exports.Matrix3x3 = Matrix3x3;
exports.Matrix4x4 = Matrix4x4;
exports.Mesh = Mesh;
exports.MeshFilter = MeshFilter;
exports.MeshReader = MeshReader;
exports.MeshRenderDynamicBatchManager = MeshRenderDynamicBatchManager;
exports.MeshRenderStaticBatchManager = MeshRenderStaticBatchManager;
exports.MeshRenderer = MeshRenderer;
exports.MeshSprite3D = MeshSprite3D;
exports.MeshSprite3DShaderDeclaration = MeshSprite3DShaderDeclaration;
exports.MeshTerrainSprite3D = MeshTerrainSprite3D;
exports.MouseTouch = MouseTouch;
exports.OctreeMotionList = OctreeMotionList;
exports.PBRMaterial = PBRMaterial;
exports.PBRSpecularMaterial = PBRSpecularMaterial;
exports.PBRStandardMaterial = PBRStandardMaterial;
exports.Physics3D = Physics3D;
exports.Physics3DUtils = Physics3DUtils;
exports.Picker = Picker;
exports.PixelLineData = PixelLineData;
exports.PixelLineFilter = PixelLineFilter;
exports.PixelLineMaterial = PixelLineMaterial;
exports.PixelLineRenderer = PixelLineRenderer;
exports.PixelLineSprite3D = PixelLineSprite3D;
exports.PixelLineVertex = PixelLineVertex;
exports.Plane = Plane;
exports.PointLight = PointLight;
exports.PostProcess = PostProcess;
exports.PostProcessEffect = PostProcessEffect;
exports.PostProcessRenderContext = PostProcessRenderContext;
exports.PrimitiveMesh = PrimitiveMesh;
exports.Quaternion = Quaternion;
exports.QuaternionKeyframe = QuaternionKeyframe;
exports.Rand = Rand;
exports.RandX = RandX;
exports.Ray = Ray;
exports.ReflectionProbe = ReflectionProbe;
exports.ReflectionProbeList = ReflectionProbeList;
exports.ReflectionProbeManager = ReflectionProbeManager;
exports.RenderContext3D = RenderContext3D;
exports.RenderElement = RenderElement;
exports.RenderQueue = RenderQueue;
exports.RenderState = RenderState;
exports.RenderTexture = RenderTexture;
exports.RenderableSprite3D = RenderableSprite3D;
exports.RotationOverLifetime = RotationOverLifetime;
exports.Scene3D = Scene3D;
exports.Scene3DShaderDeclaration = Scene3DShaderDeclaration;
exports.Scene3DUtils = Scene3DUtils;
exports.ScreenQuad = ScreenQuad;
exports.ScreenTriangle = ScreenTriangle;
exports.Script3D = Script3D;
exports.SetGlobalShaderDataCMD = SetGlobalShaderDataCMD;
exports.SetRenderTargetCMD = SetRenderTargetCMD;
exports.SetShaderDataCMD = SetShaderDataCMD;
exports.Shader3D = Shader3D;
exports.ShaderData = ShaderData;
exports.ShaderDefine = ShaderDefine;
exports.ShaderInit3D = ShaderInit3D;
exports.ShaderInstance = ShaderInstance;
exports.ShaderPass = ShaderPass;
exports.ShaderVariable = ShaderVariable;
exports.ShaderVariant = ShaderVariant;
exports.ShaderVariantCollection = ShaderVariantCollection;
exports.ShadowCasterPass = ShadowCasterPass;
exports.ShadowCullInfo = ShadowCullInfo;
exports.ShadowSliceData = ShadowSliceData;
exports.ShadowSpotData = ShadowSpotData;
exports.ShadowUtils = ShadowUtils;
exports.ShapeUtils = ShapeUtils;
exports.ShuriKenParticle3D = ShuriKenParticle3D;
exports.ShuriKenParticle3DShaderDeclaration = ShuriKenParticle3DShaderDeclaration;
exports.ShurikenParticleData = ShurikenParticleData;
exports.ShurikenParticleMaterial = ShurikenParticleMaterial;
exports.ShurikenParticleRenderer = ShurikenParticleRenderer;
exports.ShurikenParticleSystem = ShurikenParticleSystem;
exports.SimpleSingletonList = SimpleSingletonList;
exports.SimpleSkinnedMeshRenderer = SimpleSkinnedMeshRenderer;
exports.SimpleSkinnedMeshSprite3D = SimpleSkinnedMeshSprite3D;
exports.SingletonList = SingletonList;
exports.Size = Size;
exports.SizeOverLifetime = SizeOverLifetime;
exports.SkinnedMeshRenderer = SkinnedMeshRenderer;
exports.SkinnedMeshSprite3D = SkinnedMeshSprite3D;
exports.SkinnedMeshSprite3DShaderDeclaration = SkinnedMeshSprite3DShaderDeclaration;
exports.SkyBox = SkyBox;
exports.SkyBoxMaterial = SkyBoxMaterial;
exports.SkyDome = SkyDome;
exports.SkyMesh = SkyMesh;
exports.SkyPanoramicMaterial = SkyPanoramicMaterial;
exports.SkyProceduralMaterial = SkyProceduralMaterial;
exports.SkyRenderer = SkyRenderer;
exports.SphereShape = SphereShape;
exports.SphericalHarmonicsL2 = SphericalHarmonicsL2;
exports.SpotLight = SpotLight;
exports.Sprite3D = Sprite3D;
exports.StartFrame = StartFrame;
exports.StaticBatchManager = StaticBatchManager;
exports.SubMesh = SubMesh;
exports.SubMeshDynamicBatch = SubMeshDynamicBatch;
exports.SubMeshInstanceBatch = SubMeshInstanceBatch;
exports.SubMeshRenderElement = SubMeshRenderElement;
exports.SubMeshStaticBatch = SubMeshStaticBatch;
exports.SubShader = SubShader;
exports.TextMesh = TextMesh;
exports.TextureCube = TextureCube;
exports.TextureGenerator = TextureGenerator;
exports.TextureMode = TextureMode;
exports.TextureSheetAnimation = TextureSheetAnimation;
exports.Touch = Touch;
exports.TrailFilter = TrailFilter;
exports.TrailGeometry = TrailGeometry;
exports.TrailMaterial = TrailMaterial;
exports.TrailRenderer = TrailRenderer;
exports.TrailSprite3D = TrailSprite3D;
exports.Transform3D = Transform3D;
exports.UnlitMaterial = UnlitMaterial;
exports.Utils3D = Utils3D;
exports.Vector2 = Vector2;
exports.Vector3 = Vector3;
exports.Vector3Keyframe = Vector3Keyframe;
exports.Vector4 = Vector4;
exports.VelocityOverLifetime = VelocityOverLifetime;
exports.VertexBuffer3D = VertexBuffer3D;
exports.VertexDeclaration = VertexDeclaration;
exports.VertexElement = VertexElement;
exports.VertexElementFormat = VertexElementFormat;
exports.VertexMesh = VertexMesh;
exports.VertexPositionTerrain = VertexPositionTerrain;
exports.VertexPositionTexture0 = VertexPositionTexture0;
exports.VertexShuriKenParticle = VertexShuriKenParticle;
exports.VertexShurikenParticleBillboard = VertexShurikenParticleBillboard;
exports.VertexShurikenParticleMesh = VertexShurikenParticleMesh;
exports.VertexTrail = VertexTrail;
exports.Viewport = Viewport;
exports.WaterPrimaryMaterial = WaterPrimaryMaterial;
exports.skinnedMatrixCache = skinnedMatrixCache;
}(window.Laya = window.Laya || {}, Laya));