Hello everyone, I've been working on a personal project lately that involves the amazing library three.js
.
Specifically, I've been exploring collision detection using the example from this GitHub repository, focusing on detecting overlaps between objects using voxels
.
To illustrate my issue, I've been referencing the interactive voxel painter example.
When rendering a voxel
on the screen, I noticed that placing another voxel
above the cube works fine, but doing so below a certain radius doesn't allow me to render it:
https://i.sstatic.net/A8B1n.png
Above is an image of a rendered "cube": https://i.sstatic.net/XKRWb.png
Here is a function I created based on stemkoski's example:
checkOverlapObject: function(voxel) //This function checks for overlapping objects
{
var originPoint = voxel.position.clone();
var collidableObjs = this.rooms;
for (var vertexIndex = 0; vertexIndex < voxel.geometry.vertices.length; vertexIndex++)
{
var localVertex = voxel.geometry.vertices[vertexIndex].clone();
console.log(localVertex);
var globalVertex = localVertex.applyMatrix4( voxel.matrix );
console.log(globalVertex);
var directionVector = globalVertex.sub(voxel.position);
console.log(directionVector);
console.log(originPoint);
console.log(directionVector.clone().normalize());
if(collidableObjs.length > 0)
{
var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
var collisionResults = ray.intersectObjects(collidableObjs);
if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length())
{
console.log(collisionResults);
console.log(collisionResults[0].distance);
console.log(directionVector.length());
return false;
}
}
}
return true;
},
Prior to adding a rendered voxel
, users can preview whether they have permission to add it. This is achieved by passing a voxel
created as follows:
var voxel = new THREE.Mesh(this.room.cubeGeometry, this.room.cubeTmpHoverMaterial);
voxel.geometry.computeBoundingBox();
voxel.position.copy(intersect.point).add(intersect.face.normal);
voxel.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);
voxel.material.color.setHex(this.colorTmpHover);
Into our checkOverlapObject
function to detect any overlap with already rendered objects on the screen or grid.
Following the creation of this neat little function, I added several console.log
outputs for debugging purposes. Here are some of the results:
T…E.Vector3 {x: 25, y: 25, z: 25} <!-- our localVertex
T…E.Vector3 {x: 25, y: 25, z: 25} <!-- our globalVertex
T…E.Vector3 {x: 0, y: 0, z: -350} <!-- our directionVector
T…E.Vector3 {x: 25, y: 25, z: 375} <!-- our originPoint
T…E.Vector3 {x: 0, y: 0, z: -1} <!-- our directionVector.clone().normalize()
[Object, Object] <!-- our collisionResults
225 <!-- our collisionResults[0].distance
350 <!-- our directionVector.length()
This data is based on the first picture provided in the post.
I should mention that I have other voxels
occupying more than one block on the grid. Thus, the function needs to consider the entire object when checking for overlaps with existing voxels
. Touching adjacent objects is allowed.
If anyone has suggestions or thoughts on what might be causing the issue, please feel free to share.