根据带有点的数组在three.js中创建一个房间

时间:2019-03-23 09:06:32

标签: three.js

我是Three.js的新手。我根据带点数组中的数据创建一个房间。我使用了How to draw walls in ThreeJS from path or 2d array?的提示,正在创建我的房间。 但: 1)您看不到所有的墙-我知道它们是,因为使用OrbitControls时可以看到它-但我不想看到 2)我希望墙壁消失,如以下示例所示:http://jsfiddle.net/he6t10r8/(当我创建“传统”房间时-只有四面墙壁-此解决方案在此起作用,我无法将其固定在可以起作用的地方

这是我的代码(https://codepen.io/jagodanat/pen/pYqMMR?editors=1010):

var wallPoint = [
  {
    "X": 0,
    "Y": 0
  },
  {
    "X": 5,
    "Y": 0
  },
  {
    "X": 5,
    "Y": 3
  },
  {
    "X": 7,
    "Y": 3
  },
  {
    "X": 7,
    "Y": 5
  },
  {
    "X": 5,
    "Y": 5
  },
  {
    "X": 5,
    "Y": 7
  },
  {
    "X": 0,
    "Y": 7
  }
];

function init() {
    container = document.createElement( 'div' );
    container.id = 'container';
    document.body.appendChild( container );
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, 0.95*window.innerHeight );
    renderer.setClearColor( 0x889988 );
    container.appendChild( renderer.domElement );

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight);
    camera.position.set (10, 3, 15) ;
    scene.add(camera);
    var light = new THREE.PointLight( 0xffffff, 0.8 );
    camera.add( light );

    controls = new THREE.OrbitControls( camera, mesh );
    controls.enableZoom = false;
    controls.enablePan = false;
    controls.maxPolarAngle = Math.PI / 2;

     scene.add( new THREE.AmbientLight( 0x444444 ) );

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

 var walls = new THREE.Geometry();
    for(var i = 0; i < wallPoint.length; i++){
        var coordinates = wallPoint[i];
        walls.vertices.push(new THREE.Vector3(coordinates.X, coordinates.Y, 0)); //vertex at floor level
        walls.vertices.push(new THREE.Vector3(coordinates.X, coordinates.Y, 2.5)); //vertex at the top part of the wall, directly above the last
    }
    var previousVertexIndex = walls.vertices.length - 2;
    for( i = 0; i < walls.vertices.length; i += 2){
        walls.faces.push(new THREE.Face3(i, i + 1, previousVertexIndex));
        walls.faces.push(new THREE.Face3(i + 1, previousVertexIndex + 1, previousVertexIndex));
        previousVertexIndex = i;
    }
    walls.computeVertexNormals();
    walls.computeFaceNormals();

  var wallsMaterial = new THREE.MeshLambertMaterial( {
        color: 0xff0ff
    } );
    console.log(walls);

    var mesh = new THREE.Mesh(walls, wallsMaterial);
    mesh.rotation.set(-Math.PI/3, 0.3, -0.3 );
    scene.add(mesh);

}

function animate() {

    requestAnimationFrame( animate );
    renderer.render( scene, camera );

}

init();
animate();

1 个答案:

答案 0 :(得分:0)

除了法线计算错误外,其他所有看起来都很不错。尝试以下操作:

  1. 翻转法线以使墙壁“在房间内看”,
  2. 请勿执行walls.computeVertexNormals()以避免在拐角处进行平滑处理。

建议的修改(在代码中关注我的评论)

var previousVertexIndex = walls.vertices.length - 2;
for (i = 0; i < walls.vertices.length; i += 2) {

    // fix#1 - swap 0 and 1 verts in each face to flip normals

    walls.faces.push(new THREE.Face3(i + 1, i, previousVertexIndex));
    walls.faces.push(new THREE.Face3(previousVertexIndex + 1, i + 1, previousVertexIndex));
    previousVertexIndex = i;
}

//walls.computeVertexNormals(); // fix #2 - don't do this to make room corners sharp
walls.computeFaceNormals();

var wallsMaterial = new THREE.MeshLambertMaterial({
    color: 0xff0ff,
    // side: THREE.DoubleSide // fix #3 - can do this to make room walls visible from both sides.
});

另外: 如果您想将房间“合并”成一个计划,并给墙壁增加一些“厚度”,请考虑使用https://github.com/junmer/clipper-lib