细分几何体的特定面。 three.js所

时间:2015-07-15 13:36:23

标签: 3d three.js

简单的问题,但我已经处理了很多。谁能想到你怎么能将3或4个顶点面分成2个或更多个较小的面?

1 个答案:

答案 0 :(得分:1)

您可能必须手动执行此操作,但对我来说似乎很有可能! 由于three.js总是处理三角形,因为2013年四边形被删除,你必须考虑细分三角形。当你处理伪4顶点面时,它会变得难看,因为它们是由两个三角形构成的。 通过一些矢量计算,你绝对可以解决问题,但需要做大量的工作!

我为你写了一个小小的演示。到目前为止还不完美,但我希望你能得到这个原则;)

http://codepen.io/anon/pen/aOjgeL

HTML:

<html>
  <head>
    Subdivision
  </head>
  <body>
    <div class="button">Subdivide faces</div>
    <div id="rotateX">Rotate X</div>
    <div id="rotateY">Rotate Y</div>
    <div id="rotateZ">Rotate Z</div>
    <div id="container"></div>
  </body>
</html>

CSS:

#container {
    height: 400px;
    width: 800px;
    background-color: #feefee;
}
.button {
  background-color: BLACK;
  color: white;
  width: 150px;
  text-align: center;
}
#rotateX  {
  background-color: RED;
  color: white;
  width: 150px;
  text-align: center;
}
#rotateY  {
  background-color: GREEN;
  color: white;
  width: 150px;
  text-align: center;
}
#rotateZ  {
  background-color: BLUE;
  color: white;
  width: 150px;
  text-align: center;
}

使用Javascript:

var scene, camera, renderer, mesh;
var rotateX, rotateY, rotateZ;

$(document).ready(function(){
    init();
    animate();
});

function init(){
    // Create scene
    scene = new THREE.Scene();

    var container = document.getElementById("container");

    // Create WebGL renderer and add it to the DOM
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(800, 400);
    container.appendChild(renderer.domElement);

    // Create camera, zoom it out from the model and add it to the scene
    camera = new THREE.PerspectiveCamera(45, 800/400, 1, 10000);
    camera.position.set(6, 1, 2);

    // Set background color
    renderer.setClearColor(0xFFFFFF, scene);

    // Add light
    var light = new THREE.PointLight(0xFFFFFF);
    light.position.set(-1, 1, 1);
    scene.add(light);
    var light2 = new THREE.PointLight(0xFFFFFF);
    light2.position.set(1, 1, 1);
    scene.add(light2);
    var light3 = new THREE.PointLight(0xFFFFFF);
    light3.position.set(0, 0, 3);
    light3.intensity = 0.5;
    scene.add(light3);

    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    var material = new THREE.MeshPhongMaterial( {color: 0x000fff, side: THREE.DoubleSide} );
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );

    camera.lookAt(mesh.position);

  var wireframe = new THREE.WireframeHelper(mesh, 0x00ff00);
  scene.add(wireframe);
}

$("#rotateX").click(function(){
  rotateX = (rotateX == true ? false : true);
});

$("#rotateY").click(function(){
  rotateY = (rotateY == true ? false : true);
});

$("#rotateZ").click(function(){
  rotateZ = (rotateZ == true ? false : true);
});

// This is where the magic happens
$(".button").click(function() {
  // Get the wanted face
  var face = mesh.geometry.faces[0];
  // Get the middle between two of the three vectors
  var vector = new THREE.Vector3( (mesh.geometry.vertices[face.b].x + mesh.geometry.vertices[face.c].x) / 2, (mesh.geometry.vertices[face.b].y + mesh.geometry.vertices[face.c].y) / 2, (mesh.geometry.vertices[face.b].z + mesh.geometry.vertices[face.c].z) / 2 );
  // Push vector in vertices array
  mesh.geometry.vertices.push(vector);
  var index = mesh.geometry.vertices.length - 1; // This method of getting the index is not thread safe!
  // Adding first face
  var temp = mesh.geometry.faces[0].b;
  mesh.geometry.faces[0] = new THREE.Face3(mesh.geometry.faces[0].a, index ,mesh.geometry.faces[0].c, mesh.geometry.faces[0].normal, mesh.geometry.faces[0].color, mesh.geometry.faces[0].materialIndex);
  // Adding second face
  mesh.geometry.faces.push( new THREE.Face3(temp, index, mesh.geometry.faces[0].c, mesh.geometry.faces[0].normal, mesh.geometry.faces[0].color, mesh.geometry.faces[0].materialIndex ) );

  mesh.geometry.verticesNeedUpdate = true;
  mesh.geometry.facesNeedUpdate = true;
});

function animate() {
  if(rotateY) mesh.rotateY(0.01);
  if(rotateZ) mesh.rotateZ(0.01);
  if(rotateX) mesh.rotateX(0.01);
  // Render the scene
  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}