I have this code that generates some clouds in random position, rotation and random scale. Since they can be generated next to another, or next to another mesh, they can clip together. I want to set a minimum distance, like if(cloud position x and z is < 10 FROM ANOTHER CLOUD) then set distance how can I do? Here's the code:
for(let i = 0; i < 10; i+= 1){
loader.load('/clouds/clouds2/scene.gltf', function (clouds2) {
const cloud = clouds2.scene
const child1 = cloud.children[0].children[0].children[0].children[2].children[0]
const child2 = cloud.children[0].children[0].children[0].children[3].children[0]
const child3 = cloud.children[0].children[0].children[0].children[4].children[0]
child1.material = new THREE.MeshStandardMaterial({ emissive: 'white', emissiveIntensity: 0.3})
child2.material = new THREE.MeshStandardMaterial({ emissive: 'white', emissiveIntensity: 0.3})
child3.material = new THREE.MeshStandardMaterial({ emissive: 'white', emissiveIntensity: 0.3})
cloud.scale.x = (Math.random() * (0.06 - 0.04 ) + 0.04)
cloud.scale.y = (Math.random() * (0.06 - 0.04 ) + 0.04)
cloud.scale.z = (Math.random() * (0.06 - 0.04 ) + 0.04)
cloud.position.x = (Math.random() - 0.5) * 500
cloud.position.y = (Math.random() + 80)
cloud.position.z = (Math.random() - 1) * 500
cloud.rotation.x = Math.random()
cloud.rotation.y = Math.random()
cloud.rotation.z = Math.random()
scene.add(cloud)
})
}
First, there is no shame in placing things statically, and then using random values to create variance. For example, consider a set of 4 clouds arranged at the corners of a square. If you then modified their positions with fixed-range random values, you would get a random effect while still maintaining separation.
const clouds = [...] // cloud meshes
const maxChange = ... // the maximum amount of position change in one direction
const staticPositions = [
new THREE.Vector3(...),
new THREE.Vector3(...),
new THREE.Vector3(...),
new THREE.Vector3(...)
]
for(let i = 0; i < 4; ++i){
let cloud = clouds[i]
cloud.position.copy(staticPositions[i])
// random variance
cloud.position.x += (Math.random() * (maxChange * 2)) - maxChange
cloud.position.y += (Math.random() * (maxChange * 2)) - maxChange
cloud.position.z += (Math.random() * (maxChange * 2)) - maxChange
}
But if you really want to go full random, then you will need to check the new position against all other clouds before committing to it.
const clouds = [...] // cloud meshes
const minDistanceSquared = ... // the minimum (squared) distance allowed between clouds
// checks if a cloud is far enough away from all other clouds
function isFarEnoughAway(cloud){
let retVal = true
for(let i = 0, l = clouds.length; i < l && retVal; ++i){
if(cloud !== clouds[i] && cloud.position.distanceToSquared(clouds[i].position) < minDistSquared){
retVal = false
}
}
return retVal
}