diff --git a/src/viewport-three/viewport-host.ts b/src/viewport-three/viewport-host.ts index 05a7d4c3..658ad54b 100644 --- a/src/viewport-three/viewport-host.ts +++ b/src/viewport-three/viewport-host.ts @@ -2989,6 +2989,55 @@ export class ViewportHost { cachedTexture?.texture.dispose(); + private collectViewportWaterContactPatches( + document: SceneDocument, + excludedBrushId: string, + center: Vec3, + rotationDegrees: Vec3, + size: Vec3 + ) { + const contactBounds: GeneratedColliderBounds[] = []; + + for (const brush of Object.values(document.brushes)) { + if (brush.id === excludedBrushId || brush.volume.mode !== "none") { + continue; + } + + contactBounds.push(getBoxBrushBounds(brush)); + } + + for (const modelInstance of getModelInstances(document.modelInstances)) { + if (modelInstance.collision.mode === "none") { + continue; + } + + const asset = this.projectAssets[modelInstance.assetId]; + + if (asset?.kind !== "model") { + continue; + } + + try { + const generatedCollider = buildGeneratedModelCollider(modelInstance, asset, this.loadedModelAssets[modelInstance.assetId]); + + if (generatedCollider !== null) { + contactBounds.push(generatedCollider.worldBounds); + } + } catch { + // Validation already surfaces unsupported collider modes; the viewport keeps rendering. + } + } + + return collectWaterContactPatches( + { + center, + rotationDegrees, + size + }, + contactBounds + ); + } + const texture = createStarterMaterialTexture(material); this.materialTextureCache.set(material.id, {