@woosh/meep-engine 2.43.20 → 2.43.21
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/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.js +12 -3
- package/engine/graphics/micron/format/MicronGeometryPatch.d.ts +1 -1
- package/engine/graphics/micron/format/MicronGeometryPatch.js +2 -1
- package/engine/graphics/sh3/path_tracer/PathTracedMesh.js +4 -0
- package/engine/graphics/sh3/path_tracer/PathTracer.js +88 -35
- package/engine/graphics/sh3/path_tracer/prototypePathTracer.js +41 -8
- package/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.js +28 -13
- package/package.json +1 -1
|
@@ -16,12 +16,21 @@ export class SGMeshHighlightSystem extends System {
|
|
|
16
16
|
* @param {number} entity
|
|
17
17
|
* @private
|
|
18
18
|
*/
|
|
19
|
-
__apply_highlight(
|
|
19
|
+
__apply_highlight(event, entity) {
|
|
20
20
|
const ecd = this.entityManager.dataset;
|
|
21
21
|
|
|
22
22
|
const sg_mesh = ecd.getComponent(entity, SGMesh);
|
|
23
|
+
|
|
24
|
+
if (sg_mesh === undefined) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
const highlight = ecd.getComponent(entity, Highlight);
|
|
24
29
|
|
|
30
|
+
if (highlight === undefined) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
25
34
|
const node = sg_mesh.__node;
|
|
26
35
|
|
|
27
36
|
node.traverse(t => {
|
|
@@ -35,7 +44,7 @@ export class SGMeshHighlightSystem extends System {
|
|
|
35
44
|
* @param {number} entity
|
|
36
45
|
* @private
|
|
37
46
|
*/
|
|
38
|
-
__remove_highlight(
|
|
47
|
+
__remove_highlight(event, entity) {
|
|
39
48
|
|
|
40
49
|
const ecd = this.entityManager.dataset;
|
|
41
50
|
|
|
@@ -56,7 +65,7 @@ export class SGMeshHighlightSystem extends System {
|
|
|
56
65
|
*/
|
|
57
66
|
link(highlight, mesh, entity) {
|
|
58
67
|
if (mesh.__node !== null) {
|
|
59
|
-
this.__apply_highlight(undefined,
|
|
68
|
+
this.__apply_highlight(undefined, entity);
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
const ecd = this.entityManager.dataset;
|
|
@@ -35,7 +35,7 @@ export class MicronGeometryPatch {
|
|
|
35
35
|
this.group_bounding_box = null;
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* TODO get rid of this, use bounding box instead for smaller memory footprint
|
|
39
39
|
* @type {number[]|Float32Array}
|
|
40
40
|
*/
|
|
41
41
|
this.group_bounding_box_corners = null;
|
|
@@ -124,6 +124,7 @@ export class MicronGeometryPatch {
|
|
|
124
124
|
* @returns {number}
|
|
125
125
|
*/
|
|
126
126
|
allocate_metadata(buffer, offset) {
|
|
127
|
+
assert.isNonNegativeInteger(offset, 'offset');
|
|
127
128
|
assert.greaterThanOrEqual(buffer.byteLength, offset + 144, 'buffer underflow');
|
|
128
129
|
|
|
129
130
|
this.bounding_box = new Float32Array(buffer, offset, 6);
|
|
@@ -23,14 +23,12 @@ import { linear_to_sRGB } from "../../../../core/color/linear_to_sRGB.js";
|
|
|
23
23
|
import { random_in_hemisphere } from "./random_in_hemisphere.js";
|
|
24
24
|
import { sample_triangle_attribute } from "./sample_triangle_attribute.js";
|
|
25
25
|
import { vec3_uint8_to_float } from "./vec3_uint8_to_float.js";
|
|
26
|
-
import { make_sky_rtiw } from "./make_sky_rtiw.js";
|
|
27
26
|
import { apply_texture_clamping_to_coordinate } from "./apply_texture_clamping_to_coordinate.js";
|
|
28
27
|
import { ebvh_sort_for_traversal_depth_first } from "../../../../core/bvh2/bvh3/ebvh_sort_for_traversal_depth_first.js";
|
|
29
|
-
import { clamp01 } from "../../../../core/math/clamp01.js";
|
|
30
28
|
import { v3_dot } from "../../../../core/geom/v3_dot.js";
|
|
31
|
-
import { LightType } from "../../ecs/light/LightType.js";
|
|
32
|
-
import { make_zero_vector3 } from "./make_zero_vector3.js";
|
|
33
29
|
import { make_one_vector3 } from "./make_one_vector3.js";
|
|
30
|
+
import { transform_normal_m4 } from "./ray_hit_apply_transform.js";
|
|
31
|
+
import { ray3_array_compose } from "../../../../core/geom/3d/ray/ray3_array_compose.js";
|
|
34
32
|
|
|
35
33
|
/*
|
|
36
34
|
Ray hit data layout:
|
|
@@ -49,13 +47,22 @@ const texture_uv = [0, 0];
|
|
|
49
47
|
const color = [];
|
|
50
48
|
|
|
51
49
|
const irradiance = [0, 0, 0];
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* @type {number[]|vec3}
|
|
54
|
+
*/
|
|
55
|
+
const throughputColor = [1, 1, 1];
|
|
52
56
|
const trace_result = [];
|
|
53
57
|
|
|
54
|
-
const
|
|
58
|
+
const _ray_0 = [];
|
|
59
|
+
const _ray_1 = [];
|
|
55
60
|
|
|
56
61
|
const tmp_0 = [];
|
|
57
62
|
const tmp_1 = [];
|
|
58
63
|
|
|
64
|
+
const null_output = [];
|
|
65
|
+
|
|
59
66
|
|
|
60
67
|
export class PathTracer {
|
|
61
68
|
constructor() {
|
|
@@ -320,6 +327,9 @@ export class PathTracer {
|
|
|
320
327
|
const normal_array = normal_attribute.array;
|
|
321
328
|
|
|
322
329
|
sample_triangle_attribute(out, 3, index_0, index_1, index_2, normal_array, 3, u, v);
|
|
330
|
+
|
|
331
|
+
// apply transform
|
|
332
|
+
transform_normal_m4(out, 3, out, 3, mesh.transform);
|
|
323
333
|
} else {
|
|
324
334
|
// copy hit normal
|
|
325
335
|
array_copy(hit, 3, out, 3, 3);
|
|
@@ -417,16 +427,17 @@ export class PathTracer {
|
|
|
417
427
|
*
|
|
418
428
|
* @param {number[]} out
|
|
419
429
|
* @param {number} out_offset
|
|
420
|
-
* @param {number[]}
|
|
421
|
-
* @param {number}
|
|
430
|
+
* @param {number[]} ray
|
|
431
|
+
* @param {number} ray_address
|
|
422
432
|
*/
|
|
423
|
-
sample_lights(out, out_offset,
|
|
433
|
+
sample_lights(out, out_offset, ray, ray_address) {
|
|
424
434
|
let lights_sampled = false;
|
|
425
435
|
|
|
426
436
|
const lights = this.__lights;
|
|
427
437
|
const light_count = lights.length;
|
|
428
438
|
|
|
429
439
|
for (let i = 0; i < 3; i++) {
|
|
440
|
+
// initialize contribution to 0
|
|
430
441
|
out[out_offset + i] = 0;
|
|
431
442
|
}
|
|
432
443
|
|
|
@@ -436,25 +447,47 @@ export class PathTracer {
|
|
|
436
447
|
if (light.isDirectionalLight === true) {
|
|
437
448
|
const dir = light.direction;
|
|
438
449
|
|
|
450
|
+
// see https://github.com/mrdoob/three.js/blob/f0a9e0cf90a2f1ba5017fcb7fd46f02748b920cf/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js#L172
|
|
451
|
+
|
|
452
|
+
const ray_direction_x = ray[ray_address + 3];
|
|
453
|
+
const ray_direction_y = ray[ray_address + 4];
|
|
454
|
+
const ray_direction_z = ray[ray_address + 5];
|
|
455
|
+
|
|
456
|
+
const light_dir_inv_x = -dir.x;
|
|
457
|
+
const light_dir_inv_y = -dir.y;
|
|
458
|
+
const light_dir_inv_z = -dir.z;
|
|
459
|
+
|
|
460
|
+
const dotNL = v3_dot(ray_direction_x, ray_direction_y, ray_direction_z, light_dir_inv_x, light_dir_inv_y, light_dir_inv_z);
|
|
461
|
+
|
|
462
|
+
if (dotNL <= 0) {
|
|
463
|
+
// no contribution, facing away from the light
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const ray_origin_x = ray[ray_address + 0];
|
|
468
|
+
const ray_origin_y = ray[ray_address + 1];
|
|
469
|
+
const ray_origin_z = ray[ray_address + 2];
|
|
470
|
+
|
|
471
|
+
ray3_array_compose(_ray_1,
|
|
472
|
+
ray_origin_x, ray_origin_y, ray_origin_z,
|
|
473
|
+
light_dir_inv_x, light_dir_inv_y, light_dir_inv_z
|
|
474
|
+
);
|
|
475
|
+
|
|
439
476
|
// check if there are any obstacles in the direction of the light
|
|
440
|
-
if (this.trace(
|
|
441
|
-
hit_info[hit_info_address + 0],
|
|
442
|
-
hit_info[hit_info_address + 1],
|
|
443
|
-
hit_info[hit_info_address + 2],
|
|
444
|
-
-dir.x, -dir.y, -dir.z
|
|
445
|
-
], 0.0001, Infinity) > 0) {
|
|
477
|
+
if (this.trace(null_output, _ray_1, 0.0001, Infinity) > 0) {
|
|
446
478
|
// light is occluded
|
|
447
|
-
|
|
479
|
+
continue;
|
|
448
480
|
}
|
|
449
481
|
|
|
450
|
-
// see https://github.com/mrdoob/three.js/blob/f0a9e0cf90a2f1ba5017fcb7fd46f02748b920cf/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js#L172
|
|
451
482
|
|
|
452
|
-
const
|
|
483
|
+
const intensity = dotNL * light.intensity.getValue();
|
|
453
484
|
|
|
454
485
|
for (let j = 0; j < 3; j++) {
|
|
455
486
|
// irradiance
|
|
456
|
-
out[out_offset + j] +=
|
|
487
|
+
out[out_offset + j] += light.color[j] * intensity;
|
|
457
488
|
}
|
|
489
|
+
|
|
490
|
+
lights_sampled = true;
|
|
458
491
|
}
|
|
459
492
|
}
|
|
460
493
|
|
|
@@ -464,28 +497,30 @@ export class PathTracer {
|
|
|
464
497
|
path_trace(out, ray, max_distance, max_bounce, random = Math.random) {
|
|
465
498
|
//TODO add importance sampling, see https://raytracing.github.io/books/RayTracingTheRestOfYourLife.html#lightscattering/thescatteringpdf
|
|
466
499
|
|
|
467
|
-
array_copy(ray, 0,
|
|
500
|
+
array_copy(ray, 0, _ray_0, 0, 6);
|
|
468
501
|
|
|
469
|
-
irradiance[0] =
|
|
470
|
-
irradiance[1] =
|
|
471
|
-
irradiance[2] =
|
|
502
|
+
irradiance[0] = 1;
|
|
503
|
+
irradiance[1] = 1;
|
|
504
|
+
irradiance[2] = 1;
|
|
472
505
|
|
|
473
506
|
let got_emission = false;
|
|
474
507
|
|
|
475
508
|
let i;
|
|
476
509
|
for (i = 0; i < max_bounce; i++) {
|
|
477
510
|
|
|
478
|
-
const hit_distance = this.trace(trace_result,
|
|
511
|
+
const hit_distance = this.trace(trace_result, _ray_0, 0.0001, max_distance);
|
|
512
|
+
|
|
479
513
|
|
|
480
514
|
if (hit_distance < 0) {
|
|
481
515
|
// ray didn't hit anything
|
|
482
516
|
|
|
483
517
|
// sample "environment" and terminate path as there is nothing to reflect off of
|
|
484
518
|
|
|
485
|
-
this.sample_background(tmp_0, 0,
|
|
519
|
+
this.sample_background(tmp_0, 0, _ray_0, 3);
|
|
486
520
|
|
|
487
521
|
vec3.multiply(irradiance, irradiance, tmp_0);
|
|
488
522
|
|
|
523
|
+
|
|
489
524
|
got_emission = true;
|
|
490
525
|
|
|
491
526
|
break;
|
|
@@ -498,28 +533,36 @@ export class PathTracer {
|
|
|
498
533
|
this.sample_material(tmp_0, trace_result);
|
|
499
534
|
|
|
500
535
|
// adjust normal on the hit
|
|
501
|
-
|
|
536
|
+
array_copy(tmp_0, 3, trace_result, 3, 3);
|
|
502
537
|
|
|
503
|
-
// sample light
|
|
504
|
-
this.sample_lights(tmp_1, 0, trace_result, 0);
|
|
505
|
-
vec3.add(irradiance, irradiance, tmp_1);
|
|
506
538
|
|
|
507
539
|
// reflect ray
|
|
508
|
-
array_copy(trace_result, 0,
|
|
540
|
+
array_copy(trace_result, 0, _ray_0, 0, 3);
|
|
509
541
|
|
|
510
542
|
// getBiasedNormalSample(_ray, 3, tmp, 3, 1, random);
|
|
511
|
-
random_in_hemisphere(random,
|
|
543
|
+
random_in_hemisphere(random, _ray_0, 3, tmp_0, 3);
|
|
512
544
|
|
|
545
|
+
// accumulate
|
|
513
546
|
vec3.multiply(irradiance, irradiance, tmp_0);
|
|
514
547
|
}
|
|
515
548
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
549
|
+
|
|
550
|
+
if (i > 0) {
|
|
551
|
+
|
|
552
|
+
// directly sample light at the end of the path
|
|
553
|
+
this.sample_lights(tmp_1, 0, trace_result, 0);
|
|
554
|
+
|
|
555
|
+
vec3.multiply(irradiance, irradiance, tmp_1);
|
|
521
556
|
}
|
|
522
557
|
|
|
558
|
+
//
|
|
559
|
+
// if (got_emission === false) {
|
|
560
|
+
// // no light source was hit, propagate shadow(darkness) along the ray
|
|
561
|
+
// irradiance[0] = 0;
|
|
562
|
+
// irradiance[1] = 0;
|
|
563
|
+
// irradiance[2] = 0;
|
|
564
|
+
// }
|
|
565
|
+
|
|
523
566
|
array_copy(irradiance, 0, out, 0, 3);
|
|
524
567
|
}
|
|
525
568
|
}
|
|
@@ -534,3 +577,13 @@ function compute_hit_reaction_standard_material(material, hit) {
|
|
|
534
577
|
}
|
|
535
578
|
|
|
536
579
|
|
|
580
|
+
/**
|
|
581
|
+
*
|
|
582
|
+
* @param {number[]|vec3} out
|
|
583
|
+
* @param {number} value
|
|
584
|
+
*/
|
|
585
|
+
function vec3_set_scalar(out, value) {
|
|
586
|
+
out[0] = value;
|
|
587
|
+
out[1] = value;
|
|
588
|
+
out[2] = value;
|
|
589
|
+
}
|
|
@@ -21,7 +21,7 @@ import { Camera } from "../../ecs/camera/Camera.js";
|
|
|
21
21
|
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
22
22
|
import { scaleSampler2D } from "../../texture/sampler/scaleSampler2D.js";
|
|
23
23
|
import { seededRandom } from "../../../../core/math/random/seededRandom.js";
|
|
24
|
-
import { mat4 } from "gl-matrix";
|
|
24
|
+
import { mat4, vec3 } from "gl-matrix";
|
|
25
25
|
import { v3_distance } from "../../../../core/geom/v3_distance.js";
|
|
26
26
|
import ConcurrentExecutor from "../../../../core/process/executor/ConcurrentExecutor.js";
|
|
27
27
|
import Task from "../../../../core/process/task/Task.js";
|
|
@@ -38,6 +38,7 @@ import { Color } from "../../../../core/color/Color.js";
|
|
|
38
38
|
import { min2 } from "../../../../core/math/min2.js";
|
|
39
39
|
import { makeGeometryIndexed } from "../../geometry/buffered/makeGeometryIndexed.js";
|
|
40
40
|
import { DirectionalLight } from "../../render/forward_plus/model/DirectionalLight.js";
|
|
41
|
+
import { kelvin_to_rgb } from "../../../../core/color/kelvin_to_rgb.js";
|
|
41
42
|
|
|
42
43
|
document.body.style.margin = 0;
|
|
43
44
|
document.body.style.overflow = "hidden";
|
|
@@ -103,6 +104,32 @@ const gltfLoader = new GLTFLoader();
|
|
|
103
104
|
// );
|
|
104
105
|
//
|
|
105
106
|
|
|
107
|
+
function make_sun({
|
|
108
|
+
temperature = 5000, // around clear-sky day
|
|
109
|
+
color = '#FFFFFF',
|
|
110
|
+
intensity = 1,
|
|
111
|
+
direction = new Vector3(-0.5, -1, -0.05)
|
|
112
|
+
} = {}) {
|
|
113
|
+
|
|
114
|
+
const temp_c = new Color();
|
|
115
|
+
|
|
116
|
+
kelvin_to_rgb(temp_c, 0, temperature);
|
|
117
|
+
|
|
118
|
+
const light = new DirectionalLight();
|
|
119
|
+
|
|
120
|
+
light.color.parse(color);
|
|
121
|
+
vec3.multiply(light.color, light.color, temp_c);
|
|
122
|
+
|
|
123
|
+
const n = vec3.length(light.color);
|
|
124
|
+
vec3.scale(light.color, light.color, 1 / n); // normalize color vector
|
|
125
|
+
|
|
126
|
+
light.intensity.set(intensity * n);
|
|
127
|
+
light.direction.copy(direction);
|
|
128
|
+
light.direction.normalize();
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
return light;
|
|
132
|
+
}
|
|
106
133
|
|
|
107
134
|
function prepare_scene_sphere_01(pt, camera) {
|
|
108
135
|
camera.position.set(0, 0, -2.1);
|
|
@@ -132,7 +159,7 @@ function prepare_scene_sphere_01(pt, camera) {
|
|
|
132
159
|
light.direction.set(-1, -1, 0);
|
|
133
160
|
light.direction.normalize();
|
|
134
161
|
|
|
135
|
-
pt.addLight(
|
|
162
|
+
pt.addLight(make_sun());
|
|
136
163
|
}
|
|
137
164
|
|
|
138
165
|
function promise_ply(url) {
|
|
@@ -189,6 +216,8 @@ async function prepare_scene_gltf(pt, camera, url) {
|
|
|
189
216
|
|
|
190
217
|
box3.getBoundingSphere(sphere);
|
|
191
218
|
|
|
219
|
+
pt.addLight(make_sun());
|
|
220
|
+
|
|
192
221
|
camera.position.set(1, 1.3, 1)
|
|
193
222
|
.normalize()
|
|
194
223
|
.multiplyScalar(sphere.radius * 2.6);
|
|
@@ -226,6 +255,8 @@ async function prepare_scene_lucy(pt, camera) {
|
|
|
226
255
|
}).matrix);
|
|
227
256
|
|
|
228
257
|
|
|
258
|
+
pt.addLight(make_sun());
|
|
259
|
+
|
|
229
260
|
camera.position.set(0, 0, -2300);
|
|
230
261
|
camera.lookAt(0, 0, 0);
|
|
231
262
|
}
|
|
@@ -336,6 +367,8 @@ async function prepare_scene_rtiow(pt, camera) {
|
|
|
336
367
|
}
|
|
337
368
|
|
|
338
369
|
|
|
370
|
+
pt.addLight(make_sun());
|
|
371
|
+
|
|
339
372
|
camera.position.set(13, 2, 3);
|
|
340
373
|
camera.lookAt(0, 0, 0);
|
|
341
374
|
|
|
@@ -376,7 +409,7 @@ function* render(target, pt, camera, progress = { current: 0, total: 0 }) {
|
|
|
376
409
|
const pixel_scale_x = 1 / (width - 1);
|
|
377
410
|
const pixel_scale_y = 1 / (height - 1);
|
|
378
411
|
|
|
379
|
-
const pixel_sample_count =
|
|
412
|
+
const pixel_sample_count = 500;
|
|
380
413
|
|
|
381
414
|
progress.total = width * height;
|
|
382
415
|
|
|
@@ -426,7 +459,7 @@ function* render(target, pt, camera, progress = { current: 0, total: 0 }) {
|
|
|
426
459
|
ray_direction.x, ray_direction.y, ray_direction.z
|
|
427
460
|
);
|
|
428
461
|
|
|
429
|
-
pt.path_trace(out, ray, Infinity,
|
|
462
|
+
pt.path_trace(out, ray, Infinity, 16, random);
|
|
430
463
|
|
|
431
464
|
out2[0] += out[0];
|
|
432
465
|
out2[1] += out[1];
|
|
@@ -476,12 +509,12 @@ const camera = new PerspectiveCamera();
|
|
|
476
509
|
async function start_renderer(camera) {
|
|
477
510
|
camera.aspect = vCanvas.size.x / vCanvas.size.y;
|
|
478
511
|
|
|
479
|
-
|
|
480
|
-
const path = 'data/models/road_bike/road_bike.gltf'; //large CAD-type model
|
|
512
|
+
const path = 'data/models/LowPolyTownshipSet/Small_house/Small_house.gltf';
|
|
513
|
+
// const path = 'data/models/road_bike/road_bike.gltf'; //large CAD-type model
|
|
481
514
|
|
|
482
515
|
// await prepare_scene_lucy(pt, camera);
|
|
483
|
-
|
|
484
|
-
await prepare_scene_sphere_01(pt, camera);
|
|
516
|
+
await prepare_scene_rtiow(pt, camera);
|
|
517
|
+
// await prepare_scene_sphere_01(pt, camera);
|
|
485
518
|
// await prepare_scene_gltf(pt, camera, path);
|
|
486
519
|
|
|
487
520
|
pt.build();
|
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
import { v3_length } from "../../../../core/geom/v3_length.js";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number[]} output
|
|
6
|
+
* @param {number} output_offset
|
|
7
|
+
* @param {number[]} normal
|
|
8
|
+
* @param {number} normal_offset
|
|
9
|
+
* @param {number[]} m 4x4 matrix
|
|
10
|
+
*/
|
|
11
|
+
export function transform_normal_m4(output, output_offset, normal, normal_offset, m) {
|
|
12
|
+
|
|
13
|
+
const n_x = normal[normal_offset];
|
|
14
|
+
const n_y = normal[normal_offset + 1];
|
|
15
|
+
const n_z = normal[normal_offset + 2];
|
|
16
|
+
|
|
17
|
+
const result_n_x = m[0] * n_x + m[4] * n_y + m[8] * n_z;
|
|
18
|
+
const result_n_y = m[1] * n_x + m[5] * n_y + m[9] * n_z;
|
|
19
|
+
const result_n_z = m[2] * n_x + m[6] * n_y + m[10] * n_z;
|
|
20
|
+
|
|
21
|
+
const vec_length = v3_length(result_n_x, result_n_y, result_n_z);
|
|
22
|
+
|
|
23
|
+
const normal_multiplier = vec_length === 0 ? 0 : 1 / vec_length;
|
|
24
|
+
|
|
25
|
+
output[output_offset] = result_n_x * normal_multiplier;
|
|
26
|
+
output[output_offset + 1] = result_n_y * normal_multiplier;
|
|
27
|
+
output[output_offset + 2] = result_n_z * normal_multiplier;
|
|
28
|
+
}
|
|
29
|
+
|
|
3
30
|
/**
|
|
4
31
|
*
|
|
5
32
|
* @param {number[]} output
|
|
@@ -25,18 +52,6 @@ export function ray_hit_apply_transform(output, hit, m) {
|
|
|
25
52
|
output[2] = result_p_z;
|
|
26
53
|
|
|
27
54
|
// transform normal
|
|
28
|
-
|
|
29
|
-
const n_y = hit[4];
|
|
30
|
-
const n_z = hit[5];
|
|
31
|
-
|
|
32
|
-
const result_n_x = m[0] * n_x + m[4] * n_y + m[8] * n_z;
|
|
33
|
-
const result_n_y = m[1] * n_x + m[5] * n_y + m[9] * n_z;
|
|
34
|
-
const result_n_z = m[2] * n_x + m[6] * n_y + m[10] * n_z;
|
|
35
|
-
|
|
36
|
-
const normal_multiplier = 1 / v3_length(result_n_x, result_n_y, result_n_z);
|
|
37
|
-
|
|
38
|
-
output[3] = result_n_x * normal_multiplier;
|
|
39
|
-
output[4] = result_n_y * normal_multiplier;
|
|
40
|
-
output[5] = result_n_z * normal_multiplier;
|
|
55
|
+
transform_normal_m4(output, 3, hit, 3, m);
|
|
41
56
|
|
|
42
57
|
}
|
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.43.
|
|
8
|
+
"version": "2.43.21",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|