matrix-engine-wgpu 1.3.3 → 1.3.6
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/index.js +2 -1
- package/package.json +1 -1
- package/src/engine/raycast.js +128 -3
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// import {degToRad, radToDeg} from "./utils";
|
|
7
7
|
import {downloadMeshes} from "./src/engine/loader-obj.js";
|
|
8
8
|
import MatrixEngineWGPU from "./src/world.js";
|
|
9
|
-
import {addRaycastListener, getRayFromMouse, rayIntersectsSphere} from "./src/engine/raycast.js";
|
|
9
|
+
import {addRaycastsAABBListener, addRaycastListener, getRayFromMouse, rayIntersectsSphere} from "./src/engine/raycast.js";
|
|
10
10
|
|
|
11
11
|
var about = () => {
|
|
12
12
|
console.log("Hi npm. matrix-engine for webgpu is ready...")
|
|
@@ -25,5 +25,6 @@ export {
|
|
|
25
25
|
rayIntersectsSphere,
|
|
26
26
|
getRayFromMouse,
|
|
27
27
|
addRaycastListener,
|
|
28
|
+
addRaycastsAABBListener,
|
|
28
29
|
about
|
|
29
30
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matrix-engine-wgpu",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "obj sequence anim +HOTFIX raycast, webGPU powered pwa application. Crazy fast rendering with AmmoJS physics support. Simple raycaster hit object added.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
package/src/engine/raycast.js
CHANGED
|
@@ -72,8 +72,8 @@ export function rayIntersectsSphere(rayOrigin, rayDirection, sphereCenter, spher
|
|
|
72
72
|
return discriminant > 0;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
export function addRaycastListener() {
|
|
76
|
-
let canvasDom = document.getElementById(
|
|
75
|
+
export function addRaycastListener(canvasId = "canvas1") {
|
|
76
|
+
let canvasDom = document.getElementById(canvasId);
|
|
77
77
|
canvasDom.addEventListener('click', (event) => {
|
|
78
78
|
let camera = app.cameras.WASD;
|
|
79
79
|
const {rayOrigin, rayDirection} = getRayFromMouse(event, canvasDom, camera);
|
|
@@ -89,4 +89,129 @@ export function addRaycastListener() {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
});
|
|
92
|
-
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function rayIntersectsAABB(
|
|
95
|
+
rayOrigin,
|
|
96
|
+
rayDirection,
|
|
97
|
+
boxMin,
|
|
98
|
+
boxMax
|
|
99
|
+
) {
|
|
100
|
+
let tmin = (boxMin[0] - rayOrigin[0]) / rayDirection[0];
|
|
101
|
+
let tmax = (boxMax[0] - rayOrigin[0]) / rayDirection[0];
|
|
102
|
+
if(tmin > tmax) [tmin, tmax] = [tmax, tmin];
|
|
103
|
+
|
|
104
|
+
let tymin = (boxMin[1] - rayOrigin[1]) / rayDirection[1];
|
|
105
|
+
let tymax = (boxMax[1] - rayOrigin[1]) / rayDirection[1];
|
|
106
|
+
if(tymin > tymax) [tymin, tymax] = [tymax, tymin];
|
|
107
|
+
|
|
108
|
+
if(tmin > tymax || tymin > tmax) return false;
|
|
109
|
+
if(tymin > tmin) tmin = tymin;
|
|
110
|
+
if(tymax < tmax) tmax = tymax;
|
|
111
|
+
|
|
112
|
+
let tzmin = (boxMin[2] - rayOrigin[2]) / rayDirection[2];
|
|
113
|
+
let tzmax = (boxMax[2] - rayOrigin[2]) / rayDirection[2];
|
|
114
|
+
if(tzmin > tzmax) [tzmin, tzmax] = [tzmax, tzmin];
|
|
115
|
+
|
|
116
|
+
if(tmin > tzmax || tzmin > tmax) return false;
|
|
117
|
+
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function computeAABBFromVertices(vertices) {
|
|
122
|
+
const min = [Infinity, Infinity, Infinity];
|
|
123
|
+
const max = [-Infinity, -Infinity, -Infinity];
|
|
124
|
+
|
|
125
|
+
for(let i = 0;i < vertices.length;i += 3) {
|
|
126
|
+
const x = vertices[i];
|
|
127
|
+
const y = vertices[i + 1];
|
|
128
|
+
const z = vertices[i + 2];
|
|
129
|
+
|
|
130
|
+
min[0] = Math.min(min[0], x);
|
|
131
|
+
min[1] = Math.min(min[1], y);
|
|
132
|
+
min[2] = Math.min(min[2], z);
|
|
133
|
+
|
|
134
|
+
max[0] = Math.max(max[0], x);
|
|
135
|
+
max[1] = Math.max(max[1], y);
|
|
136
|
+
max[2] = Math.max(max[2], z);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return [min, max];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function computeWorldAABB(vertices, modelMatrix) {
|
|
143
|
+
const min = [Infinity, Infinity, Infinity];
|
|
144
|
+
const max = [-Infinity, -Infinity, -Infinity];
|
|
145
|
+
const v = [0, 0, 0];
|
|
146
|
+
|
|
147
|
+
for (let i = 0; i < vertices.length; i += 3) {
|
|
148
|
+
v[0] = vertices[i];
|
|
149
|
+
v[1] = vertices[i + 1];
|
|
150
|
+
v[2] = vertices[i + 2];
|
|
151
|
+
|
|
152
|
+
const worldV = vec3.transformMat4([], v, modelMatrix);
|
|
153
|
+
|
|
154
|
+
min[0] = Math.min(min[0], worldV[0]);
|
|
155
|
+
min[1] = Math.min(min[1], worldV[1]);
|
|
156
|
+
min[2] = Math.min(min[2], worldV[2]);
|
|
157
|
+
|
|
158
|
+
max[0] = Math.max(max[0], worldV[0]);
|
|
159
|
+
max[1] = Math.max(max[1], worldV[1]);
|
|
160
|
+
max[2] = Math.max(max[2], worldV[2]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return [min, max];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function addRaycastsAABBListener(canvasId = "canvas1") {
|
|
167
|
+
const canvasDom = document.getElementById(canvasId);
|
|
168
|
+
if(!canvasDom) {
|
|
169
|
+
console.warn(`Canvas with id ${canvasId} not found`);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
canvasDom.addEventListener('click', (event) => {
|
|
174
|
+
const camera = app.cameras.WASD;
|
|
175
|
+
const {rayOrigin, rayDirection} = getRayFromMouse(event, canvasDom, camera);
|
|
176
|
+
|
|
177
|
+
for(const object of app.mainRenderBundle) {
|
|
178
|
+
// Compute AABB min/max from object position and size
|
|
179
|
+
const pos = [object.position.x,object.position.y,object.position.z]; // [x,y,z]
|
|
180
|
+
// Works only for 0,0,0 static object
|
|
181
|
+
// const [boxMinLocal, boxMaxLocal] = computeAABBFromVertices(object.mesh.vertices);
|
|
182
|
+
const [boxMin, boxMax] = computeWorldAABB(object.mesh.vertices, object.viewMatrix);
|
|
183
|
+
// Optionally transform to world space using object.position
|
|
184
|
+
// const pos = object.position;
|
|
185
|
+
// const boxMin = [
|
|
186
|
+
// boxMinLocal[0] + pos[0],
|
|
187
|
+
// boxMinLocal[1] + pos[1],
|
|
188
|
+
// boxMinLocal[2] + pos[2]
|
|
189
|
+
// ];
|
|
190
|
+
// const boxMax = [
|
|
191
|
+
// boxMaxLocal[0] + pos[0],
|
|
192
|
+
// boxMaxLocal[1] + pos[1],
|
|
193
|
+
// boxMaxLocal[2] + pos[2]
|
|
194
|
+
// ];
|
|
195
|
+
//////////////
|
|
196
|
+
// const size = object.size || [1, 1, 1]; // Replace with actual object size or default 1x1x1
|
|
197
|
+
// const boxMin = [
|
|
198
|
+
// pos[0] - size[0] / 2,
|
|
199
|
+
// pos[1] - size[1] / 2,
|
|
200
|
+
// pos[2] - size[2] / 2
|
|
201
|
+
// ];
|
|
202
|
+
// const boxMax = [
|
|
203
|
+
// pos[0] + size[0] / 2,
|
|
204
|
+
// pos[1] + size[1] / 2,
|
|
205
|
+
// pos[2] + size[2] / 2
|
|
206
|
+
// ];
|
|
207
|
+
|
|
208
|
+
if(rayIntersectsAABB(rayOrigin, rayDirection, boxMin, boxMax)) {
|
|
209
|
+
console.log('AABB hit:', object.name);
|
|
210
|
+
|
|
211
|
+
canvasDom.dispatchEvent(new CustomEvent('ray.hit.event', {
|
|
212
|
+
detail: {hitObject: object}
|
|
213
|
+
}));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}
|