ThreeJS 2D 3D对象边界框

时间:2017-08-24 11:14:55

标签: javascript three.js

我需要弄清楚我的3D对象使用的屏幕区域。

我已经尝试过谷歌寻求答案,但没有成功。

函数package com.java; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; import jxl.Sheet; import jxl.Workbook; import jxl.read.biff.BiffException; public class ReadXls { public static void main(String[] args) { ReadXls reading = new ReadXls(); String filePath = "D:/demo.xls"; String sheetName = "demo"; List al = null; al = reading.readExcelFile(filePath,sheetName); System.out.println("ReadXls.main() al ::: "+al); } public List readExcelFile(String filePath, String sheetName) { FileInputStream fs = null; try { File f = new File(filePath); fs = new FileInputStream(f); } catch (FileNotFoundException e) { e.printStackTrace(); } Workbook wb = null; try { wb = Workbook.getWorkbook(fs); } catch (BiffException | IOException e) { e.printStackTrace(); } Sheet sh = wb.getSheet(sheetName); int totalNoOfRows = sh.getRows(); int totalNoOfCols = sh.getColumns(); List finalData = new ArrayList(); for (int row = 0; row < totalNoOfRows; row++) { for (int col = 0; col < totalNoOfCols; col++) { String eachColCell = sh.getCell(col, row).getContents(); finalData.add(sh.getCell(col, row).getContents()); } } return finalData; } } 仅返回3D边界框。

如何将其转换为2D边界框?

3 个答案:

答案 0 :(得分:3)

您只需将所有顶点转换为屏幕空间并从中创建2D边界框:

function computeScreenSpaceBoundingBox(mesh, camera) {
  var vertices = mesh.geometry.vertices;
  var vertex = new THREE.Vector3();
  var min = new THREE.Vector3(1, 1, 1);
  var max = new THREE.Vector3(-1, -1, -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]。您可以通过乘以渲染器高度和宽度的一半来获取像素:

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

在此处查看演示文稿:http://jsfiddle.net/holgerl/6fy9d54t/

编辑:通过@WestLangley

的建议减少内循环中的内存使用量

EDIT2:修复了@manthrax发现的错误

答案 1 :(得分:0)

指出了一个错误...学到了一些东西...

答案 2 :(得分:0)

聚会晚了一点,但这是一个处理组,子级和缓冲几何的版本:

function computeScreenSpaceBoundingBox(obj, camera) {
    var min;
    var max;

    // Is this an array of objects?
    if(Array.isArray(obj)) {
        for(var i = 0; i < obj.length; ++i) {
            let box2 = computeScreenSpaceBoundingBox(obj[i], camera);
            if(min === undefined) {
                min = box2.min.clone();
                max = box2.max.clone();
            } else {
                min.min(box2.min);
                max.max(box2.max);
            }
        }
    }

    // Does this object have geometry?
    if(obj.geometry !== undefined) {
        var vertices = obj.geometry.vertices;
        if(vertices === undefined
            && obj.geometry.attributes !== undefined
            && 'position' in obj.geometry.attributes) {
            // Buffered geometry
            var vertex = new THREE.Vector3();       
            var pos = obj.geometry.attributes.position;
            for(var i = 0; i < pos.count * pos.itemSize; i += pos.itemSize)
            {
                vertex.set(pos.array[i], pos.array[i + 1], pos.array[1 + 2]);
                var vertexWorldCoord = vertex.applyMatrix4(obj.matrixWorld);
                var vertexScreenSpace = vertexWorldCoord.project(camera);
                if(min === undefined) {
                    min = vertexScreenSpace.clone();
                    max = vertexScreenSpace.clone();
                }
                min.min(vertexScreenSpace);
                max.max(vertexScreenSpace);
            }
        } else {
            // Regular geometry
            var vertex = new THREE.Vector3();       
            for(var i = 0; i < vertices.length; ++i) {
                var vertexWorldCoord = vertex.copy(vertices[i]).applyMatrix4(obj.matrixWorld);
                var vertexScreenSpace = vertexWorldCoord.project(camera);
                if(min === undefined) {
                    min = vertexScreenSpace.clone();
                    max = vertexScreenSpace.clone();
                }
                min.min(vertexScreenSpace);
                max.max(vertexScreenSpace);
            }
        }
    }
    
    // Does this object have children?
    if(obj.children !== undefined) {
        for(var i = 0; i < obj.children.length; ++i) {
            let box2 = computeScreenSpaceBoundingBox(obj.children[i], camera);
            if(min === undefined) {
                min = box2.min.clone();
                max = box2.max.clone();
            } else {
                min.min(box2.min);
                max.max(box2.max);
            }
        }
    }
    
    return new THREE.Box2(min, max);
}