littlejsengine 1.21.0 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -121,6 +121,32 @@ declare module "littlejsengine" {
121
121
  */
122
122
  renderPost?: () => void;
123
123
  };
124
+ /**
125
+ * The draw state's values, behind render3D's accessors, and the rgb emissiveMapColor had when it was set
126
+ */
127
+ export type Render3DDrawState = {
128
+ blend: boolean;
129
+ additive: boolean;
130
+ depthTest: boolean;
131
+ depthWrite: boolean;
132
+ cullBackFaces: boolean;
133
+ mirrored: boolean;
134
+ lighting: boolean;
135
+ emissive: number;
136
+ receiveShadow: boolean;
137
+ specular: number;
138
+ pixelated: boolean;
139
+ shader: Shader | undefined;
140
+ normalMap: TextureInfo | undefined;
141
+ normalScale: number;
142
+ shininess: number;
143
+ reflectivity: number;
144
+ emissiveMap: TextureInfo | undefined;
145
+ emissiveMapColor: Color;
146
+ emissiveR: number;
147
+ emissiveG: number;
148
+ emissiveB: number;
149
+ };
124
150
  /**
125
151
  * A particle as a ParticleEmitter3D's callbacks see it: one object the emitter reuses, set from the particle for each
126
152
  * call and written back after it, so copy what you keep
@@ -146,6 +172,11 @@ declare module "littlejsengine" {
146
172
  * - Seconds it lives
147
173
  */
148
174
  lifeTime: number;
175
+ /**
176
+ * - How much the emitter grows its effect, from its scale3D and its parents', as the 2D
177
+ * particle's scale
178
+ */
179
+ scale: number;
149
180
  /**
150
181
  * - Set by destroy
151
182
  */
@@ -2086,8 +2117,9 @@ declare module "littlejsengine" {
2086
2117
  * @param {boolean} [useWebGL] - Should use WebGL if available?
2087
2118
  * @param {boolean|Array<number>} [wrap] - Should the texture wrap (REPEAT) or clamp (CLAMP_TO_EDGE)? Or the WebGL
2088
2119
  * modes across and down, like [gl.CLAMP_TO_EDGE, gl.MIRRORED_REPEAT], as a glTF sampler gives them
2120
+ * @param {boolean} [pixelated] - Hard edged or smooth for this texture alone, undefined follows tilesPixelated
2089
2121
  */
2090
- constructor(image: HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap, useWebGL?: boolean, wrap?: boolean | Array<number>);
2122
+ constructor(image: HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap, useWebGL?: boolean, wrap?: boolean | Array<number>, pixelated?: boolean);
2091
2123
  /** @property {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas|ImageBitmap} - image source */
2092
2124
  image: OffscreenCanvas | ImageBitmap | HTMLCanvasElement | HTMLImageElement;
2093
2125
  /** @property {Vector2} - size of the image */
@@ -2101,6 +2133,10 @@ declare module "littlejsengine" {
2101
2133
  * across and down
2102
2134
  * @type {boolean|Array<number>} */
2103
2135
  wrap: boolean | Array<number>;
2136
+ /** @property {boolean|undefined} - Hard edged or smooth for this texture alone, a soft glow in a pixel art
2137
+ * game or pixel art in a smooth one; undefined follows tilesPixelated
2138
+ * @type {boolean|undefined} */
2139
+ pixelated: boolean | undefined;
2104
2140
  /** Creates the WebGL texture, updates if already created */
2105
2141
  createWebGLTexture(): void;
2106
2142
  /** Destroys the WebGL texture */
@@ -2112,6 +2148,10 @@ declare module "littlejsengine" {
2112
2148
  * @param {boolean|Array<number>} [wrap] - true for REPEAT, false for CLAMP_TO_EDGE, or the WebGL modes across
2113
2149
  * and down */
2114
2150
  setWrap(wrap?: boolean | Array<number>): void;
2151
+ /** Make this texture hard edged or smooth on its own, whatever tilesPixelated says for the rest; it is made again
2152
+ * with the new filtering
2153
+ * @param {boolean} [pixelated] - undefined follows tilesPixelated again */
2154
+ setPixelated(pixelated?: boolean): void;
2115
2155
  }
2116
2156
  /** Load a texture at a specific index after engineInit, the images passed to engineInit load this way
2117
2157
  * @param {number} textureIndex - Index to store the texture at, an unused one
@@ -2759,9 +2799,10 @@ declare module "littlejsengine" {
2759
2799
  * Restores the active texture when done
2760
2800
  * @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas|ImageBitmap} [image]
2761
2801
  * @param {boolean|Array<number>} [wrap] - true for REPEAT, false for CLAMP_TO_EDGE, or the WebGL modes across and down
2802
+ * @param {boolean} [pixelated] - Hard edged or smooth, undefined follows tilesPixelated
2762
2803
  * @return {WebGLTexture}
2763
2804
  * @memberof WebGL */
2764
- export function glCreateTexture(image?: HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap, wrap?: boolean | Array<number>): WebGLTexture;
2805
+ export function glCreateTexture(image?: HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap, wrap?: boolean | Array<number>, pixelated?: boolean): WebGLTexture;
2765
2806
  /** Deletes a WebGL texture
2766
2807
  * @param {WebGLTexture} [texture]
2767
2808
  * @memberof WebGL */
@@ -2769,8 +2810,9 @@ declare module "littlejsengine" {
2769
2810
  /** Set WebGL texture data from an image, restores the active texture when done
2770
2811
  * @param {WebGLTexture} texture
2771
2812
  * @param {HTMLImageElement|HTMLCanvasElement|OffscreenCanvas|ImageBitmap} image
2813
+ * @param {boolean} [pixelated] - Hard edged or smooth, undefined follows tilesPixelated
2772
2814
  * @memberof WebGL */
2773
- export function glSetTextureData(texture: WebGLTexture, image: HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap): void;
2815
+ export function glSetTextureData(texture: WebGLTexture, image: HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap, pixelated?: boolean): void;
2774
2816
  /** Draw all sprites and clear out the buffer, called automatically by the system whenever necessary
2775
2817
  * @memberof WebGL */
2776
2818
  export function glFlush(): void;
@@ -2783,6 +2825,17 @@ declare module "littlejsengine" {
2783
2825
  * @param {boolean} [antialias]
2784
2826
  * @memberof WebGL */
2785
2827
  export function glSetAntialias(antialias?: boolean): void;
2828
+ /** The largest texture this device makes, in pixels across, 0 until WebGL starts; at least 2048 with WebGL2
2829
+ * @type {number}
2830
+ * @memberof WebGL */
2831
+ export let glMaxTextureSize: number;
2832
+ /** A texture size this device can make: the size asked for, or the largest it supports when that is smaller
2833
+ * - The engine sizes the textures it makes itself through this, the shadow maps and the like, so a size a device
2834
+ * does not have falls back instead of failing
2835
+ * @param {number} size - Pixels across
2836
+ * @return {number}
2837
+ * @memberof WebGL */
2838
+ export function glClampTextureSize(size: number): number;
2786
2839
  /** Add a sprite to the gl draw list, used by all gl draw functions
2787
2840
  * @param {number} x
2788
2841
  * @param {number} y
@@ -3152,6 +3205,9 @@ declare module "littlejsengine" {
3152
3205
  constructor(asset?: string | URL | any[], randomness?: number, range?: number, taper?: number, onloadCallback?: SoundLoadCallback);
3153
3206
  /** @property {number} - World space max range of sound */
3154
3207
  range: number;
3208
+ /** @property {boolean} - No range was given, so it got soundDefaultRange; played in 3D such a sound is heard
3209
+ * to render3D.soundDefaultRange instead, which is further */
3210
+ rangeIsDefault: boolean;
3155
3211
  /** @property {number} - At what percentage of range should it start tapering */
3156
3212
  taper: number;
3157
3213
  /** @property {number} - How much to randomize frequency each time sound plays
@@ -3435,9 +3491,9 @@ declare module "littlejsengine" {
3435
3491
  * @param {number} [decay] - Decay time, how long to reach sustain after attack (seconds)
3436
3492
  * @param {number} [tremolo] - Trembling effect, rate controlled by repeat time (percent)
3437
3493
  * @param {number} [filter] - Filter cutoff frequency, positive for HPF, negative for LPF (Hz)
3438
- * @return {Array} - Array of audio samples
3494
+ * @return {Float32Array} - The audio samples
3439
3495
  * @memberof Audio */
3440
- export function zzfxG(volume?: number, randomness?: number, frequency?: number, attack?: number, sustain?: number, release?: number, shape?: number, shapeCurve?: number, slide?: number, deltaSlide?: number, pitchJump?: number, pitchJumpTime?: number, repeatTime?: number, noise?: number, modulation?: number, bitCrush?: number, delay?: number, sustainVolume?: number, decay?: number, tremolo?: number, filter?: number): any[];
3496
+ export function zzfxG(volume?: number, randomness?: number, frequency?: number, attack?: number, sustain?: number, release?: number, shape?: number, shapeCurve?: number, slide?: number, deltaSlide?: number, pitchJump?: number, pitchJumpTime?: number, repeatTime?: number, noise?: number, modulation?: number, bitCrush?: number, delay?: number, sustainVolume?: number, decay?: number, tremolo?: number, filter?: number): Float32Array;
3441
3497
  /**
3442
3498
  * LittleJS Object System
3443
3499
  * - EngineObject is the base class for all game objects
@@ -4119,6 +4175,13 @@ declare module "littlejsengine" {
4119
4175
  localSpace: boolean;
4120
4176
  /** @property {number} - If non zero the particle is drawn as a trail, stretched in the direction of velocity */
4121
4177
  trailScale: number;
4178
+ /** @property {number} - Grows the whole effect as each particle is born: the spawn area, the particles' sizes,
4179
+ * speed and fall, so it looks the same only bigger; 1 is as made, and a particle keeps the scale it was born
4180
+ * with, so a change never moves the ones already out */
4181
+ scale: number;
4182
+ /** @property {number} - The effect's own fall, added to each particle's velocity y every frame, on top of the
4183
+ * world's gravity times gravityScale; an effect that sets its own looks the same in any game */
4184
+ gravity: number;
4122
4185
  /** @property {ParticleCallback|undefined} - Callback when particle is created
4123
4186
  * @type {ParticleCallback|undefined} */
4124
4187
  particleCreateCallback: ParticleCallback | undefined;
@@ -4169,6 +4232,8 @@ declare module "littlejsengine" {
4169
4232
  constructor(emitter: ParticleEmitter, pos: Vector2, angle: number, colorStart: Color, colorEnd: Color, lifeTime: number, sizeStart: number, sizeEnd: number, velocity?: Vector2, angleVelocity?: number);
4170
4233
  /** @property {ParticleEmitter} - The emitter this particle came from */
4171
4234
  emitter: ParticleEmitter;
4235
+ /** @property {number} - The emitter's scale when it was made, which grows its fall */
4236
+ scale: number;
4172
4237
  /** @property {Vector2} - Position, world space or local to the emitter when localSpace is set */
4173
4238
  pos: Vector2;
4174
4239
  /** @property {number} - Angle in radians */
@@ -4487,6 +4552,8 @@ declare module "littlejsengine" {
4487
4552
  * new PostProcessPlugin(shaderCode);
4488
4553
  */
4489
4554
  constructor(shaderCode?: string, includeMainCanvas?: boolean, feedbackTexture?: boolean);
4555
+ /** @property {string} - The shadertoy style mainImage code it shades with, see setShaderCode */
4556
+ shaderCode: string;
4490
4557
  /** @property {WebGLProgram|undefined} - Shader for post processing
4491
4558
  * @type {WebGLProgram|undefined} */
4492
4559
  shader: WebGLProgram | undefined;
@@ -4499,6 +4566,10 @@ declare module "littlejsengine" {
4499
4566
  /** @property {WebGLVertexArrayObject|undefined} - Vertex array object
4500
4567
  * @type {WebGLVertexArrayObject|undefined} */
4501
4568
  vao: WebGLVertexArrayObject | undefined;
4569
+ /** Shade with new code from the next frame on, to switch effects while the game runs; the shader is made again
4570
+ * @param {string} [shaderCode] - Shadertoy style mainImage code, postProcessEffects builds it; none passes the
4571
+ * frame through */
4572
+ setShaderCode(shaderCode?: string): void;
4502
4573
  }
4503
4574
  /**
4504
4575
  * Set up post processing with a bloom effect, so bright colors and lights glow
@@ -4523,6 +4594,98 @@ declare module "littlejsengine" {
4523
4594
  * @memberof PostProcess
4524
4595
  */
4525
4596
  export function postProcessBloomShader(threshold?: number, strength?: number, size?: number): string;
4597
+ /**
4598
+ * Join effects into one post process shader, in the order given, for PostProcessPlugin or setShaderCode
4599
+ * - Each effect is a piece of shader code on c, the pixel's color, and uv, where it is on the screen from 0 to 1;
4600
+ * your own code is a piece too, a line of GLSL or many, dropped in where you put it
4601
+ * - Put the ones that bend the picture or sample it first: postProcessCurve, postProcessChromatic, postProcessGlow
4602
+ * @param {...string} effects - The pieces, from the effect functions or your own code
4603
+ * @return {string} - Shadertoy style mainImage code
4604
+ * @example
4605
+ * new PostProcessPlugin(postProcessEffects(
4606
+ * postProcessScanlines(.5), postProcessVignette(), 'c.rgb *= vec3(1, .9, .8);'));
4607
+ * @memberof PostProcess
4608
+ */
4609
+ export function postProcessEffects(...effects: string[]): string;
4610
+ /**
4611
+ * Bright parts glow, the bloom as an effect to join with others; postProcessBloom sets up bloom on its own
4612
+ * @param {number} [threshold] - Brightness where the glow starts, 0 is everything and 1 is only pure white
4613
+ * @param {number} [strength] - How much glow to add
4614
+ * @param {number} [size] - How far the glow spreads in pixels, which also sets how many samples it takes
4615
+ * @return {string}
4616
+ * @memberof PostProcess
4617
+ */
4618
+ export function postProcessGlow(threshold?: number, strength?: number, size?: number): string;
4619
+ /**
4620
+ * Scan lines across the screen, like an old TV
4621
+ * @param {number} [strength] - How dark the lines are, and how bright between them
4622
+ * @param {number} [spacing] - Pixels from one line to the next
4623
+ * @return {string}
4624
+ * @memberof PostProcess
4625
+ */
4626
+ export function postProcessScanlines(strength?: number, spacing?: number): string;
4627
+ /**
4628
+ * Static noise over the picture, changing every frame
4629
+ * @param {number} [strength] - How bright the static is
4630
+ * @param {number} [size] - Size of a speck in pixels
4631
+ * @return {string}
4632
+ * @memberof PostProcess
4633
+ */
4634
+ export function postProcessNoise(strength?: number, size?: number): string;
4635
+ /**
4636
+ * Darken toward the edges and corners
4637
+ * @param {number} [strength] - How dark the corners get, 1 is black
4638
+ * @param {number} [falloff] - How far in it reaches, low darkens most of the screen, high only the corners
4639
+ * @return {string}
4640
+ * @memberof PostProcess
4641
+ */
4642
+ export function postProcessVignette(strength?: number, falloff?: number): string;
4643
+ /**
4644
+ * Bend the picture like the bulged glass of an old TV, black past the corners; put it first
4645
+ * @param {number} [strength] - How much it bends
4646
+ * @return {string}
4647
+ * @memberof PostProcess
4648
+ */
4649
+ export function postProcessCurve(strength?: number): string;
4650
+ /**
4651
+ * Split red and blue apart toward the edges, like a cheap lens; put it before what shades the picture
4652
+ * @param {number} [strength] - How far apart at the edge, as a part of the screen
4653
+ * @return {string}
4654
+ * @memberof PostProcess
4655
+ */
4656
+ export function postProcessChromatic(strength?: number): string;
4657
+ /**
4658
+ * Draw lines where the 3D depth jumps, around objects and along their creases; needs render3D.depthTexture on
4659
+ * @param {Color} [color] - The lines' color, its alpha how strong they are
4660
+ * @param {number} [thickness] - How wide the lines are in pixels
4661
+ * @param {number} [threshold] - How big a jump makes a line, as a part of the distance, lower draws more
4662
+ * @return {string}
4663
+ * @memberof PostProcess
4664
+ */
4665
+ export function postProcessOutline(color?: Color, thickness?: number, threshold?: number): string;
4666
+ /**
4667
+ * The look of an old TV, as one effect to use alone or join with others: static noise, scan lines, a soft glow and
4668
+ * a vignette, and a bulged screen when curve is set; any setting at 0 leaves that part out
4669
+ * @param {Object} [settings]
4670
+ * @param {number} [settings.noise] - Static noise strength
4671
+ * @param {number} [settings.scanlines] - Scan line strength
4672
+ * @param {number} [settings.scanlineSpacing] - Pixels from one scan line to the next
4673
+ * @param {number} [settings.glow] - Soft glow strength
4674
+ * @param {number} [settings.vignette] - Vignette strength
4675
+ * @param {number} [settings.curve] - How much the screen bulges, 0 by default for flat
4676
+ * @return {string}
4677
+ * @example
4678
+ * new PostProcessPlugin(postProcessEffects(postProcessTV({scanlines: .4, curve: .1})));
4679
+ * @memberof PostProcess
4680
+ */
4681
+ export function postProcessTV({ noise, scanlines, scanlineSpacing, glow, vignette, curve }?: {
4682
+ noise?: number;
4683
+ scanlines?: number;
4684
+ scanlineSpacing?: number;
4685
+ glow?: number;
4686
+ vignette?: number;
4687
+ curve?: number;
4688
+ }): string;
4526
4689
  /**
4527
4690
  * LittleJS Light System Plugin
4528
4691
  * - Adds 2D dynamic lighting to the scene
@@ -4545,6 +4708,8 @@ declare module "littlejsengine" {
4545
4708
  * shadow map through renderShadow(), which calls render() by default; obj.castShadow = false keeps it
4546
4709
  * out (a floor TileLayer, a background), a draw's alpha sets how much light it blocks, and
4547
4710
  * setShadowTransparent lets its color tint the light
4711
+ * - Set light.glow for a soft hazy glow over a light, like a lamp at night; it is added over the lit scene after the
4712
+ * lightmap, so it shows in the dark and sits in front of everything there
4548
4713
  * - Must be constructed BEFORE PostProcessPlugin so post-process sees lit pixels
4549
4714
  * @namespace LightSystem
4550
4715
  */
@@ -4642,6 +4807,9 @@ declare module "littlejsengine" {
4642
4807
  shadowMapWorldSize: number;
4643
4808
  shadowMapSizeAllocated: number;
4644
4809
  shadowTextureSizeAllocated: number;
4810
+ /** Bring the sizes of the textures it makes down to what the device can make: shadowMapSize, shadowTextureSize
4811
+ * and a textureSize given by hand; called before they are made, so a size too big falls back instead of failing */
4812
+ clampTextureSizes(): void;
4645
4813
  /** Draw a single Light's falloff blob into the currently bound lightmap.
4646
4814
  * Called by Light.renderLight() during the plugin's render pass.
4647
4815
  * @param {Light} light */
@@ -4689,6 +4857,17 @@ declare module "littlejsengine" {
4689
4857
  * or torch that holds it, or the player carrying it, does not block it; it has to reach past that object's
4690
4858
  * corners, about half its diagonal and a little more, or dark rays run out from them */
4691
4859
  shadowCore: number;
4860
+ /** @property {number} - Size across of a soft hazy glow drawn over the light, like a lamp at night, 0 for
4861
+ * none; it is added over the lit scene, in front of everything there */
4862
+ glow: number;
4863
+ /** @property {number} - How fast the glow fades from its middle: 1 by default, .5 a wide haze, 2 a tight
4864
+ * bright core */
4865
+ glowFalloff: number;
4866
+ /** @type {TileInfo|undefined} */
4867
+ glowTileInfo: TileInfo | undefined;
4868
+ /** Draw this light's glow, soft and round, its glow size across and in its color, added over the lit scene;
4869
+ * called by LightSystemPlugin after the lightmap is applied */
4870
+ renderGlow(): void;
4692
4871
  }
4693
4872
  /**
4694
4873
  * LittleJS ZzFXM Plugin
@@ -7686,6 +7865,10 @@ declare module "littlejsengine" {
7686
7865
  * new EngineObject3D(vec3(), buildBox());
7687
7866
  */
7688
7867
  export class Render3DPlugin {
7868
+ /** @type {Render3DDrawState} */
7869
+ drawState: Render3DDrawState;
7870
+ /** @property {number} - Goes up when a draw state field changes, so a batch sees at a glance that none did */
7871
+ stateVersion: number;
7689
7872
  /** @property {Camera3D} - The camera */
7690
7873
  camera: Camera3D;
7691
7874
  /** @property {Vector3} - Direction toward the sun, where its light comes from, like a directional Light3D;
@@ -7724,8 +7907,16 @@ declare module "littlejsengine" {
7724
7907
  depthTexture: boolean;
7725
7908
  /** @property {boolean} - Cast real shadows from the sun, off by default and free when off */
7726
7909
  shadows: boolean;
7910
+ /** @property {number} - How far a sound played with playSound is heard when it was made with no range of
7911
+ * its own, in world units; further than the 2D soundDefaultRange, a 3D world is bigger */
7912
+ soundDefaultRange: number;
7727
7913
  /** @property {number} - Size of the shadow map in pixels, bigger is sharper and slower */
7728
7914
  shadowMapSize: number;
7915
+ /** @property {Light3D|undefined} - A spotlight, a Light3D with a coneAngle, to cast the shadows in place
7916
+ * of the sun, a flashlight in the dark: the shadow map looks down its cone, as far as its radius, and the
7917
+ * sun still lights the scene but casts none; undefined for the sun, as is a light that is off or has no cone
7918
+ * @type {Light3D|undefined} */
7919
+ shadowLight: Light3D | undefined;
7729
7920
  /** @property {number} - World size the shadow map covers around shadowCenter, smaller is sharper; it is a
7730
7921
  * square facing the light, so it turns as the light does, and about 1.5 times an area's width covers it from
7731
7922
  * any angle */
@@ -7737,46 +7928,6 @@ declare module "littlejsengine" {
7737
7928
  shadowBias: number;
7738
7929
  /** @property {number} - How much to blur the shadow edges */
7739
7930
  shadowSoftness: number;
7740
- /** @property {boolean} - Apply lighting, when false draws plain vertex color times texture and casts no shadow;
7741
- * off for billboards, lines, ribbons and soft discs, an object sets emissive instead */
7742
- lighting: boolean;
7743
- /** @property {number} - How much a surface lights itself, set per object by its emissive */
7744
- emissive: number;
7745
- /** @property {boolean} - Additive blending instead of alpha, in the transparent stage */
7746
- additive: boolean;
7747
- /** @property {boolean} - Test against the depth buffer, reset to true before each object and callback; a draw
7748
- * with it off goes over what was drawn before it and under what is drawn after, by render order, which
7749
- * ends the batch of meshes before it, so one per object costs a draw per object */
7750
- depthTest: boolean;
7751
- /** @property {boolean} - Write to the depth buffer, owned by the stages: on for opaque, off for transparent */
7752
- depthWrite: boolean;
7753
- cullBackFaces: boolean;
7754
- mirrored: boolean;
7755
- /** @property {number} - Strength of the highlight where the sun and the Light3D objects reflect, 0 is none and
7756
- * 1 adds a light's full color at its brightest; shininess sets its size */
7757
- specular: number;
7758
- /** @property {number} - The highlight's exponent, how small and sharp it is: 4 is broad like rubber, 100 sharp
7759
- * like polished metal; set from each object's shininess */
7760
- shininess: number;
7761
- /** @property {TextureInfo|undefined} - Normal map for the next draws, set from each object's normalMap
7762
- * @type {TextureInfo|undefined} */
7763
- normalMap: TextureInfo | undefined;
7764
- /** @property {number} - How strongly the normal map bends the surface, set from each object's normalScale */
7765
- normalScale: number;
7766
- /** @property {number} - How much the surface reflects the sky, 0 to 1, set from each object's reflectivity */
7767
- reflectivity: number;
7768
- /** @property {TextureInfo|undefined} - Emissive map for the next draws, set from each object's emissiveMap
7769
- * @type {TextureInfo|undefined} */
7770
- emissiveMap: TextureInfo | undefined;
7771
- /** @property {Color} - Multiplies the emissive map, set from each object's emissiveMapColor */
7772
- emissiveMapColor: Color;
7773
- /** @property {Shader|undefined} - Custom Shader for the next draws, set from each object's shader; undefined
7774
- * draws with the plugin's own
7775
- * @type {Shader|undefined} */
7776
- shader: Shader | undefined;
7777
- /** @property {boolean} - Darken by the shadow map when shadows are on, turn it off for things that should stay
7778
- * lit inside a shadow */
7779
- receiveShadow: boolean;
7780
7931
  /** @property {Function|undefined} - Draw solid world here, it runs again for shadows so only draw in it
7781
7932
  * @type {Function|undefined} */
7782
7933
  onRenderOpaque: Function | undefined;
@@ -7798,9 +7949,6 @@ declare module "littlejsengine" {
7798
7949
  /** @property {boolean} - Sample textures through mipmaps so they do not shimmer in the distance, false uses
7799
7950
  * each texture's own filtering like 2D */
7800
7951
  mipmaps: boolean;
7801
- /** @property {boolean} - Draw state: keep texture pixels hard edged, no mipmaps and no blending between them,
7802
- * set per object by pixelated */
7803
- pixelated: boolean;
7804
7952
  /** @property {number} - Anisotropic filtering for textures seen at an angle, 1 to 16, 1 is off; needs mipmaps */
7805
7953
  anisotropy: number;
7806
7954
  /** @property {Mesh} - A box of size 1 that drawBox uses, for any object that is a box; set the object's scale3D
@@ -7835,7 +7983,6 @@ declare module "littlejsengine" {
7835
7983
  /** @property {Vector3} - Camera forward axis this frame */
7836
7984
  cameraForward: Vector3;
7837
7985
  cameraBack: Vector3;
7838
- blend: boolean;
7839
7986
  /** @type {Array<Array<number>>} */
7840
7987
  frustumPlanes: Array<Array<number>>;
7841
7988
  /** @type {Array<Array<number>>} */
@@ -7877,6 +8024,9 @@ declare module "littlejsengine" {
7877
8024
  passIsDefault: boolean;
7878
8025
  lightPositions: Float32Array;
7879
8026
  lightColors: Float32Array;
8027
+ lightCones: Float32Array;
8028
+ shadowLightIndex: number;
8029
+ shadowDepthBias: number;
7880
8030
  /** @type {WebGLBuffer|undefined} */
7881
8031
  streamBuffer: WebGLBuffer | undefined;
7882
8032
  /** @type {Array<WebGLBuffer>} */
@@ -7901,6 +8051,89 @@ declare module "littlejsengine" {
7901
8051
  state: any;
7902
8052
  draw: () => void;
7903
8053
  }> | undefined;
8054
+ set lighting(arg: boolean);
8055
+ /** Apply lighting, when false draws plain vertex color times texture and casts no shadow;
8056
+ * off for billboards, lines, ribbons and soft discs, an object sets emissive instead
8057
+ * @return {boolean} */
8058
+ get lighting(): boolean;
8059
+ set emissive(arg: number);
8060
+ /** How much a surface lights itself, set per object by its emissive
8061
+ * @return {number} */
8062
+ get emissive(): number;
8063
+ set additive(arg: boolean);
8064
+ /** Additive blending instead of alpha, in the transparent stage
8065
+ * @return {boolean} */
8066
+ get additive(): boolean;
8067
+ set depthTest(arg: boolean);
8068
+ /** Test against the depth buffer, reset to true before each object and callback; a draw
8069
+ * with it off goes over what was drawn before it and under what is drawn after, by render order, which
8070
+ * ends the batch of meshes before it, so one per object costs a draw per object
8071
+ * @return {boolean} */
8072
+ get depthTest(): boolean;
8073
+ set depthWrite(arg: boolean);
8074
+ /** Write to the depth buffer, owned by the stages: on for opaque, off for transparent
8075
+ * @return {boolean} */
8076
+ get depthWrite(): boolean;
8077
+ set cullBackFaces(arg: boolean);
8078
+ /** Skip back faces, set by drawMesh from each mesh: off for strips so they show from
8079
+ * both sides
8080
+ * @return {boolean} */
8081
+ get cullBackFaces(): boolean;
8082
+ set mirrored(arg: boolean);
8083
+ /** The transform mirrors the draw, so the other winding is the front, set by drawMesh
8084
+ * from each transform
8085
+ * @return {boolean} */
8086
+ get mirrored(): boolean;
8087
+ set specular(arg: number);
8088
+ /** Strength of the highlight where the sun and the Light3D objects reflect, 0 is none and
8089
+ * 1 adds a light's full color at its brightest; shininess sets its size
8090
+ * @return {number} */
8091
+ get specular(): number;
8092
+ set shininess(arg: number);
8093
+ /** The highlight's exponent, how small and sharp it is: 4 is broad like rubber, 100 sharp
8094
+ * like polished metal; set from each object's shininess
8095
+ * @return {number} */
8096
+ get shininess(): number;
8097
+ set normalMap(arg: TextureInfo);
8098
+ /** Normal map for the next draws, set from each object's normalMap
8099
+ * @return {TextureInfo|undefined} */
8100
+ get normalMap(): TextureInfo;
8101
+ set normalScale(arg: number);
8102
+ /** How strongly the normal map bends the surface, set from each object's normalScale
8103
+ * @return {number} */
8104
+ get normalScale(): number;
8105
+ set reflectivity(arg: number);
8106
+ /** How much the surface reflects the sky, 0 to 1, set from each object's reflectivity
8107
+ * @return {number} */
8108
+ get reflectivity(): number;
8109
+ set emissiveMap(arg: TextureInfo);
8110
+ /** Emissive map for the next draws, set from each object's emissiveMap
8111
+ * @return {TextureInfo|undefined} */
8112
+ get emissiveMap(): TextureInfo;
8113
+ set emissiveMapColor(arg: Color);
8114
+ /** Multiplies the emissive map, set from each object's emissiveMapColor; compared by its rgb, so a Color
8115
+ * changed in place is seen when it is set again, and undefined is white
8116
+ * @return {Color} */
8117
+ get emissiveMapColor(): Color;
8118
+ set shader(arg: Shader);
8119
+ /** Custom Shader for the next draws, set from each object's shader; undefined draws
8120
+ * with the plugin's own
8121
+ * @return {Shader|undefined} */
8122
+ get shader(): Shader;
8123
+ set receiveShadow(arg: boolean);
8124
+ /** Darken by the shadow map when shadows are on, turn it off for things that should
8125
+ * stay lit inside a shadow
8126
+ * @return {boolean} */
8127
+ get receiveShadow(): boolean;
8128
+ set pixelated(arg: boolean);
8129
+ /** Keep texture pixels hard edged, no mipmaps and no blending between them, set per
8130
+ * object by pixelated
8131
+ * @return {boolean} */
8132
+ get pixelated(): boolean;
8133
+ set blend(arg: boolean);
8134
+ /** Blending on, set by the stages
8135
+ * @return {boolean} */
8136
+ get blend(): boolean;
7904
8137
  /** Rebuild the view and projection matrices from the camera, called automatically each frame
7905
8138
  * @param {number} [aspect] - Width over height, defaults to the main canvas */
7906
8139
  updateMatrices(aspect?: number): void;
@@ -7941,7 +8174,8 @@ declare module "littlejsengine" {
7941
8174
  distance: number;
7942
8175
  } | undefined;
7943
8176
  /** Play a sound at a 3D position, quieter with distance from the camera and panned by its side, like Sound.play
7944
- * with a 2D position
8177
+ * with a 2D position; a sound made with no range of its own is heard to soundDefaultRange, 100, and one given
8178
+ * a range keeps it
7945
8179
  * @param {Sound} sound
7946
8180
  * @param {Vector3} pos3D
7947
8181
  * @param {number} [volume]
@@ -8532,20 +8766,24 @@ declare module "littlejsengine" {
8532
8766
  * InstancedMesh3D - Many copies of one mesh drawn as one call, with their transforms kept on the GPU
8533
8767
  * - For big sets that mostly stay put: an instance costs nothing per frame until it changes, so a hundred thousand
8534
8768
  * trees cost what one tree does; objects and drawMesh batch by themselves too, but rebuild their batch every frame
8535
- * - setMatrixAt and setColorAt change one instance, and only the changed range uploads before the next draw
8769
+ * - setTransformAt, setMatrixAt and setColorAt change one instance, and only the changed range uploads before the
8770
+ * next draw; the matrices and the colors are kept apart, so moving instances uploads 64 bytes each
8771
+ * - For many instances moving every frame, setTransforms places a run of them from arrays of positions, rotations
8772
+ * and scales in one loop, the fastest way; or write matrixData directly and call markDirtyRange
8536
8773
  * - The instances are in world space; the object's own pos3D, rotation3D and scale3D do not move them
8537
- * - The whole set is culled by one bounding sphere around the origin, and casts and receives shadows like any object
8774
+ * - The whole set is culled by one bounding sphere around the origin, worked out when culling reads it, or set by hand
8775
+ * with radius; it casts and receives shadows like any object
8538
8776
  * - The object's flags cover the whole set, one emissive, one tileInfo, one shader; only the colors are per instance
8539
8777
  * - A mirrored instance, one with a negative scale, shows its inside unless the mesh is doubleSided
8540
8778
  * - A transparent set draws in one go in the transparent stage, its instances are not sorted against each other;
8541
8779
  * the set sorts against other transparent draws by the object's position, so put pos3D at its middle
8542
- * - pick, the raycast and the collect helpers do not see the instances, test them yourself from instanceData
8780
+ * - pick, the raycast and the collect helpers do not see the instances, test them yourself from matrixData
8543
8781
  * @extends EngineObject3D
8544
8782
  * @memberof Render3D
8545
8783
  * @example
8546
8784
  * const forest = new InstancedMesh3D(treeMesh, 1000);
8547
8785
  * for (let i = 0; i < 1000; ++i)
8548
- * forest.setMatrixAt(i, buildMatrix(randomGroundPos(), vec3(0, rand(2*PI), 0)));
8786
+ * forest.setTransformAt(i, randomGroundPos(), vec3(0, rand(2*PI), 0));
8549
8787
  */
8550
8788
  export class InstancedMesh3D extends EngineObject3D {
8551
8789
  /** Create a set of instances of a mesh, each at the origin in the object's color until it is set
@@ -8558,21 +8796,53 @@ declare module "littlejsengine" {
8558
8796
  count: number;
8559
8797
  /** @property {number} - How many instances it was made with */
8560
8798
  maxCount: number;
8561
- /** @property {Float32Array} - The per instance values the shader reads, 24 floats each: the matrix, the color
8562
- * and the uv rect; edit it directly and call markDirty for the instances changed */
8563
- instanceData: Float32Array;
8564
- /** @property {number} - Radius of the sphere around the origin that holds every instance set so far, for
8565
- * culling; from the farthest instance and the largest scale, and the mesh's size when it draws */
8566
- radius: number;
8567
- reach: number;
8568
- maxScale: number;
8569
- /** @property {number} - First instance to upload before the next draw */
8799
+ /** @property {Float32Array} - Each instance's matrix, 16 floats, what moving them uploads; edit it directly and
8800
+ * call markDirty for the instances changed */
8801
+ matrixData: Float32Array;
8802
+ /** @property {Float32Array} - Each instance's color and uv rect, 8 floats, uploaded only when they change; edit
8803
+ * it directly and call markColorDirty for the instances changed */
8804
+ colorData: Float32Array;
8805
+ /** @property {number} - First instance whose matrix uploads before the next draw */
8570
8806
  dirtyStart: number;
8571
- /** @property {number} - One past the last instance to upload, so nothing uploads when it is not past dirtyStart */
8807
+ /** @property {number} - One past the last instance whose matrix uploads, nothing when it is not past dirtyStart */
8572
8808
  dirtyEnd: number;
8809
+ /** @property {number} - First instance whose color uploads before the next draw */
8810
+ colorDirtyStart: number;
8811
+ /** @property {number} - One past the last instance whose color uploads */
8812
+ colorDirtyEnd: number;
8813
+ reachSquared: number;
8814
+ scaleSquared: number;
8815
+ boundsStart: number;
8816
+ boundsEnd: number;
8817
+ /** @type {number|undefined} */
8818
+ fixedRadius: number | undefined;
8573
8819
  buffer: WebGLBuffer;
8820
+ /** @type {WebGLBuffer|undefined} */
8821
+ colorBuffer: WebGLBuffer | undefined;
8574
8822
  bufferGeneration: number;
8575
8823
  uvTileInfo: TileInfo | TextureInfo;
8824
+ /** Place an instance by its position, rotation and scale, what buildMatrix takes, written straight in with no
8825
+ * matrix made; in world space
8826
+ * @param {number} i
8827
+ * @param {Vector3} [pos]
8828
+ * @param {Vector3} [rotation] - Euler angles in radians
8829
+ * @param {Vector3} [scale] */
8830
+ setTransformAt(i: number, pos?: Vector3, rotation?: Vector3, scale?: Vector3): void;
8831
+ /** Place a run of instances from arrays indexed by instance, plain or typed, as a game keeps them: each is placed
8832
+ * as setTransformAt places it, all in one loop with nothing made, the fastest way to move many every frame;
8833
+ * in world space
8834
+ * @param {number} start - First instance
8835
+ * @param {number} count - How many
8836
+ * @param {ArrayLike<number>} x - Positions
8837
+ * @param {ArrayLike<number>} y
8838
+ * @param {ArrayLike<number>} z
8839
+ * @param {ArrayLike<number>} [rx] - Euler angles in radians, all three or none for upright
8840
+ * @param {ArrayLike<number>} [ry]
8841
+ * @param {ArrayLike<number>} [rz]
8842
+ * @param {ArrayLike<number>} [sx] - Scales, all three or none for 1
8843
+ * @param {ArrayLike<number>} [sy]
8844
+ * @param {ArrayLike<number>} [sz] */
8845
+ setTransforms(start: number, count: number, x: ArrayLike<number>, y: ArrayLike<number>, z: ArrayLike<number>, rx?: ArrayLike<number>, ry?: ArrayLike<number>, rz?: ArrayLike<number>, sx?: ArrayLike<number>, sy?: ArrayLike<number>, sz?: ArrayLike<number>): void;
8576
8846
  /** Place an instance, in world space
8577
8847
  * @param {number} i
8578
8848
  * @param {Matrix4} matrix */
@@ -8585,10 +8855,26 @@ declare module "littlejsengine" {
8585
8855
  * @param {number} i
8586
8856
  * @param {Color} color */
8587
8857
  setColorAt(i: number, color: Color): void;
8588
- /** Note that an instance changed, so it uploads before the next draw and the bounds hold it; setMatrixAt and
8589
- * setColorAt call this, and so must an edit made straight to instanceData
8858
+ /** Note that an instance's matrix changed, so it uploads before the next draw and the bounds take it in when
8859
+ * they are read; setTransformAt and setMatrixAt call this, and so must an edit made straight to matrixData
8590
8860
  * @param {number} i */
8591
8861
  markDirty(i: number): void;
8862
+ /** Note that a run of instances' matrices changed, for code that writes matrixData directly, the lowest level
8863
+ * way to move many: they upload before the next draw and the bounds take them in when they are read
8864
+ * @param {number} start - First instance
8865
+ * @param {number} end - One past the last */
8866
+ markDirtyRange(start: number, end: number): void;
8867
+ /** Note that an instance's color changed, so it uploads before the next draw; setColorAt calls this, and so must
8868
+ * an edit made straight to colorData
8869
+ * @param {number} i */
8870
+ markColorDirty(i: number): void;
8871
+ set radius(arg: number);
8872
+ /** Radius of the sphere around the origin that holds every instance set so far, for culling: the farthest
8873
+ * instance, and the mesh's size at the largest scale; it only grows, and takes in the instances set since it
8874
+ * was last read, so with frustum culling off it is never worked out. Set it to fix the sphere, which a big set
8875
+ * that is culled can use to skip that work, and set it to undefined to go back to the bounds
8876
+ * @return {number} */
8877
+ get radius(): number;
8592
8878
  }
8593
8879
  /**
8594
8880
  * Spin a flat outline around the Y axis to make a round shape, like a vase or a wheel
@@ -9024,7 +9310,10 @@ declare module "littlejsengine" {
9024
9310
  /**
9025
9311
  * Light3D - A light that is an EngineObject3D, so it can move, follow a parent or be destroyed like anything else
9026
9312
  * - A point light: it lights what is near it and fades out by its radius, DirectionalLight3D shines from far away
9027
- * - Only the sun, render3D.sunDirection, casts shadows; these light and make highlights without one
9313
+ * - A coneAngle makes it a spotlight: it shines along its own forward, turned by rotation3D or by what it is
9314
+ * attached to, inside the cone, fading over the part of it coneSoftness says
9315
+ * - The sun, render3D.sunDirection, casts the shadows; a spotlight can cast them in its place, see
9316
+ * render3D.shadowLight; the other lights light and make highlights without one
9028
9317
  * - Only the 8 lights nearest the camera are used each frame
9029
9318
  * - radius is where the light fades out, and it fades fast, so a small radius wants a higher intensity
9030
9319
  * - intensity multiplies the color, above 1 for a light brighter than white
@@ -9050,6 +9339,12 @@ declare module "littlejsengine" {
9050
9339
  /** @property {boolean} - Shine from far away, from its position toward the origin, instead of out from its
9051
9340
  * position with a falloff; DirectionalLight3D sets it */
9052
9341
  directional: boolean;
9342
+ /** @property {number} - Makes it a spotlight: the angle in radians from its forward out to the edge of its
9343
+ * cone, so the beam is twice this across; 0 for a light that shines every way */
9344
+ coneAngle: number;
9345
+ /** @property {number} - How much of the cone is its fading edge: 0 a hard edge, .2 by default, the outer
9346
+ * fifth, 1 fading all the way from the middle of the beam */
9347
+ coneSoftness: number;
9053
9348
  /** @property {number} - Size of a soft hazy glow drawn over the light, like a lamp at night, 0 for none; it
9054
9349
  * is added onto what is behind it, and what is in front of the light hides it */
9055
9350
  glow: number;
@@ -9167,6 +9462,8 @@ declare module "littlejsengine" {
9167
9462
  * @property {Vector3} velocity - How far it moves each frame
9168
9463
  * @property {number} age - Seconds it has lived
9169
9464
  * @property {number} lifeTime - Seconds it lives
9465
+ * @property {number} scale - How much the emitter grows its effect, from its scale3D and its parents', as the 2D
9466
+ * particle's scale
9170
9467
  * @property {boolean} destroyed - Set by destroy
9171
9468
  * @property {function(): void} destroy - End it this update, the destroy callback gets it
9172
9469
  * @memberof Render3D
@@ -9193,8 +9490,9 @@ declare module "littlejsengine" {
9193
9490
  * - emitConeAngle spreads them, PI sprays in every direction
9194
9491
  * - Speeds are per frame and sizes are world units, the same as the 2D emitter
9195
9492
  * - scale3D, its own or a parent's, grows the whole effect: the spawn area, the sizes, the speed and the fall
9196
- * - gravity here is its own number added to velocity y each frame: it is neither the engine's 2D
9197
- * gravity nor render3D.gravity, so an effect keeps its own fall wherever it is used
9493
+ * - gravity here is its own number added to velocity y each frame, so an effect keeps its own fall wherever it is
9494
+ * used, the same as the 2D emitter's gravity; gravityScale adds a share of render3D.gravity on top, as the 2D
9495
+ * emitter's gravityScale adds the engine's gravity
9198
9496
  * - An emitter with an emitTime destroys itself once its last particle is gone, like the 2D emitter
9199
9497
  * - Callbacks as the 2D emitter's: particleCreateCallback, particleUpdateCallback, particleCollideCallback and
9200
9498
  * particleDestroyCallback, each given a Particle3D, one object the emitter reuses for every particle and call
@@ -9223,14 +9521,17 @@ declare module "littlejsengine" {
9223
9521
  * @param {number} [sizeEnd] - Particle size at end of life
9224
9522
  * @param {number} [speed] - Spawn speed in world units per frame
9225
9523
  * @param {number} [damping] - Per frame velocity multiplier, 1 is none
9226
- * @param {number} [gravity] - Per frame change to velocity y, negative pulls down; its own number,
9227
- * not render3D.gravity, so the 2D emitter's gravityScale has no equivalent here
9524
+ * @param {number} [gravity] - Per frame change to velocity y, negative pulls down; its own number, and
9525
+ * gravityScale adds a share of render3D.gravity on top
9228
9526
  * @param {number} [fadeRate] - Fraction of life spent fading, half in and half out
9229
9527
  * @param {number} [randomness] - Extra randomness applied to speed, size and life
9230
9528
  * @param {boolean} [additive] - Additive blending */
9231
9529
  constructor(pos3D?: Vector3, emitSize?: number | Vector3, emitTime?: number, emitRate?: number, emitConeAngle?: number, tileInfo?: TileInfo | TextureInfo, colorStartA?: Color, colorStartB?: Color, colorEndA?: Color, colorEndB?: Color, particleTime?: number, sizeStart?: number, sizeEnd?: number, speed?: number, damping?: number, gravity?: number, fadeRate?: number, randomness?: number, additive?: boolean);
9232
9530
  /** @property {number|Vector3} - Spawn area, a number for a sphere diameter or a vec3 for a box */
9233
9531
  emitSize: number | Vector3;
9532
+ /** @property {boolean} - Flatten the spawn area across the way it emits, its own up: a sphere becomes a disc
9533
+ * and a box a flat rectangle, for rain from a sheet of sky or flames from a patch of ground */
9534
+ emitFlat: boolean;
9234
9535
  /** @property {number} - How long to keep emitting, 0 is forever */
9235
9536
  emitTime: number;
9236
9537
  /** @property {number} - Particles per second, 0 does not emit */
@@ -9342,6 +9643,91 @@ declare module "littlejsengine" {
9342
9643
  clear(): void;
9343
9644
  worldPos3D: Vector3;
9344
9645
  }
9646
+ /**
9647
+ * LensFlare3D - The sun's lens flare, the old kind: a glow at the sun and a row of discs and rings of different
9648
+ * sizes along the line from the sun through the middle of the screen
9649
+ * - Make one and it shows, over the 3D scene and under what the game draws after, a HUD; destroy it to take it away
9650
+ * - It follows render3D.sunDirection, and fades out as the sun leaves the screen or goes behind something
9651
+ * - flareSize, count, intensity and saturation set its look, seed picks another arrangement, and its color tints it,
9652
+ * with the sun's own color; or give it elements of your own
9653
+ * - visible is how much of the sun shows, 0 to 1, eased over fadeTime, there for a game to read
9654
+ * - What hides the sun is found with a ray from the camera, against the level and every object that is not see
9655
+ * through, each as the box around its mesh, see render3D.pick; turn it off with occlusion
9656
+ * - It needs WebGL, and it draws nothing in the shadow of renderAfter2D
9657
+ * @extends EngineObject3D
9658
+ * @memberof Render3D
9659
+ * @example
9660
+ * new LensFlare3D; // the sun flares
9661
+ * new LensFlare3D(1.5, 10, .7, 0); // bigger, 10 ghosts, dimmer, all one color
9662
+ */
9663
+ export class LensFlare3D extends EngineObject3D {
9664
+ /** Create the sun's lens flare
9665
+ * @param {number} [size] - Scales every part of it, 1 by default
9666
+ * @param {number} [count] - How many ghosts there are along the line, besides the glow at the sun
9667
+ * @param {number} [intensity] - How bright it is
9668
+ * @param {number} [saturation] - How colorful the ghosts are, 0 for all the flare's own color, 1 a rainbow
9669
+ * @param {Color} [color] - Tints the whole flare, with the sun's color */
9670
+ constructor(size?: number, count?: number, intensity?: number, saturation?: number, color?: Color);
9671
+ /** @property {number} - Scales every part of the flare */
9672
+ flareSize: number;
9673
+ /** @property {number} - How many ghosts there are along the line, besides the glow at the sun */
9674
+ count: number;
9675
+ /** @property {number} - How bright it is */
9676
+ intensity: number;
9677
+ /** @property {number} - How colorful the ghosts are, 0 for all the flare's own color, 1 a rainbow */
9678
+ saturation: number;
9679
+ /** @property {number} - Picks the arrangement of the ghosts, another seed is another flare */
9680
+ seed: number;
9681
+ /** @property {Array<{at: number, size: number, color: Color, shape: string}>|undefined} - The parts of the
9682
+ * flare, to set your own in place of the ones made from count, seed and saturation: at is where along the
9683
+ * line, 0 the sun, 1 the middle of the screen, 2 as far past it; size is across, as a part of the screen's
9684
+ * height; shape is glow, disc or ring
9685
+ * @type {Array<{at: number, size: number, color: Color, shape: string}>|undefined} */
9686
+ elements: {
9687
+ at: number;
9688
+ size: number;
9689
+ color: Color;
9690
+ shape: string;
9691
+ }[];
9692
+ /** @property {boolean} - Fade out when something is between the camera and the sun */
9693
+ occlusion: boolean;
9694
+ /** @property {number} - Seconds the flare takes to fade out or in when the sun is hidden or shows again */
9695
+ fadeTime: number;
9696
+ /** @property {number} - How much of the sun shows, 0 hidden or behind the camera to 1 in plain view, eased */
9697
+ visible: number;
9698
+ madeKey: string;
9699
+ /** @type {Array<{at: number, size: number, color: Color, shape: string}>} */
9700
+ made: {
9701
+ at: number;
9702
+ size: number;
9703
+ color: Color;
9704
+ shape: string;
9705
+ }[];
9706
+ /** The parts of the flare: the elements set by hand, or the ones made from count, seed and saturation, a glow
9707
+ * and a core at the sun and the ghosts, made again when one of those changes
9708
+ * @return {Array<{at: number, size: number, color: Color, shape: string}>} */
9709
+ getElements(): Array<{
9710
+ at: number;
9711
+ size: number;
9712
+ color: Color;
9713
+ shape: string;
9714
+ }>;
9715
+ /** Where the sun is on the screen, in pixels like mousePosScreen, undefined when it is behind the camera
9716
+ * @return {Vector2|undefined} */
9717
+ getSunScreenPos(): Vector2 | undefined;
9718
+ /** The parts of the flare as they are drawn now: each one's place on the screen, its size in pixels and its
9719
+ * color, dimmed by how much of the sun shows; empty when there is nothing to draw
9720
+ * @return {Array<{pos: Vector2, size: number, color: Color, shape: string}>} */
9721
+ getScreenElements(): Array<{
9722
+ pos: Vector2;
9723
+ size: number;
9724
+ color: Color;
9725
+ shape: string;
9726
+ }>;
9727
+ /** Is something between the camera and the sun: the level, or an object that is not see through
9728
+ * @return {boolean} */
9729
+ isSunHidden(): boolean;
9730
+ }
9345
9731
  /**
9346
9732
  * Collect the EngineObject3D objects whose boxes overlap a sphere or a box, the 3D twin of engineObjectsCollect
9347
9733
  * - Each object is its size3D box at its world position, turned as it is turned; lights, emitters and trails have no
@@ -9671,10 +10057,31 @@ declare module "littlejsengine" {
9671
10057
  * - What a file written by hand gets wrong uses the default: a value that is not of its default's type
9672
10058
  * - An object its type can not make is skipped with an error in debug builds, where asserts throw, and the rest
9673
10059
  * of the level is made
10060
+ * - A level may hold a map of blocks, in a voxels block: pos, its corner, size, its cells along x, y and z, and
10061
+ * blocks, runs of a count and a type along x, then y, then z; it is made a VoxelMap, the first of what is
10062
+ * returned, see level3DVoxelSetup for its sheet
10063
+ * - A level may hold a terrain, in a terrain block: pos, its center, size, its size in the world along x and z,
10064
+ * height, how tall a full height is, color, and heights, rows of 0 to 1 from -z to +z, each from -x to +x; it
10065
+ * is made a HeightMap, returned with what else was made
10066
+ * - A level may set the scene too, in a scene block beside its objects: sky, three colors for straight up, the
10067
+ * horizon and straight down, ambient, how much of them lights the scene, .5 when not given, sunDirection and
10068
+ * sunColor, fog, its start and end, fogColor, the horizon color when not given, and shadows; what the block
10069
+ * leaves out stays as the game set it, and a level with no block changes nothing
9674
10070
  * @param {Object} level - The level, the level editor edits this same object
9675
10071
  * @return {Array<any>} - What each object's type made, a function that made nothing is left out
9676
10072
  * @memberof Level3D */
9677
10073
  export function level3DLoad(level: any): Array<any>;
10074
+ /** How a level's block map is made: the sheet its blocks show tiles of, and a function to set it up
10075
+ * - A level's voxels block makes a VoxelMap when the level loads, with texture 0 and the default tile size unless
10076
+ * a sheet is given here; a block's type shows that tile of the sheet on every face
10077
+ * - setup is called with each map a level makes, to give block types their own faces or make them see-through
10078
+ * - Call it before level3DLoad; with no arguments the defaults are back
10079
+ * @param {TileInfo} [tileInfo] - The sheet's first tile, as for a VoxelMap
10080
+ * @param {function(VoxelMap): void} [setup]
10081
+ * @example
10082
+ * level3DVoxelSetup(tile(0, 16, 1), (map)=> map.setBlockType(1, {top: 0, side: 1, bottom: 2})); // grass
10083
+ * @memberof Level3D */
10084
+ export function level3DVoxelSetup(tileInfo?: TileInfo, setup?: (arg0: VoxelMap) => void): void;
9678
10085
  /**
9679
10086
  * LittleJS Three.js Plugin
9680
10087
  * - Renders a three.js scene on a canvas behind the LittleJS canvases
@@ -9875,6 +10282,177 @@ declare module "littlejsengine" {
9875
10282
  * }
9876
10283
  * @memberof TextureSheets */
9877
10284
  export function spritesReady(): Promise<any>;
10285
+ /**
10286
+ * LittleJS Particle Effects Plugin
10287
+ * - Ready made particle effects in one line, particleEffect('fire', pos), and particleEffect3D for 3D
10288
+ * - Every built-in effect is tuned around a one unit emitter; options.scale grows it to fit, options.hue and
10289
+ * options.saturation recolor it
10290
+ * - Effects are plain data, {name, settings, behaviors}, the format the particle designer saves: load a library the
10291
+ * designer saved with particleEffectsLoad and play its effects by name
10292
+ * - The built-in effects draw with a sheet of shapes the plugin draws itself, so they need no image
10293
+ * @namespace ParticleEffects
10294
+ */
10295
+ /** The groups the settings are in, in order
10296
+ * @type {Array<string>}
10297
+ * @memberof ParticleEffects */
10298
+ export const particleEffectGroups: Array<string>;
10299
+ /** Every setting an effect has: its name, kind (number, checkbox, color or shape), default, the range the designer's
10300
+ * slider covers (min, max, step), the hard limits a typed value is clamped to, and whether it is set after the
10301
+ * emitter is made rather than passed to its constructor (extra)
10302
+ * @type {Array<{group:string, name:string, kind:string, value:any, min:number, max:number, step:number,
10303
+ * description:string, hardMin:number, hardMax:number, extra:boolean}>}
10304
+ * @memberof ParticleEffects */
10305
+ export const particleEffectSettings: Array<{
10306
+ group: string;
10307
+ name: string;
10308
+ kind: string;
10309
+ value: any;
10310
+ min: number;
10311
+ max: number;
10312
+ step: number;
10313
+ description: string;
10314
+ hardMin: number;
10315
+ hardMax: number;
10316
+ extra: boolean;
10317
+ }>;
10318
+ /** The behaviors an effect can use, each a push applied to every particle every update, with a 2D and a 3D version
10319
+ * @type {Array<{name:string, update:(Function|undefined), update3D:(Function|undefined), min:number, max:number,
10320
+ * value:number, description:string}>}
10321
+ * @memberof ParticleEffects */
10322
+ export const particleEffectBehaviors: Array<{
10323
+ name: string;
10324
+ update: (Function | undefined);
10325
+ update3D: (Function | undefined);
10326
+ min: number;
10327
+ max: number;
10328
+ value: number;
10329
+ description: string;
10330
+ }>;
10331
+ /** Names of the shapes the plugin draws, for an effect's shape setting
10332
+ * @type {Array<string>}
10333
+ * @memberof ParticleEffects */
10334
+ export const particleEffectShapes: Array<string>;
10335
+ /** Any input into a whole effect: missing fields take their defaults, bad ones are dropped or clamped
10336
+ * @param {Object} [raw] - {name, settings, behaviors}, from a library file, the designer or code
10337
+ * @return {{name:string, settings:Object, behaviors:Array<{name:string, strength:number}>}}
10338
+ * @memberof ParticleEffects */
10339
+ export function particleEffectSanitize(raw?: any): {
10340
+ name: string;
10341
+ settings: any;
10342
+ behaviors: {
10343
+ name: string;
10344
+ strength: number;
10345
+ }[];
10346
+ };
10347
+ /** A copy of an effect with its four colors turned around the color wheel and their saturation scaled; lightness and
10348
+ * alpha stay, and grey and white have no hue to turn
10349
+ * @param {Object} effect
10350
+ * @param {number} [hue] - How far around the wheel, 1 is all the way
10351
+ * @param {number} [saturation] - Multiplies the saturation, 0 is grey, clamped to 1
10352
+ * @return {Object}
10353
+ * @memberof ParticleEffects */
10354
+ export function particleEffectRecolor(effect: any, hue?: number, saturation?: number): any;
10355
+ /** Add effects to play by name, sanitized; one with the name of an effect already there replaces it
10356
+ * @param {Array<Object>|Object} effects
10357
+ * @memberof ParticleEffects */
10358
+ export function particleEffectsAdd(effects: Array<any> | any): void;
10359
+ /** The effect with a name, any case, undefined if there is none
10360
+ * @param {string} name
10361
+ * @return {Object|undefined}
10362
+ * @memberof ParticleEffects */
10363
+ export function particleEffectsGet(name: string): any | undefined;
10364
+ /** A library file, or one effect, into sanitized effects; throws on bad input
10365
+ * @param {string} text
10366
+ * @return {Array<Object>}
10367
+ * @memberof ParticleEffects */
10368
+ export function particleEffectsParse(text: string): Array<any>;
10369
+ /** The text of a library file with these effects, what particleEffectsLoad and the designer read
10370
+ * @param {Array<Object>} effects
10371
+ * @return {string}
10372
+ * @memberof ParticleEffects */
10373
+ export function particleEffectsText(effects: Array<any>): string;
10374
+ /** Load a library file the particle designer saved and add its effects
10375
+ * @param {string} url
10376
+ * @return {Promise<Array<Object>>} - The effects it had
10377
+ * @memberof ParticleEffects */
10378
+ export function particleEffectsLoad(url: string): Promise<Array<any>>;
10379
+ /** The tile of a built-in shape, on a sheet the plugin draws once; undefined headless, without a canvas or without
10380
+ * WebGL, where an effect draws untextured squares
10381
+ * @param {string} name - One of particleEffectShapes
10382
+ * @return {TileInfo|undefined}
10383
+ * @memberof ParticleEffects */
10384
+ export function particleEffectShapeTile(name: string): TileInfo | undefined;
10385
+ /** Play an effect: a 2D emitter set to it, placed, scaled and recolored
10386
+ * - A continuous effect (fire, a torch) goes until destroyed or given an emitTime, a one-shot ends itself
10387
+ * - Any setting in the options replaces the effect's own for this play: {emitTime: .5} for a burst of a continuous
10388
+ * effect, {emitTime: 0, emitRate: 30} to keep a one-shot going, or speed, particleTime and the rest
10389
+ * - Attach it to an object with addChild to follow it
10390
+ * @param {string|Object} nameOrEffect - A built-in or added effect's name, or an effect
10391
+ * @param {Vector2} [pos]
10392
+ * @param {Object} [options]
10393
+ * @param {number} [options.scale] - Grows the whole effect, the built-ins fit a one unit object at 1
10394
+ * @param {number} [options.hue] - Turns its colors around the color wheel, 1 is all the way
10395
+ * @param {number} [options.saturation] - Multiplies its saturation, 0 is grey
10396
+ * @param {number} [options.angle] - Direction, 0 is up; the effect's own angle when not given
10397
+ * @param {TileInfo|TextureInfo} [options.tileInfo] - The game's own art to draw with in place of the effect's shape,
10398
+ * tinted by its colors; a whole texture draws as one tile
10399
+ * @param {*} [options.settings] - Any effect setting by its name, emitTime, emitRate, speed and the rest, replacing
10400
+ * the effect's own for this play
10401
+ * @return {ParticleEmitter|undefined} - undefined when there is no such effect
10402
+ * @memberof ParticleEffects */
10403
+ export function particleEffect(nameOrEffect: string | any, pos?: Vector2, options?: {
10404
+ scale?: number;
10405
+ hue?: number;
10406
+ saturation?: number;
10407
+ angle?: number;
10408
+ tileInfo?: TileInfo | TextureInfo;
10409
+ settings?: any;
10410
+ }): ParticleEmitter | undefined;
10411
+ /** Play an effect in 3D: a ParticleEmitter3D set to it, placed, scaled and recolored
10412
+ * - The same effect data as particleEffect, so the look carries across: a circle spawn area becomes a sphere and a
10413
+ * rectangle a box as deep as it is wide, both flat across the way it emits with options.flatten, a disc or a
10414
+ * sheet; a trail becomes a streak of the same length, and the settings the 3D emitter lacks (particleConeAngle,
10415
+ * randomColorLinear, velocityInheritance, localSpace) are left out; the stick behavior becomes the friction a
10416
+ * particle lands with
10417
+ * @param {string|Object} nameOrEffect - A built-in or added effect's name, or an effect
10418
+ * @param {Vector3} [pos3D]
10419
+ * @param {Object} [options] - scale, hue, saturation, angle, tileInfo and any setting as particleEffect; angle turns it
10420
+ * about z, so 0 is up; flatten makes the spawn area flat across the way it emits
10421
+ * @return {ParticleEmitter3D|undefined} - undefined when there is no such effect
10422
+ * @memberof ParticleEffects */
10423
+ export function particleEffect3D(nameOrEffect: string | any, pos3D?: Vector3, options?: any): ParticleEmitter3D | undefined;
10424
+ /** The names of the built-in effects, in the order a gallery shows them
10425
+ * @type {Array<string>}
10426
+ * @memberof ParticleEffects */
10427
+ export const particleEffectsBuiltIn: Array<string>;
10428
+ /** Set a 2D emitter to an effect, live, so a running one keeps its particles
10429
+ * @param {ParticleEmitter} emitter
10430
+ * @param {Object} effect
10431
+ * @memberof ParticleEffects */
10432
+ export function particleEffectApply(emitter: ParticleEmitter, effect: any): void;
10433
+ /** Set a 3D emitter to an effect, live, so a running one keeps its particles; its place, scale and flatten stay
10434
+ * @param {ParticleEmitter3D} emitter
10435
+ * @param {Object} effect
10436
+ * @memberof ParticleEffects */
10437
+ export function particleEffectApply3D(emitter: ParticleEmitter3D, effect: any): void;
10438
+ /** An effect with a 2D emitter's settings, to save, build again, or build in 3D with particleEffect3D; its tile is
10439
+ * left out, since a hand made emitter's tile is its own texture and not one an effect can name, and so is its
10440
+ * scale, which an effect does not keep: pass it again with options.scale
10441
+ * @param {ParticleEmitter} emitter
10442
+ * @param {string} [name]
10443
+ * @return {Object}
10444
+ * @memberof ParticleEffects */
10445
+ export function particleEffectFromEmitter(emitter: ParticleEmitter, name?: string): any;
10446
+ /** Add a behavior effects can use by name, or replace one
10447
+ * @param {string} name
10448
+ * @param {function(Particle, number): void} update - Pushes a 2D particle, given the strength
10449
+ * @param {function(Particle3D, number): void} [update3D] - The same for a 3D particle, none leaves 3D alone
10450
+ * @param {number} [min] - Strength range the designer offers
10451
+ * @param {number} [max]
10452
+ * @param {number} [value] - Strength when first added
10453
+ * @param {string} [description]
10454
+ * @memberof ParticleEffects */
10455
+ export function particleEffectsAddBehavior(name: string, update: (arg0: Particle, arg1: number) => void, update3D?: (arg0: Particle3D, arg1: number) => void, min?: number, max?: number, value?: number, description?: string): void;
9878
10456
  /**
9879
10457
  * LittleJS Level Editor
9880
10458
  * - Paint the game's tile layers while it is paused, then keep playing with the changes