【问题标题】:Three.js - calculate 3D coordinates from UV coordinatesThree.js - 从 UV 坐标计算 3D 坐标
【发布时间】:2017-05-30 10:15:38
【问题描述】:

我正在尝试将 THREE.js 中对象的位置从平面 2D 坐标(放置在 2D 图像上的注释)转换为 3D 坐标,此时图像被包裹为 3D 形状周围的纹理。想法是在等效的 3D 坐标处放置一个小的 3D 对象来表示 2D 注释。

我可以通过获取与非常整洁的光线投射器相交的对象的 uv.x 和 uv.y 属性来做相反的事情。

以上三个可能吗?我需要能够考虑不同的几何形状。

【问题讨论】:

    标签: three.js uv-mapping


    【解决方案1】:

    想通了:

    给定您要定位的点的 UV 坐标:

    首先,您需要递归遍历模型中的每个三角形,传入每个三角形的 UV 坐标,并使用重心技术与面顶点 UV 阵列进行比较,以根据 UV 判断该点是否存在于三角形内部。

    一旦找到正确的三角形,您就可以找到三角形的相关顶点并将重心坐标应用于它以获得局部空间中的坐标。

    然后转换到世界空间。

    代码如下,有点粗略,但你明白了:

    // Recursively traverse through the model.
    var traversePolygonsForGeometries = function (node, uvx, uvy) {
    if (node.geometry) {
        // Return a list of triangles that have the point within them.
        // The returned objects will have the x,y,z barycentric coordinates of the point inside the respective triangle
        var baryData = annotationTest(uvx, uvy, node.geometry.faceVertexUvs);
        if (baryData.length) {
            for (var j = 0; j < baryData.length; j++) {
                // In my case I only want to return materials with certain names.
                if (node.geometry.faces[baryData[j][0]].daeMaterial === 
                    "frontMaterial" || node.geometry.faces[baryData[j][0]].daeMaterial ===
                    "print_area1_0"
                    ) {
                    // Find the vertices corresponding to the triangle in the model
                    var vertexa = node.geometry.vertices[node.geometry.faces[baryData[j][0]].a];
                    var vertexb = node.geometry.vertices[node.geometry.faces[baryData[j][0]].b];
                    var vertexc = node.geometry.vertices[node.geometry.faces[baryData[j][0]].c];
                    // Sum the barycentric coordinates and apply to the vertices to get the coordinate in local space
                    var worldX = vertexa.x * baryData[j][1] + vertexb.x * baryData[j][2] + vertexc.x * baryData[j][3];
                    var worldY = vertexa.y * baryData[j][1] + vertexb.y * baryData[j][2] + vertexc.y * baryData[j][3];
                    var worldZ = vertexa.z * baryData[j][1] + vertexb.z * baryData[j][2] + vertexc.z * baryData[j][3];
                    var vector = new THREE.Vector3(worldX, worldY, worldZ);
                    // Translate to world space
                    var worldVector = vector.applyMatrix4(node.matrixWorld);
                    return worldVector;
                }
            }
        }
    }
    if (node.children) {
        for (var i = 0; i < node.children.length; i++) {
            var worldVectorPoint = traversePolygonsForGeometries(node.children[i], uvx, uvy);
            if (worldVectorPoint) return worldVectorPoint;
        }
    }
    };
    
    // Loops through each face vertex UV item and tests if it is within the triangle.
    function annotationTest(uvX, uvY, faceVertexUvArray) {
        var point = {};
        point.x = uvX;
        point.y = uvY;
        var results = [];
        for (i = 0; i < faceVertexUvArray[0].length; i++) {
            var result = ptInTriangle(point, faceVertexUvArray[0][i][0], faceVertexUvArray[0][i][1], faceVertexUvArray[0][i][2]);
            if (result.length) {
                results.push([i, result[0], result[1], result[2]]);
            }
        }
        return results;
    };
    
    // This is a standard barycentric coordinate function.
    function ptInTriangle(p, p0, p1, p2) {
        var x0 = p.x;
        var y0 = p.y;
        var x1 = p0.x;
        var y1 = p0.y;
        var x2 = p1.x;
        var y2 = p1.y;
        var x3 = p2.x;
        var y3 = p2.y;
    
        var b0 = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)
        var b1 = ((x2 - x0) * (y3 - y0) - (x3 - x0) * (y2 - y0)) / b0
        var b2 = ((x3 - x0) * (y1 - y0) - (x1 - x0) * (y3 - y0)) / b0
        var b3 = ((x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0)) / b0
    
        if (b1 > 0 && b2 > 0 && b3 > 0) {
            return [b1, b2, b3];
        } else {
            return [];
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-07
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      相关资源
      最近更新 更多