Raycasting работает только на одной половине объекта - PullRequest
0 голосов
/ 07 февраля 2019

Обновление : решение найдено, если кто-то может столкнуться с такой же проблемой.Необходимо сделать две вещи:

  1. После добавления модели в сцену нам нужно обновить MatrixWorld: scene.updateMatrixWorld();

  2. Векторыиспользование raycaster должно быть нормализовано.Таким образом, мы должны изменить две строки кода на: geometry.vertices.push(v1.normalize()); geometry.vertices.push(v2.normalize());


Цель состоит в том, чтобы проследить внутренний контур объекта.и выдавить этот контур в новую форму.Лучевое вещание начинается в середине мира (0,0,0) с obj.вокруг него.

file: /// D: /Mach%20Parat/raycasting/raycast_stackoverflow/raycast.html

Красные линии - это визуализированные направления лучей.Каждый раз, когда лучи пересекаются с объектом, координаты помещаются в массив - на основе этого массива генерируется желтый объект выдавливания.

Проблема в том, что только половина лучей, кажется, регистрирует попадание в объект.

Объ.это чайник, созданный в Blender - Думаю, чашка наполовину полнаhttps://images -wixmp-ed30a86b8c4ca887773594c2.wixmp.com / посредник / f / 8a5fae76-ef7d-4795-9d79-f9b354b893db / dcz4o34-80b02357-3fec-469a-b290-00103ng * 102830 * 102830 Использование простого объекта, такого как сфера (объект по умолчанию в Blender) работает нормально: https://images -wixmp-ed30a86b8c4ca887773594c2.wixmp.com / посредник / f / 8a5fae76-ef7d-4795-9d79-f9b354b893db / dcz4o2r3 19c4077b1d-458c-b39a-61189839a044.png

Но только до тех пор, пока объект центрирован (0,0,0).Переместите его на несколько пикселей, и возникнет та же проблема: https://images -wixmp-ed30a86b8c4ca887773594c2.wixmp.com / посредник / f / 8a5fae76-ef7d-4795-9d79-f9b354b893db / dcz4o2l-2c6a17f8-e3a422-4-e0a44-4e-e3a4-4-4-e0a44-464151839581355.png

можно скачать здесь, если вы хотите проверить сами: http://download.mach -parat.de / raycast.zip

            //////////////////////// Model
            var model= "models/teapot.obj";

            addObject(model);

        }


        function addObject (model){

            var loader = new THREE.OBJLoader();

                loader.load( model, function ( object ) {
                console.log("load");
                console.log(object);
                var material = new THREE.MeshBasicMaterial( {color: 0xffffff, side: THREE.DoubleSide  } );

                scene.add( object );

                object.traverse( function ( child ) {
                       if ( child instanceof THREE.Mesh ) {
                          child.material = material;

                            child.updateMatrix(); // as needed
                        child.updateMatrixWorld(); // as needed
                          objects.push(child);
                       }
                } );

                setupRaycaster();


            });

        } 

        /////////////////////////////////// RAYCASTER AND RED LINE VISUALISATION
        function setupRaycaster(){

            var material = new THREE.LineBasicMaterial({color: 0xff0000});
            var raylength=100;
            var count=90;

            var angle=360/count;


            for (var i=0; i<count; i++){ 

                var x=0;
                var y=0;
                var z=0;


                var v1=new THREE.Vector3( x, y, z);
                var v2=new THREE.Vector3( x+raylength*Math.cos(i*angle*Math.PI/180), y+raylength*Math.sin(i*angle*Math.PI/180), z);

                var geometry = new THREE.Geometry();
                geometry.vertices.push(v1); 
                geometry.vertices.push(v2);

                var line = new THREE.Line( geometry, material );
                scene.add( line );

                var raycaster = new THREE.Raycaster();
                raycaster.set ( v1, v2 );


                var intersects = raycaster.intersectObjects( objects , true);
                console.log(i,intersects);
                if(intersects[0]){
                    cutOutPoints.push(intersects[0].point);
                }

            }

            console.log(cutOutPoints);



            /////////////////////////////////// YELLOW EXTRUDE GEOMETRY
            var cutOutShape = new THREE.Shape();

            if(cutOutPoints.length){// wenn cutpoints in Array
                cutOutShape.moveTo(cutOutPoints[0].x, cutOutPoints[0].y);

                for (var i=1; i<cutOutPoints.length; i++){ 
                    cutOutShape.lineTo(cutOutPoints[i].x, cutOutPoints[i].y);
                }

                var cutOutMaterial = new THREE.LineBasicMaterial({color: 0xffcc00});

                var extrudeSettings = { amount: 60, bevelEnabled: false};

                var geometry = new THREE.ExtrudeGeometry( cutOutShape, extrudeSettings );

                var cutOutMesh = new THREE.Mesh( geometry, cutOutMaterial );
                scene.add( cutOutMesh );
            }

        }

Некоторое время назад я пытался решить эту оригинальную проблему вырезания раковины из буфета: Вычитание трехмерной раковины из трехмерного буфета в ThreeJS

К сожалению, другие решения далине желаемые результаты, но использование трассировки лучей для отслеживания внутренней части раковины (и создания новой формы, которая будет функционировать как логическое значение) выглядит как многообещающее преимущество.

...