【问题标题】:create a room in three.js based on the array with points基于带点的数组在three.js中创建一个房间
【发布时间】:2019-03-23 23:04:09
【问题描述】:

我是 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();

【问题讨论】:

    标签: three.js


    【解决方案1】:

    一切看起来都不错,只是法线计算错误。请尝试以下操作:

    1. 翻转法线,使墙壁“看到房间内部”,
    2. 不要使用walls.computeVertexNormals() 以避免对角进行平滑处理。

    建议编辑(在代码中关注我的 cmets)

    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

    【讨论】:

    • 感谢您的快速响应和帮助 - 特别是 cmets 解释了为什么我必须改变某些东西/放弃某些东西。现在一切正常。
    猜你喜欢
    • 2016-05-05
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    相关资源
    最近更新 更多