Три. js вершины BufferGeometry не обновляются - PullRequest
0 голосов
/ 18 февраля 2020

Я ищу, чтобы соединить плоские ячейки геометрической сетки буфера, которые имеют реальные данные высот из IndexedDB Моя проблема в том, что разрешение данных на высоте STRM не является идеальным, поэтому границы между плитками не совпадают. Мне нужно по существу усреднить все края сетки между соприкасающимися вершинами, чтобы создать бесшовную местность.

Когда я копирую, вставляю код в консоль в сцене, это работает. Однако только в коде это не так. Переданный sceneRef действителен, а остальная часть кодовой базы правильно использует sceneRef.

Плитки имеют размер 3 x 3, при этом текущая плитка сетки является центром в 1,1 в диапазоне 0,0–2. , 2.

function connectTiles(currGridKey, sceneRef){
console.log("connectTiles");
console.log("currGridKey");
// Current Tile Connection
for (var lat = 0; lat < currGridKey[0]+2; lat++) {
    for (var long = 0; long < currGridKey[1]+2; long++) {
        const currentTile = sceneRef.getObjectByName(`${lat}-${long}`); 
        // Current Grid Tile Per Loop
        if (currentTile) {
            const currentTileVerts = currentTile.geometry.attributes.position.array,
                  latPlusTile = sceneRef.getObjectByName(`${lat}-${long+1}`),
                  longPlusTile = sceneRef.getObjectByName(`${lat+1}-${long}`);

            // Connect Latitudinally
            if (latPlusTile) {
                const latPlusTileVerts = latPlusTile.geometry.attributes.position.array;
                for (var z = 0; z < currentTileVerts.length; z+=27) {
                    const newVertHeight = (currentTileVerts[z] + latPlusTileVerts[z]) / 2;
                    latPlusTileVerts[z] = newVertHeight;
                    currentTileVerts[z] = newVertHeight;
                }
                latPlusTile.geometry.attributes.position.needsUpdate = true;
                currentTile.geometry.attributes.position.needsUpdate = true;
            }
            // Connection Longitudinally
            if (longPlusTile) {
                const longPlusTileVerts = longPlusTile.geometry.attributes.position.array;
                for (var x = 0; x < currentTileVerts.length; x+=3) {
                    const newVertHeight = (currentTileVerts[x] + longPlusTileVerts[x]) / 2;
                    longPlusTileVerts[x] = newVertHeight;
                    currentTileVerts[x] = newVertHeight;
                }
                longPlusTile.geometry.attributes.position.needsUpdate = true;
                currentTile.geometry.attributes.position.needsUpdate = true;
            }       
        }
    }
}

1 Ответ

0 голосов
/ 22 февраля 2020

Если все значения внутри массива фактически обновляются, возможно, они просто не загружаются в графический процессор. Вместо непосредственного изменения значения внутри geometry.attributes.position, попробуйте использовать метод .setAttribute() . Документы утверждают, что использование .setAttribute() и .getAttribute() предпочтительнее, чем прямой доступ к нему , поскольку он имеет собственный механизм внутренней памяти.

const latPlusTileVerts = latPlusTile.geometry.getAttribute("position").array;
// ... Loops
latPlusTile.geometry.getAttribute("position").needsUpdate = true;

// Or an alternative is to generate a new attribute...
// in case updating the old one fails 
const posAttrib = new THREE.BufferAttribute(latPlusTileVerts, 3);
latPlusTile.geometry.setAttribute("position", posAttrib);
...