0

I'm new to three.js and I have 2 scenes in the same window. It seems like the raycaster is not finding intersects (only on the first scene and not in the second one). What did I do wrong?

I created a new heart shape in each scene. I have a raycaster in each scene. I created a new javascript object cvRenderer that is creating the scene and also has the mousedown event that will trigger the raycaster to work. All fine with the first scene but the raycaster does not find the intersects in the second scene.

var cvRenderer = function () {
    this.scene = null,
    this.camera = null,
    this.renderer = null,
    this.controls = null,
    this.clock = null,
    this.stats = null,
    this.raycaster = null,
    this.INTERSECTED = null,
    this.mouse = null,

    this.init = function (container, width, height) { 
        this.raycaster = new THREE.Raycaster();
        this.mouse = new THREE.Vector2();

        // create main scene
        this.scene = new THREE.Scene();
        this.scene.background = new THREE.Color(0xf0f0f0);

        var SCREEN_WIDTH = width,
            SCREEN_HEIGHT = height;

        // prepare camera
        var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 5000;
        this.camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
        this.scene.add(this.camera);
        //  this.camera.position.set(0, 100, 300);
        this.camera.position.set(0, 100, 1000);
        this.camera.lookAt(new THREE.Vector3(0, 0, 0));

        // prepare renderer
        this.renderer = new THREE.WebGLRenderer({ antialias: true });
        this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
        this.renderer.shadowMapEnabled = true;
        this.renderer.shadowMapSoft = true;

        // prepare container
        container.appendChild(this.renderer.domElement);

        // events
        container.addEventListener('mousedown', (event) => {

            event.preventDefault();
            this.setMouse(event.clientX, event.clientY );

            this.findIntersects(event.clientX, event.clientY);

        }, false);

        // prepare controls (OrbitControls)
        this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
        this.controls.target = new THREE.Vector3(0, 0, 0);
        this.controls.maxDistance = 5000;
        this.controls.enableRotate = false;

        // prepare clock
        this.clock = new THREE.Clock();

        var light = new THREE.PointLight(0xffffff, 0.8);
        this.scene.add(light);

        // load a model
        this.loadModel();
    },
    this.findIntersects = function (clientX, clientY) { 
        this.setMouse(clientX, clientY);

        this.raycaster.setFromCamera(this.mouse, this.camera);

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

        if (intersects.length > 0) {

            intersects[0].object.callback();

        }
    },
    this.setMouse = function (clientX, clientY) { 
        this.mouse.x = (clientX / this.renderer.domElement.clientWidth) * 2 - 1;
        this.mouse.y = - (clientY / this.renderer.domElement.clientHeight) * 2 + 1;
    },
    this.loadModel = function () {
        var extrudeSettings = { depth: 8, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 };

        var heartShape = new THREE.Shape();
        var x = 0, y = 0;
        heartShape.moveTo(x + 25, y + 25);
        heartShape.bezierCurveTo(x + 25, y + 25, x + 20, y, x, y);
        heartShape.bezierCurveTo(x - 30, y, x - 30, y + 35, x - 30, y + 35);
        heartShape.bezierCurveTo(x - 30, y + 55, x - 10, y + 77, x + 25, y + 95);
        heartShape.bezierCurveTo(x + 60, y + 77, x + 80, y + 55, x + 80, y + 35);
        heartShape.bezierCurveTo(x + 80, y + 35, x + 80, y, x + 50, y);
        heartShape.bezierCurveTo(x + 35, y, x + 25, y + 25, x + 25, y + 25);


        var heartgeometry = new THREE.ExtrudeBufferGeometry(heartShape, extrudeSettings);
        var heartmesh = new THREE.Mesh(heartgeometry, new THREE.MeshPhongMaterial({ color: 0xff80f0 }));
        heartmesh.position.set(0, 100, -75);
        heartmesh.rotation.set(0, 0, Math.PI);
        heartmesh.scale.set(1, 1, 1);
        heartmesh.callback = function () {
            console.log("heart was clicked");
        }

        this.scene.add(heartmesh);
    }
};

     var rs = null;
     function animate() {
        requestAnimationFrame(animate);
        render(rs[0]);
        update(rs[0]);
        render(rs[1]);
        update(rs[1]);
    }

    // Update controls and stats
    function update(canvasRenderer) {
        canvasRenderer.controls.update(canvasRenderer.clock.getDelta());
    }

    // Render the scene
    function render(canvasRenderer) {
        if (canvasRenderer.renderer) {
            canvasRenderer.raycaster.setFromCamera(canvasRenderer.mouse, canvasRenderer.camera);
            var intersects = canvasRenderer.raycaster.intersectObjects(canvasRenderer.scene.children, true);
            if (intersects.length > 0) {
                if (canvasRenderer.INTERSECTED != intersects[0].object) {
                    if (canvasRenderer.INTERSECTED) canvasRenderer.INTERSECTED.material.emissive.setHex(canvasRenderer.INTERSECTED.currentHex);
                    canvasRenderer.INTERSECTED = intersects[0].object;
                    canvasRenderer.INTERSECTED.currentHex = canvasRenderer.INTERSECTED.material.emissive.getHex();
                    canvasRenderer.INTERSECTED.material.emissive.setHex(0xfff000);
                }
            } else {
                if (canvasRenderer.INTERSECTED) canvasRenderer.INTERSECTED.material.emissive.setHex(canvasRenderer.INTERSECTED.currentHex);
                canvasRenderer.INTERSECTED = null;
            }
            canvasRenderer.renderer.render(canvasRenderer.scene, canvasRenderer.camera);
        }
    }

    function initializeCanvas() {
        this.container = document.createElement('div');
        document.body.appendChild(this.container);
        var canvasRenderer1 = new cvRenderer();
        canvasRenderer1.init(container, 600, 400, false);


        this.container2 = document.createElement('div');
        document.body.appendChild(this.container2);
        var canvasRenderer2 = new cvRenderer();
        canvasRenderer2.init(container2, 600, 400, false);
        rs = [canvasRenderer1, canvasRenderer2]
        animate();
    }
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • 1
    Possible duplicate of [THREE.js Ray Intersect fails by adding div](https://stackoverflow.com/questions/13542175/three-js-ray-intersect-fails-by-adding-div) – Mugen87 Apr 03 '19 at 09:34
  • the working fix for this problem works just half for me. Inside a container with style or inside of (ionic framework) still the fix is not working – user11271541 Apr 04 '19 at 12:51
  • Any chances to demonstrate the issue as a [live example](https://jsfiddle.net/f2Lommf5/)? This will make it easier to debug your issue and provide more help. – Mugen87 Apr 04 '19 at 15:20

0 Answers0