In this demonstration, you can observe two clickable particles that both respond to clicks. I am seeking a way to detect clicks on particles without removing them from the scene, similar to this:
if (intersects.length>0){
if(intersects[0].object.type == "Points"){
intersects[0].object.material.color.setHex( Math.random() * 0xffffff );
}
}
I prioritize using particles because they maintain a consistent size relative to the camera, eliminating the need for a secondary orthographic camera. Ultimately, my goal is to achieve something reminiscent of the ARK Starmap from Star Citizen, where systems remain consistently sized and clickable.
$(function(){
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var stats;
var camera, controls, scene, renderer;
var group;
var objectControls;
var particleSystem, raycaster;
var mouse = new THREE.Vector2();
var projector = new THREE.Projector();
function init() {
var width = window.innerWidth;
var height = window.innerHeight;
camera = new THREE.PerspectiveCamera(50, width / height, 1, 10000000);
camera.position.z = 1500;
camera.position.y = 100;
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setClearColor("black");
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.autoClear = false;
var container = document.getElementById('container');
container.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableZoom = false;
controls.minDistance = 50;
controls.maxDistance = 500000;
var loader = new THREE.TextureLoader();
loader.load("textures/systempoint.png", function(texture) {
particles = new THREE.Geometry(),
pMaterial = new THREE.PointsMaterial({ map: texture, size: 32, transparent: true, sizeAttenuation: false });
particle = new THREE.Vector3(400, 300, 300);
particles.vertices.push(particle);
particle = new THREE.Vector3(300, 400, 300);
particles.vertices.push(particle);
// create the particle system
particleSystem = new THREE.Points(particles, pMaterial);
particleSystem.sortParticles = false;
particleSystem.name = "systems";
scene.add(particleSystem);
});
//////////////////////////////////////////////////////////////////////////
// Lights
//////////////////////////////////////////////////////////////////////////
light = new THREE.AmbientLight(0x666666);
scene.add(light);
var params = { recursive: true };
objectControls = new ObjectControls(camera, params);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild(stats.domElement);
window.addEventListener('resize', onWindowResize, false);
console.log(scene);
}
function onWindowResize() {
var width = window.innerWidth;
var height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
}
var lastTimeMsec = null;
var nowMsec = null;
function animate() {
requestAnimationFrame(animate);
//controls.update(); // required if controls.enableDamping = true, or if controls.autoRotate = true
stats.update();
objectControls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
$(document).mousedown(function(e) {
e.preventDefault();
var mouseVector = new THREE.Vector3(
(e.clientX / window.innerWidth) * 2 - 1,
-(e.clientY / window.innerHeight) * 2 + 1,
1
);
mouseVector.unproject(camera);
var raycaster = new THREE.Raycaster(camera.position, mouseVector.sub(camera.position).normalize());
raycaster.params.Points.threshold = 15;
var intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
if (intersects[0].object.type == "Points") {
console.log(intersects[0].object.position);
intersects[0].object.material.color.setHex(Math.random() * 0xffffff);
}
}
});
init();
animate();
});