Three.js - ขับไล่จุดยอด / ใบหน้าบางส่วนออกจาก BufferGeometry
ฉันสร้างnew THREE.PlaneBufferGeometry(100, 100, 100, 100);
และอัปเดตตำแหน่งของจุดยอดเพื่อเปลี่ยนรูปร่างของตาข่ายดังต่อไปนี้:
![](https://post.nghiatu.com/assets/images/s/87BMP.png)
ฉันทำได้โดยทำตามการสนทนานี้: Threejs ลากจุด
ฉันกำลังมองหาอะไร
ฉันต้องการที่จะขับไล่ใบหน้า (คว้า 4 จุดยอด) ดังนั้นฉันจึงบรรลุสิ่งนี้:
![](https://post.nghiatu.com/assets/images/s/DtYxI.jpg)
ฉันต้องการให้มันเป็นส่วนหนึ่งของตาข่ายเดียวกันเพื่อให้มันสะอาดเพราะฉันจะส่งออกเป็นตาข่ายเดียวกับColladaExporter
.
แก้ไข
เพื่อให้บรรลุเป้าหมายนี้ฉันจะต้องโคลนจุดยอดและขับไล่พวกมันขึ้นไป ซึ่งหมายความว่าการเพิ่มจุดยอดใหม่ 4 จุดและเชื่อมต่อเข้าด้วยกัน
ฉันลองสิ่งนี้:
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);
และฉันได้รับสิ่งนี้:
![](https://post.nghiatu.com/assets/images/s/MkBsK.png)
ฉันหวังว่าจุดยอดทั้งหมดจะรวมกับเครื่องบินโดยทิ้งระนาบแบน ฉันทำสิ่งนี้เพื่อจุดประสงค์ในการทดสอบ แต่รวมเพียงมุมเดียว
ฉันเริ่มสร้าง "คิวบ์" ด้วยหลาย ๆ อันและวางไว้ในจุดที่ถูกต้องจากนั้นจึงนำไปใช้อีกครั้งBufferGeometryUtils.mergeVertices
แต่ดูเหมือนว่าจุดยอดจะรวมกันไม่ถูกต้อง:
![](https://post.nghiatu.com/assets/images/s/M3zAL.png)
แก้ไข 2 / ความคืบหน้า
ฉันจัดการเพื่อสร้างPlaneBufferGeometry
และขับไล่มันโดยการแก้ไขจุดยอดและบรรทัดฐานด้วยตนเองตามที่บอกใน:https://threejs.org/docs/#api/en/core/BufferGeometry
เครื่องบินอัดมีจุดยอดทั้งหมดเชื่อมต่อกันดังนั้นเมื่อใดก็ตามที่ฉันลากจุดยอดหนึ่งมันจะลากทั้งชิ้นปัญหาตอนนี้คือฉันต้องเชื่อมต่อจุดยอดใหม่เหล่านี้กับกริดเดิมเพื่อหลีกเลี่ยงสิ่งนี้:
![](https://post.nghiatu.com/assets/images/s/8s1Bp.png)
เป้าหมายคือการรวมจุดยอดทั้งหมดตอนนี้ฉันต้องหาวิธีผสานระนาบฐานกับชิ้นส่วนที่อัดขึ้นใหม่
แก้ไข 3 / เสร็จสิ้น
ฉันทำไว้ฉันจะโพสต์คำตอบเมื่อมีเวลา ฉันใช้เวลาทั้งวันในวันนี้และเหนื่อยมากแล้ว
![](https://post.nghiatu.com/assets/images/s/89IZs.png)
คำตอบ
ไม่แน่ใจว่านั่นคือสิ่งที่คุณต้องการหรือไม่ แต่นี่คือตัวอย่างที่แก้ไขจากคำตอบที่คุณอ้างถึง (โปรดสังเกตความแตกต่างในการใช้งาน mouseMove) ฉันได้ขยายให้เป็นสองคะแนนเท่านั้น แต่ฉันเชื่อว่าคุณควรได้รับแนวคิด:
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>