Three.js - BufferGeometry'den belirli köşe / yüzleri çıkarın

Aug 16 2020

Bir yaptım new THREE.PlaneBufferGeometry(100, 100, 100, 100);ve ağın şeklini aşağıdaki gibi değiştirmek için köşelerin konumunu güncelleyebildim:

Bunu şu tartışmayı izleyerek başardım : Threejs sürükleme noktaları

Ne arıyorum?

Bir yüzü ekstrüze edebilmek istiyorum (4 köşe kapmak), bu yüzden şöyle bir şey elde ediyorum:

Temiz tutmak için hepsini aynı ağın parçası tutmak istiyorum, çünkü bunu ColladaExporter.

Düzenle

Bunu başarmak için, tepe noktasını klonlamam ve yukarı doğru çıkarmam gerekir. Bu, 4 yeni köşe eklemek ve bunları birbirine bağlamak anlamına gelir.

Bunu denedim:

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);

Ve bunu anladım:

Düz bir düzlem bırakarak tüm köşelerin uçakla birleştiğini umuyordum. Bunu test amaçlı yaptım, ancak yalnızca bir köşeyi birleştirdi.

Birden çok içeren bir "küp" oluşturmaya ve bunları doğru noktaya yerleştirmeye başladım, sonra tekrar uyguladım BufferGeometryUtils.mergeVertices, ancak köşeler doğru şekilde birleşmiyor gibi görünüyor:

Düzenle 2 / İlerleme

Aşağıda anlatıldığı gibi, tepe ve normalleri manuel olarak değiştirerek bir oluşturmayı PlaneBufferGeometryve ekstrüzyon yapmayı başardım :https://threejs.org/docs/#api/en/core/BufferGeometry

Ekstrüde düzlemin tüm köşeleri birbirine bağlıdır, bu yüzden bir tepe noktasını ne zaman sürüklesem bütün bir parçayı sürüklesem, şimdi sorun şu ki, bundan kaçınmak için bu yeni köşeleri orijinal ızgaraya bağlamam gerekiyor:

Hedef, tüm köşeleri birleştirmek, şimdi temel düzlemi yeni ekstrüde parça ile birleştirmenin bir yolunu bulmam gerekiyor.

Düzenle 3 / Bitti

Ben yaptım, biraz zamanım olduğunda cevabı göndereceğim. Bugün bütün günümü bunlarla geçirdim ve zaten çok yorgunum.

Yanıtlar

MarekPiotrowski Aug 16 2020 at 02:32

İhtiyaç duyduğunuz şeyin bu olup olmadığından emin değilim, ancak burada bahsettiğiniz yanıtın değiştirilmiş örneği var (lütfen mouseMove uygulamasındaki farklılığa dikkat edin). Bunu yalnızca iki puan için genişlettim, ancak şu fikri anlamanız gerektiğine inanıyorum:

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>