# Detect collision of instanced mesh and planes

Following up this topic of detecting rain drop collision with a Plane, i have this function bellow, using ray cast to find collision point and reset the rain drop (instanced mesh) whenever it get pass the collision point on the plane:

const intersectionPoints = []; // Array to store intersection points for visualization

function updateRainPositions() {
intersectionPoints.length = 0; // Clear intersection points array

raindrops.forEach((raindrop, index) => {
// Update position
raindrop.y -= raindrop.velocity; // Move the raindrop upward

// Check if raindrop is out of screen
if (raindrop.y < -3.5) {
raindrop.y = 10; // Reset position above the screen
raindrop.velocity = THREE.MathUtils.randFloat(0.1, 0.5); // Reset velocity
console.log("reset");
}
// Raycast to check for collision with the plane and the roof
const raycaster = new THREE.Raycaster(
new THREE.Vector3(raindrop.x, raindrop.y, raindrop.z),
new THREE.Vector3(0, -1, 0)
);

let intersects = raycaster.intersectObjects([planeMesh, roofMesh]);

let collided = false; // Flag to track collision
let intersectionPoint = null; // Store intersection point

// Check for intersection with the plane
if (intersects.length > 0) {
intersectionPoint = intersects[0].point; // Get the intersection point
let check1 = intersectionPoint.y - raindrop.y;
// collided = intersectionPoint.y <= raindrop.y; // Check if collision happened at or below the raindrop
collided = check1 <= 0.001;
// console.log(intersectionPoint.y);
}

// Reset raindrop if collision detected
if (collided) {
// Store the intersection point for visualization
intersectionPoints.push(intersectionPoint);

// Check if raindrop passed the collision point
if (raindrop.y < intersectionPoint.y) {
console.log("passed collision point, resetting");

// Reset raindrop position and velocity
raindrop.y = 10; // Reset position above the screen
raindrop.velocity = THREE.MathUtils.randFloat(0.1, 0.5); // Reset velocity
}
}
});

// Update rainMesh positions
for (let i = 0; i < gCount; i++) {
const raindrop = raindrops[i];
const matrix = new THREE.Matrix4().makeTranslation(raindrop.x, raindrop.y, raindrop.z);
rainMesh.setMatrixAt(i, matrix);
}

rainMesh.instanceMatrix.needsUpdate = true; // Update instance matrix

// Visualize intersection points
visualizeIntersectionPoints();
}

However, no rain drop were reset when they pass through the collision point at all. I used a sphere to visualize the collision point. And it does show the sphere at each point till the rain drop fall through that point, which mean it did detect collision of the points. I also make a console log to print out whenever a rain drop get pass a collision point, but no message was printed out. What could be the problem here?

Such types of problems are easier to resolve by debugging. And as you are the only one that can debug the code, it is up to you. Here are a few suggestions:

• simplify the code by removing all unnecessary things (e.g., for all intersections you can use just one raycaster, instead of creating a new raycaster for each raindrop in each frame)
• make just one drop and debug how its coordinates change
• use normal (non-instance) object and test your algorithm β if it is working, the issue might be with how you manage instancing, if it is not working, then the bug is not in the instancing
• double check all values, for example, is gCount the same as raindrops.length?
• check your axes, e.g. I am confused by this comment βMove the raindrop upwardβ. Is your scene upside-down?
• try to make an online debuggable minimal program with ground, roof, and a few drops, if you still have problems with this simple program, then ask again for help (and provide a link).
2 Likes

Just out of curiousity: is it really need to be that physically correct, when a raindrop hits a surface, then it stars an effect at the exact spot of the hitting?
Maybe itβs enough to show ripples on surfaces, generated with noise in shaders?

1 Like