-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9382952
commit eaeed45
Showing
2 changed files
with
113 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import * as SPLAT from "gsplat"; | ||
|
||
function getSplatCorners(position: SPLAT.Vector3, rotation: SPLAT.Quaternion, scale: SPLAT.Vector3) { | ||
const localCorners = [ | ||
new SPLAT.Vector3(-0.5, -0.5, 0), | ||
new SPLAT.Vector3(0.5, -0.5, 0), | ||
new SPLAT.Vector3(0.5, 0.5, 0), | ||
new SPLAT.Vector3(-0.5, 0.5, 0), | ||
]; | ||
|
||
const worldCorners = localCorners.map((corner) => { | ||
corner = corner.multiply(scale).multiply(4); | ||
corner = rotation.apply(corner); | ||
corner = corner.add(position); | ||
return corner; | ||
}); | ||
|
||
return worldCorners; | ||
} | ||
|
||
function rayIntersectsTriangle(origin: SPLAT.Vector3, direction: SPLAT.Vector3, triangle: SPLAT.Vector3[]) { | ||
const EPISLON = 0.000001; | ||
const vertex0 = triangle[0]; | ||
const vertex1 = triangle[1]; | ||
const vertex2 = triangle[2]; | ||
|
||
let edge1 = new SPLAT.Vector3(); | ||
let edge2 = new SPLAT.Vector3(); | ||
let h = new SPLAT.Vector3(); | ||
let s = new SPLAT.Vector3(); | ||
let q = new SPLAT.Vector3(); | ||
|
||
edge1 = vertex1.subtract(vertex0); | ||
edge2 = vertex2.subtract(vertex0); | ||
h = direction.cross(edge2); | ||
const a = edge1.dot(h); | ||
|
||
if (a > -EPISLON && a < EPISLON) { | ||
return null; | ||
} | ||
|
||
const f = 1.0 / a; | ||
s = origin.subtract(vertex0); | ||
const u = f * s.dot(h); | ||
|
||
if (u < 0.0 || u > 1.0) { | ||
return null; | ||
} | ||
|
||
q = s.cross(edge1); | ||
const v = f * direction.dot(q); | ||
|
||
if (v < 0.0 || u + v > 1.0) { | ||
return null; | ||
} | ||
|
||
const t = f * edge2.dot(q); | ||
|
||
if (t > EPISLON) { | ||
const intersectionPoint = origin.add(direction.multiply(t)); | ||
return { distance: t, point: intersectionPoint }; | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
function findIntersectedPoint(splat: SPLAT.Splat, origin: SPLAT.Vector3, direction: SPLAT.Vector3) { | ||
let closestPoint = null; | ||
let minDistance = Infinity; | ||
|
||
for (let i = 0; i < splat.data.vertexCount; i++) { | ||
const position = new SPLAT.Vector3( | ||
splat.data.positions[3 * i + 0], | ||
splat.data.positions[3 * i + 1], | ||
splat.data.positions[3 * i + 2], | ||
); | ||
|
||
const rotation = new SPLAT.Quaternion( | ||
splat.data.rotations[4 * i + 1], | ||
splat.data.rotations[4 * i + 2], | ||
splat.data.rotations[4 * i + 3], | ||
-splat.data.rotations[4 * i + 0], | ||
); | ||
|
||
const scale = new SPLAT.Vector3( | ||
splat.data.scales[3 * i + 0], | ||
splat.data.scales[3 * i + 1], | ||
splat.data.scales[3 * i + 2], | ||
); | ||
|
||
const corners = getSplatCorners(position, rotation, scale); | ||
const triangles = [ | ||
[corners[0], corners[1], corners[2]], | ||
[corners[0], corners[2], corners[3]], | ||
]; | ||
|
||
for (const triangle of triangles) { | ||
const intersection = rayIntersectsTriangle(origin, direction, triangle); | ||
if (intersection && intersection.distance < minDistance) { | ||
minDistance = intersection.distance; | ||
closestPoint = i; | ||
} | ||
} | ||
} | ||
|
||
return closestPoint; | ||
} | ||
|
||
export { findIntersectedPoint }; |