2017-08-24 112 views
5

我需要找出我的三維物體使用的屏幕區域。三維物體的三維二維邊界框

我試過谷歌的答案,但沒有成功。

功能geometry.computeBoundingBox()只返回3D邊界框。

我該如何將其轉換爲2D邊界框?

+1

這聽起來像是一個很好的挑戰。物體或相機是否會動畫?如果是這樣,你是否需要計算每幀佔用一次的屏幕空間? – Marquizzo

+1

是的,我很驚訝它還沒有實現。兩者都可以是動畫,但我有一個想法。 BRB。 – vaid

回答

2

您只需所有頂點轉換成屏幕空間,使二維邊框從他們:

function computeScreenSpaceBoundingBox(mesh, camera) { 
    var vertices = mesh.geometry.vertices; 
    var vertex = new THREE.Vector3(); 
    var min = new THREE.Vector3(1); 
    var max = new THREE.Vector3(-1); 

    for (var i = 0; i < vertices.length; i++) { 
    var vertexWorldCoord = vertex.copy(vertices[i]).applyMatrix4(mesh.matrixWorld); 
    var vertexScreenSpace = vertexWorldCoord.project(camera); 
    min.min(vertexScreenSpace); 
    max.max(vertexScreenSpace); 
    } 

    return new THREE.Box2(min, max); 
} 

產生的BOX2是標準化屏幕座標[1,1]。從@WestLangley在內環減少內存使用情況的建議:

function normalizedToPixels(coord, renderWidthPixels, renderHeightPixels) { 
    var halfScreen = new THREE.Vector2(renderWidthPixels/2, renderHeightPixels/2) 
    return coord.clone().multiply(halfScreen); 
} 

看到它在這裏演示:http://jsfiddle.net/holgerl/6fy9d54t/

編輯您可以通過高度的一半和寬度您的渲染相乘得到的像素

+1

您每秒創建多少個實例?不要在緊密循環中調用'new'或'clone()'。重構你的代碼,並創建一個單一的實例,並使用'copy()'或'set()'重用它。 – WestLangley

+0

好點。我現在更新了內部循環,以減少創建的實例。顯然可以通過使邊界框成爲需要更新的網格上的屬性來進一步優化。再加上一些其他優化。但我想讓代碼易於閱讀,因爲我的主要觀點是如何回答原始問題。 @WestLangley –