@woosh/meep-engine 2.36.26 → 2.36.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/bvh2/bvh3/{bvh_query_user_data_by_frustum.js → bvh_query_user_data_overlaps_frustum.js} +4 -5
- package/core/color/Color.js +54 -3
- package/core/color/hsv2rgb.js +3 -3
- package/core/color/kelvin_to_rgb.js +51 -0
- package/core/color/kelvin_to_rgb.spec.js +61 -0
- package/core/color/linear_to_sRGB.js +17 -0
- package/core/color/prototype_kelvin_to_rgb.js +44 -0
- package/core/color/rgb_to_kelvin.js +34 -0
- package/core/color/rgb_to_kelvin.spec.js +15 -0
- package/core/color/sRGB_to_linear.js +16 -0
- package/core/geom/3d/line/line3_computeSegmentPointDistance_sqr.js +2 -2
- package/core/geom/LineSegment.js +2 -2
- package/core/geom/Vector3.js +14 -0
- package/core/math/DEG_TO_RAD.js +1 -0
- package/core/math/MathUtils.spec.js +0 -13
- package/core/math/RAD_TO_DEG.js +1 -0
- package/core/math/clamp01.js +15 -0
- package/core/math/fract.js +10 -0
- package/core/math/newton_solver_1d.js +21 -0
- package/core/math/smoothStep.js +3 -3
- package/core/math/solveQuadratic.js +32 -12
- package/core/math/solveQuadratic.spec.js +18 -0
- package/core/primitives/strings/StringUtils.js +10 -0
- package/core/process/task/TaskUtils.js +2 -2
- package/editor/view/ecs/components/color/GaugeView.js +2 -2
- package/editor/view/ecs/components/particles/ColorParameterLUTController.js +5 -4
- package/editor/view/ecs/components/particles/ScalarParameterLUTController.js +5 -3
- package/engine/Clock.js +4 -0
- package/engine/UserController.js +2 -1
- package/engine/animation/behavior/animateProperty.js +6 -1
- package/engine/animation/keyed2/behavior/AnimationBehavior.js +0 -1
- package/engine/ecs/EntityBuilder.js +12 -1
- package/engine/ecs/animation/OneBoneSurfaceAlignmentSolver.js +2 -1
- package/engine/ecs/animation/TwoBoneInverseKinematicsSolver.js +2 -1
- package/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js +14 -11
- package/engine/ecs/systems/AimControllerSystem.js +3 -2
- package/engine/ecs/systems/RangedAttackSystem.js +3 -2
- package/engine/ecs/systems/SteeringSystem.js +3 -3
- package/engine/ecs/terrain/ecs/ClingToTerrainSystem.js +2 -2
- package/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +2 -2
- package/engine/graphics/GraphicsEngine.js +2 -1
- package/engine/graphics/camera/CameraShake.js +4 -4
- package/engine/graphics/ecs/animation/animator/graph/AnimationTransition.js +2 -2
- package/engine/graphics/ecs/camera/TiltCameraController.js +3 -2
- package/engine/graphics/ecs/compileAllMaterials.js +2 -2
- package/engine/graphics/ecs/highlight/renderer/OutlineRenderer.js +14 -24
- package/engine/graphics/ecs/light/LightSystem.js +2 -3
- package/engine/graphics/ecs/mesh/createTaskWaitForMeshesToLoad.js +2 -2
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts +6 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +19 -0
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +4 -2
- package/engine/graphics/ecs/mesh-v2/render/adapters/AbstractRenderAdapter.js +9 -0
- package/engine/graphics/ecs/mesh-v2/render/optimization/RuntimeDrawMethodOptimizer.js +11 -0
- package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +3 -0
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +31 -0
- package/engine/graphics/micron/build/fill_patch_geometry_data.js +2 -2
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -82
- package/engine/graphics/micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js +28 -3
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +5 -3
- package/engine/graphics/render/gizmo/Gizmo.js +3 -0
- package/engine/graphics/render/gizmo/GizmoRenderingPlugin.js +5 -0
- package/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +91 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +110 -18
- package/engine/graphics/three/OrbitControls.js +3 -2
- package/engine/graphics/trail/x/simulator/RibbonXFixedPhysicsSimulator.js +2 -2
- package/engine/graphics/util/makeMeshPreviewScene.js +11 -3
- package/engine/intelligence/behavior/Behavior.js +36 -17
- package/engine/intelligence/behavior/SelectorBehavior.js +6 -5
- package/engine/intelligence/behavior/composite/ParallelBehavior.js +0 -66
- package/engine/intelligence/behavior/composite/ParallelBehaviorSerializationAdapter.js +63 -0
- package/engine/intelligence/behavior/composite/SequenceBehavior.js +36 -11
- package/engine/intelligence/behavior/decorator/AbstractDecoratorBehavior.js +0 -2
- package/engine/intelligence/behavior/decorator/IgnoreFailureBehavior.js +2 -4
- package/engine/intelligence/behavior/decorator/InverterBehavior.js +3 -3
- package/engine/intelligence/behavior/decorator/RepeatBehavior.js +0 -35
- package/engine/intelligence/behavior/decorator/RepeatBehavior.spec.js +0 -10
- package/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js +37 -0
- package/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -3
- package/engine/intelligence/behavior/decorator/RepeatUntilSuccessBehavior.js +5 -10
- package/engine/intelligence/behavior/ecs/BehaviorComponent.js +95 -7
- package/engine/intelligence/behavior/ecs/BehaviorComponentSerializationAdapter.js +15 -8
- package/engine/intelligence/behavior/ecs/BehaviorSystem.js +28 -37
- package/engine/intelligence/behavior/ecs/DieBehavior.js +2 -7
- package/engine/intelligence/behavior/ecs/WaitForEventBehavior.js +2 -29
- package/engine/intelligence/behavior/ecs/WaitForEventBehaviorSerializationAdapter.js +29 -0
- package/engine/intelligence/behavior/primitive/ActionBehavior.js +6 -13
- package/engine/intelligence/behavior/primitive/FailingBehavior.js +1 -29
- package/engine/intelligence/behavior/primitive/FailingBehaviorSerializationAdapter.js +29 -0
- package/engine/intelligence/behavior/primitive/PromiseBehavior.js +15 -3
- package/engine/intelligence/behavior/selector/WeightedRandomBehavior.js +1 -5
- package/engine/intelligence/behavior/util/ConditionBehavior.js +1 -3
- package/engine/intelligence/behavior/util/ConditionBehavior.spec.js +1 -7
- package/engine/intelligence/behavior/util/ConditionalBehavior.js +3 -6
- package/engine/intelligence/behavior/util/DelayBehavior.js +2 -4
- package/engine/intelligence/behavior/util/SelectorBehavior.js +13 -12
- package/engine/intelligence/blackboard/AbstractBlackboard.js +16 -2
- package/engine/plugin/EnginePluginManager.js +4 -14
- package/engine/sound/ecs/emitter/SoundEmitter.js +3 -0
- package/generation/filtering/numeric/math/CellFilterSaturate.js +2 -2
- package/generation/grid/generation/GridTaskDensityMarkerDistribution.js +3 -2
- package/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.spec.js +1 -1
- package/generation/rules/CellMatcherLayerBitMaskTest.js +3 -3
- package/package.json +1 -1
- package/view/elements/progress/SmoothProgressBar.js +2 -2
- package/view/elements/progress/segmented/SegmentedResourceBarView.js +3 -3
- package/view/elements/radial/RadialProgressView.js +2 -2
package/core/bvh2/bvh3/{bvh_query_user_data_by_frustum.js → bvh_query_user_data_overlaps_frustum.js}
RENAMED
|
@@ -14,12 +14,11 @@ const scratch_aabb = [];
|
|
|
14
14
|
* @param {ExplicitBinaryBoundingVolumeHierarchy} bvh
|
|
15
15
|
* @param {number[]|Float32Array} frustum
|
|
16
16
|
*/
|
|
17
|
-
export function
|
|
17
|
+
export function bvh_query_user_data_overlaps_frustum(
|
|
18
18
|
result,
|
|
19
19
|
result_offset,
|
|
20
20
|
bvh,
|
|
21
|
-
frustum
|
|
22
|
-
) {
|
|
21
|
+
frustum) {
|
|
23
22
|
const root = bvh.root;
|
|
24
23
|
|
|
25
24
|
if (root === NULL_NODE) {
|
|
@@ -30,9 +29,9 @@ export function bvh_query_user_data_by_frustum(
|
|
|
30
29
|
*
|
|
31
30
|
* @type {number}
|
|
32
31
|
*/
|
|
33
|
-
let traversal_cursor =
|
|
32
|
+
let traversal_cursor = 1;
|
|
34
33
|
|
|
35
|
-
traversal_stack[
|
|
34
|
+
traversal_stack[0] = root;
|
|
36
35
|
|
|
37
36
|
let result_cursor = result_offset;
|
|
38
37
|
|
package/core/color/Color.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { assert } from "../assert.js";
|
|
2
2
|
import Signal from "../events/signal/Signal.js";
|
|
3
3
|
import { parseColor } from "./ColorUtils.js";
|
|
4
|
-
import { clamp } from "../math/clamp.js";
|
|
5
4
|
import { min2 } from "../math/min2.js";
|
|
6
5
|
import { max2 } from "../math/max2.js";
|
|
7
6
|
import { min3 } from "../math/min3.js";
|
|
@@ -9,7 +8,11 @@ import { computeHashIntegerArray } from "../collection/array/computeHashIntegerA
|
|
|
9
8
|
import { computeHashFloat } from "../math/hash/computeHashFloat.js";
|
|
10
9
|
import { rgb2hsv } from "./rgb2hsv.js";
|
|
11
10
|
import { rgb2uint24 } from "./rgb2uint24.js";
|
|
11
|
+
import { clamp01 } from "../math/clamp01.js";
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* @class
|
|
15
|
+
*/
|
|
13
16
|
export class Color {
|
|
14
17
|
/**
|
|
15
18
|
*
|
|
@@ -44,6 +47,54 @@ export class Color {
|
|
|
44
47
|
this.onChanged = new Signal();
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @returns {number}
|
|
53
|
+
*/
|
|
54
|
+
get 0() {
|
|
55
|
+
return this.r;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @param {number} v
|
|
61
|
+
*/
|
|
62
|
+
set 0(v) {
|
|
63
|
+
this.r = v;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* @returns {number}
|
|
69
|
+
*/
|
|
70
|
+
get 1() {
|
|
71
|
+
return this.g;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
* @param {number} v
|
|
77
|
+
*/
|
|
78
|
+
set 1(v) {
|
|
79
|
+
this.g = v;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
*
|
|
84
|
+
* @returns {number}
|
|
85
|
+
*/
|
|
86
|
+
get 2() {
|
|
87
|
+
return this.b;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
*
|
|
92
|
+
* @param {number} v
|
|
93
|
+
*/
|
|
94
|
+
set 2(v) {
|
|
95
|
+
this.b = v;
|
|
96
|
+
}
|
|
97
|
+
|
|
47
98
|
/**
|
|
48
99
|
*
|
|
49
100
|
* @param {number} r
|
|
@@ -227,8 +278,8 @@ export class Color {
|
|
|
227
278
|
_h = h + 1;
|
|
228
279
|
}
|
|
229
280
|
|
|
230
|
-
const _s =
|
|
231
|
-
const _v =
|
|
281
|
+
const _s = clamp01(s);
|
|
282
|
+
const _v = clamp01(v);
|
|
232
283
|
|
|
233
284
|
let r, g, b;
|
|
234
285
|
|
package/core/color/hsv2rgb.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { clamp01 } from "../math/clamp01.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
@@ -15,8 +15,8 @@ export function hsv2rgb(h, s, v) {
|
|
|
15
15
|
_h = h + 1;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const _s =
|
|
19
|
-
const _v =
|
|
18
|
+
const _s = clamp01(s);
|
|
19
|
+
const _v = clamp01(v);
|
|
20
20
|
|
|
21
21
|
let r, g, b, i, f, p, q, t;
|
|
22
22
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { clamp01 } from "../math/clamp01.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @see https://www.zombieprototypes.com/?p=210
|
|
5
|
+
* @see https://tannerhelland.com/2012/09/18/convert-temperature-rgb-algorithm-code.html
|
|
6
|
+
* TODO: not sure if output is in linear or sRGB space, looking at the way colors look in Unity - it appears that colors are in sRGB and need to be shifted to linear before being used
|
|
7
|
+
* @param {number[]} result RGB output
|
|
8
|
+
* @param {number} result_offset
|
|
9
|
+
* @param {number} temperature in Kelvin
|
|
10
|
+
*/
|
|
11
|
+
export function kelvin_to_rgb(result, result_offset, temperature) {
|
|
12
|
+
let r;
|
|
13
|
+
let g;
|
|
14
|
+
let b;
|
|
15
|
+
|
|
16
|
+
// Temperature divided by 100 for calculations
|
|
17
|
+
const t = temperature / 100;
|
|
18
|
+
|
|
19
|
+
if (t <= 66) {
|
|
20
|
+
r = 1;
|
|
21
|
+
|
|
22
|
+
g = clamp01(
|
|
23
|
+
-0.6088425710866344 - 0.001748900018414868 * (t - 2) + 0.4097731842899564 * Math.log(t - 2)
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (t <= 20) {
|
|
27
|
+
b = 0;
|
|
28
|
+
} else {
|
|
29
|
+
|
|
30
|
+
b = clamp01(
|
|
31
|
+
-0.9990954974165059 + 0.0032447435545127036 * (t - 10) + 0.453646839257496 * Math.log(t - 10)
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
|
|
37
|
+
r = clamp01(
|
|
38
|
+
1.3803015908551253 + 0.0004478684462124118 * (t - 55) - 0.15785750232675008 * Math.log(t - 55)
|
|
39
|
+
); // in normalized scale
|
|
40
|
+
|
|
41
|
+
g = clamp01(
|
|
42
|
+
1.2762722061615583 + 0.0003115080994769546 * (t - 50) - 0.11013841706194392 * Math.log(t - 50)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
b = 1;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
result[result_offset + 0] = r;
|
|
49
|
+
result[result_offset + 1] = g;
|
|
50
|
+
result[result_offset + 2] = b;
|
|
51
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { kelvin_to_rgb } from "./kelvin_to_rgb.js";
|
|
2
|
+
import { v3_distance } from "../geom/v3_distance.js";
|
|
3
|
+
import { Color } from "./Color.js";
|
|
4
|
+
|
|
5
|
+
function rgb([r255, g255, b255]) {
|
|
6
|
+
return [r255 * 255, g255 * 255, b255 * 255];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function closeTo(actual, expected, error = 0.05) {
|
|
10
|
+
const distance = v3_distance(
|
|
11
|
+
actual[0], actual[1], actual[2],
|
|
12
|
+
expected[0], expected[1], expected[2]
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
expect(distance).toBeLessThan(error * 255);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* NOTE: original function is fit from that dataset
|
|
20
|
+
* @see http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html
|
|
21
|
+
* @type {(number|string)[]}
|
|
22
|
+
*/
|
|
23
|
+
const bbr_color_table_2deg = [
|
|
24
|
+
1000, "#ff3300",
|
|
25
|
+
1100, "#ff4500",
|
|
26
|
+
2000, "#ff8d0b",
|
|
27
|
+
3000, "#ffb969",
|
|
28
|
+
4000, "#ffd5a1",
|
|
29
|
+
5000, "#ffe7cc",
|
|
30
|
+
6000, "#fff4ed",
|
|
31
|
+
7000, "#f7f5ff",
|
|
32
|
+
8000, "#e5e9ff",
|
|
33
|
+
9000, "#d9e1ff",
|
|
34
|
+
10000, "#cfdaff",
|
|
35
|
+
11000, "#c8d5ff",
|
|
36
|
+
12000, "#c3d1ff",
|
|
37
|
+
13000, "#beceff",
|
|
38
|
+
14000, "#bacbff",
|
|
39
|
+
15000, "#b7c9ff",
|
|
40
|
+
15000, "#b7c9ff",
|
|
41
|
+
16000, "#b5c7ff",
|
|
42
|
+
20000, "#adc1ff",
|
|
43
|
+
30000, "#a5baff",
|
|
44
|
+
40000, "#a1b7ff",
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
test("table", () => {
|
|
48
|
+
const t = [];
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < bbr_color_table_2deg.length;) {
|
|
51
|
+
const temp = bbr_color_table_2deg[i++];
|
|
52
|
+
const color = bbr_color_table_2deg[i++];
|
|
53
|
+
|
|
54
|
+
kelvin_to_rgb(t, 0, temp);
|
|
55
|
+
|
|
56
|
+
const color_obj = Color.parse(color);
|
|
57
|
+
|
|
58
|
+
closeTo(rgb(t), [color_obj.r * 255, color_obj.g * 255, color_obj.b * 255]);
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
function convert(c){
|
|
3
|
+
return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {number[]} output
|
|
9
|
+
* @param {number} output_offset
|
|
10
|
+
* @param {number[]} input
|
|
11
|
+
* @param {number} input_offset
|
|
12
|
+
*/
|
|
13
|
+
export function linear_to_sRGB(output, output_offset, input, input_offset) {
|
|
14
|
+
output[output_offset] = convert(input[input_offset]);
|
|
15
|
+
output[output_offset + 1] = convert(input[input_offset + 1]);
|
|
16
|
+
output[output_offset + 2] = convert(input[input_offset + 2]);
|
|
17
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CanvasView } from "../../view/elements/CanvasView.js";
|
|
2
|
+
import { kelvin_to_rgb } from "./kelvin_to_rgb.js";
|
|
3
|
+
import { lerp } from "../math/lerp.js";
|
|
4
|
+
import { Sampler2D } from "../../engine/graphics/texture/sampler/Sampler2D.js";
|
|
5
|
+
import sampler2D2Canvas from "../../engine/graphics/texture/sampler/Sampler2D2Canvas.js";
|
|
6
|
+
import { sRGB_to_linear } from "./sRGB_to_linear.js";
|
|
7
|
+
|
|
8
|
+
const view = new CanvasView();
|
|
9
|
+
|
|
10
|
+
view.css({
|
|
11
|
+
position: 'fixed',
|
|
12
|
+
left: '10px',
|
|
13
|
+
top: '10px',
|
|
14
|
+
zIndex: 5
|
|
15
|
+
});
|
|
16
|
+
view.size.set(400, 50);
|
|
17
|
+
|
|
18
|
+
document.body.append(view.el);
|
|
19
|
+
|
|
20
|
+
view.link();
|
|
21
|
+
|
|
22
|
+
const sampler = Sampler2D.float32(4, 400, 50);
|
|
23
|
+
|
|
24
|
+
const color = [1, 1, 1, 1];
|
|
25
|
+
for (let i = 0; i < sampler.width; i++) {
|
|
26
|
+
const f = i / (sampler.width - 1);
|
|
27
|
+
const k = lerp(1500, 20000, f);
|
|
28
|
+
kelvin_to_rgb(color, 0, k);
|
|
29
|
+
|
|
30
|
+
sRGB_to_linear(color, 0, color, 0);
|
|
31
|
+
|
|
32
|
+
for (let j = 0; j < sampler.height; j++) {
|
|
33
|
+
sampler.set(i, j, color);
|
|
34
|
+
// sampler.set(i, j, [f, f, f, 1]);
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
// sampler.set(i, sampler.height - 1, [f, f, f, 1]);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
console.log(sampler);
|
|
41
|
+
|
|
42
|
+
sampler2D2Canvas(sampler, 255, 0, view.el);
|
|
43
|
+
|
|
44
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { kelvin_to_rgb } from "./kelvin_to_rgb.js";
|
|
2
|
+
|
|
3
|
+
const scratch_rgb = [];
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.zombieprototypes.com/?p=210
|
|
8
|
+
* @param {number[]|ArrayLike<number>|{0:number,1:number,2:number}} input input array
|
|
9
|
+
* @param {number} input_offset offset into input array
|
|
10
|
+
*/
|
|
11
|
+
export function rgb_to_kelvin(input, input_offset = 0) {
|
|
12
|
+
const r = input[input_offset];
|
|
13
|
+
const g = input[input_offset + 1];
|
|
14
|
+
const b = input[input_offset + 2];
|
|
15
|
+
|
|
16
|
+
// use solver to reverse function, slow but hey - it works
|
|
17
|
+
var temperature;
|
|
18
|
+
var epsilon=0.4;
|
|
19
|
+
var minTemperature = 1000;
|
|
20
|
+
var maxTemperature = 40000;
|
|
21
|
+
|
|
22
|
+
while (maxTemperature - minTemperature > epsilon) {
|
|
23
|
+
temperature = (maxTemperature + minTemperature) / 2;
|
|
24
|
+
kelvin_to_rgb(scratch_rgb,0,temperature);
|
|
25
|
+
if ((scratch_rgb[2] / scratch_rgb[0]) >= (b / r)) {
|
|
26
|
+
maxTemperature = temperature;
|
|
27
|
+
} else {
|
|
28
|
+
minTemperature = temperature;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return Math.round(temperature);
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { rgb_to_kelvin } from "./rgb_to_kelvin.js";
|
|
2
|
+
import { Color } from "./Color.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
test("1000 K", () => {
|
|
6
|
+
const actual = rgb_to_kelvin(Color.parse("#ff3e00"));
|
|
7
|
+
|
|
8
|
+
expect(Math.abs(actual - 1000)).toBeLessThan(100);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("40000 K", () => {
|
|
12
|
+
const actual = rgb_to_kelvin(Color.parse("#8cb4ff"));
|
|
13
|
+
|
|
14
|
+
expect(Math.abs(actual - 40000)).toBeLessThan(100);
|
|
15
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function convert(c) {
|
|
2
|
+
return (c < 0.04045) ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {number[]} output
|
|
8
|
+
* @param {number} output_offset
|
|
9
|
+
* @param {number[]} input
|
|
10
|
+
* @param {number} input_offset
|
|
11
|
+
*/
|
|
12
|
+
export function sRGB_to_linear(output, output_offset, input, input_offset) {
|
|
13
|
+
output[output_offset] = convert(input[input_offset]);
|
|
14
|
+
output[output_offset + 1] = convert(input[input_offset + 1]);
|
|
15
|
+
output[output_offset + 2] = convert(input[input_offset + 2]);
|
|
16
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { clamp } from "../../../math/clamp.js";
|
|
2
1
|
import { v3_distance_sqr } from "../../v3_distance_sqr.js";
|
|
2
|
+
import { clamp01 } from "../../../math/clamp01.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Computes shortest distance between a line segment(defined by 2 points) and a point
|
|
@@ -29,7 +29,7 @@ export function line3_computeSegmentPointDistance_sqr(x0, y0, z0, x1, y1, z1, px
|
|
|
29
29
|
|
|
30
30
|
const d3 = line_delta_x * sp0_x + line_delta_y * sp0_y + line_delta_z * sp0_z;
|
|
31
31
|
|
|
32
|
-
const t =
|
|
32
|
+
const t = clamp01(d3 / d2);
|
|
33
33
|
|
|
34
34
|
// compute point on the line
|
|
35
35
|
const lp_x = line_delta_x * t + x0;
|
package/core/geom/LineSegment.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Created by Alex on 18/03/14.
|
|
3
3
|
*/
|
|
4
|
-
import { clamp } from "../math/clamp.js";
|
|
5
4
|
import Vector3 from "./Vector3.js";
|
|
5
|
+
import { clamp01 } from "../math/clamp01.js";
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
const SMALL_NUM = 1e-9;
|
|
@@ -30,7 +30,7 @@ LineSegment.prototype.closestPointToPointParameter = function (point, clampToLin
|
|
|
30
30
|
|
|
31
31
|
if (clampToLine) {
|
|
32
32
|
|
|
33
|
-
t =
|
|
33
|
+
t = clamp01(t);
|
|
34
34
|
|
|
35
35
|
}
|
|
36
36
|
|
package/core/geom/Vector3.js
CHANGED
|
@@ -928,6 +928,20 @@ class Vector3 {
|
|
|
928
928
|
static distance(a, b) {
|
|
929
929
|
return v3_length(a.x - b.x, a.y - b.y, a.z - b.z);
|
|
930
930
|
}
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
*
|
|
934
|
+
* @param {number[]} input
|
|
935
|
+
* @param {number} [offset]
|
|
936
|
+
* @returns {Vector3}
|
|
937
|
+
*/
|
|
938
|
+
static fromArray(input, offset = 0) {
|
|
939
|
+
return new Vector3(
|
|
940
|
+
input[offset],
|
|
941
|
+
input[offset + 1],
|
|
942
|
+
input[offset + 2]
|
|
943
|
+
);
|
|
944
|
+
}
|
|
931
945
|
}
|
|
932
946
|
|
|
933
947
|
Vector3.prototype.lengthSq = Vector3.prototype.lengthSqr;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DEG_TO_RAD = Math.PI / 180;
|
|
@@ -10,7 +10,6 @@ import { min3 } from "./min3.js";
|
|
|
10
10
|
import { sign } from "./sign.js";
|
|
11
11
|
import { isValueBetween } from "./isValueBetween.js";
|
|
12
12
|
import { isValueBetweenInclusive } from "./isValueBetweenInclusive.js";
|
|
13
|
-
import { solveQuadratic } from "./solveQuadratic.js";
|
|
14
13
|
import { overlap1D } from "./overlap1D.js";
|
|
15
14
|
import { computeHashFloat } from "./hash/computeHashFloat.js";
|
|
16
15
|
|
|
@@ -223,18 +222,6 @@ test("isValueBetweenInclusive", () => {
|
|
|
223
222
|
});
|
|
224
223
|
|
|
225
224
|
|
|
226
|
-
test("solveQuadratic", () => {
|
|
227
|
-
expect(solveQuadratic(0, 0, 0)).toStrictEqual([0, 0]);
|
|
228
|
-
|
|
229
|
-
expect(solveQuadratic(0, 0, 1)).toStrictEqual(null);
|
|
230
|
-
|
|
231
|
-
expect(solveQuadratic(0, 2, 3)).toStrictEqual([-1.5, -1.5]);
|
|
232
|
-
|
|
233
|
-
expect(solveQuadratic(1, -2, -3)).toStrictEqual([-1, 3]);
|
|
234
|
-
|
|
235
|
-
expect(solveQuadratic(1, -2, 3)).toBe(null);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
225
|
test('overlap1D', () => {
|
|
239
226
|
expect(overlap1D(0, 0, 0, 0)).toBe(false);
|
|
240
227
|
expect(overlap1D(-3, -1, -2, -0.5)).toBe(true);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const RAD_TO_DEG = 180 / Math.PI;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clamps a value to 0..1 range
|
|
3
|
+
* Same as `clamp(value, 0, 1)`
|
|
4
|
+
* @param {number} value
|
|
5
|
+
* @returns {number}
|
|
6
|
+
*/
|
|
7
|
+
export function clamp01(value) {
|
|
8
|
+
if (value < 0) {
|
|
9
|
+
return 0;
|
|
10
|
+
} else if (value > 1) {
|
|
11
|
+
return 1;
|
|
12
|
+
} else {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* compute the fractional part of the argument
|
|
3
|
+
* GLSL "fract" function port
|
|
4
|
+
* @see https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/fract.xhtml
|
|
5
|
+
* @param {number} v
|
|
6
|
+
* @returns {number} returns the fractional part of x. This is calculated as x - floor(x).
|
|
7
|
+
*/
|
|
8
|
+
export function fract(v) {
|
|
9
|
+
return v % 1;
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Newtonian solver, works by moving along the curve in the direction of gradient
|
|
3
|
+
* @template T
|
|
4
|
+
* @param {function(T):number} f
|
|
5
|
+
* @param {T} xStart
|
|
6
|
+
* @param {number} [max_steps]
|
|
7
|
+
* @param {number} [eps]
|
|
8
|
+
* @returns {number}
|
|
9
|
+
*/
|
|
10
|
+
export function newton_solver_1d(f, xStart, max_steps = 1000, eps = 0.00000001) {
|
|
11
|
+
let x = xStart, fx;
|
|
12
|
+
|
|
13
|
+
let remaining_steps = max_steps;
|
|
14
|
+
|
|
15
|
+
while ((remaining_steps--) && Math.abs(fx = f(x)) > eps) {
|
|
16
|
+
const dfdx = (f(x + eps) - fx) / eps;
|
|
17
|
+
x = x - fx / dfdx;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return x;
|
|
21
|
+
}
|
package/core/math/smoothStep.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { clamp01 } from "./clamp01.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adapted from OpenGL spec
|
|
@@ -11,7 +11,7 @@ export function smoothStep(edge0, edge1, x) {
|
|
|
11
11
|
|
|
12
12
|
const span = edge1 - edge0;
|
|
13
13
|
|
|
14
|
-
const t =
|
|
14
|
+
const t = clamp01((x - edge0) / span);
|
|
15
15
|
|
|
16
16
|
return t * t * (3 - 2 * t);
|
|
17
|
-
}
|
|
17
|
+
}
|
|
@@ -1,25 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Return solutions for quadratic
|
|
2
|
+
* Return solutions for a quadratic equation
|
|
3
3
|
* @param {number} a
|
|
4
4
|
* @param {number} b
|
|
5
5
|
* @param {number} c
|
|
6
|
-
* @
|
|
6
|
+
* @param {number[]} result solutions are written here
|
|
7
|
+
* @param {number} result_offset offset into result array where solutions are written to
|
|
8
|
+
* @returns {number} number of found solutions (roots)
|
|
7
9
|
*/
|
|
8
|
-
export function solveQuadratic(a, b, c) {
|
|
9
|
-
|
|
10
|
+
export function solveQuadratic(result, result_offset, a, b, c) {
|
|
11
|
+
|
|
10
12
|
if (Math.abs(a) < 1e-6) {
|
|
11
13
|
if (Math.abs(b) < 1e-6) {
|
|
12
|
-
|
|
14
|
+
if (Math.abs(c) < 1e-6) {
|
|
15
|
+
|
|
16
|
+
result[result_offset] = 0;
|
|
17
|
+
result[result_offset + 1] = 0;
|
|
18
|
+
|
|
19
|
+
return 2;
|
|
20
|
+
|
|
21
|
+
}
|
|
13
22
|
} else {
|
|
14
|
-
|
|
23
|
+
result[result_offset] = -c / b;
|
|
24
|
+
result[result_offset + 1] = -c / b;
|
|
25
|
+
|
|
26
|
+
return 2;
|
|
15
27
|
}
|
|
16
28
|
} else {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
const disc_sqr = b * b - 4 * a * c;
|
|
30
|
+
|
|
31
|
+
if (disc_sqr >= 0) {
|
|
32
|
+
const disc = Math.sqrt(disc_sqr);
|
|
33
|
+
const a2 = 2 * a;
|
|
34
|
+
|
|
35
|
+
result[result_offset] = (-b - disc) / a2;
|
|
36
|
+
result[result_offset + 1] = (-b + disc) / a2;
|
|
37
|
+
|
|
38
|
+
return 2;
|
|
22
39
|
}
|
|
40
|
+
|
|
23
41
|
}
|
|
24
|
-
|
|
42
|
+
|
|
43
|
+
// no roots
|
|
44
|
+
return 0;
|
|
25
45
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { solveQuadratic } from "./solveQuadratic.js";
|
|
2
|
+
|
|
3
|
+
test("solveQuadratic", () => {
|
|
4
|
+
const roots = [];
|
|
5
|
+
|
|
6
|
+
solveQuadratic(roots, 0, 0, 0, 0)
|
|
7
|
+
expect(roots).toStrictEqual([0, 0]);
|
|
8
|
+
|
|
9
|
+
expect(solveQuadratic(roots, 0, 0, 0, 1)).toStrictEqual(0);
|
|
10
|
+
|
|
11
|
+
solveQuadratic(roots, 0, 0, 2, 3);
|
|
12
|
+
expect(roots).toStrictEqual([-1.5, -1.5]);
|
|
13
|
+
|
|
14
|
+
solveQuadratic(roots, 0, 1, -2, -3);
|
|
15
|
+
expect(roots).toStrictEqual([-1, 3]);
|
|
16
|
+
|
|
17
|
+
expect(solveQuadratic(roots, 0, 1, -2, 3)).toBe(0);
|
|
18
|
+
});
|
|
@@ -93,3 +93,13 @@ export function computeCommonPrefix(strings) {
|
|
|
93
93
|
export function camelToKebab(string) {
|
|
94
94
|
return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
95
95
|
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
*
|
|
100
|
+
* @param {string} string
|
|
101
|
+
* @returns {string}
|
|
102
|
+
*/
|
|
103
|
+
export function kebabToUnderscore(string) {
|
|
104
|
+
return string.replace('-', '_');
|
|
105
|
+
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Created by Alex on 22/05/2016.
|
|
3
3
|
*/
|
|
4
4
|
import { randomizeArrayElementOrder } from "../../collection/ArrayUtils.js";
|
|
5
|
-
import { clamp } from "../../math/clamp.js";
|
|
6
5
|
import { seededRandom } from "../../math/random/seededRandom.js";
|
|
7
6
|
import Task from "./Task.js";
|
|
8
7
|
import TaskSignal from "./TaskSignal.js";
|
|
8
|
+
import { clamp01 } from "../../math/clamp01.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
*
|
|
@@ -180,7 +180,7 @@ export function delayTask(delay, name = "unnamed") {
|
|
|
180
180
|
fraction = 0;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
return
|
|
183
|
+
return clamp01(fraction);
|
|
184
184
|
},
|
|
185
185
|
estimatedDuration
|
|
186
186
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { clamp } from "../../../../../core/math/clamp.js";
|
|
2
1
|
import GuiControl from "../../../../../view/controller/controls/GuiControl.js";
|
|
3
2
|
import EmptyView from "../../../../../view/elements/EmptyView.js";
|
|
4
3
|
import LabelView from "../../../../../view/common/LabelView.js";
|
|
5
4
|
import { PointerDevice } from "../../../../../engine/input/devices/PointerDevice.js";
|
|
6
5
|
import { AutoCanvasView } from "../common/AutoCanvasView.js";
|
|
6
|
+
import { clamp01 } from "../../../../../core/math/clamp01.js";
|
|
7
7
|
|
|
8
8
|
export class GaugeView extends GuiControl {
|
|
9
9
|
/**
|
|
@@ -80,7 +80,7 @@ export class GaugeView extends GuiControl {
|
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
model.set(
|
|
83
|
+
model.set(clamp01(v));
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
function setValueFromMouseEvent(event) {
|