ThreeJS - how to pick just one type of objects?

♀尐吖头ヾ 提交于 2019-11-26 18:37:50

问题


I'm new to ThreeJS and I have an issue with picking objects by raycasting. I have created some spheres and some lines but only want to change the spheres on mouseover. I think I need to add some condition in the raycast code but I have no idea what...

Here's my code, hope anyone can help:

This creates the objects:

var numSpheres = 10;
var angRand = [numSpheres];
var spread = 10;
var radius = windowY/5;
var radiusControl = 20;

//sphere
var sphereGeometry = new THREE.SphereGeometry(0.35, 100, 100);

//line
var lineGeometry = new THREE.Geometry();
var lineMaterial = new THREE.LineBasicMaterial({
    color: 0xCCCCCC
});

//create dynamically
for (var i = 0; i < numSpheres; i++) {

    var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x334455});
    var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

    var line = new THREE.Line(lineGeometry, lineMaterial);

    angRand[i] = Math.floor((Math.random() * 360) + 1);//random angle for each sphere/line
    var radiusIncr = spread * (angRand[i]+200)/180;
    var xPos = Math.cos((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
    var yPos = Math.sin((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
    var offsetY = Math.floor((Math.random()*5)+1);

    sphere.position.x = xPos/radiusControl;
    sphere.position.y = yPos/radiusControl + offsetY; 

    lineGeometry.vertices.push(
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(sphere.position.x, sphere.position.y, 0)
    );

    scene.add(sphere);
    scene.add(line);
}

And this is my raycast:

var mouse = {
        x: 0,
        y: 0
    },
    INTERSECTED;

window.addEventListener('mousemove', onMouseMove, false);
window.requestAnimationFrame(render);

function onMouseMove(event) {
    // calculate mouse position in normalized device coordinates 
    // (-1 to +1) for both components 
    //event.preventDefault();
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    //console.log(mouse.x + " | " + mouse.y);
}

function mousePos() {
    // find intersections

    // create a Ray with origin at the mouse position
    //   and direction into the scene (camera direction)
    var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
    vector.unproject(camera);

    var ray = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
    ray.linePrecision = 1;

    // create an array containing all objects in the scene with which the ray intersects
    var intersects = ray.intersectObjects(scene.children, true);

    //console.log(intersects.length);

    // INTERSECTED = the object in the scene currently closest to the camera 
    //      and intersected by the Ray projected from the mouse position    

    // if there is one (or more) intersections
    if (intersects.length > 0) {
        // if the closest object intersected is not the currently stored intersection object
        if (intersects[0].object != INTERSECTED) {
            // restore previous intersection object (if it exists) to its original color
            if (INTERSECTED)
                INTERSECTED.material.color.setHex(INTERSECTED.currentHex);

            // store reference to closest object as current intersection object
            INTERSECTED = intersects[0].object;
            // store color of closest object (for later restoration)
            INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
            // set a new color for closest object
            INTERSECTED.material.color.setHex(0xEE7F00);
            //INTERSECTED.radius.set( 1, 2, 2 );
        }
    } else // there are no intersections
    {
        // restore previous intersection object (if it exists) to its original color
        if (INTERSECTED)
            INTERSECTED.material.color.setHex(INTERSECTED.currentHex);
        //INTERSECTED.scale.set( 1, 1, 1 );
        // remove previous intersection object reference
        //     by setting current intersection object to "nothing"
        INTERSECTED = null;
    }
}

回答1:


The raycast returns an intersect array of objects which itself contains information about what the ray hit.

Since you only have spheres and lines you can branch on the geometry type intersects[0].object.geometry.type which would be either 'LineGeometry' or 'SphereGeometry'.

Edit: Obligatory jsfiddle, see console for hit output. http://jsfiddle.net/z43hjqm9/1/




回答2:


To simplify working with the mouse, you can use the class EventsControls. Try to make through this example.

<script src="js/controls/EventsControls.js"></script>

EventsControls = new EventsControls( camera, renderer.domElement );

EventsControls.attachEvent('mouseOver', function() {

    this.container.style.cursor = 'pointer';
    this.mouseOvered.material = selMaterial;
    ... 

});

EventsControls.attachEvent('mouseOut', function() {

    this.container.style.cursor = 'auto';
    this.mouseOvered.material = autoMaterial;
    ...

});

    //

    function render() {
           EventsControls.update();
           controls.update();
           renderer.render(scene, camera);
    }



回答3:


In your code,

var intersects = ray.intersectObjects(scene.children, true);

the first parameter to the call is an object that will be evaluated to see if it, or any of its descendants (recursive is true) intersect the ray.

So, simply create an object target and add the spheres to it (but not the lines).

This will make your call also more effective




回答4:


1.use different arrays to place different objects
a.for all objectType1,after scene.add(objectType1)-> do array1.push(objectType1)
b.for all objectType 2,after scene.add(objectType2)-> do array2.push(objectType2)

now whichever type of objects you want to interact, pass that array in intersect as-
var intersects = raycaster.intersectObjects( arrayType1,true);

now only the arrayType1 objects will interact.



来源:https://stackoverflow.com/questions/28675875/threejs-how-to-pick-just-one-type-of-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!