Three.js - Extrudieren Sie einen bestimmten Scheitelpunkt / eine bestimmte Fläche aus BufferGeometry
Ich habe eine erstellt new THREE.PlaneBufferGeometry(100, 100, 100, 100);
und konnte die Position von Scheitelpunkten aktualisieren, um die Form des Netzes wie folgt zu ändern:

Ich habe dies erreicht, indem ich dieser Diskussion gefolgt bin : Drei Punkte ziehen
Wonach suche ich?
Ich möchte in der Lage sein, ein Gesicht zu extrudieren (4 Eckpunkte greifen), also erreiche ich so etwas:

Ich möchte, dass alles Teil desselben Netzes ist, um es sauber zu halten, da ich es als einzelnes Netz mit dem exportieren werde ColladaExporter
.
Bearbeiten
Um dies zu erreichen, müsste ich den Scheitelpunkt klonen und nach oben extrudieren. Dies bedeutet, 4 neue Scheitelpunkte hinzuzufügen und diese miteinander zu verbinden.
Ich habe es versucht:
var geo = new THREE.PlaneBufferGeometry(1, 1, 1, 1);
geo.rotateX(-Math.PI * 0.5);
geo.translate(0,0.5,0);
//And the merge them together
var newplane = BufferGeometryUtils.mergeBufferGeometries([plane, geo]);
newplane = BufferGeometryUtils.mergeVertices(newplane,1);
Und ich habe folgendes:

Ich hatte gehofft, dass alle Eckpunkte mit der Ebene verschmolzen und eine flache Ebene hinterließen. Ich habe dies zu Testzwecken gemacht, aber es wurde nur eine Ecke zusammengeführt.
Ich habe angefangen, einen "Würfel" mit mehreren zu erstellen und sie an der richtigen Stelle zu platzieren, um sie dann erneut anzuwenden BufferGeometryUtils.mergeVertices
, aber die Eckpunkte scheinen nicht richtig zu verschmelzen:

Bearbeiten 2 / Fortschritt
Ich habe es geschafft, ein zu erstellen PlaneBufferGeometry
und es zu extrudieren, indem ich die Scheitelpunkte und Normalen manuell geändert habe , wie in:https://threejs.org/docs/#api/en/core/BufferGeometry
In der extrudierten Ebene sind alle Scheitelpunkte verbunden. Wenn ich also einen Scheitelpunkt ziehe, wird ein ganzes Stück gezogen. Das Problem besteht nun darin, dass ich diese neuen Scheitelpunkte mit dem ursprünglichen Raster verbinden muss, um dies zu vermeiden:

Ziel ist es, alle Eckpunkte zusammenzuführen. Jetzt muss ich einen Weg finden, um die Basisebene mit dem neuen extrudierten Teil zusammenzuführen.
Bearbeiten 3 / Fertig
Ich habe es geschafft, ich werde eine Antwort posten, wenn ich etwas Zeit habe. Ich habe heute den ganzen Tag damit verbracht und war schon sehr müde.

Antworten
Sie sind sich nicht sicher, ob Sie dies benötigen, aber hier ist das geänderte Beispiel aus der Antwort, auf die Sie verwiesen haben (beachten Sie bitte den Unterschied in der Implementierung von mouseMove). Ich habe das nur um zwei Punkte erweitert, aber ich glaube, Sie sollten auf die Idee kommen:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(1.25, 7, 7);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.PlaneBufferGeometry(10, 10, 10, 10);
geometry.rotateX(-Math.PI * 0.5);
var plane = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
wireframe: true,
color: "red"
}));
scene.add(plane);
var points = new THREE.Points(geometry, new THREE.PointsMaterial({
size: 0.25,
color: "yellow"
}));
scene.add(points);
var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = 0.25;
var mouse = new THREE.Vector2();
var intersects = null;
var plane = new THREE.Plane();
var planeNormal = new THREE.Vector3();
var currentIndex = null;
var planePoint = new THREE.Vector3();
var dragging = false;
window.addEventListener("mousedown", mouseDown, false);
window.addEventListener("mousemove", mouseMove, false);
window.addEventListener("mouseup", mouseUp, false);
function mouseDown(event) {
setRaycaster(event);
getIndex();
dragging = true;
}
function mouseMove(event) {
if (dragging && currentIndex !== null) {
setRaycaster(event);
raycaster.ray.intersectPlane(plane, planePoint);
var indicesToMoveUp = [currentIndex-1, currentIndex];
var delta_x = geometry.attributes.position.getX(currentIndex) - planePoint.x;
geometry.attributes.position.setXYZ(currentIndex, planePoint.x, planePoint.y, planePoint.z);
geometry.attributes.position.needsUpdate = true;
var old_x_neighbour = geometry.attributes.position.getX(currentIndex - 1);
geometry.attributes.position.setY(currentIndex-1, planePoint.y);
geometry.attributes.position.setZ(currentIndex-1, planePoint.z);
geometry.attributes.position.setX(currentIndex-1, old_x_neighbour - delta_x);
geometry.attributes.position.needsUpdate = true;
}
}
function mouseUp(event) {
dragging = false;
currentIndex = null;
}
function getIndex() {
intersects = raycaster.intersectObject(points);
if (intersects.length === 0) {
currentIndex = null;
return;
}
currentIndex = intersects[0].index;
setPlane(intersects[0].point);
}
function setPlane(point) {
planeNormal.subVectors(camera.position, point).normalize();
plane.setFromNormalAndCoplanarPoint(planeNormal, point);
}
function setRaycaster(event) {
getMouse(event);
raycaster.setFromCamera(mouse, camera);
}
function getMouse(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>