2017-01-15 7 views
0

Я пытаюсь преобразовать положение объекта в THREE.js из плоской 2D-координаты (аннотации, помещенной на 2D-изображение) в трехмерную координату, когда изображение обертывается как текстура вокруг трехмерной фигуры. Идея заключалась бы в размещении небольшого 3D-объекта в эквивалентных трехмерных координатах для представления 2D-аннотации.Three.js - вычислить 3D-координаты из UV-координат

Я могу сделать обратное, получив свойства uv.x и uv.y объекта, который пересекается raycaster, который действительно опрятен.

Возможно ли это в ТРИ? Мне нужно было бы учитывать разные формы геометрии.

ответ

0

Фигурного это:

Учитывая УФ Coords точки, которые вы хотите найти:

Прежде всего, необходимо пройти через каждый треугольник в модели рекурсивна, проходящий в УФ-координатах от каждого, и сравнить с лицевой вершиной УФ-массива с использованием барицентрической техники, чтобы увидеть, существует ли точка внутри треугольника в соответствии с УФ.

Как только правильный треугольник расположен, вы можете найти связанные вершины для треугольника и применить к нему координаты с барицентрическими координатами для получения координаты в локальном пространстве.

Затем конвертировать в мировое пространство.

код следующим образом, немного грубый и готов, но вы получите идею:

// 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 []; 
    } 
};