2016-06-20 4 views
1

Я хочу избежать создания новых типизированных массивов и последующего gc(). Я сделал свою геометрию с использованием BufferedGeometry. После получения событий обновляются мои вершины и индексы faces. Я могу обновить координаты, установив verticesNeedUpdate, но он не обновляет лица. Обновление называется ~ 20-50 раз в секунду, что может быть тяжелым в браузере. Как я могу это сделать, избегая создания мусора для сборщика мусора JavaScript? (См. Метод update() ниже).Как эффективно обновить топологию геометрии в ThreeJS?

function WGeometry77(verts, faces) { 
    THREE.Geometry.call(this); 
    this.type = 'WGeometry77'; 
    this.parameters = {}; 
    // Initially create the mesh the easy way, by copying from a BufferGeometry 
    this.fromBufferGeometry(new MyBufferGeometry77(verts, faces)); 
}; 

WGeometry77.prototype = Object.create(THREE.Geometry.prototype); 
WGeometry77.prototype.constructor = WGeometry77; 

WGeometry77.prototype.update = function(verts, faces) { 
    var geom = this; 
    var nl = Math.min(geom.vertices.length, verts.length/3); 
    for (var vi = 0; vi < nl; vi ++) { 
     geom.vertices[ vi ].x = verts[vi*3+0]; 
     geom.vertices[ vi ].y = verts[vi*3+1]; 
     geom.vertices[ vi ].z = verts[vi*3+2]; 
    } 
    var nf = Math.min(geom.faces.length, faces.length/3); 
    for (var fi = 0; fi < nf; fi ++) { 
     geom.faces[ fi ].a = faces[fi*3+0]; 
     geom.faces[ fi ].b = faces[fi*3+1]; 
     geom.faces[ fi ].c = faces[fi*3+2]; 
    } 
    geom.verticesNeedUpdate = true; // Does not update the geom.faces 
} 

PS. Мой код написан в Emscripten, что делает что-то вроде этого:

var verts = Module.HEAPF32.subarray(verts_address/_FLOAT_SIZE, verts_address/_FLOAT_SIZE + 3*nverts); 

То, что я хочу сделать, это почти анимировать, или динамической геометрии (рассчитанной с использованием марширует кубы). Но моя топология (график сетки) также обновляется. Какой класс 3JS я должен использовать? Если такого класса нет, следует ли создать новый класс, например UpdatableBufferedGeometry?

+1

Update 'BufferGeometry' непосредственно. Не создавайте экземпляр «Геометрии» для этой цели. – WestLangley

+0

Спасибо. Вы увидите мой комментарий ниже ответа @ MrDoob? –

ответ

1

Чтобы обновить THREE.BufferGeometry после его визуализации, вы можете использовать этот шаблон:

geometry.attributes.position.setXYZ(index, x, y, z); 

geometry.attributes.position.needsUpdate = true; 

индексированных BufferGeometry, вы можете изменить index массив так:

geometry.index.array[ index ] = value; 

geometry.index.needsUpdate = true; 

Вы не можете RESI ze buffers - только изменить их содержимое. Вы можете предварительно выделить большие массивы и использовать

geometry.setDrawRange(0, numVertices); 

Three.js R.78

+0

Если я «не могу изменить индексный массив, если вы используете индексированную BufferGeometry», то каково это решение? (@mrdoob). Для этого нужен новый класс в Тройстве? Я могу сделать запрос на растяжение. –

+1

Извините. Исправленный ответ. – WestLangley

+0

Отлично! Мне нужно было использовать 'setDrawRange()', чтобы я мог повторно использовать один и тот же объект, используя другое количество треугольников. В моем тесте кажется, что даже не нужно устанавливать 'needsUpdate' (оба). r77 –

1

Если вам нужна эффективность, вы должны создать BufferGeometry вместо Geometry.

Вы можете использовать исходный код этого примера в качестве ссылки: http://threejs.org/examples/#webgl_buffergeometry_uint

+0

У меня есть BufferGeometry. Когда я обновляю его напрямую (см. Ниже), изменения не отражаются на экране. Только когда я сделаю из нее геометрию. Когда Mesh добавляется, если я делаю следующее, я не вижу визуального изменения в моей сетке в следующем файле renderer.render(). Я это сделать: 'reused_geometry.attributes.position [4] + = 20;' ' reused_geometry.index.array [2] = 9;' Даже если я удалить сетку и создал другую сетку из одной и той же геометрии экземпляр объекта, он не обновляется на экране. Мое намерение состоит в том, чтобы избежать даже создания экземпляра BufferGeometry в моем цикле анимации. @WestLangley –

+0

Я получил класс из BufferGeometry, называемый 'MyBufferGeometry77' (см. Основной код). Возможно, я делаю это неправильно, например. Я должен реализовать виртуальный метод? –

Смежные вопросы