2008-10-15 9 views
9

Tôi có một đối tượng, đang đối mặt với một hướng cụ thể với (ví dụ) một trường 45 độ xem và phạm vi chế độ xem giới hạn. Tôi đã thực hiện tất cả các kiểm tra ban đầu (nút Quadtree, và khoảng cách), nhưng bây giờ tôi cần kiểm tra xem một đối tượng cụ thể có nằm trong hình nón đó không (Trong trường hợp này để quyết định chỉ theo dõi đối tượng đó nếu chúng ta có thể nhìn thấy nó).Làm cách nào để kiểm tra xem một đối tượng trò chơi có thể nhìn thấy đối tượng khác không?

Ngoài việc tạo một tia cho mỗi mức độ từ Direction - (FieldOfView/2) đến Direction + (FieldOfView/2) (Tôi đang làm điều đó vào lúc này và thật khủng khiếp), cách tốt nhất để thực hiện kiểm tra khả năng hiển thị này là gì?

Trả lời

9

Tính toán góc giữa hướng xem của bạn (được hiểu là vectơ) và vectơ bắt đầu tại bạn và kết thúc tại đối tượng. Nếu nó nằm trong FieldOfView/2, bạn có thể xem đối tượng.

góc Đó là:

arccos(scalarProduct(viewDirection, (object - you))/(norm(viewDirection)*norm(object - you))). 
+0

Cảm ơn, chính xác những gì tôi đang tìm kiếm. Tôi nghĩ đây có lẽ là cách đơn giản nhất để đạt được điều này dựa trên những gì tôi đã có. – AshtonKJ

2

Nếu bạn đang làm 3D và có thể xác định phạm vi xem như một frustrum, sau đó bạn có thể sử dụng một cái gì đó tương tự như kỹ thuật Frustrum Culling này.

3

Lấy góc giữa vector tiêu đề của người xem và vectơ từ trình xem đến mục tiêu. Nếu góc đó nhỏ hơn (FieldOfView/2), thì mục tiêu nằm trong trường xem của người xem.

Nếu véc tơ của bạn là 2d hoặc 3d, điều này sẽ hoạt động tương tự. (Trong 3D, nếu bạn có một cái nhìn thất vọng thay vì hình nón, sau đó bạn sẽ cần phải tách các góc thành hai thành phần.) Bạn chỉ cần tìm góc giữa hai vectơ.

Nếu bạn muốn kiểm tra các mục tiêu lớn hơn một điểm, bạn sẽ cần nhiều điểm cho mỗi mục tiêu, chẳng hạn như các góc của một hộp giới hạn. Nếu véc tơ từ người xem đến bất kỳ điểm nào trong số này cho một góc bên trong trường xem, thì góc đó của hộp hiển thị.

10

Tôi đã làm việc trong ngành công nghiệp trò chơi điện tử và tôi có thể nói rằng thực hiện các chức năng trig như arccos mỗi khung hình ít hơn lý tưởng. Thay vào đó, bạn precompute cosin của góc cho hình nón:

float cos_angle = cos(PI/4); // 45 degrees, for example 

Sau đó, mỗi khung hình bạn có thể nhanh chóng kiểm tra xem một điểm rơi bên trong nón rằng bằng cách so sánh rằng với sự chấm sản phẩm của hình nón và.

vector test_point_vector = normalize(test_point_loc - cone_origin); 
float dot_product = dot(normalized_cone_vector, text_point_vector); 
bool inside_code = dot_product > cos_angle; 

Không có chức năng trig, chỉ cần nhân đôi, chia và bổ sung. Hầu hết các công cụ trò chơi đều có chức năng chuẩn hóa() tối ưu hóa cho vectơ.

này hoạt động vì phương trình này:

A · B = |A| * |B| * cos(Θ) 

Nếu bạn bình thường hóa các vectơ (A -> An), phương trình được đơn giản hóa:

An · Bn = cos(Θ) 
+0

Cảm ơn vì điều đó. Tôi thích ý tưởng hạn chế số lượng các chức năng trig trên mỗi khung hình. Tôi chắc chắn sẽ xem xét cố gắng này ra (Đáng buồn thay, chỉ một lần các kỳ thi được hoàn thành). – AshtonKJ

+0

Tôi thích câu trả lời này. Như một lưu ý, giải pháp này sẽ chỉ làm một "kiểm tra thất vọng" và không đối phó với tắc nghẽn bởi các bức tường và các đối tượng khác. –

1

câu trả lời tốt đã nhưng tôi chỉ muốn cung cấp cho bạn một liên kết đến blog của Wolfire, gần đây họ đã bắt đầu một chuỗi đại số có phương trình "trường xem" là một ví dụ. Go read it, được viết tốt và dễ dàng.