处理物体离开飞机 - Three.js

时间:2015-08-08 17:24:09

标签: javascript three.js

我正在开发一个我的项目,其plane grid允许您只捕捉对象。在我被困的地方,我似乎无法弄清楚如何判断一个物体悬在飞机上,而不是在用户触发click时不添加它。

目前:

          event.preventDefault();
          this.mouse.x = ( event.clientX / this.renderer.domElement.width ) * 2 - 1;
          this.mouse.y = - ( event.clientY / this.renderer.domElement.height ) * 2 + 1;

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

          var intersects = this.raycaster.intersectObjects( this.blocks );

          if ( intersects.length > 0 ) {

              var intersect = intersects[ 0 ];

              if ( this.isShiftDown ) { // see if shift is down to remove

                  if ( intersect.object != this.plane ) {

                      this.scene.remove( intersect.object );

                     this.blocks.splice( this.blocks.indexOf( intersect.object ), 1 );

                  }

              } else if(intersect.object == this.plane ){ // add room to canvas

                  var voxel = new THREE.Mesh( this.room.cubeGeometry.clone(), this.room.cubeMaterial.clone() );
                  voxel.position.copy( intersect.point ).add( intersect.face.normal );
                  voxel.position.divideScalar( 50 ).floor().multiplyScalar( 50 ).addScalar( 25 );
                  this.scene.add( voxel );
                  this.blocks.push( voxel );
                  var domEvents   = new THREEx.DomEvents(this.camera.cam, this.renderer.domElement)
                    console.log(voxel);
                  // DOM events for inside 3d rendering
                    domEvents.addEventListener(voxel, 'mouseover', this.onDocumentMouseOverCube.bind(this),false);
                    domEvents.addEventListener(voxel, 'mouseout', this.onDocumentMouseOutCube.bind(this),false);

              }

              this.render();

          }

所以这里发生的事情是:首先我们得到mouse position - 将其发送到raycaster进行设置。比我们查看是否有intersected any objects。现在这一切都很棒,除了。如果一个对象大于单个20x20插槽,它将覆盖平面画布。如果对象悬挂我的飞机,我希望能够拒绝用户放置任何东西。 plane对象始终位于this.blocks[0]位置。正如您在else if中看到的那样,我们会检查它是否在飞机上。但我没有考虑,超过object overhang

有关实现此目标的最佳方法的任何建议吗?

2 个答案:

答案 0 :(得分:1)

  1. 计算对象的边界框。

    var voxel = new THREE.Mesh( this.room.cubeGeometry.clone(), this.room.cubeMaterial.clone() ); voxel.geometry.computeBoundingBox();

  2. 当用户点击平面时,将对象移动到那里并将交点坐标(x,z)与边界框min和max(x,z)值进行比较。

  3. 如果其中一个边界框值大于或小于平面,则它会突出显示。
  4. 这只是一个想法,我没有测试过这个。如果您需要有关代码的帮助,请与我们联系。

答案 1 :(得分:1)

根据福尔克要求分享我的功能,我创造了他的答案。

在处理我们的volex创建时,此处的关键是在每cube.geometry.computeBoundingBox()次创建时设置volex。原因是,默认情况下我们不会有最小或最大边界大小。哪个能够抓取我们depth and width对象的crucial

我们已经知道,在我的情况下,用户位于PlaneBufferGeometryplane。因此,我们将volexplane传递给名为checkOverlapPlane(volex,plane)

的自定义函数

现在,这个函数快速地抓住了planevolex max and min边界。此外,我们抓住volex位置,这对于找出x and z axis上的volex位置至关重要。我们将所有变量转换为正数只是因为它可以轻松处理正数并添加我们的不同x and z。在将我们的intagers转换为积极的intagers后,我们得到total position of the min and max volex z and the volex x。然后将其与我们的plane min x z and max x z进行比较,以返回volex是否悬挂在我们的飞机上。

以下是代码:

     checkOverlapPlane: function(voxel,plane) { // THIS IS USED TO TELL US IF WE ARE OUTSIDE THE GRIDS BOUNDRIES
            // Now before doing anything lets check out min and max boundries to see if our x and z are either bigger or smaller
            var planeMX = plane.geometry.boundingBox.max.x;
            var planeMZ = plane.geometry.boundingBox.max.z;
            var planemX = plane.geometry.boundingBox.min.x;
            var planemZ = plane.geometry.boundingBox.min.z;
                //lets get our voxel min and max vars
            var voxelMX = voxel.geometry.boundingBox.max.x;
            var voxelMZ = voxel.geometry.boundingBox.max.z;
            var voxelmX = voxel.geometry.boundingBox.min.x;
            var voxelmZ = voxel.geometry.boundingBox.min.z;
                // we need to get our voxel position ad to do some math to see if voxel min and max do not go beyound our boundries for our plane
            var voxelPX = voxel.position.x;
            var voxelPZ = voxel.position.z;
                // lets do some calucation and condition
                    // first lets turn everything over to positive for some easy calcuation
            voxelPX = Math.abs(voxelPX); // positions on world view
            voxelPZ = Math.abs(voxelPZ);

            voxelmZ = Math.abs(voxelmZ); // min and max values of our voxel
            voxelmX = Math.abs(voxelmX);
            voxelMZ = Math.abs(voxelMZ);
            voxelMX = Math.abs(voxelMX);

            planemZ = Math.abs(planemZ); // min and max values of our plane our voxels are on
            planemX = Math.abs(planemX);
            planeMZ = Math.abs(planeMZ);
            planeMX = Math.abs(planeMX);
                // now lets calucate X and Z to see if total goes over any of our planes min and max X or Y - remember everything is position but so we can add it to see if its above - we will not actually change the direct objects values
            var totalPositionVoxelminZ = (voxelPZ + voxelmZ);
            var totalPositionVoxelminX = (voxelPX + voxelmX);
            var totalPositionVoxelMAXZ = (voxelPZ + voxelMZ);
            var totalPositionVoxelMAXX = (voxelPX + voxelMX);

                // now lets compare
            if(totalPositionVoxelminZ > planemZ)
                return false; // do nothing
            else if(totalPositionVoxelminX > planemX)
                return false; // do nothing
            else if(totalPositionVoxelMAXZ > planeMZ)
                return false; // do nothing
            else if(totalPositionVoxelMAXX > planeMX)
                return false; // do nothing
            else
                return true;
        },

结果如下:

enter image description here

enter image description here

随意使用并将其纳入任何项目中!