私はthree.jsでアプリケーションを構築していますが、パフォーマンスに大きな問題があります。このアプリケーションのこの部分は、Voxel Painter exampleに基づいています。私のバージョンでは、ユーザーはセルをクリックして配置を開始し、カーソルを配置を終了する位置にドラッグし、クリックして終了します。ユーザーがマウスを移動したときRayCasterでonMouseMoveを使用した場合、Three.jsのパフォーマンスが非常に遅い
function onDocumentMouseMove(event) {
//set up mouse and raycaster
event.preventDefault();
mouse.set((event.clientX/window.innerWidth) * 2 - 1, -(event.clientY/window.innerHeight) * 2 + 1);
raycaster.setFromCamera(mouse, camera);
switch (buildMode) {
case buildModes.CORRIDOR:
scene.add(rollOverFloor);
var intersects = raycaster.intersectObjects(gridObject);
if (intersects.length > 0) {
var intersect = intersects[0];
if (beginPlace == true) {
//store the intersection position
var endPlace = new THREE.Vector3(0, 0, 0);
endPlace.copy(intersect.point).add(intersect.face.normal);
endPlace.divideScalar(step).floor().multiplyScalar(step).addScalar(step/step);
endPlace.set(endPlace.x, 0, endPlace.z);
corridorDrag(endPlace);
}
//if user hasn't begun to place the wall
else {
//show temporary wall on grid
rollOverFloor.position.copy(intersect.point).add(intersect.face.normal);
rollOverFloor.position.divideScalar(step).floor().multiplyScalar(step).addScalar(step/step);
rollOverFloor.position.set(rollOverFloor.position.x, 0, rollOverFloor.position.z);
}
}
break;
}
render();
}
上記のコードは、(そこにメインのアプリケーションには多くのbuildmodesがありますが、私はそれらをここに含まれていない)と呼ばれています。この関数は単に開始および終了ポイントを取得し、corridorDrag()関数は、開始点と終了点との間の細胞を充填:
function corridorDrag(endPlace) {
deleteFromScene(stateType.CORRIDOR_DRAG);
var startPoint = startPlace;
var endPoint = endPlace;
var zIntersect = new THREE.Vector3(startPoint.x, 0, endPoint.z);
var xIntersect = new THREE.Vector3(endPoint.x, 0, startPoint.z);
var differenceZ = Math.abs(startPlace.z - zIntersect.z);
var differenceX = Math.abs(startPlace.x - xIntersect.x);
var mergedGeometry = new THREE.Geometry();
for (var i = 0; i <= (differenceZ/step); i++) {
for (var j = 0; j <= (differenceX/step); j++) {
var x = startPlace.x;
var y = startPlace.y;
var z = startPlace.z;
if (endPoint.x <= (startPlace.x)) {
if (endPoint.z <= (startPlace.z)) {
x = x - (step * j);
z = z - (step * i);
}
else if (endPoint.z >= (startPlace.z)) {
x = x - (step * j);
z = z + (step * i);
}
} else if (endPoint.x >= (startPlace.x)) {
if (endPoint.z <= (startPlace.z)) {
x = x + (step * j);
z = z - (step * i);
}
else if (endPoint.z >= (startPlace.z)) {
x = x + (step * j);
z = z + (step * i);
}
}
floorGeometry.translate(x, y, z);
mergedGeometry.merge(floorGeometry);
floorGeometry.translate(-x, -y, -z);
}
}
var voxel = new THREE.Mesh(mergedGeometry, tempMaterial);
voxel.state = stateType.CORRIDOR_DRAG;
scene.add(voxel);
tempObjects.push(voxel);
}
まず、deleteFromScene()関数は、シーンのすべての現在強調表示された細胞を除去する(参照します以下)。その後、コードは(私は信じて)、開始点と終了点に応じていくつかのメッシュを作成し、それらをシーンに追加する必要があります。
function deleteFromScene(state) {
tempObjects = [];
var i = scene.children.length;
while (i--) {
if (scene.children[i].state != undefined)
if (scene.children[i].state == state)
scene.children.splice(i, 1);
}
}
私が言ったように、非常に遅いです。また、WebGLRendererの統計ウィンドウに表示されるように、奇妙な量の頂点をレンダラーに追加するように見えます。私はそれがなぜ非常に多くの頂点を追加しているのか分かりませんが、それがとてもゆっくりとレンダリングされていると仮定しています。
The application can be viewed here - 問題は、1つのセルをクリックし、グリッドのもう一方の端にカーソルをドラッグし、セルを埋める時間を観察することで確認できます。
ありがとうございます。これは本当に最後の手段です。
非常に雄弁な解決策です。 – jdmdevdotnet
私のonDocumentMouseMove(イベント)関数の上にスニペットを追加して下にコードを配置すると、とても良い解決策になりました。@ Brandon.Blanchyard – user3329161
コード実行時にこれらのエラーが発生します。 捕捉されなかっにReferenceError:isVectorEqualはHTMLDocument.onDocumentMouseDown(3dblueprint.uk/:216) –