@woosh/meep-engine 2.34.28 → 2.34.32
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/aabb3/aabb3_array_contains_point.js +18 -0
- package/core/collection/table/DataTypeByteSizes.js +16 -0
- package/core/geom/3d/sphere/sphere_array_intersects_point.js +15 -0
- package/engine/ecs/transform/Transform.js +1 -1
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +16 -3
- package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +52 -0
- package/engine/graphics/ecs/mesh-v2/{prototypeShadedGeometry.js → sample/prototypeShadedGeometry.js} +5 -5
- package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +37 -0
- package/engine/graphics/micron/build/PatchRepresentation.js +4 -0
- package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +20 -0
- package/engine/graphics/micron/build/compute_micron_buffer_array_constructor.js +2 -0
- package/engine/graphics/micron/build/fill_patch_geometry_data.js +35 -2
- package/engine/graphics/micron/build/hierarchy/buildAbstractPatchHierarchy.js +10 -1
- package/engine/graphics/micron/format/MicronGeometry.d.ts +3 -0
- package/engine/graphics/micron/format/MicronGeometry.js +29 -31
- package/engine/graphics/micron/format/MicronGeometryPatch.d.ts +3 -0
- package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.spec.js +63 -0
- package/engine/graphics/micron/format/validate_patch_bounds.js +69 -0
- package/engine/graphics/micron/prototypeVirtualGeometry.js +7 -1
- package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +3 -0
- package/engine/graphics/micron/render/instanced/shader/shader_rewrite_standard.js +23 -0
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {ArrayLike<number>|number[]} aabb
|
|
6
|
+
* @param {number} x
|
|
7
|
+
* @param {number} y
|
|
8
|
+
* @param {number} z
|
|
9
|
+
* @return {boolean}
|
|
10
|
+
*/
|
|
11
|
+
export function aabb3_array_contains_point(aabb, x, y, z) {
|
|
12
|
+
return x >= aabb[0]
|
|
13
|
+
&& x <= aabb[3]
|
|
14
|
+
&& y >= aabb[1]
|
|
15
|
+
&& y <= aabb[4]
|
|
16
|
+
&& z >= aabb[2]
|
|
17
|
+
&& z <= aabb[5];
|
|
18
|
+
}
|
|
@@ -19,3 +19,19 @@ export const DataTypeByteSizes = {
|
|
|
19
19
|
[DataType.Float32]: 4,
|
|
20
20
|
[DataType.Float64]: 8
|
|
21
21
|
};
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param {DataType} type
|
|
27
|
+
* @return {number}
|
|
28
|
+
*/
|
|
29
|
+
export function dataTypeByteSize(type) {
|
|
30
|
+
const size = DataTypeByteSizes[type];
|
|
31
|
+
|
|
32
|
+
if (size === undefined) {
|
|
33
|
+
throw new Error(`Unsupported type '${type}'`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return size;
|
|
37
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { sphereIntersectsPoint } from "./sphereIntersectsPoint.js";
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {ArrayLike<number>|number[]} sphere
|
|
8
|
+
* @param {number} x
|
|
9
|
+
* @param {number} y
|
|
10
|
+
* @param {number} z
|
|
11
|
+
* @return {boolean}
|
|
12
|
+
*/
|
|
13
|
+
export function sphere_array_intersects_point(sphere, x, y, z) {
|
|
14
|
+
return sphereIntersectsPoint(sphere[0], sphere[1], sphere[2], sphere[3], x, y, z);
|
|
15
|
+
}
|
|
@@ -125,16 +125,29 @@ export class ShadedGeometry {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
__build_object() {
|
|
128
|
+
/**
|
|
129
|
+
* @type {THREE.Object3D}
|
|
130
|
+
*/
|
|
131
|
+
let object;
|
|
132
|
+
|
|
128
133
|
const mode = this.mode;
|
|
134
|
+
const shader = this.material;
|
|
135
|
+
const geo = this.geometry;
|
|
136
|
+
|
|
129
137
|
if (mode === DrawMode.Triangles) {
|
|
130
|
-
|
|
138
|
+
object = new Mesh(geo, shader);
|
|
131
139
|
} else if (mode === DrawMode.Lines) {
|
|
132
|
-
|
|
140
|
+
object = new Line(geo, shader);
|
|
133
141
|
} else if (mode === DrawMode.LineSegments) {
|
|
134
|
-
|
|
142
|
+
object = new LineSegments(geo, shader);
|
|
135
143
|
} else {
|
|
136
144
|
throw new Error(`Unsupported draw mode '${mode}'`);
|
|
137
145
|
}
|
|
146
|
+
|
|
147
|
+
object.matrixAutoUpdate = false;
|
|
148
|
+
object.frustumCulled = false;
|
|
149
|
+
|
|
150
|
+
this.__cached_object = object;
|
|
138
151
|
}
|
|
139
152
|
|
|
140
153
|
get bvh() {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { EngineHarness } from "../../../../EngineHarness.js";
|
|
2
|
+
import { ShadedGeometrySystem } from "../ShadedGeometrySystem.js";
|
|
3
|
+
import { GameAssetType } from "../../../../asset/GameAssetType.js";
|
|
4
|
+
import { EngineConfiguration } from "../../../../EngineConfiguration.js";
|
|
5
|
+
import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
|
|
6
|
+
import { three_object_to_entity_composition } from "../three_object_to_entity_composition.js";
|
|
7
|
+
|
|
8
|
+
const eh = new EngineHarness();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {EngineHarness} harness
|
|
13
|
+
* @return {Promise<void>}
|
|
14
|
+
*/
|
|
15
|
+
async function init(harness) {
|
|
16
|
+
const engine = harness.engine;
|
|
17
|
+
|
|
18
|
+
const config = new EngineConfiguration();
|
|
19
|
+
|
|
20
|
+
config.addSystem(new ShadedGeometrySystem(engine));
|
|
21
|
+
config.addLoader(GameAssetType.ModelGLTF_JSON, new GLTFAssetLoader());
|
|
22
|
+
|
|
23
|
+
await config.apply(engine);
|
|
24
|
+
|
|
25
|
+
eh.initialize().then(main);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @param {Engine} engine
|
|
31
|
+
*/
|
|
32
|
+
async function main(engine) {
|
|
33
|
+
|
|
34
|
+
const em = engine.entityManager;
|
|
35
|
+
|
|
36
|
+
EngineHarness.buildBasics({
|
|
37
|
+
engine,
|
|
38
|
+
enableWater: false
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const ecd = em.dataset;
|
|
42
|
+
|
|
43
|
+
const asset = await engine.assetManager.promise('moicon/06_04_hapro/08-clickable-assets-new/model.gltf', GameAssetType.ModelGLTF_JSON);
|
|
44
|
+
|
|
45
|
+
const three_object = asset.create();
|
|
46
|
+
|
|
47
|
+
const composition = three_object_to_entity_composition(three_object);
|
|
48
|
+
|
|
49
|
+
composition.build(ecd);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
init(eh);
|
package/engine/graphics/ecs/mesh-v2/{prototypeShadedGeometry.js → sample/prototypeShadedGeometry.js}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { EngineHarness } from "
|
|
2
|
-
import { ShadedGeometrySystem } from "
|
|
3
|
-
import EntityBuilder from "
|
|
4
|
-
import { Transform } from "
|
|
5
|
-
import { ShadedGeometry } from "
|
|
1
|
+
import { EngineHarness } from "../../../../EngineHarness.js";
|
|
2
|
+
import { ShadedGeometrySystem } from "../ShadedGeometrySystem.d.ts";
|
|
3
|
+
import EntityBuilder from "../../../../ecs/EntityBuilder.d.ts";
|
|
4
|
+
import { Transform } from "../../../../ecs/transform/Transform.d.ts";
|
|
5
|
+
import { ShadedGeometry } from "../ShadedGeometry.d.ts";
|
|
6
6
|
import { BoxBufferGeometry, MeshBasicMaterial } from "three";
|
|
7
7
|
|
|
8
8
|
const eh = new EngineHarness();
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { EntityNode } from "../../../ecs/parent/EntityNode.js";
|
|
2
|
+
import { Transform } from "../../../ecs/transform/Transform.js";
|
|
3
|
+
import { ShadedGeometry } from "./ShadedGeometry.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {THREE.Object3D} root
|
|
8
|
+
* @returns {EntityNode}
|
|
9
|
+
*/
|
|
10
|
+
export function three_object_to_entity_composition(root) {
|
|
11
|
+
const node = new EntityNode();
|
|
12
|
+
|
|
13
|
+
const transform = new Transform();
|
|
14
|
+
transform.fromMatrix4(root.matrix.elements);
|
|
15
|
+
|
|
16
|
+
node.entity.add(transform);
|
|
17
|
+
|
|
18
|
+
if (root.isMesh) {
|
|
19
|
+
if (root.isSkinnedMesh) {
|
|
20
|
+
throw new Error(`Skinned meshes are not supported`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
node.entity.add(ShadedGeometry.from(root.geometry, root.material));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const children = root.children;
|
|
27
|
+
const child_count = children.length;
|
|
28
|
+
for (let i = 0; i < child_count; i++) {
|
|
29
|
+
const child = children[i];
|
|
30
|
+
|
|
31
|
+
const child_node = three_object_to_entity_composition(child);
|
|
32
|
+
|
|
33
|
+
node.addChild(child_node);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return node;
|
|
37
|
+
}
|
|
@@ -51,6 +51,17 @@ function custom_attribute_format_uv(spec, source) {
|
|
|
51
51
|
spec.type = DataType.Float16;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param {AttributeSpec} spec
|
|
57
|
+
* @param {THREE.BufferAttribute} source
|
|
58
|
+
*/
|
|
59
|
+
function custom_attribute_format_color(spec, source) {
|
|
60
|
+
// crush color data to 8 bit
|
|
61
|
+
spec.type = DataType.Uint8;
|
|
62
|
+
spec.normalized = true;
|
|
63
|
+
}
|
|
64
|
+
|
|
54
65
|
/**
|
|
55
66
|
*
|
|
56
67
|
* @param {AttributeSpec} spec
|
|
@@ -70,7 +81,11 @@ function format_attribute(spec, source, name) {
|
|
|
70
81
|
case 'normal':
|
|
71
82
|
custom_attribute_format_normal(spec, source);
|
|
72
83
|
break;
|
|
84
|
+
case 'color':
|
|
85
|
+
custom_attribute_format_color(spec, source);
|
|
86
|
+
break;
|
|
73
87
|
default:
|
|
88
|
+
spec.normalized = source.normalized;
|
|
74
89
|
spec.type = typedArrayToDataType(source.array)
|
|
75
90
|
}
|
|
76
91
|
|
|
@@ -202,6 +217,11 @@ export async function buildMicronGeometryFromBufferGeometry(input) {
|
|
|
202
217
|
|
|
203
218
|
|
|
204
219
|
const t_build_hierarchy_start = current_time_millis();
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
*
|
|
223
|
+
* @type {PatchRepresentation}
|
|
224
|
+
*/
|
|
205
225
|
const root = await buildAbstractPatchHierarchy(patches);
|
|
206
226
|
|
|
207
227
|
if (PRINT_VERBOSE_STATS) {
|
|
@@ -9,6 +9,9 @@ import { DataType } from "../../../../core/collection/table/DataType.js";
|
|
|
9
9
|
import { passThrough } from "../../../../core/function/Functions.js";
|
|
10
10
|
import { to_half_float_uint16 } from "../../../../core/binary/to_half_float_uint16.js";
|
|
11
11
|
import { compute_micron_buffer_array_constructor } from "./compute_micron_buffer_array_constructor.js";
|
|
12
|
+
import { typedArrayToDataType } from "../../../../core/collection/array/typedArrayToDataType.js";
|
|
13
|
+
import { dataTypeByteSize } from "../../../../core/collection/table/DataTypeByteSizes.js";
|
|
14
|
+
import { clamp } from "../../../../core/math/clamp.js";
|
|
12
15
|
|
|
13
16
|
function UintArrayForCount(count) {
|
|
14
17
|
|
|
@@ -90,6 +93,17 @@ function copy_attribute_data(vertex_count, index_map_backward, itemSize, attribu
|
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
95
|
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @param {number} value
|
|
99
|
+
* @returns {number}
|
|
100
|
+
*/
|
|
101
|
+
function resample_normalized_uint16_to_uint8(value) {
|
|
102
|
+
const normalized = clamp(value / 65535, 0, 1);
|
|
103
|
+
|
|
104
|
+
return Math.round(normalized * 255);
|
|
105
|
+
}
|
|
106
|
+
|
|
93
107
|
/**
|
|
94
108
|
*
|
|
95
109
|
* @param {number} value
|
|
@@ -105,7 +119,8 @@ function normalize_to_int8(value) {
|
|
|
105
119
|
const DataConverterType = {
|
|
106
120
|
None: passThrough,
|
|
107
121
|
Number2HalfFloat: to_half_float_uint16,
|
|
108
|
-
Normalize2Int8: normalize_to_int8
|
|
122
|
+
Normalize2Int8: normalize_to_int8,
|
|
123
|
+
ResampleNormalized_Uint16_to_Uint8: resample_normalized_uint16_to_uint8
|
|
109
124
|
};
|
|
110
125
|
|
|
111
126
|
/**
|
|
@@ -125,7 +140,25 @@ function compute_attribute_data_converter(source, spec) {
|
|
|
125
140
|
throw new Error(`Unsupported normalized type '${spec.type}'`);
|
|
126
141
|
}
|
|
127
142
|
} else {
|
|
128
|
-
|
|
143
|
+
const source_array = source.array;
|
|
144
|
+
|
|
145
|
+
const source_type = typedArrayToDataType(source_array);
|
|
146
|
+
|
|
147
|
+
const target_byte_size = dataTypeByteSize(spec.type);
|
|
148
|
+
const source_byte_size = dataTypeByteSize(source_type)
|
|
149
|
+
|
|
150
|
+
if (target_byte_size !== source_byte_size) {
|
|
151
|
+
// wrong data size
|
|
152
|
+
|
|
153
|
+
if (spec.type === DataType.Uint8 && source_type === DataType.Uint16) {
|
|
154
|
+
return DataConverterType.ResampleNormalized_Uint16_to_Uint8;
|
|
155
|
+
} else {
|
|
156
|
+
throw new Error(`Unsupported conversion ${source_type} -> `);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
} else {
|
|
160
|
+
return DataConverterType.None;
|
|
161
|
+
}
|
|
129
162
|
}
|
|
130
163
|
}
|
|
131
164
|
|
|
@@ -48,13 +48,15 @@ async function assemble_graph(nodes) {
|
|
|
48
48
|
*/
|
|
49
49
|
let __nodes = nodes.slice();
|
|
50
50
|
|
|
51
|
+
const initial_node_count = __nodes.length;
|
|
52
|
+
|
|
51
53
|
/**
|
|
52
54
|
*
|
|
53
55
|
* @type {{value: number}}
|
|
54
56
|
* @private
|
|
55
57
|
*/
|
|
56
58
|
const __node_count = {
|
|
57
|
-
value:
|
|
59
|
+
value: initial_node_count
|
|
58
60
|
};
|
|
59
61
|
|
|
60
62
|
let level = 0;
|
|
@@ -136,6 +138,13 @@ async function assemble_graph(nodes) {
|
|
|
136
138
|
// return root
|
|
137
139
|
const root = __nodes[0];
|
|
138
140
|
|
|
141
|
+
if (initial_node_count === 1) {
|
|
142
|
+
// there are no children, whole hierarchy is just one node, set group bounds to equal node bounds
|
|
143
|
+
root.group_bounding_sphere.set(root.bounding_sphere);
|
|
144
|
+
root.group_aabb.copy(root.bounding_box);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
139
148
|
return root;
|
|
140
149
|
}
|
|
141
150
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {BufferGeometry} from "three";
|
|
2
2
|
import {VertexDataSpec} from "../../geometry/VertexDataSpec";
|
|
3
3
|
import {SurfacePoint3} from "../../../../core/geom/3d/SurfacePoint3";
|
|
4
|
+
import {MicronGeometryPatch} from "./MicronGeometryPatch";
|
|
4
5
|
|
|
5
6
|
export class MicronGeometry {
|
|
6
7
|
vertex_spec: VertexDataSpec
|
|
@@ -14,4 +15,6 @@ export class MicronGeometry {
|
|
|
14
15
|
): SurfacePoint3[]
|
|
15
16
|
|
|
16
17
|
readonly isMicronGeometry: boolean
|
|
18
|
+
|
|
19
|
+
readonly patches: MicronGeometryPatch[]
|
|
17
20
|
}
|
|
@@ -3,6 +3,7 @@ import { assert } from "../../../../core/assert.js";
|
|
|
3
3
|
import { computeTriangleRayIntersection } from "../../../../core/geom/3d/triangle/computeTriangleRayIntersection.js";
|
|
4
4
|
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
5
5
|
import { aabb3_array_intersects_ray } from "../../../../core/bvh2/aabb3/aabb3_array_intersects_ray.js";
|
|
6
|
+
import { sphere_array_intersects_ray } from "../../../../core/geom/3d/sphere/sphere_array_intersects_ray.js";
|
|
6
7
|
|
|
7
8
|
let id_counter = 0;
|
|
8
9
|
|
|
@@ -105,43 +106,18 @@ export class MicronGeometry {
|
|
|
105
106
|
|
|
106
107
|
const patch = stack[stack_cursor];
|
|
107
108
|
|
|
108
|
-
// using group bounds because it's conservative, as we want to be able to hit LOD_0
|
|
109
|
-
|
|
110
|
-
// sphere test
|
|
111
|
-
|
|
112
|
-
// TODO check what's wrong with sphere tests and re-enable them
|
|
113
|
-
// if (!sphere_array_intersects_ray(patch.group_bounding_sphere,
|
|
114
|
-
// origin_x, origin_y, origin_z,
|
|
115
|
-
// direction_x, direction_y, direction_z
|
|
116
|
-
// )) {
|
|
117
|
-
// continue;
|
|
118
|
-
// }
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// box test (more expensive, different volume)
|
|
122
|
-
if (!aabb3_array_intersects_ray(
|
|
123
|
-
patch.group_bounding_box,
|
|
124
|
-
origin_x, origin_y, origin_z,
|
|
125
|
-
direction_x, direction_y, direction_z
|
|
126
|
-
)) {
|
|
127
|
-
// no intersection
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
109
|
if (patch.lod === 0) {
|
|
132
110
|
// LOD 0 - source geometry
|
|
133
111
|
|
|
134
112
|
// cast against bounds
|
|
135
113
|
|
|
136
114
|
// sphere test
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// continue;
|
|
144
|
-
// }
|
|
115
|
+
if (!sphere_array_intersects_ray(patch.bounding_sphere,
|
|
116
|
+
origin_x, origin_y, origin_z,
|
|
117
|
+
direction_x, direction_y, direction_z
|
|
118
|
+
)) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
145
121
|
|
|
146
122
|
// box test
|
|
147
123
|
if (!aabb3_array_intersects_ray(
|
|
@@ -200,6 +176,28 @@ export class MicronGeometry {
|
|
|
200
176
|
}
|
|
201
177
|
|
|
202
178
|
} else {
|
|
179
|
+
|
|
180
|
+
// using group bounds because it's conservative, as we want to be able to hit LOD_0
|
|
181
|
+
|
|
182
|
+
// sphere test
|
|
183
|
+
if (!sphere_array_intersects_ray(patch.group_bounding_sphere,
|
|
184
|
+
origin_x, origin_y, origin_z,
|
|
185
|
+
direction_x, direction_y, direction_z
|
|
186
|
+
)) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
// box test (more expensive, different volume)
|
|
192
|
+
if (!aabb3_array_intersects_ray(
|
|
193
|
+
patch.group_bounding_box,
|
|
194
|
+
origin_x, origin_y, origin_z,
|
|
195
|
+
direction_x, direction_y, direction_z
|
|
196
|
+
)) {
|
|
197
|
+
// no intersection
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
|
|
203
201
|
// refine more
|
|
204
202
|
const children = patch.children;
|
|
205
203
|
|
package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.spec.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { MicronGeometryPatch } from "../MicronGeometryPatch.js";
|
|
2
|
+
import { BinaryBuffer } from "../../../../../core/binary/BinaryBuffer.js";
|
|
3
|
+
import { MicronGeometry } from "../MicronGeometry.js";
|
|
4
|
+
import { VertexDataSpec } from "../../../geometry/VertexDataSpec.js";
|
|
5
|
+
import { AttributeSpec } from "../../../geometry/AttributeSpec.js";
|
|
6
|
+
import { DataType } from "../../../../../core/collection/table/DataType.js";
|
|
7
|
+
import { MicronGeometryBinarySerializationAdapter } from "./MicronGeometryBinarySerializationAdapter.js";
|
|
8
|
+
|
|
9
|
+
function sampleGeometry() {
|
|
10
|
+
const a = new MicronGeometryPatch();
|
|
11
|
+
|
|
12
|
+
a.vertex_attribute_arrays[0] = new Uint8Array([
|
|
13
|
+
7, 11, 13,
|
|
14
|
+
17, 23, 29,
|
|
15
|
+
31, 39, 43
|
|
16
|
+
]);
|
|
17
|
+
a.vertex_count = 3;
|
|
18
|
+
|
|
19
|
+
a.face_indices = new Uint8Array([1, 2, 3]);
|
|
20
|
+
a.polygon_count = 1;
|
|
21
|
+
|
|
22
|
+
a.group_error = 1.234;
|
|
23
|
+
|
|
24
|
+
a.bounding_box.set([7, 11, 13, 31, 39, 43]);
|
|
25
|
+
a.group_bounding_box.set([7, 11, 13, 31, 39, 43]);
|
|
26
|
+
a.bounding_sphere.set([19, 25, 28, 50.1]);
|
|
27
|
+
a.group_bounding_sphere.set([19, 25, 28, 50.1]);
|
|
28
|
+
|
|
29
|
+
const g_a = new MicronGeometry();
|
|
30
|
+
|
|
31
|
+
const vertex_spec = new VertexDataSpec();
|
|
32
|
+
vertex_spec.add(AttributeSpec.fromJSON({
|
|
33
|
+
name: 'position',
|
|
34
|
+
type: DataType.Uint8,
|
|
35
|
+
itemSize: 3,
|
|
36
|
+
normalized: false
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
g_a.vertex_spec = vertex_spec;
|
|
40
|
+
g_a.root = a;
|
|
41
|
+
g_a.initialize();
|
|
42
|
+
|
|
43
|
+
return g_a;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
test("serialization/deserialization consistency", () => {
|
|
47
|
+
const g_a = sampleGeometry();
|
|
48
|
+
|
|
49
|
+
const buffer = new BinaryBuffer();
|
|
50
|
+
|
|
51
|
+
const adapter = new MicronGeometryBinarySerializationAdapter();
|
|
52
|
+
|
|
53
|
+
adapter.serialize(buffer, g_a);
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const g_b = new MicronGeometry();
|
|
57
|
+
|
|
58
|
+
buffer.position = 0;
|
|
59
|
+
adapter.deserialize(buffer, g_b);
|
|
60
|
+
|
|
61
|
+
expect(g_b.vertex_spec.equals(g_a.vertex_spec)).toBe(true);
|
|
62
|
+
expect(g_b.patches.length).toEqual(g_a.patches.length);
|
|
63
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { noop } from "../../../../core/function/Functions.js";
|
|
2
|
+
import { aabb3_array_contains_point } from "../../../../core/bvh2/aabb3/aabb3_array_contains_point.js";
|
|
3
|
+
import { sphere_array_intersects_point } from "../../../../core/geom/3d/sphere/sphere_array_intersects_point.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {MicronGeometryPatch} patch
|
|
8
|
+
* @param {VertexDataSpec} vertex_spec
|
|
9
|
+
* @param {function(string)} [error_consumer]
|
|
10
|
+
* @returns {boolean}
|
|
11
|
+
*/
|
|
12
|
+
export function validate_patch_bounds(patch, vertex_spec, error_consumer = noop) {
|
|
13
|
+
const position_attribute_index = vertex_spec.getAttributeIndexByName('position');
|
|
14
|
+
|
|
15
|
+
if (position_attribute_index === -1) {
|
|
16
|
+
error_consumer(`No 'position' attribute found`);
|
|
17
|
+
// technically any bounds are valid if there is no position
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const position_data = patch.vertex_attribute_arrays[position_attribute_index];
|
|
22
|
+
|
|
23
|
+
let b_sphere_valid = true;
|
|
24
|
+
let b_box_valid = true;
|
|
25
|
+
let gb_sphere_valid = true;
|
|
26
|
+
let gb_box_valid = true;
|
|
27
|
+
|
|
28
|
+
for (let i = 0; i < this.vertex_count; i++) {
|
|
29
|
+
const i3 = i * 3;
|
|
30
|
+
|
|
31
|
+
const x = position_data[i3];
|
|
32
|
+
const y = position_data[i3 + 1];
|
|
33
|
+
const z = position_data[i3 + 2];
|
|
34
|
+
|
|
35
|
+
if (!aabb3_array_contains_point(patch.bounding_box, x, y, z)) {
|
|
36
|
+
b_box_valid = false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!aabb3_array_contains_point(patch.group_bounding_box, x, y, z)) {
|
|
40
|
+
gb_box_valid = false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!sphere_array_intersects_point(patch.bounding_sphere, x, y, z)) {
|
|
44
|
+
b_sphere_valid = false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!sphere_array_intersects_point(patch.group_bounding_sphere, x, y, z)) {
|
|
48
|
+
gb_sphere_valid = false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!b_sphere_valid) {
|
|
53
|
+
error_consumer('.bounding_sphere is violated');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!gb_sphere_valid) {
|
|
57
|
+
error_consumer('.group_bounding_sphere is violated');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!b_box_valid) {
|
|
61
|
+
error_consumer('.bounding_box is violated');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!gb_box_valid) {
|
|
65
|
+
error_consumer('.group_bounding_box is violated');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return b_sphere_valid && gb_sphere_valid && b_box_valid && gb_box_valid;
|
|
69
|
+
}
|
|
@@ -455,7 +455,7 @@ function init() {
|
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
// sample_gltf_sponza();
|
|
458
|
-
gltf_sample('data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf');
|
|
458
|
+
// gltf_sample('data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf');
|
|
459
459
|
// sample_lucy();
|
|
460
460
|
// sample_gltf_hapro_2();
|
|
461
461
|
// sample_gltf_hapro_1();
|
|
@@ -468,6 +468,12 @@ function init() {
|
|
|
468
468
|
// gltf_sample('moicon/29_Dec_2021_Nammo/1/model.gltf');
|
|
469
469
|
// gltf_sample('moicon/29_Dec_2021_Nammo/1-onematerial/model.gltf');
|
|
470
470
|
// gltf_sample('moicon/29_Dec_2021_Nammo/2/model.gltf');
|
|
471
|
+
// gltf_sample('moicon/03_Jan_22_Demo/1-ground_floor/model.gltf');
|
|
472
|
+
// gltf_sample('moicon/03_Jan_22_Demo/2-1st_floor/model.gltf');
|
|
473
|
+
// gltf_sample('moicon/03_Jan_22_Demo/3-area_ground_floor/model.gltf');
|
|
474
|
+
// gltf_sample('moicon/03_Jan_22_Demo/4-area_1st_floor/model.gltf');
|
|
475
|
+
// gltf_sample('moicon/03_Jan_22_Demo/8-assets/model.gltf');
|
|
476
|
+
gltf_sample('moicon/03_Jan_22_Demo/worker_test/model.gltf');
|
|
471
477
|
|
|
472
478
|
document.addEventListener("mousemove", onDocumentMouseMove);
|
|
473
479
|
|
|
@@ -160,6 +160,29 @@ export function shader_rewrite_standard(shader, uniforms, spec, column_count) {
|
|
|
160
160
|
|
|
161
161
|
if (attribute_spec_color !== undefined) {
|
|
162
162
|
// using color
|
|
163
|
+
const vx_color_value = `texelFetch(${gen_micron_vertex_attribute_texture_name('color')}, micron_vertex_uv, 0)`
|
|
164
|
+
|
|
165
|
+
rewrittenVertexShader = rewrittenVertexShader.replace(
|
|
166
|
+
'#include <color_vertex>',
|
|
167
|
+
`
|
|
168
|
+
#if defined( USE_COLOR_ALPHA )
|
|
169
|
+
vColor = vec4( 1.0 );
|
|
170
|
+
#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )
|
|
171
|
+
vColor = vec3( 1.0 );
|
|
172
|
+
#endif
|
|
173
|
+
|
|
174
|
+
#ifdef USE_COLOR
|
|
175
|
+
|
|
176
|
+
#ifdef USE_COLOR_ALPHA
|
|
177
|
+
vColor *= ${vx_color_value}.rgba;
|
|
178
|
+
#else
|
|
179
|
+
vColor *= ${vx_color_value}.rgb;
|
|
180
|
+
#endif
|
|
181
|
+
|
|
182
|
+
#endif
|
|
183
|
+
|
|
184
|
+
`
|
|
185
|
+
);
|
|
163
186
|
|
|
164
187
|
}
|
|
165
188
|
|
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.34.
|
|
8
|
+
"version": "2.34.32",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|