@woosh/meep-engine 2.75.8 → 2.75.9
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/build/bundle-worker-terrain.js +1 -1
- package/build/meep.cjs +784 -982
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +784 -982
- package/editor/actions/concrete/ModifyPatchSampler2DAction.js +6 -3
- package/editor/actions/concrete/PatchTerrainTextureAction.js +6 -3
- package/editor/process/EditorProcess.js +12 -16
- package/editor/process/ProcessEngine.js +9 -10
- package/package.json +1 -1
- package/src/core/binary/dec2hex.js +1 -1
- package/src/{engine/ecs/ik/IKMath.js → core/geom/vec3/v3_computeOffsetVector.js} +1 -1
- package/src/core/math/newton_solver_1d.js +13 -4
- package/src/core/math/solveQuadratic.js +5 -3
- package/src/core/math/spline/catmull_rom_compute_T.js +19 -0
- package/src/{engine/navigation/ecs/components → core/math/spline}/computeCatmullRomSpline.js +3 -3
- package/src/{engine/navigation/ecs/components → core/math/spline}/computeCatmullRomSplineUniformDistance.js +3 -3
- package/src/core/math/spline/computeNonuniformCatmullRomSplineSample.js +109 -0
- package/src/core/math/spline/interpolate_bicubic.js +12 -0
- package/src/core/math/spline/spline_catmullrom_1d.js +120 -0
- package/src/engine/control/ControlContext.js +25 -27
- package/src/engine/ecs/EntityManager.js +12 -9
- package/src/engine/ecs/EntityObserver.js +26 -22
- package/src/engine/ecs/binding/ComponentPropertyPath.js +12 -12
- package/src/engine/ecs/components/Motion.js +5 -7
- package/src/engine/ecs/components/SerializationMetadata.js +5 -3
- package/src/engine/ecs/dynamic_actions/actions/definition/AbstractActionDescription.js +0 -2
- package/src/engine/ecs/dynamic_actions/actions/definition/ActionSequenceDescription.js +7 -9
- package/src/engine/ecs/dynamic_actions/actions/definition/DelayActionDescription.js +3 -5
- package/src/engine/ecs/dynamic_actions/actions/definition/SendRequestActionDescription.js +6 -8
- package/src/engine/ecs/dynamic_actions/actions/definition/SpeakLineActionDescription.js +14 -17
- package/src/engine/ecs/dynamic_actions/actions/definition/WeightedRandomActionDescription.js +8 -11
- package/src/engine/ecs/dynamic_actions/actions/definition/WriteToBlackboardActionDescription.js +15 -18
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +7 -7
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +6 -6
- package/src/engine/ecs/parent/EntityNode.js +39 -37
- package/src/engine/ecs/speaker/VoiceSystem.js +36 -39
- package/src/engine/ecs/system/SystemEntityContext.js +25 -23
- package/src/engine/ecs/tag/find_entities_with_tag.js +18 -0
- package/src/engine/ecs/terrain/TerrainClouds.js +23 -24
- package/src/engine/ecs/terrain/ecs/splat/SplatMapMaterialPatch.js +5 -2
- package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +15 -14
- package/src/engine/ecs/tooltip/TooltipComponent.js +6 -7
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +0 -4
- package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +1 -5
- package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +2 -6
- package/src/engine/graphics/ecs/water2/shader/testWaterShader.js +12 -14
- package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +22 -20
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +3 -4
- package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +0 -4
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +0 -4
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +0 -4
- package/src/engine/graphics/shadows/testShadowMapRendering.js +0 -2
- package/src/engine/graphics/texture/atlas/TextureAtlas.js +13 -11
- package/src/engine/graphics/texture/sampler/Sampler2D.js +15 -366
- package/src/engine/graphics/texture/sampler/Sampler2D.spec.js +0 -31
- package/src/engine/graphics/texture/sampler/sampler2d_copy_with_margins.js +166 -0
- package/src/engine/graphics/texture/sampler/sampler2d_copy_with_margins.spec.js +31 -0
- package/src/engine/graphics/texture/sampler/sampler2d_paint.js +81 -0
- package/src/engine/graphics/texture/sampler/sampler2d_sub_copy_same_item_size.js +50 -0
- package/src/engine/navigation/ecs/components/Path.js +10 -9
- package/src/engine/physics/computeInterceptPoint.js +44 -0
- package/src/engine/plugin/EnginePlugin.js +1 -2
- package/src/engine/ecs/components/AlignToVelocity.js +0 -9
- package/src/engine/ecs/components/CharacterController.js +0 -31
- package/src/engine/ecs/components/PhysicalBody.js +0 -51
- package/src/engine/ecs/components/Steering.js +0 -111
- package/src/engine/ecs/components/SteeringSerializationAdapter.js +0 -34
- package/src/engine/ecs/systems/AlignToVelocitySystem.js +0 -51
- package/src/engine/ecs/systems/CharacterControlSystem.js +0 -134
- package/src/engine/ecs/systems/PhysicsSystem.js +0 -89
- package/src/engine/ecs/systems/PropertySetSystem.js +0 -18
- package/src/engine/ecs/systems/SteeringSystem.js +0 -171
- package/src/engine/ecs/systems/TagSystem.d.ts +0 -5
- package/src/engine/ecs/systems/TagSystem.js +0 -31
- package/src/engine/graphics/texture/sampler/bicubic.js +0 -59
- package/src/engine/graphics/texture/sampler/bicubic.spec.js +0 -13
- package/src/engine/navigation/ecs/components/computeNonuniformCatmullRomSplineSample.js +0 -242
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
import { clamp } from "../../../../core/math/clamp.js";
|
|
7
|
-
import { max2 } from "../../../../core/math/max2.js";
|
|
8
|
-
import { min2 } from "../../../../core/math/min2.js";
|
|
9
|
-
import { mix } from "../../../../core/math/mix.js";
|
|
10
|
-
import { BlendingType } from "./BlendingType.js";
|
|
11
6
|
import { assert } from "../../../../core/assert.js";
|
|
12
|
-
import {
|
|
13
|
-
import { typedArrayToDataType } from "../../../../core/collection/array/typed/typedArrayToDataType.js";
|
|
7
|
+
import { Base64 } from "../../../../core/binary/Base64.js";
|
|
14
8
|
import {
|
|
15
9
|
compute_typed_array_constructor_from_data_type
|
|
16
10
|
} from "../../../../core/binary/type/DataType2TypedArrayConstructorMapping.js";
|
|
17
|
-
import { Base64 } from "../../../../core/binary/Base64.js";
|
|
18
|
-
import { computeStridedIntegerArrayHash } from "../../../../core/primitives/array/computeStridedIntegerArrayHash.js";
|
|
19
11
|
import { is_typed_array_equals } from "../../../../core/collection/array/typed/is_typed_array_equals.js";
|
|
12
|
+
import { typedArrayToDataType } from "../../../../core/collection/array/typed/typedArrayToDataType.js";
|
|
13
|
+
import { clamp } from "../../../../core/math/clamp.js";
|
|
14
|
+
import { max2 } from "../../../../core/math/max2.js";
|
|
15
|
+
import { min2 } from "../../../../core/math/min2.js";
|
|
16
|
+
import { mix } from "../../../../core/math/mix.js";
|
|
17
|
+
import { interpolate_bicubic } from "../../../../core/math/spline/interpolate_bicubic.js";
|
|
18
|
+
import { computeStridedIntegerArrayHash } from "../../../../core/primitives/array/computeStridedIntegerArrayHash.js";
|
|
19
|
+
import { typedArrayConstructorByInstance } from "./typedArrayConstructorByInstance.js";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Data Texture class, providing an abstraction around 2d numerical arrays, mostly for sampling purposes
|
|
@@ -82,35 +82,6 @@ export class Sampler2D {
|
|
|
82
82
|
this.version = 0;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
/**
|
|
86
|
-
* @deprecated
|
|
87
|
-
* @param {number} [channel=0]
|
|
88
|
-
* @returns {{x: number, index: number, y: number, value: number}}
|
|
89
|
-
*/
|
|
90
|
-
computeMax(channel = 0) {
|
|
91
|
-
throw new Error("deprecated, use sampler2d_channel_compute_max");
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* @deprecated
|
|
96
|
-
* @param {number[]} result
|
|
97
|
-
* @param {number} result_offset
|
|
98
|
-
* @param {number} [channel=0]
|
|
99
|
-
* @returns {number} number of matches written to result array
|
|
100
|
-
*/
|
|
101
|
-
computeMinIndices(result, result_offset = 0, channel = 0) {
|
|
102
|
-
throw new Error("deprecated, use sampler2d_channel_compute_min_indices")
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @deprecated
|
|
107
|
-
* @param {number} [channel=0]
|
|
108
|
-
* @returns {{x: number, index: number, y: number, value: number}}
|
|
109
|
-
*/
|
|
110
|
-
computeMin(channel = 0) {
|
|
111
|
-
throw new Error("deprecated, use sampler2d_channel_compute_min");
|
|
112
|
-
}
|
|
113
|
-
|
|
114
85
|
/**
|
|
115
86
|
*
|
|
116
87
|
* @deprecated
|
|
@@ -120,18 +91,7 @@ export class Sampler2D {
|
|
|
120
91
|
* @returns {number}
|
|
121
92
|
*/
|
|
122
93
|
get(x, y, result) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const t = [];
|
|
126
|
-
|
|
127
|
-
this.sampleBilinear(x, y, t, 0);
|
|
128
|
-
|
|
129
|
-
if (result !== undefined) {
|
|
130
|
-
result.readFromArray(t, 0);
|
|
131
|
-
return result;
|
|
132
|
-
} else {
|
|
133
|
-
return t[0];
|
|
134
|
-
}
|
|
94
|
+
throw new Error("Deprecated method, use sampleBilinear instead");
|
|
135
95
|
}
|
|
136
96
|
|
|
137
97
|
/**
|
|
@@ -334,23 +294,14 @@ export class Sampler2D {
|
|
|
334
294
|
const vl2 = data[row3_address + col2_offset];
|
|
335
295
|
const vl3 = data[row3_address + col3_offset];
|
|
336
296
|
|
|
337
|
-
|
|
338
|
-
// return bicubic(xd, yd,
|
|
339
|
-
// vi0, vi1, vi2, vi3,
|
|
340
|
-
// vj0, vj1, vj2, vj3,
|
|
341
|
-
// vk0, vk1, vk2, vk3,
|
|
342
|
-
// vl0, vl1, vl2, vl3,
|
|
343
|
-
// );
|
|
344
|
-
|
|
345
|
-
|
|
346
297
|
// perform filtering in X (rows)
|
|
347
|
-
const s0 =
|
|
348
|
-
const s1 =
|
|
349
|
-
const s2 =
|
|
350
|
-
const s3 =
|
|
298
|
+
const s0 = interpolate_bicubic(xd, vi0, vi1, vi2, vi3);
|
|
299
|
+
const s1 = interpolate_bicubic(xd, vj0, vj1, vj2, vj3);
|
|
300
|
+
const s2 = interpolate_bicubic(xd, vk0, vk1, vk2, vk3);
|
|
301
|
+
const s3 = interpolate_bicubic(xd, vl0, vl1, vl2, vl3);
|
|
351
302
|
|
|
352
303
|
// filter in Y (columns)
|
|
353
|
-
return
|
|
304
|
+
return interpolate_bicubic(yd, s0, s1, s2, s3);
|
|
354
305
|
}
|
|
355
306
|
|
|
356
307
|
/**
|
|
@@ -589,162 +540,6 @@ export class Sampler2D {
|
|
|
589
540
|
result.set(x, y);
|
|
590
541
|
}
|
|
591
542
|
|
|
592
|
-
/**
|
|
593
|
-
* Copy a patch from another sampler with a margin.
|
|
594
|
-
* This is useful for texture rendering where filtering can cause bleeding along the edges of the patch.
|
|
595
|
-
* @param {Sampler2D} source where to copy from
|
|
596
|
-
* @param {Number} sourceX where to start reading from, X coordinate
|
|
597
|
-
* @param {Number} sourceY where to start reading from, X coordinate
|
|
598
|
-
* @param {Number} destinationX where to start writing to, X coordinate
|
|
599
|
-
* @param {Number} destinationY where to start writing to, X coordinate
|
|
600
|
-
* @param {Number} width size of the patch that is to be copied
|
|
601
|
-
* @param {Number} height size of the patch that is to be copied
|
|
602
|
-
* @param {Number} marginLeft
|
|
603
|
-
* @param {Number} marginRight
|
|
604
|
-
* @param {Number} marginTop
|
|
605
|
-
* @param {Number} marginBottom
|
|
606
|
-
*/
|
|
607
|
-
copyWithMargin(source, sourceX, sourceY, destinationX, destinationY, width, height, marginLeft, marginRight, marginTop, marginBottom) {
|
|
608
|
-
const dItemSize = this.itemSize;
|
|
609
|
-
const sItemSize = source.itemSize;
|
|
610
|
-
const _itemSize = Math.min(dItemSize, sItemSize);
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
const dRowSize = dItemSize * this.width;
|
|
614
|
-
const sRowSize = sItemSize * source.width;
|
|
615
|
-
|
|
616
|
-
const sData = source.data;
|
|
617
|
-
const dData = this.data;
|
|
618
|
-
|
|
619
|
-
let x, y, i, j;
|
|
620
|
-
|
|
621
|
-
let xMax, yMax;
|
|
622
|
-
|
|
623
|
-
let dA, sA, dOffset, sOffset;
|
|
624
|
-
//Write top-left corner
|
|
625
|
-
sOffset = sourceY * sRowSize + sourceX * dItemSize;
|
|
626
|
-
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
|
|
627
|
-
dA = y * dRowSize;
|
|
628
|
-
|
|
629
|
-
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
|
|
630
|
-
|
|
631
|
-
dOffset = dA + x * dItemSize;
|
|
632
|
-
|
|
633
|
-
for (i = 0; i < _itemSize; i++) {
|
|
634
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
//Write top margin
|
|
639
|
-
sA = sourceY * sRowSize;
|
|
640
|
-
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
|
|
641
|
-
dA = y * dRowSize;
|
|
642
|
-
|
|
643
|
-
for (x = 0; x < width; x++) {
|
|
644
|
-
|
|
645
|
-
dOffset = dA + (x + destinationX) * dItemSize;
|
|
646
|
-
sOffset = sA + (x + sourceX) * dItemSize;
|
|
647
|
-
for (i = 0; i < _itemSize; i++) {
|
|
648
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
//Write top-right corner
|
|
653
|
-
sOffset = sourceY * sRowSize + (sourceX + width - 1) * dItemSize;
|
|
654
|
-
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
|
|
655
|
-
dA = y * dRowSize;
|
|
656
|
-
|
|
657
|
-
for (x = destinationX + width, xMax = Math.min(this.width, x + marginRight); x < xMax; x++) {
|
|
658
|
-
|
|
659
|
-
dOffset = dA + x * dItemSize;
|
|
660
|
-
|
|
661
|
-
for (i = 0; i < _itemSize; i++) {
|
|
662
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
//Write left margin
|
|
667
|
-
for (y = 0; y < height; y++) {
|
|
668
|
-
dA = (y + destinationY) * dRowSize;
|
|
669
|
-
sA = (y + sourceY) * sRowSize;
|
|
670
|
-
|
|
671
|
-
sOffset = sA + (sourceX) * dItemSize;
|
|
672
|
-
|
|
673
|
-
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
|
|
674
|
-
|
|
675
|
-
dOffset = dA + x * dItemSize;
|
|
676
|
-
|
|
677
|
-
for (i = 0; i < _itemSize; i++) {
|
|
678
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
//write actual patch
|
|
683
|
-
this.copy(source, sourceX, sourceY, destinationX, destinationY, width, height);
|
|
684
|
-
|
|
685
|
-
//Write right margin
|
|
686
|
-
for (y = 0; y < height; y++) {
|
|
687
|
-
dA = (y + destinationY) * dRowSize;
|
|
688
|
-
sA = (y + sourceY) * sRowSize;
|
|
689
|
-
|
|
690
|
-
sOffset = sA + (sourceX + width - 1) * dItemSize;
|
|
691
|
-
|
|
692
|
-
for (x = destinationX + width, xMax = Math.min(this.width, x + marginRight); x < xMax; x++) {
|
|
693
|
-
|
|
694
|
-
dOffset = dA + x * dItemSize;
|
|
695
|
-
|
|
696
|
-
for (i = 0; i < _itemSize; i++) {
|
|
697
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
//Write Bottom-left margin
|
|
703
|
-
sOffset = (sourceY + height - 1) * sRowSize + sourceX * dItemSize;
|
|
704
|
-
for (y = destinationY + width, yMax = Math.min(this.height, y + marginBottom); y < yMax; y++) {
|
|
705
|
-
dA = y * dRowSize;
|
|
706
|
-
|
|
707
|
-
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
|
|
708
|
-
|
|
709
|
-
dOffset = dA + x * dItemSize;
|
|
710
|
-
|
|
711
|
-
for (i = 0; i < _itemSize; i++) {
|
|
712
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
//Write Bottom margin
|
|
717
|
-
sA = (sourceY + height - 1) * sRowSize;
|
|
718
|
-
for (y = destinationY + width, yMax = Math.min(this.height, y + marginBottom); y < yMax; y++) {
|
|
719
|
-
dA = y * dRowSize;
|
|
720
|
-
|
|
721
|
-
for (x = 0; x < width; x++) {
|
|
722
|
-
|
|
723
|
-
dOffset = dA + (x + destinationX) * dItemSize;
|
|
724
|
-
sOffset = sA + (x + sourceX) * dItemSize;
|
|
725
|
-
for (i = 0; i < _itemSize; i++) {
|
|
726
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
//Write Bottom-right margin
|
|
731
|
-
sOffset = (sourceY + height - 1) * sRowSize + (sourceX + width - 1) * dItemSize;
|
|
732
|
-
for (y = destinationY + width, yMax = Math.min(this.height, y + marginBottom); y < yMax; y++) {
|
|
733
|
-
dA = y * dRowSize;
|
|
734
|
-
|
|
735
|
-
for (x = destinationX + width, xMax = Math.min(this.width, x + marginRight); x < xMax; x++) {
|
|
736
|
-
|
|
737
|
-
dOffset = dA + x * dItemSize;
|
|
738
|
-
|
|
739
|
-
for (i = 0; i < _itemSize; i++) {
|
|
740
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
this.version++;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
543
|
/**
|
|
749
544
|
* Copy a patch from another sampler
|
|
750
545
|
* @param {Sampler2D} source where to copy from
|
|
@@ -801,106 +596,6 @@ export class Sampler2D {
|
|
|
801
596
|
this.version++;
|
|
802
597
|
}
|
|
803
598
|
|
|
804
|
-
/**
|
|
805
|
-
* Copy a patch from another sampler with the same itemSize
|
|
806
|
-
* @param {Sampler2D} source where to copy from
|
|
807
|
-
* @param {Number} sourceX where to start reading from, X coordinate
|
|
808
|
-
* @param {Number} sourceY where to start reading from, X coordinate
|
|
809
|
-
* @param {Number} destinationX where to start writing to, X coordinate
|
|
810
|
-
* @param {Number} destinationY where to start writing to, X coordinate
|
|
811
|
-
* @param {Number} width size of the patch that is to be copied
|
|
812
|
-
* @param {Number} height size of the patch that is to be copied
|
|
813
|
-
*/
|
|
814
|
-
copy_sameItemSize(source, sourceX, sourceY, destinationX, destinationY, width, height) {
|
|
815
|
-
const itemSize = this.itemSize;
|
|
816
|
-
const sItemSize = source.itemSize;
|
|
817
|
-
|
|
818
|
-
assert.equal(sItemSize, sItemSize, `source.itemSize(=${sItemSize}) != this.itemSize(=${itemSize})`);
|
|
819
|
-
|
|
820
|
-
const _w = Math.min(width, source.width - sourceX, this.width - destinationX);
|
|
821
|
-
const _h = Math.min(height, source.height - sourceY, this.height - destinationY);
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
const dRowSize = itemSize * this.width;
|
|
825
|
-
const sRowSize = itemSize * source.width;
|
|
826
|
-
|
|
827
|
-
const sData = source.data;
|
|
828
|
-
const dData = this.data;
|
|
829
|
-
|
|
830
|
-
const patchRowSize = _w * itemSize;
|
|
831
|
-
|
|
832
|
-
let y, i;
|
|
833
|
-
|
|
834
|
-
for (y = 0; y < _h; y++) {
|
|
835
|
-
const dA = (y + destinationY) * dRowSize;
|
|
836
|
-
const sA = (y + sourceY) * sRowSize;
|
|
837
|
-
|
|
838
|
-
const dOffset = dA + destinationX * itemSize;
|
|
839
|
-
const sOffset = sA + sourceX * itemSize;
|
|
840
|
-
|
|
841
|
-
for (i = 0; i < patchRowSize; i++) {
|
|
842
|
-
|
|
843
|
-
dData[dOffset + i] = sData[sOffset + i];
|
|
844
|
-
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
this.version++;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
/**
|
|
852
|
-
* Assumes both samplers are uint8 with values 0-255
|
|
853
|
-
* @param {Sampler2D} source
|
|
854
|
-
* @param sourceX
|
|
855
|
-
* @param sourceY
|
|
856
|
-
* @param destinationX
|
|
857
|
-
* @param destinationY
|
|
858
|
-
* @param width
|
|
859
|
-
* @param height
|
|
860
|
-
* @param {BlendingType} [blendMode]
|
|
861
|
-
*/
|
|
862
|
-
paint(source, sourceX, sourceY, destinationX, destinationY, width, height, blendMode = BlendingType.Normal) {
|
|
863
|
-
let blendFunction;
|
|
864
|
-
if (blendMode === BlendingType.Normal) {
|
|
865
|
-
blendFunction = blendFunctionNormal;
|
|
866
|
-
} else {
|
|
867
|
-
throw new Error(`Unsupported blendType(=${blendMode})`);
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
const _w = Math.min(width, source.width - sourceX, this.width - destinationX);
|
|
871
|
-
const _h = Math.min(height, source.height - sourceY, this.height - destinationY);
|
|
872
|
-
|
|
873
|
-
const _x0 = Math.max(0, -destinationX);
|
|
874
|
-
const _y0 = Math.max(0, -destinationY);
|
|
875
|
-
|
|
876
|
-
const c0 = [0, 0, 0, 255];
|
|
877
|
-
const c1 = [0, 0, 0, 255];
|
|
878
|
-
|
|
879
|
-
const c3 = [];
|
|
880
|
-
|
|
881
|
-
let x, y;
|
|
882
|
-
|
|
883
|
-
for (y = _y0; y < _h; y++) {
|
|
884
|
-
for (x = _x0; x < _w; x++) {
|
|
885
|
-
const d_x = Math.round(x + destinationX);
|
|
886
|
-
const d_y = Math.round(y + destinationY);
|
|
887
|
-
|
|
888
|
-
this.read(d_x, d_y, c0);
|
|
889
|
-
|
|
890
|
-
const s_x = Math.round(x + sourceY);
|
|
891
|
-
const s_y = Math.round(y + sourceY);
|
|
892
|
-
|
|
893
|
-
source.read(s_x, s_y, c1);
|
|
894
|
-
|
|
895
|
-
blendFunction(c1, c0, c3);
|
|
896
|
-
|
|
897
|
-
this.set(d_x, d_y, c3);
|
|
898
|
-
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
}
|
|
904
599
|
|
|
905
600
|
/**
|
|
906
601
|
* Fill data values with zeros for a given area
|
|
@@ -1161,22 +856,6 @@ export class Sampler2D {
|
|
|
1161
856
|
return dataSize + 280;
|
|
1162
857
|
}
|
|
1163
858
|
|
|
1164
|
-
/**
|
|
1165
|
-
* @deprecated Use {@link Sampler2DSerializationAdapter} adapter instead
|
|
1166
|
-
* @param {BinaryBuffer} buffer
|
|
1167
|
-
*/
|
|
1168
|
-
toBinaryBuffer(buffer) {
|
|
1169
|
-
throw new Error('Deprecated, use Sampler2DSerializationAdapter instead');
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
/**
|
|
1173
|
-
* @deprecated Use {@link Sampler2DSerializationAdapter} adapter instead
|
|
1174
|
-
* @param {BinaryBuffer} buffer
|
|
1175
|
-
*/
|
|
1176
|
-
fromBinaryBuffer(buffer) {
|
|
1177
|
-
throw new Error('Deprecated, use Sampler2DSerializationAdapter instead');
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
859
|
/**
|
|
1181
860
|
*
|
|
1182
861
|
* @param {Sampler2D} other
|
|
@@ -1389,35 +1068,5 @@ Sampler2D.prototype.isSampler2D = true;
|
|
|
1389
1068
|
*/
|
|
1390
1069
|
Sampler2D.typeName = "Sampler2D";
|
|
1391
1070
|
|
|
1392
|
-
/**
|
|
1393
|
-
* Based on code from reddit https://www.reddit.com/r/javascript/comments/jxa8x/bicubic_interpolation/
|
|
1394
|
-
* @param {number} t
|
|
1395
|
-
* @param {number} a
|
|
1396
|
-
* @param {number} b
|
|
1397
|
-
* @param {number} c
|
|
1398
|
-
* @param {number} d
|
|
1399
|
-
* @returns {number}
|
|
1400
|
-
*/
|
|
1401
|
-
function bicubic_terp(t, a, b, c, d) {
|
|
1402
|
-
return 0.5 * (c - a + (2.0 * a - 5.0 * b + 4.0 * c - d + (3.0 * (b - c) + d - a) * t) * t) * t + b;
|
|
1403
|
-
}
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
/**
|
|
1407
|
-
*
|
|
1408
|
-
* @param {number[]} source
|
|
1409
|
-
* @param {number[]} destination
|
|
1410
|
-
* @param {Array} result
|
|
1411
|
-
*/
|
|
1412
|
-
function blendFunctionNormal(source, destination, result) {
|
|
1413
|
-
|
|
1414
|
-
const a1 = source[3] / 255;
|
|
1415
|
-
const a0 = destination[3] / 255;
|
|
1416
|
-
|
|
1417
|
-
result[0] = source[0] * a1 + destination[0] * (1 - a1);
|
|
1418
|
-
result[1] = source[1] * a1 + destination[1] * (1 - a1);
|
|
1419
|
-
result[2] = source[2] * a1 + destination[2] * (1 - a1);
|
|
1420
|
-
result[3] = (a1 + a0 * (1 - a1)) * 255;
|
|
1421
|
-
}
|
|
1422
1071
|
|
|
1423
1072
|
|
|
@@ -222,34 +222,3 @@ describe("copy method", () => {
|
|
|
222
222
|
expect(target.readChannel(1, 1, 0)).toBe(2);
|
|
223
223
|
});
|
|
224
224
|
});
|
|
225
|
-
|
|
226
|
-
describe("copyWithMargin method", () => {
|
|
227
|
-
test("one texel patch with 1 texel margin all around", () => {
|
|
228
|
-
const target = Sampler2D.uint8(1, 3, 3);
|
|
229
|
-
target.data[0] = 1;
|
|
230
|
-
|
|
231
|
-
const source = Sampler2D.uint8(1, 1, 1);
|
|
232
|
-
source.data[0] = 2;
|
|
233
|
-
|
|
234
|
-
target.copyWithMargin(source, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1);
|
|
235
|
-
|
|
236
|
-
//top left
|
|
237
|
-
expect(target.readChannel(0, 0, 0)).toEqual(2);
|
|
238
|
-
//top
|
|
239
|
-
expect(target.readChannel(1, 0, 0)).toEqual(2);
|
|
240
|
-
//top right
|
|
241
|
-
expect(target.readChannel(2, 0, 0)).toEqual(2);
|
|
242
|
-
//left
|
|
243
|
-
expect(target.readChannel(0, 1, 0)).toEqual(2);
|
|
244
|
-
//copied region
|
|
245
|
-
expect(target.readChannel(1, 1, 0)).toEqual(2);
|
|
246
|
-
//right
|
|
247
|
-
expect(target.readChannel(2, 1, 0)).toEqual(2);
|
|
248
|
-
//bottom left
|
|
249
|
-
expect(target.readChannel(0, 2, 0)).toEqual(2);
|
|
250
|
-
//bottom
|
|
251
|
-
expect(target.readChannel(1, 2, 0)).toEqual(2);
|
|
252
|
-
//bottom right
|
|
253
|
-
expect(target.readChannel(2, 2, 0)).toEqual(2);
|
|
254
|
-
});
|
|
255
|
-
});
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy a patch from another sampler with a margin.
|
|
3
|
+
* This is useful for texture rendering where filtering can cause bleeding along the edges of the patch.
|
|
4
|
+
* @param {Sampler2D} destination
|
|
5
|
+
* @param {Sampler2D} source where to copy from
|
|
6
|
+
* @param {Number} sourceX where to start reading from, X coordinate
|
|
7
|
+
* @param {Number} sourceY where to start reading from, X coordinate
|
|
8
|
+
* @param {Number} destinationX where to start writing to, X coordinate
|
|
9
|
+
* @param {Number} destinationY where to start writing to, X coordinate
|
|
10
|
+
* @param {Number} width size of the patch that is to be copied
|
|
11
|
+
* @param {Number} height size of the patch that is to be copied
|
|
12
|
+
* @param {Number} marginLeft
|
|
13
|
+
* @param {Number} marginRight
|
|
14
|
+
* @param {Number} marginTop
|
|
15
|
+
* @param {Number} marginBottom
|
|
16
|
+
*/
|
|
17
|
+
export function sampler2d_copy_with_margins(
|
|
18
|
+
destination,
|
|
19
|
+
source,
|
|
20
|
+
sourceX, sourceY,
|
|
21
|
+
destinationX, destinationY,
|
|
22
|
+
width, height,
|
|
23
|
+
marginLeft,
|
|
24
|
+
marginRight,
|
|
25
|
+
marginTop,
|
|
26
|
+
marginBottom
|
|
27
|
+
) {
|
|
28
|
+
const dItemSize = destination.itemSize;
|
|
29
|
+
const sItemSize = source.itemSize;
|
|
30
|
+
const _itemSize = Math.min(dItemSize, sItemSize);
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
const dRowSize = dItemSize * destination.width;
|
|
34
|
+
const sRowSize = sItemSize * source.width;
|
|
35
|
+
|
|
36
|
+
const sData = source.data;
|
|
37
|
+
const dData = destination.data;
|
|
38
|
+
|
|
39
|
+
let x, y, i;
|
|
40
|
+
|
|
41
|
+
let xMax, yMax;
|
|
42
|
+
|
|
43
|
+
let dA, sA, dOffset, sOffset;
|
|
44
|
+
//Write top-left corner
|
|
45
|
+
sOffset = sourceY * sRowSize + sourceX * dItemSize;
|
|
46
|
+
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
|
|
47
|
+
dA = y * dRowSize;
|
|
48
|
+
|
|
49
|
+
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
|
|
50
|
+
|
|
51
|
+
dOffset = dA + x * dItemSize;
|
|
52
|
+
|
|
53
|
+
for (i = 0; i < _itemSize; i++) {
|
|
54
|
+
dData[dOffset + i] = sData[sOffset + i];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//Write top margin
|
|
59
|
+
sA = sourceY * sRowSize;
|
|
60
|
+
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
|
|
61
|
+
dA = y * dRowSize;
|
|
62
|
+
|
|
63
|
+
for (x = 0; x < width; x++) {
|
|
64
|
+
|
|
65
|
+
dOffset = dA + (x + destinationX) * dItemSize;
|
|
66
|
+
sOffset = sA + (x + sourceX) * dItemSize;
|
|
67
|
+
for (i = 0; i < _itemSize; i++) {
|
|
68
|
+
dData[dOffset + i] = sData[sOffset + i];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//Write top-right corner
|
|
73
|
+
sOffset = sourceY * sRowSize + (sourceX + width - 1) * dItemSize;
|
|
74
|
+
for (y = Math.max(0, destinationY - marginTop), yMax = destinationY; y < yMax; y++) {
|
|
75
|
+
dA = y * dRowSize;
|
|
76
|
+
|
|
77
|
+
for (x = destinationX + width, xMax = Math.min(destination.width, x + marginRight); x < xMax; x++) {
|
|
78
|
+
|
|
79
|
+
dOffset = dA + x * dItemSize;
|
|
80
|
+
|
|
81
|
+
for (i = 0; i < _itemSize; i++) {
|
|
82
|
+
dData[dOffset + i] = sData[sOffset + i];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//Write left margin
|
|
87
|
+
for (y = 0; y < height; y++) {
|
|
88
|
+
dA = (y + destinationY) * dRowSize;
|
|
89
|
+
sA = (y + sourceY) * sRowSize;
|
|
90
|
+
|
|
91
|
+
sOffset = sA + (sourceX) * dItemSize;
|
|
92
|
+
|
|
93
|
+
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
|
|
94
|
+
|
|
95
|
+
dOffset = dA + x * dItemSize;
|
|
96
|
+
|
|
97
|
+
for (i = 0; i < _itemSize; i++) {
|
|
98
|
+
dData[dOffset + i] = sData[sOffset + i];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//write actual patch
|
|
103
|
+
destination.copy(source, sourceX, sourceY, destinationX, destinationY, width, height);
|
|
104
|
+
|
|
105
|
+
//Write right margin
|
|
106
|
+
for (y = 0; y < height; y++) {
|
|
107
|
+
dA = (y + destinationY) * dRowSize;
|
|
108
|
+
sA = (y + sourceY) * sRowSize;
|
|
109
|
+
|
|
110
|
+
sOffset = sA + (sourceX + width - 1) * dItemSize;
|
|
111
|
+
|
|
112
|
+
for (x = destinationX + width, xMax = Math.min(destination.width, x + marginRight); x < xMax; x++) {
|
|
113
|
+
|
|
114
|
+
dOffset = dA + x * dItemSize;
|
|
115
|
+
|
|
116
|
+
for (i = 0; i < _itemSize; i++) {
|
|
117
|
+
dData[dOffset + i] = sData[sOffset + i];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
//Write Bottom-left margin
|
|
123
|
+
sOffset = (sourceY + height - 1) * sRowSize + sourceX * dItemSize;
|
|
124
|
+
for (y = destinationY + width, yMax = Math.min(destination.height, y + marginBottom); y < yMax; y++) {
|
|
125
|
+
dA = y * dRowSize;
|
|
126
|
+
|
|
127
|
+
for (x = Math.max(0, destinationX - marginLeft), xMax = destinationX; x < xMax; x++) {
|
|
128
|
+
|
|
129
|
+
dOffset = dA + x * dItemSize;
|
|
130
|
+
|
|
131
|
+
for (i = 0; i < _itemSize; i++) {
|
|
132
|
+
dData[dOffset + i] = sData[sOffset + i];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//Write Bottom margin
|
|
137
|
+
sA = (sourceY + height - 1) * sRowSize;
|
|
138
|
+
for (y = destinationY + width, yMax = Math.min(destination.height, y + marginBottom); y < yMax; y++) {
|
|
139
|
+
dA = y * dRowSize;
|
|
140
|
+
|
|
141
|
+
for (x = 0; x < width; x++) {
|
|
142
|
+
|
|
143
|
+
dOffset = dA + (x + destinationX) * dItemSize;
|
|
144
|
+
sOffset = sA + (x + sourceX) * dItemSize;
|
|
145
|
+
for (i = 0; i < _itemSize; i++) {
|
|
146
|
+
dData[dOffset + i] = sData[sOffset + i];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//Write Bottom-right margin
|
|
151
|
+
sOffset = (sourceY + height - 1) * sRowSize + (sourceX + width - 1) * dItemSize;
|
|
152
|
+
for (y = destinationY + width, yMax = Math.min(destination.height, y + marginBottom); y < yMax; y++) {
|
|
153
|
+
dA = y * dRowSize;
|
|
154
|
+
|
|
155
|
+
for (x = destinationX + width, xMax = Math.min(destination.width, x + marginRight); x < xMax; x++) {
|
|
156
|
+
|
|
157
|
+
dOffset = dA + x * dItemSize;
|
|
158
|
+
|
|
159
|
+
for (i = 0; i < _itemSize; i++) {
|
|
160
|
+
dData[dOffset + i] = sData[sOffset + i];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
destination.version++;
|
|
166
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Sampler2D } from "./Sampler2D.js";
|
|
2
|
+
import { sampler2d_copy_with_margins } from "./sampler2d_copy_with_margins.js";
|
|
3
|
+
|
|
4
|
+
test("one texel patch with 1 texel margin all around", () => {
|
|
5
|
+
const target = Sampler2D.uint8(1, 3, 3);
|
|
6
|
+
target.data[0] = 1;
|
|
7
|
+
|
|
8
|
+
const source = Sampler2D.uint8(1, 1, 1);
|
|
9
|
+
source.data[0] = 2;
|
|
10
|
+
|
|
11
|
+
sampler2d_copy_with_margins(target, source, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1);
|
|
12
|
+
|
|
13
|
+
//top left
|
|
14
|
+
expect(target.readChannel(0, 0, 0)).toEqual(2);
|
|
15
|
+
//top
|
|
16
|
+
expect(target.readChannel(1, 0, 0)).toEqual(2);
|
|
17
|
+
//top right
|
|
18
|
+
expect(target.readChannel(2, 0, 0)).toEqual(2);
|
|
19
|
+
//left
|
|
20
|
+
expect(target.readChannel(0, 1, 0)).toEqual(2);
|
|
21
|
+
//copied region
|
|
22
|
+
expect(target.readChannel(1, 1, 0)).toEqual(2);
|
|
23
|
+
//right
|
|
24
|
+
expect(target.readChannel(2, 1, 0)).toEqual(2);
|
|
25
|
+
//bottom left
|
|
26
|
+
expect(target.readChannel(0, 2, 0)).toEqual(2);
|
|
27
|
+
//bottom
|
|
28
|
+
expect(target.readChannel(1, 2, 0)).toEqual(2);
|
|
29
|
+
//bottom right
|
|
30
|
+
expect(target.readChannel(2, 2, 0)).toEqual(2);
|
|
31
|
+
});
|