Để xác định vị trí 3D của đối tượng tôi sẽ đề xuất dò tia.
Giả sử mô hình nằm trong tọa độ không gian thế giới, bạn cũng cần phải biết tọa độ không gian thế giới của vị trí mắt và tọa độ không gian thế giới của mặt phẳng ảnh. Sử dụng hai điểm đó, bạn có thể tính toán một tia mà bạn sẽ sử dụng để giao cắt với mô hình, mà tôi giả định bao gồm các hình tam giác.
Sau đó, bạn có thể sử dụng phép thử tam giác tia để xác định vị trí 3D của lần chạm, bằng cách tìm hình tam giác có giao điểm gần nhất với mặt phẳng ảnh. Nếu bạn muốn chạm vào tam giác nào, bạn cũng sẽ muốn lưu thông tin đó khi thực hiện các bài kiểm tra giao lộ.
Trang này đưa ra một ví dụ về cách làm ray kiểm tra giao tam giác: http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-9-ray-triangle-intersection/ray-triangle-intersection-geometric-solution/
Edit:
cập nhật để có một số mẫu mã. Một số mã hơi sửa đổi của nó tôi đã lấy từ một dự án raytracing C++ tôi đã làm một lúc trước, do đó bạn sẽ cần phải sửa đổi nó một chút để làm cho nó làm việc cho iOS. Ngoài ra các mã trong hình thức hiện tại của nó thậm chí sẽ không hữu ích vì nó không trả lại điểm giao nhau thực tế mà là nếu tia cắt giao nhau tam giác hay không.
// d is the direction the ray is heading in
// o is the origin of the ray
// verts is the 3 vertices of the triangle
// faceNorm is the normal of the triangle surface
bool
Triangle::intersect(Vector3 d, Vector3 o, Vector3* verts, Vector3 faceNorm)
{
// Check for line parallel to plane
float r_dot_n = (dot(d, faceNorm));
// If r_dot_n == 0, then the line and plane are parallel, but we need to
// do the range check due to floating point precision
if (r_dot_n > -0.001f && r_dot_n < 0.001f)
return false;
// Then we calculate the distance of the ray origin to the triangle plane
float t = (dot(faceNorm, (verts[0] - o))/r_dot_n);
if (t < 0.0)
return false;
// We can now calculate the barycentric coords of the intersection
Vector3 ba_ca = cross(verts[1]-verts[0], verts[2]-verts[0]);
float denom = dot(-d, ba_ca);
dist_out = dot(o-verts[0], ba_ca)/denom;
float b = dot(-d, cross(r.o-verts[0], verts[2]-verts[0]))/denom;
float c = dot(-d, cross(verts[1]-verts[0], o-verts[0]))/denom;
// Check if in tri or if b & c have NaN values
if ( b < 0 || c < 0 || b+c > 1 || b != b || c != c)
return false;
// Use barycentric coordinates to calculate the intersection point
Vector3 P = (1.f-b-c)*verts[0] + b*verts[1] + c*verts[2];
return true;
}
Điểm giao thực tế bạn sẽ quan tâm đến là P.
+1 - Nó rất đơn giản và dễ thực hiện kỹ thuật. Ở đây bạn có thêm thông tin và mã nguồn trong Xử lý (ví dụ như Java) - http://wiki.processing.org/w/Picking_with_a_color_buffer – cyriel
tôi có thể có bất kỳ mã mẫu ios nào trong chủ đề này không? –
Tìm kiếm Hiển thị kết cấu để hiển thị. Sau đó, nó sẽ dễ dàng cho bạn để tìm màu sắc. http://stackoverflow.com/questions/8439697/opengl-es-2-0-render-to-texture – codetiger