未捕获的TypeError:无法读取属性' length' null - Three.js

时间:2017-03-13 22:51:55

标签: three.js typeerror

我试图通过鼠标点击坐标并挤出它来绘制方形墙。 我通过点击现场来拾取鼠标坐标。



var onDocumentMouseDown = function ( event ) 
    {
        //update the mouse variable
        mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
            mouse.y = -( event.clientY / window.innerHeight ) * 2 + 1;
        var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
        vector.unproject( camera );
        var dir = vector.sub( camera.position ).normalize();
        var distance = - camera.position.z / dir.z;
        var pos = camera.position.clone().add( dir.multiplyScalar( distance));
        console.log('mouse_x ' + pos.x + ' mouse_y ' + pos.y);
        if (clickCount <= 3){
            coord[clickCount] = {'x' : pos.x, 'y' : pos.y};
            clickCount ++;
        } else {
        //make new wall and stop function
            newshape = new THREE.Shape();
            shape.moveTo(coord['0'].x ,coord['0'].y);
            shape.lineTo(coord['0'].x, coord['1'].y);
            shape.lineTo(coord['2'].x, +coord['2'].y);
            shape.lineTo(coord['3'].x, coord['3'].y);
            shape.lineTo(coord['0'].x, coord['0'].y);
            var newextrudeSettings = {
            //*******/
            };
        }
&#13;
&#13;
&#13;

当我收到四个坐标时,三个.js抛出错误:

  

未捕获的TypeError:无法读取属性&#39;长度&#39;为null       at Object.triangulateShape(three.js:26140)       在ExtrudeGeometry.addShape(three.js:26330)       在ExtrudeGeometry.addShapeList(three.js:26235)       在新的ExtrudeGeometry(three.js:26211)       在HTMLDocument.onDocumentMouseDown(script.js:116)

1 个答案:

答案 0 :(得分:1)

为了找到交叉点,我更喜欢使用THREE.Raycaster()(虽然我从未使用THREE.Projector()来实现此目的)。

这是我的代码的结果: enter image description here

我希望得到你的概念。因此,你需要的所有东西都在这里:

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects;
var controlPoints = [];
var clickCount = 0;

function onMouseDown(event) {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  raycaster.setFromCamera(mouse, camera);
  intersects = raycaster.intersectObjects(objects); // objects is an array which contains just the mesh of the plane
  if (intersects.length > 0) { 
    if (clickCount <= 3) { // I took your idea of 4 clicks
      controlPoints[clickCount] = intersects[0].point.clone(); // add a control point to the array

      // visualization of a control point
      var cp = new THREE.Mesh(new THREE.SphereGeometry(0.125, 16, 12), new THREE.MeshBasicMaterial({color: "red"}));
      cp.position.copy(intersects[0].point);
      scene.add(cp);

      clickCount++;
    } else { // on the fifth click we'll create our wall
      shape = new THREE.Shape();
      shape.moveTo(controlPoints[0].x, -controlPoints[0].z);
      shape.lineTo(controlPoints[1].x, -controlPoints[1].z);
      shape.lineTo(controlPoints[2].x, -controlPoints[2].z);
      shape.lineTo(controlPoints[3].x, -controlPoints[3].z);
      shape.lineTo(controlPoints[0].x, -controlPoints[0].z);
      var extrudeSettings = {
        steps: 1,
        amount: 2,
        bevelEnabled: false
      };
      var extrudeGeom = new THREE.ExtrudeGeometry(shape, extrudeSettings);
      extrudeGeom.rotateX(-Math.PI / 2);
      var wall = new THREE.Mesh(extrudeGeom, new THREE.MeshStandardMaterial({
        color: "gray"
      }));
      scene.add(wall);
      controlPoints = []; // we clear the array of control points
      clickCount = 0; // and reset the counter of clicks
    };
  };
};

jsfiddle示例。 4次点击设置控制点,第五次点击创建墙,依此类推。