Update collision detection to handle triangle meshes and transformed colliders
This commit is contained in:
@@ -592,19 +592,36 @@ export class RuntimeHost {
|
||||
}
|
||||
collectRuntimeStaticWaterContactPatches(brush) {
|
||||
const contactBounds = [];
|
||||
for (const otherBrush of this.runtimeScene?.brushes ?? []) {
|
||||
if (otherBrush.id === brush.id || otherBrush.volume.mode !== "none") {
|
||||
const runtimeBrushesById = new Map((this.runtimeScene?.brushes ?? []).map((runtimeBrush) => [runtimeBrush.id, runtimeBrush]));
|
||||
for (const collider of this.runtimeScene?.colliders ?? []) {
|
||||
if (collider.source === "brush") {
|
||||
const otherBrush = runtimeBrushesById.get(collider.brushId);
|
||||
if (otherBrush === undefined || otherBrush.id === brush.id || otherBrush.volume.mode !== "none") {
|
||||
continue;
|
||||
}
|
||||
contactBounds.push({
|
||||
kind: "triangleMesh",
|
||||
vertices: collider.vertices,
|
||||
indices: collider.indices,
|
||||
transform: {
|
||||
position: collider.center,
|
||||
rotationDegrees: collider.rotationDegrees,
|
||||
scale: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
continue;
|
||||
}
|
||||
contactBounds.push({
|
||||
kind: "orientedBox",
|
||||
center: otherBrush.center,
|
||||
rotationDegrees: otherBrush.rotationDegrees,
|
||||
size: otherBrush.size
|
||||
});
|
||||
}
|
||||
for (const collider of this.runtimeScene?.colliders ?? []) {
|
||||
if (collider.source !== "modelInstance") {
|
||||
if (collider.kind === "trimesh") {
|
||||
contactBounds.push({
|
||||
kind: "triangleMesh",
|
||||
vertices: collider.vertices,
|
||||
indices: collider.indices,
|
||||
transform: collider.transform
|
||||
});
|
||||
continue;
|
||||
}
|
||||
contactBounds.push({
|
||||
|
||||
@@ -815,21 +815,40 @@ export class RuntimeHost {
|
||||
private collectRuntimeStaticWaterContactPatches(brush: RuntimeBoxBrushInstance) {
|
||||
const contactBounds: Parameters<typeof collectWaterContactPatches>[1] = [];
|
||||
|
||||
for (const otherBrush of this.runtimeScene?.brushes ?? []) {
|
||||
if (otherBrush.id === brush.id || otherBrush.volume.mode !== "none") {
|
||||
const runtimeBrushesById = new Map((this.runtimeScene?.brushes ?? []).map((runtimeBrush) => [runtimeBrush.id, runtimeBrush]));
|
||||
|
||||
for (const collider of this.runtimeScene?.colliders ?? []) {
|
||||
if (collider.source === "brush") {
|
||||
const otherBrush = runtimeBrushesById.get(collider.brushId);
|
||||
|
||||
if (otherBrush === undefined || otherBrush.id === brush.id || otherBrush.volume.mode !== "none") {
|
||||
continue;
|
||||
}
|
||||
|
||||
contactBounds.push({
|
||||
kind: "triangleMesh",
|
||||
vertices: collider.vertices,
|
||||
indices: collider.indices,
|
||||
transform: {
|
||||
position: collider.center,
|
||||
rotationDegrees: collider.rotationDegrees,
|
||||
scale: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
contactBounds.push({
|
||||
kind: "orientedBox",
|
||||
center: otherBrush.center,
|
||||
rotationDegrees: otherBrush.rotationDegrees,
|
||||
size: otherBrush.size
|
||||
});
|
||||
}
|
||||
|
||||
for (const collider of this.runtimeScene?.colliders ?? []) {
|
||||
if (collider.source !== "modelInstance") {
|
||||
if (collider.kind === "trimesh") {
|
||||
contactBounds.push({
|
||||
kind: "triangleMesh",
|
||||
vertices: collider.vertices,
|
||||
indices: collider.indices,
|
||||
transform: collider.transform
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -2204,11 +2204,20 @@ export class ViewportHost {
|
||||
if (brush.id === excludedBrushId || brush.volume.mode !== "none") {
|
||||
continue;
|
||||
}
|
||||
const derivedMesh = buildBoxBrushDerivedMeshData(brush);
|
||||
contactBounds.push({
|
||||
kind: "orientedBox",
|
||||
center: brush.center,
|
||||
rotationDegrees: brush.rotationDegrees,
|
||||
size: brush.size
|
||||
kind: "triangleMesh",
|
||||
vertices: derivedMesh.colliderVertices,
|
||||
indices: derivedMesh.colliderIndices,
|
||||
transform: {
|
||||
position: brush.center,
|
||||
rotationDegrees: brush.rotationDegrees,
|
||||
scale: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
for (const modelInstance of getModelInstances(document.modelInstances)) {
|
||||
@@ -2222,7 +2231,17 @@ export class ViewportHost {
|
||||
try {
|
||||
const generatedCollider = buildGeneratedModelCollider(modelInstance, asset, this.loadedModelAssets[modelInstance.assetId]);
|
||||
if (generatedCollider !== null) {
|
||||
contactBounds.push(generatedCollider.worldBounds);
|
||||
if (generatedCollider.kind === "trimesh") {
|
||||
contactBounds.push({
|
||||
kind: "triangleMesh",
|
||||
vertices: generatedCollider.vertices,
|
||||
indices: generatedCollider.indices,
|
||||
transform: generatedCollider.transform
|
||||
});
|
||||
}
|
||||
else {
|
||||
contactBounds.push(generatedCollider.worldBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -3013,11 +3013,21 @@ export class ViewportHost {
|
||||
continue;
|
||||
}
|
||||
|
||||
const derivedMesh = buildBoxBrushDerivedMeshData(brush);
|
||||
|
||||
contactBounds.push({
|
||||
kind: "orientedBox",
|
||||
center: brush.center,
|
||||
rotationDegrees: brush.rotationDegrees,
|
||||
size: brush.size
|
||||
kind: "triangleMesh",
|
||||
vertices: derivedMesh.colliderVertices,
|
||||
indices: derivedMesh.colliderIndices,
|
||||
transform: {
|
||||
position: brush.center,
|
||||
rotationDegrees: brush.rotationDegrees,
|
||||
scale: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3036,7 +3046,16 @@ export class ViewportHost {
|
||||
const generatedCollider = buildGeneratedModelCollider(modelInstance, asset, this.loadedModelAssets[modelInstance.assetId]);
|
||||
|
||||
if (generatedCollider !== null) {
|
||||
contactBounds.push(generatedCollider.worldBounds);
|
||||
if (generatedCollider.kind === "trimesh") {
|
||||
contactBounds.push({
|
||||
kind: "triangleMesh",
|
||||
vertices: generatedCollider.vertices,
|
||||
indices: generatedCollider.indices,
|
||||
transform: generatedCollider.transform
|
||||
});
|
||||
} else {
|
||||
contactBounds.push(generatedCollider.worldBounds);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Validation already surfaces unsupported collider modes; the viewport keeps rendering.
|
||||
|
||||
Reference in New Issue
Block a user