gpt4 book ai didi

three.js - 从 UV 坐标计算 3D 坐标

转载 作者:行者123 更新时间:2023-12-03 09:12:04 24 4
gpt4 key购买 nike

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

我可以通过获取与光线转换器相交的对象的 uv.x 和 uv.y 属性来执行相反的操作,这非常简洁。

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

最佳答案

弄清楚了:

给定您要定位的点的 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 [];
}
};

关于three.js - 从 UV 坐标计算 3D 坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41661751/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com