2015-07-15 5 views
0

Простой вопрос, но я имею дело с ним довольно много. Может ли кто-нибудь подумать о том, как вы можете разделить 3 или 4 вершины лица на 2 или более мелких лица?Разделите конкретную грань геометрии. Three.js

+0

Не говоря о SubdivisionMo difier. Представьте, что вы хотите щелкнуть по определенному лицу, если хотите, чтобы оно было разделено, а не вся геометрия. –

ответ

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); 
} 
+0

Определенно работает, но это перегрузка t0o для больших моделей. Во всяком случае, я получу эту идею, и я попытаюсь ее развить. : D –

+0

@MiguelXoelGarcia Удачи;) – Kailijan