Sepertinya Anda ingin belajar tentang Pohon!
Dan saya serius, jika Anda saat ini mengulang array dari semua kubus Anda, maka Anda benar-benar harus melihat ke dalam berbagai struktur data spasial. Untuk kasus ini, cara terbaik untuk membayangkan kembali dunia kubus Anda adalah sebagai pohon.
Sebelum kita masuk ke alasan mengapa, mari kita pikirkan masalah kita. Kami sedang mencari solusi di mana, untuk biaya sesedikit mungkin, kami dapat mengambil daftar kubus terdekat yang mungkin bertabrakan dengan pemain. Daftar ini harus sekecil mungkin, namun setepat mungkin.
Sekarang untuk menentukan zona ini, kita perlu memetakan ruang koordinat pemain kita ke ruang koordinat peta kubus; yaitu, kita perlu memetakan posisi titik mengambang pemain ke indeks diskrit array multi-dimensi kubus (contoh notasi mungkin world[31][31][31]
, yaitu tepat tengah untuk array multidimensi 64 * 64 * 64).
Kita bisa menghitung blok di sekitarnya menggunakan pengindeksan diskrit yang sama, mungkin mengambil sampel hanya kubus di dekatnya, tetapi ini masih membutuhkan perhitungan ulang yang konstan, dan tidak memungkinkan untuk objek yang tidak terpisah dalam penempatan (yaitu mungkin tidak memetakan ke kubus peta).
Situasi yang ideal adalah satu set ember yang berisi set kubus kami untuk bagian tertentu dari peta kubus kami, dibagi rata sehingga alih-alih menghitung ulang daerah sekitarnya, kami cukup bergerak masuk dan keluar dari zona ini . Untuk perhitungan non-sepele, memegang data kami seperti ini bisa menghilangkan iterasi semua kubus, dan hanya set individu ini yang berada di dekatnya.
Pertanyaannya adalah: Bagaimana kita menerapkan ini?
Untuk dunia 64 * 64 * 64, bayangkan dunia dipecah menjadi 8 * 8 * 8 zona . Ini berarti bahwa di dunia Anda, Anda akan memiliki 8 zona per sumbu (X, Y, Z). Masing-masing zona ini akan berisi 8 kubus, mudah diambil oleh indeks baru yang disederhanakan ini.
Jika Anda perlu melakukan operasi pada satu set kubus terdekat, alih-alih iterasi setiap kubus di dunia Anda, Anda bisa dengan mudah beralih ke zona ini , meruntuhkan jumlah iterasi maksimum dari 64 * 64 * 64 (262144) asli ke hanya 520 (8 * 8 * 8 + 8).
Sekarang perkecil dari dunia zona ini, dan tempatkan zona itu ke zona super besar ; dimana masing - masing zona super berisi 2 * 2 * 2 zona reguler . Karena dunia Anda saat ini berisi 512 (8 * 8 * 8) zona , kami dapat memecah 8 * 8 * 8 zona menjadi 64 (4 * 4 * 4) zona super dengan membagi 8 zona dengan 2 zona per zona super . Menerapkan logika yang sama dari atas, ini akan mematahkan iterasi maksimum dari 512 ke 8 untuk menemukan super-zone ; dan kemudian maksimum 64 untuk menemukan zona proses(total maks 72)! Anda dapat melihat bagaimana ini sudah menghemat banyak iterasi (262144: 72).
Saya yakin Anda dapat melihat sekarang betapa bermanfaatnya pohon. Setiap zona adalah cabang di pohon, dengan masing - masing zona super sebagai cabang sebelumnya. Anda hanya melintasi pohon untuk menemukan apa yang Anda butuhkan; menggunakan set data yang lebih kecil untuk meminimalkan biaya keseluruhan.
Diagram di bawah ini akan membantu Anda memvisualisasikan konsep. (gambar dari Wikipedia: Octrees ):
Penolakan:
Dalam pengaturan ideal seperti di atas, di mana dunia voxel Anda sudah diletakkan dalam array multi-dimensi ukuran tetap, Anda bisa menanyakan posisi pemain, lalu mengindeks blok di sekitarnya dengan biaya O (1)! (Lihat penjelasan Olhovskys) Tapi ini menjadi lebih sulit ketika Anda mulai mempertimbangkan bahwa dunia Anda jarang ukuran tetap dalam permainan voxel; dan Anda mungkin perlu struktur data Anda untuk dapat memuat seluruh zona super dari HDD ke memori. Tidak seperti array multi-dimensi ukuran tetap, pohon mudah memungkinkan ini tanpa terlalu banyak waktu dihabiskan untuk algoritma kombinatori.