Âm thanh như bạn đang muốn tìm hiểu về Cây!
Và tôi đang nghiêm túc, nếu bạn hiện đang lặp lại một mảng của tất cả các hình khối của bạn, thì bạn thực sự nên xem xét các cấu trúc dữ liệu không gian khác nhau. Trong trường hợp này, cách tốt nhất để tưởng tượng lại thế giới khối của bạn là một cái cây.
Trước khi chúng ta đi vào lý do là tại sao, hãy suy nghĩ về vấn đề của chúng ta. Chúng tôi đang tìm kiếm một giải pháp trong đó, với chi phí thấp nhất có thể, chúng tôi có thể truy xuất danh sách các hình khối gần đó mà người chơi có thể va chạm. Danh sách này nên nhỏ, nhưng chính xác nhất có thể.
Bây giờ để xác định vùng này, chúng ta cần ánh xạ không gian tọa độ của người chơi sang không gian tọa độ của bản đồ khối; nghĩa là, chúng ta cần ánh xạ vị trí dấu phẩy động của người chơi thành một chỉ số riêng biệt của mảng khối đa chiều (ký hiệu ví dụ có thể là world[31][31][31]
, tức là chính xác ở giữa cho mảng đa chiều 64 * 64 * 64).
Chúng ta có thể chỉ cần tính toán các khối xung quanh bằng cách lập chỉ mục rời rạc tương tự này, có thể chỉ lấy mẫu các khối gần đó, nhưng điều này vẫn đòi hỏi phải tính toán lại liên tục và không cho phép bất kỳ đối tượng nào không rời rạc trong vị trí (nghĩa là không thể ánh xạ vào khối bản đồ).
Tình huống lý tưởng là một nhóm các thùng chứa các bộ khối cho các phần cụ thể của bản đồ khối của chúng tôi, được chia đều cho nhau thay vì tính toán lại khu vực xung quanh, chúng tôi chỉ cần di chuyển vào và ra khỏi những khu vực . Đối với bất kỳ phép tính không tầm thường nào, việc giữ dữ liệu của chúng tôi như thế này có thể loại bỏ việc lặp lại tất cả các hình khối và chỉ những bộ riêng lẻ này ở gần đó.
Câu hỏi là: Làm thế nào để chúng ta thực hiện điều này?
Đối với thế giới 64 * 64 * 64, hãy tưởng tượng nó được chia thành 8 * 8 * 8 vùng . Điều này có nghĩa là trong thế giới của bạn, bạn sẽ có 8 vùng trên mỗi trục (X, Y, Z). Mỗi cái khu vực này sẽ chứa 8 khối, có thể dễ dàng truy xuất bằng chỉ mục đơn giản hóa mới này.
Nếu bạn cần thực hiện một thao tác trên một tập hợp các hình khối gần đó, thay vì lặp lại mọi khối lập phương trong thế giới của bạn, bạn có thể chỉ cần lặp lại các khu vực này , phá vỡ số lần lặp tối đa từ 64 * 64 * 64 (262144) ban đầu để chỉ cần 520 (8 * 8 * 8 + 8).
Bây giờ hãy thu nhỏ từ thế giới khu vực này và đặt các khu vực thành các siêu khu vực lớn hơn ; trong đó mỗi siêu vùng chứa 2 * 2 * 2 vùng thông thường . Khi thế giới của bạn hiện chứa 512 (8 * 8 * 8) khu , chúng ta có thể phá vỡ 8 * 8 * 8 khu thành 64 (4 * 4 * 4) siêu khu bằng cách chia 8 khu 2 khu mỗi siêu zone . Áp dụng logic tương tự từ phía trên, điều này sẽ phá vỡ các lần lặp tối đa từ 512 đến 8 để tìm siêu vùng ; và sau đó tối đa là 64 để tìm khu vực tố tụng (tổng tối đa 72)! Bạn có thể thấy điều này giúp bạn tiết kiệm rất nhiều lần lặp lại (262144: 72).
Tôi chắc chắn bạn có thể thấy bây giờ cây hữu ích như thế nào. Mỗi vùng là một nhánh trên cây, với mỗi siêu vùng là một nhánh trước. Bạn chỉ đơn giản là đi ngang qua cây để tìm thứ bạn cần; sử dụng các bộ dữ liệu nhỏ hơn để giảm thiểu chi phí tổng thể.
Sơ đồ dưới đây sẽ giúp bạn hình dung khái niệm. (hình ảnh từ Wikipedia: Octrees ):
Tuyên bố từ chối trách nhiệm:
Trong một thiết lập lý tưởng như trên, trong đó thế giới voxel của bạn đã được bố trí trong một mảng đa chiều có kích thước cố định, bạn có thể chỉ cần truy vấn vị trí người chơi, sau đó lập chỉ mục các khối xung quanh với chi phí O (1)! (Xem giải thích của Olhovskys) Nhưng điều này trở nên khó khăn hơn khi bạn bắt đầu xem xét rằng thế giới của bạn hiếm khi có kích thước cố định trong trò chơi voxel; và bạn có thể cần cấu trúc dữ liệu của mình để có thể tải toàn bộ siêu vùng từ ổ cứng vào bộ nhớ. Không giống như một mảng đa chiều có kích thước cố định, cây dễ dàng cho phép điều này mà không mất quá nhiều thời gian cho các thuật toán kết hợp.