细分几何体的特定面。 Three.js
Subdivide a specific face of a geometry. Three.js
简单的问题,但我已经处理了很多。谁能想一想如何将一个 3 或 4 个顶点的面分成 2 个或更多更小的面?
您可能必须手动执行此操作,但对我来说似乎很有可能!
自从 2013 年移除四边形后,three.js 始终处理三角形,因此您必须考虑细分三角形。这就是它变得丑陋的地方,当你处理伪 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);
}
简单的问题,但我已经处理了很多。谁能想一想如何将一个 3 或 4 个顶点的面分成 2 个或更多更小的面?
您可能必须手动执行此操作,但对我来说似乎很有可能! 自从 2013 年移除四边形后,three.js 始终处理三角形,因此您必须考虑细分三角形。这就是它变得丑陋的地方,当你处理伪 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);
}