@woosh/meep-engine 2.34.47 → 2.35.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.
- package/core/binary/BitSet.js +10 -3
- package/core/bvh2/BinaryNode.js +19 -35
- package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +5 -5
- package/core/bvh2/aabb3_combined_surface_area.js +21 -0
- package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +24 -12
- package/core/cache/Cache.d.ts +2 -0
- package/core/cache/Cache.js +27 -23
- package/core/geom/3d/aabb/aabb3_estimate_projected_area2.js +1 -1
- package/core/geom/3d/frustum/frustum_from_projection_matrix_array.js +29 -24
- package/core/math/max2.js +2 -6
- package/core/math/min2.js +2 -6
- package/engine/asset/loaders/geometry/geometry/computeGeometryEquality.js +3 -2
- package/engine/asset/loaders/geometry/geometry/computeGeometryHash.js +9 -1
- package/engine/ecs/EntityComponentDataset.js +7 -2
- package/engine/ecs/foliage/ViewState.js +13 -3
- package/engine/ecs/foliage/ecs/Foliage2System.js +15 -3
- package/engine/ecs/parent/EntityNode.js +23 -11
- package/engine/ecs/transform/Transform.js +15 -13
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +63 -26
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +63 -3
- package/engine/graphics/ecs/mesh-v2/render/AbstractRenderAdapter.js +67 -0
- package/engine/graphics/ecs/mesh-v2/render/GenericRendererAdapter.js +48 -0
- package/engine/graphics/ecs/mesh-v2/render/InstancedRendererAdapter.js +110 -0
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +98 -0
- package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +5 -0
- package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +23 -5
- package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +8 -3
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +23 -85
- package/engine/graphics/geometry/instancing/rewriteMaterial.js +9 -45
- package/engine/graphics/material/optimization/BUFFER_GEOMETRY_UVS.js +10 -0
- package/engine/graphics/material/optimization/MaterialDescriptor.js +46 -0
- package/engine/graphics/material/optimization/MaterialOptimizationContext.js +470 -201
- package/engine/graphics/material/optimization/UvContext.js +18 -0
- package/engine/graphics/material/optimization/is_compliant_mesh.js +71 -0
- package/engine/graphics/material/optimization/prepare_atlas_texture.js +23 -0
- package/engine/graphics/material/optimization/prototypeMaterialOptimizer.js +127 -0
- package/engine/graphics/micron/convert_three_object_to_micron.js +0 -2
- package/engine/graphics/micron/format/MicronGeometry.js +1 -3
- package/engine/graphics/micron/format/MicronGeometryPatch.js +34 -24
- package/engine/graphics/micron/format/VirtualGeometry.js +47 -11
- package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +22 -0
- package/engine/graphics/micron/prototypeVirtualGeometry.js +10 -5
- package/engine/graphics/micron/render/VirtualGeometryBuilder.js +14 -55
- package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +1 -45
- package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +18 -7
- package/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -12
- package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +118 -0
- package/engine/graphics/micron/render/v1/MaterialContext.js +3 -2
- package/engine/graphics/micron/render/v1/VGThreeRenderer.js +19 -4
- package/engine/graphics/render/utils/ThreeBypassRenderer.js +3 -2
- package/engine/graphics/texture/normalized_internal_format.js +48 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +6 -0
- package/engine/graphics/texture/sampler/sampler2d_copy_channel_data.js +25 -0
- package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -0
- package/engine/graphics/texture/sampler/util/drawSamplerHTML.js +14 -1
- package/package.json +1 -1
|
@@ -3,55 +3,11 @@ import { MICRON_PATCH_SIZE_MAX } from "../../build/MICRON_PATCH_SIZE_MAX.js";
|
|
|
3
3
|
import { typed_array_copy } from "../../../../../core/collection/array/typed/typed_array_copy.js";
|
|
4
4
|
import { channelCountToThreeTextureFormat } from "../../../texture/channelCountToThreeTextureFormat.js";
|
|
5
5
|
import { DataTexture, NearestFilter } from "three";
|
|
6
|
-
import { DataType } from "../../../../../core/collection/table/DataType.js";
|
|
7
6
|
import { compute_micron_buffer_array_constructor } from "../../build/compute_micron_buffer_array_constructor.js";
|
|
8
7
|
import { computeThreeTextureTypeFromDataType } from "../../../render/forward_plus/data/computeThreeTextureTypeFromDataType.js";
|
|
9
8
|
import { computeThreeTextureInternalFormatFromDataType } from "../../../render/forward_plus/data/computeThreeTextureInternalFormatFromDataType.js";
|
|
10
9
|
import { DataTypeByteSizes } from "../../../../../core/collection/table/DataTypeByteSizes.js";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* @returns {string}
|
|
15
|
-
* @param {DataType} dt
|
|
16
|
-
* @param {number} channel_count
|
|
17
|
-
*/
|
|
18
|
-
function normalized_internal_format(dt, channel_count) {
|
|
19
|
-
let suffix = '';
|
|
20
|
-
switch (dt) {
|
|
21
|
-
case DataType.Uint8:
|
|
22
|
-
suffix = '8';
|
|
23
|
-
break;
|
|
24
|
-
case DataType.Int8:
|
|
25
|
-
suffix = '8_SNORM';
|
|
26
|
-
break;
|
|
27
|
-
case DataType.Uint16:
|
|
28
|
-
suffix = '16UI';
|
|
29
|
-
break;
|
|
30
|
-
default:
|
|
31
|
-
throw new Error(`Unsupported data type '${dt}'`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
let prefix = '';
|
|
35
|
-
|
|
36
|
-
switch (channel_count) {
|
|
37
|
-
case 1:
|
|
38
|
-
prefix = 'R';
|
|
39
|
-
break;
|
|
40
|
-
case 2:
|
|
41
|
-
prefix = 'RG';
|
|
42
|
-
break;
|
|
43
|
-
case 3:
|
|
44
|
-
prefix = 'RGB';
|
|
45
|
-
break;
|
|
46
|
-
case 4:
|
|
47
|
-
prefix = 'RGBA';
|
|
48
|
-
break;
|
|
49
|
-
default:
|
|
50
|
-
throw new Error(`Unsupported channel count '${channel_count}'`);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return prefix + suffix;
|
|
54
|
-
}
|
|
10
|
+
import { normalized_internal_format } from "../../../texture/normalized_internal_format.js";
|
|
55
11
|
|
|
56
12
|
export class AttributeDataTexture {
|
|
57
13
|
/**
|
|
@@ -132,15 +132,16 @@ export class ThreeInstancedAdapter {
|
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
134
|
*
|
|
135
|
-
* @param {
|
|
135
|
+
* @param {Uint32Array[]} patches
|
|
136
136
|
* @param {number} patch_count
|
|
137
|
+
* @param {VirtualGeometry} virtual_geometry
|
|
137
138
|
*/
|
|
138
|
-
build(patches, patch_count) {
|
|
139
|
+
build(patches, patch_count, virtual_geometry) {
|
|
139
140
|
this.__prepare_capacity(patch_count);
|
|
140
141
|
|
|
141
142
|
const geo = this.__buffer_geometry;
|
|
142
143
|
|
|
143
|
-
const patch_transform_attribute = geo.
|
|
144
|
+
const patch_transform_attribute = geo.attributes[ATTRIBUTE_NAME_TRANSFORM];
|
|
144
145
|
/**
|
|
145
146
|
*
|
|
146
147
|
* @type {Float32Array}
|
|
@@ -149,21 +150,31 @@ export class ThreeInstancedAdapter {
|
|
|
149
150
|
|
|
150
151
|
patch_transform_attribute.needsUpdate = true;
|
|
151
152
|
|
|
152
|
-
const patch_address_attribute = geo.
|
|
153
|
+
const patch_address_attribute = geo.attributes[ATTRIBUTE_NAME_ADDRESS];
|
|
153
154
|
const patch_address_array = patch_address_attribute.array;
|
|
154
155
|
|
|
155
156
|
patch_address_attribute.needsUpdate = true;
|
|
156
157
|
|
|
157
158
|
const patch_data = this.__patch_data;
|
|
159
|
+
const transforms = virtual_geometry.lookup_instance_transforms;
|
|
160
|
+
const geometries = virtual_geometry.loolup_geometries;
|
|
158
161
|
|
|
159
162
|
for (let i = 0; i < patch_count; i++) {
|
|
160
|
-
const
|
|
163
|
+
const i3 = i * 3;
|
|
164
|
+
|
|
165
|
+
const instance_id = patches[i3];
|
|
166
|
+
const geometry_id = patches[i3 + 1];
|
|
167
|
+
const patch_id = patches[i3 + 2];
|
|
168
|
+
|
|
169
|
+
const transform = transforms[instance_id];
|
|
170
|
+
const micron_geometry = geometries[geometry_id];
|
|
171
|
+
const patch = micron_geometry.patches[patch_id];
|
|
161
172
|
|
|
162
173
|
const i16 = i * 16;
|
|
163
174
|
|
|
164
|
-
patch_transform_array.set(
|
|
175
|
+
patch_transform_array.set(transform, i16);
|
|
165
176
|
|
|
166
|
-
const patch_slot_id = patch_data.ensure(
|
|
177
|
+
const patch_slot_id = patch_data.ensure(patch);
|
|
167
178
|
|
|
168
179
|
patch_address_array[i] = patch_slot_id;
|
|
169
180
|
}
|
|
@@ -37,7 +37,6 @@ export class RefinementSpec {
|
|
|
37
37
|
*/
|
|
38
38
|
const array_buffer = new ArrayBuffer(160);
|
|
39
39
|
|
|
40
|
-
|
|
41
40
|
/**
|
|
42
41
|
* Contains transformation from camera space to object space
|
|
43
42
|
* @type {Float32Array|number[]|mat4}
|
|
@@ -50,17 +49,6 @@ export class RefinementSpec {
|
|
|
50
49
|
* @type {Float32Array}
|
|
51
50
|
*/
|
|
52
51
|
this.frustum_f32 = new Float32Array(array_buffer, 64, 24);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Object-space camera position
|
|
57
|
-
* @type {Float32Array}
|
|
58
|
-
*/
|
|
59
|
-
this.view_position = new Float32Array(3);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get frustum() {
|
|
63
|
-
throw new Error('deprecated, use .frustum_f32 instead');
|
|
64
52
|
}
|
|
65
53
|
|
|
66
54
|
/**
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { BitSet } from "../../../../../core/binary/BitSet.js";
|
|
2
|
+
import { aabb3_intersects_frustum_array } from "../../../../../core/bvh2/aabb3/aabb3_intersects_frustum_array.js";
|
|
3
|
+
import { aabb3_estimate_projected_area2 } from "../../../../../core/geom/3d/aabb/aabb3_estimate_projected_area2.js";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @type {BitSet}
|
|
9
|
+
*/
|
|
10
|
+
const scratch_traversal_bitset = new BitSet();
|
|
11
|
+
scratch_traversal_bitset.preventShrink();
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Using a pre-allocated continuous chunk of memory gets us better cache coherence
|
|
15
|
+
* @readonly
|
|
16
|
+
* @type {number[]}
|
|
17
|
+
*/
|
|
18
|
+
const scratch_traversal_stack = new Uint32Array(781250);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @param {VirtualGeometry} destination
|
|
23
|
+
* @param {RefinementSpec} spec
|
|
24
|
+
* @param {MicronGeometry} geometry
|
|
25
|
+
* @param instance_id
|
|
26
|
+
* @param transform
|
|
27
|
+
*/
|
|
28
|
+
export function get_geometry_patch_cut(
|
|
29
|
+
destination,
|
|
30
|
+
spec,
|
|
31
|
+
geometry,
|
|
32
|
+
instance_id,
|
|
33
|
+
transform
|
|
34
|
+
) {
|
|
35
|
+
|
|
36
|
+
const frustum_planes = spec.frustum_f32;
|
|
37
|
+
const projection_matrix = spec.projection_matrix;
|
|
38
|
+
const error_threshold = spec.error_threshold_normalized;
|
|
39
|
+
|
|
40
|
+
const geometry_id = geometry.id;
|
|
41
|
+
|
|
42
|
+
let output_patch_cursor = destination.patch_count;
|
|
43
|
+
|
|
44
|
+
let i;
|
|
45
|
+
let stack_cursor = 1;
|
|
46
|
+
|
|
47
|
+
// initialize stack
|
|
48
|
+
const stack = scratch_traversal_stack;
|
|
49
|
+
const root = geometry.root;
|
|
50
|
+
stack[0] = root.id;
|
|
51
|
+
|
|
52
|
+
const included_set = scratch_traversal_bitset;
|
|
53
|
+
included_set.reset();
|
|
54
|
+
|
|
55
|
+
included_set.set(root.id, true);
|
|
56
|
+
|
|
57
|
+
const patches = geometry.patches;
|
|
58
|
+
const destination_patches = destination.patches;
|
|
59
|
+
|
|
60
|
+
while (stack_cursor > 0) {
|
|
61
|
+
stack_cursor--;
|
|
62
|
+
|
|
63
|
+
const patch_id = stack[stack_cursor];
|
|
64
|
+
const patch = patches[patch_id];
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
check if node is in view frustum
|
|
68
|
+
NOTE: following suggestion in "FastMesh: Efficient View-dependent Meshing" by Renato Pajarola et al, we can do a more coarse frustum test approximating frustum as a cone initially
|
|
69
|
+
*/
|
|
70
|
+
const in_view_frustum = aabb3_intersects_frustum_array(patch.bounding_box, frustum_planes);
|
|
71
|
+
|
|
72
|
+
if (!in_view_frustum) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// check if record needs to be split
|
|
77
|
+
if (patch.lod > 0) {
|
|
78
|
+
|
|
79
|
+
// not the lowest level of LOD, see if subdivision might be necessary
|
|
80
|
+
|
|
81
|
+
// compute average triangle area
|
|
82
|
+
// const group_screen_area = aabb3_project_to_2d(patch.group_bounding_box_corners, projection_matrix);
|
|
83
|
+
const group_screen_area = aabb3_estimate_projected_area2(patch.group_bounding_box, projection_matrix);
|
|
84
|
+
const screen_space_error = patch.group_error * group_screen_area;
|
|
85
|
+
|
|
86
|
+
if (screen_space_error > error_threshold) {
|
|
87
|
+
// error too large, needs to be split
|
|
88
|
+
|
|
89
|
+
const children = patch.children;
|
|
90
|
+
const child_count = children.length;
|
|
91
|
+
|
|
92
|
+
for (i = 0; i < child_count; i++) {
|
|
93
|
+
const child = children[i];
|
|
94
|
+
|
|
95
|
+
if (included_set.getAndSet(child.id)) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
stack[stack_cursor++] = child.id;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
const target_address = output_patch_cursor * 3;
|
|
108
|
+
|
|
109
|
+
destination_patches[target_address] = instance_id;
|
|
110
|
+
destination_patches[target_address + 1] = geometry_id;
|
|
111
|
+
destination_patches[target_address + 2] = patch_id;
|
|
112
|
+
|
|
113
|
+
output_patch_cursor++;
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
destination.patch_count = output_patch_cursor;
|
|
118
|
+
}
|
|
@@ -144,8 +144,9 @@ export class MaterialContext {
|
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
146
|
*
|
|
147
|
+
* @param {VirtualGeometry} virtual_geometry
|
|
147
148
|
*/
|
|
148
|
-
build() {
|
|
149
|
+
build(virtual_geometry) {
|
|
149
150
|
|
|
150
151
|
if (this.__patch_count === 0) {
|
|
151
152
|
this.mesh.visible = false;
|
|
@@ -154,7 +155,7 @@ export class MaterialContext {
|
|
|
154
155
|
this.mesh.visible = true;
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
this.adapter.build(this.__patches, this.__patch_count);
|
|
158
|
+
this.adapter.build(this.__patches, this.__patch_count, virtual_geometry);
|
|
158
159
|
|
|
159
160
|
}
|
|
160
161
|
}
|
|
@@ -16,6 +16,7 @@ const scratch_mvc = new MaterialVertexSpec();
|
|
|
16
16
|
export class VGThreeRenderer {
|
|
17
17
|
constructor() {
|
|
18
18
|
this.geometry = new VirtualGeometry();
|
|
19
|
+
|
|
19
20
|
this.builder = new VirtualGeometryBuilder();
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -158,6 +159,10 @@ export class VGThreeRenderer {
|
|
|
158
159
|
const contexts = this.__contexts_array;
|
|
159
160
|
const context_count = contexts.length;
|
|
160
161
|
|
|
162
|
+
/**
|
|
163
|
+
*
|
|
164
|
+
* @type {Map<number, MaterialContext>}
|
|
165
|
+
*/
|
|
161
166
|
const instance_to_ctx = new Map();
|
|
162
167
|
|
|
163
168
|
for (let i = 0; i < context_count; i++) {
|
|
@@ -175,18 +180,28 @@ export class VGThreeRenderer {
|
|
|
175
180
|
const patches = geometry.patches;
|
|
176
181
|
|
|
177
182
|
for (let i = 0; i < patch_count; i++) {
|
|
178
|
-
const
|
|
183
|
+
const i3 = i * 3;
|
|
184
|
+
|
|
185
|
+
const instance_id = patches[i3];
|
|
186
|
+
const geometry_id = patches[i3 + 1];
|
|
187
|
+
const patch_id = patches[i3 + 2];
|
|
188
|
+
|
|
189
|
+
const ctx = instance_to_ctx.get(instance_id);
|
|
190
|
+
|
|
191
|
+
const target_address = ctx.__patch_count * 3;
|
|
179
192
|
|
|
180
|
-
|
|
193
|
+
ctx.__patches[target_address] = instance_id;
|
|
194
|
+
ctx.__patches[target_address + 1] = geometry_id;
|
|
195
|
+
ctx.__patches[target_address + 2] = patch_id;
|
|
181
196
|
|
|
182
|
-
ctx.
|
|
197
|
+
ctx.__patch_count++;
|
|
183
198
|
}
|
|
184
199
|
|
|
185
200
|
// build each context
|
|
186
201
|
for (let i = 0; i < context_count; i++) {
|
|
187
202
|
const ctx = contexts[i];
|
|
188
203
|
|
|
189
|
-
ctx.build();
|
|
204
|
+
ctx.build(this.geometry);
|
|
190
205
|
}
|
|
191
206
|
}
|
|
192
207
|
|
|
@@ -72,8 +72,9 @@ export class ThreeBypassRenderer {
|
|
|
72
72
|
|
|
73
73
|
let stack_top = 0;
|
|
74
74
|
let j = 0;
|
|
75
|
+
let i = 0;
|
|
75
76
|
|
|
76
|
-
for (
|
|
77
|
+
for (; i < input_size; i++) {
|
|
77
78
|
const object3D = input[i];
|
|
78
79
|
|
|
79
80
|
if (input_filter(object3D)) {
|
|
@@ -119,7 +120,7 @@ export class ThreeBypassRenderer {
|
|
|
119
120
|
const children = object3D.children;
|
|
120
121
|
const child_count = children.length;
|
|
121
122
|
|
|
122
|
-
for (
|
|
123
|
+
for (i = 0; i < child_count; i++) {
|
|
123
124
|
const child = children[i];
|
|
124
125
|
|
|
125
126
|
stack[stack_top++] = child;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { DataType } from "../../../core/collection/table/DataType.js";
|
|
2
|
+
import { assert } from "../../../core/assert.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @returns {string}
|
|
7
|
+
* @param {DataType} dt
|
|
8
|
+
* @param {number} channel_count
|
|
9
|
+
*/
|
|
10
|
+
export function normalized_internal_format(dt, channel_count) {
|
|
11
|
+
assert.isNonNegativeInteger(channel_count, 'channel_count');
|
|
12
|
+
|
|
13
|
+
let suffix = '';
|
|
14
|
+
switch (dt) {
|
|
15
|
+
case DataType.Uint8:
|
|
16
|
+
suffix = '8';
|
|
17
|
+
break;
|
|
18
|
+
case DataType.Int8:
|
|
19
|
+
suffix = '8_SNORM';
|
|
20
|
+
break;
|
|
21
|
+
case DataType.Uint16:
|
|
22
|
+
suffix = '16UI';
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
throw new Error(`Unsupported data type '${dt}'`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let prefix = '';
|
|
29
|
+
|
|
30
|
+
switch (channel_count) {
|
|
31
|
+
case 1:
|
|
32
|
+
prefix = 'R';
|
|
33
|
+
break;
|
|
34
|
+
case 2:
|
|
35
|
+
prefix = 'RG';
|
|
36
|
+
break;
|
|
37
|
+
case 3:
|
|
38
|
+
prefix = 'RGB';
|
|
39
|
+
break;
|
|
40
|
+
case 4:
|
|
41
|
+
prefix = 'RGBA';
|
|
42
|
+
break;
|
|
43
|
+
default:
|
|
44
|
+
throw new Error(`Unsupported channel count '${channel_count}'`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return prefix + suffix;
|
|
48
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Copy single channel from one sampler to another
|
|
5
|
+
* @param {Sampler2D} source
|
|
6
|
+
* @param {number} source_channel
|
|
7
|
+
* @param {Sampler2D} destination
|
|
8
|
+
* @param {number} destination_channel
|
|
9
|
+
*/
|
|
10
|
+
export function sampler2d_copy_channel_data(source, source_channel, destination, destination_channel) {
|
|
11
|
+
const pixel_count = source.height * source.width;
|
|
12
|
+
|
|
13
|
+
const source_item_size = source.itemSize;
|
|
14
|
+
const destination_item_size = destination.itemSize;
|
|
15
|
+
|
|
16
|
+
const source_data = source.data;
|
|
17
|
+
const destination_data = destination.data;
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < pixel_count; i++) {
|
|
20
|
+
const address_source = i * source_item_size + source_channel;
|
|
21
|
+
const address_destination = i * destination_item_size + destination_channel;
|
|
22
|
+
|
|
23
|
+
destination_data[address_destination] = source_data[address_source];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -10,6 +10,9 @@ import { genericResampleSampler2D } from "./genericResampleSampler2D.js";
|
|
|
10
10
|
* @param {Sampler2D} output
|
|
11
11
|
*/
|
|
12
12
|
export function scaleSampler2D(input, output) {
|
|
13
|
+
assert.equal(input.isSampler2D, true, 'input.isSampler2D !== true');
|
|
14
|
+
assert.equal(output.isSampler2D, true, 'output.isSampler2D !== true');
|
|
15
|
+
|
|
13
16
|
const targetItemSize = output.itemSize;
|
|
14
17
|
|
|
15
18
|
assert.equal(input.itemSize, targetItemSize, 'both source and target must have the same number of channels');
|
|
@@ -16,7 +16,20 @@ import { typedArrayConstructorByInstance } from "../typedArrayConstructorByInsta
|
|
|
16
16
|
export function drawSamplerHTML(parentNode, sampler, x, y, scale, offset, size) {
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const TA = typedArrayConstructorByInstance(sampler.data);
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
let target_width = size;
|
|
23
|
+
let target_height = size;
|
|
24
|
+
|
|
25
|
+
// apply aspect ratio
|
|
26
|
+
if (sampler.width > sampler.height) {
|
|
27
|
+
target_height = Math.ceil(size * (sampler.height / sampler.width));
|
|
28
|
+
} else if (sampler.width < sampler.height) {
|
|
29
|
+
target_width = Math.ceil(size * (sampler.width / sampler.height));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const target = new Sampler2D(new TA(target_width * target_height * sampler.itemSize), sampler.itemSize, target_width, target_height);
|
|
20
33
|
|
|
21
34
|
scaleSampler2D(sampler, target);
|
|
22
35
|
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"productName": "Meep",
|
|
6
6
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.
|
|
8
|
+
"version": "2.35.0",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|