Skip to content

Commit 83be1b2

Browse files
committed
change(/wiki/introduction): A lil writing
1 parent 685245a commit 83be1b2

File tree

2 files changed

+82
-16
lines changed

2 files changed

+82
-16
lines changed
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
+++
2+
title = "World Generation"
3+
description = "How to generate a world?"
4+
path = "/wiki/introduction/generation"
5+
[taxonomies]
6+
categories = ["introduction"]
7+
[extra]
8+
chapters = true
9+
chapter_prev = {text = "Basic Storage", link = "/wiki/introduction/storage"}
10+
chapter_next = false
11+
+++
12+
13+
{{ stub_notice() }}
14+
15+
{% todo_notice() %} Filling a volume via [Procedural Generation](/wiki/procgen). {% end %}

content/wiki/introduction/storage.md

+67-16
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ categories = ["introduction"]
77
[extra]
88
chapters = true
99
chapter_prev = {text = "Choosing A Language", link = "/wiki/introduction/language"}
10-
chapter_next = false
10+
chapter_next = {text = "World Generation", link = "/wiki/introduction/generation"}
1111
+++
1212

1313
As noted in the [theory section](./#what-is-a-voxel-in-theory), a voxel can be ***anything***; the only limit is your imagination... and the amount of memory and disk-space you have! Speaking of which, how *are* voxels represented in practice?
@@ -21,13 +21,13 @@ Also, for the purpose of clarity, we will *not* be using pseudocode.
2121

2222
{% warn_notice() %} **The following sections are a work-in-progress.** {% end %}
2323

24-
### Basic Storage
24+
### Storing Voxels
2525

26-
For a start, let's assume that our voxels store... nothing.
26+
For a start, let's assume that our voxels store a single byte each...
2727

2828
```rust
2929
/// This represents a single voxel sample/instance.
30-
type Voxel = (); // using the empty 'unit type' for now.
30+
type Voxel = u8; // A single byte.
3131
```
3232

3333
Since a voxel *outside* a grid is, by [definition](./#what-is-a-voxel-in-theory), *not* a voxel, we will have to put it into a grid of voxels...
@@ -57,9 +57,9 @@ pub struct VoxelGrid {
5757
Now accessing it is pretty simple:
5858

5959
```rust
60-
// Create the volume, filled with 'nothing'...
60+
// Create the volume, filled with zeroes...
6161
let mut volume = VoxelGrid {
62-
values: [[[Voxel; GRID_SIZE]; GRID_SIZE]; GRID_SIZE]
62+
values: [[[ 0 ; GRID_SIZE]; GRID_SIZE]; GRID_SIZE]
6363
};
6464

6565
// Have some coordinates...
@@ -107,19 +107,20 @@ Of course, we will now have to do the bound-checks by ourselves, but as long as
107107
```rust
108108
impl VoxelGrid {
109109
pub fn get(&self, x: u32, y: u32, z: u32) -> Option<Voxel> {
110-
if x < 0 || x >= GRID_SIZE {return None}
111-
if y < 0 || y >= GRID_SIZE {return None}
112-
if z < 0 || z >= GRID_SIZE {return None}
110+
if x < 0 || x >= GRID_SIZE {return None} // 0 ⋯ GRID_SIZE-1
111+
if y < 0 || y >= GRID_SIZE {return None} // 0 ⋯ GRID_SIZE-1
112+
if z < 0 || z >= GRID_SIZE {return None} // 0 ⋯ GRID_SIZE-1
113113
self.values[ /* ??? */] // uuuuh...?
114114
}
115115
}
116116
```
117117

118118
I suppose a function that turns `x,y,z` into an index is also needed: an **index function**!
119-
Since it depends on the bounds-check to work correctly, let's move that there too.
119+
Since it depends on the bounds-check to work correctly, let's move it there...
120120

121121
```rust
122122
impl VoxelGrid {
123+
/// A function to turn 3d coordinates into an array index.
123124
pub fn index(&self, x: u32, y: u32, z: u32) -> Option<usize> {
124125
if x < 0 || x >= GRID_SIZE {return None} // 0 ⋯ GRID_SIZE-1
125126
if y < 0 || y >= GRID_SIZE {return None} // 0 ⋯ GRID_SIZE-1
@@ -138,14 +139,16 @@ impl VoxelGrid {
138139
```
139140

140141
{% info_notice() %}
141-
The line marked with `SCHEME` declares a *spatial indexing scheme* for us, which defines the *order* and *importance* of the `x,y,z` axes, but also how to turn coordinates into a usable index. Neat!
142+
The line marked with `SCHEME` declares a (spatial) **indexing scheme** for us, which defines the *order* and *importance* of the `x,y,z` axes, but also how to turn coordinates into a usable index. Neat!
142143
{% end %}
143144

144145
And so our example becomes this:
145146

146147
```rust
147-
// Create the volume... somehow.
148-
let mut volume = VoxelGrid { /* ??? */ };
148+
// Create the volume...
149+
let mut volume = VoxelGrid {
150+
values: [ 0 ; GRID_SIZE * GRID_SIZE * GRID_SIZE]
151+
};
149152

150153
// Have some coordinates...
151154
let (x,y,z) = (/**/, /**/, /**/);
@@ -162,11 +165,59 @@ if the coordinates are ever out of bounds, crash our program; but at least you'l
162165

163166
But how to we fill it? And just what type should `Voxel` be?!
164167

168+
We will answer the second question first... after fixing a glaring issue.
169+
170+
### The Heap
171+
172+
If you tried increasing the `GRID_SIZE` a little too much,
173+
you *might* run into a problem: a stack overflow!
174+
175+
Right now our `VoxelGrid` is defined like this:
176+
177+
```rust
178+
pub struct VoxelGrid {
179+
values: [Voxel; GRID_SIZE * GRID_SIZE * GRID_SIZE];
180+
}
181+
```
182+
183+
...and 'created' like this...
184+
185+
```rust
186+
// Create the volume...
187+
let mut volume = VoxelGrid {
188+
values: [ 0 ; GRID_SIZE * GRID_SIZE * GRID_SIZE]
189+
};
190+
```
191+
192+
That line right there? It allocates our `VoxelGrid` on the stack! Which is bad,
193+
as stack memory is quite limited; putting huge things on it can (obviously)
194+
cause a stack-overflow, but will also obliterate our CPU's cache... :(
195+
196+
Thankfully avoiding this is an easy fix: Allocate it on the heap!
197+
198+
First turn the array into a vector (which is a thin abstraction over `malloc`)...
199+
200+
```rust
201+
pub struct VoxelGrid {
202+
values: Vec<Voxel>;
203+
}
204+
```
205+
206+
...create it right on the heap, like this...
207+
208+
```rust
209+
// Create the volume...
210+
let mut volume = VoxelGrid {
211+
values: vec![ 0 ; GRID_SIZE * GRID_SIZE * GRID_SIZE]
212+
};
213+
```
214+
215+
...and we're done! Now on to defining our voxel type(s)...
216+
165217
### Types of Voxel
166218

167219
{% todo_notice() %} Types of voxels. {% end %}
168220

169-
### Basic Generation
170-
171-
{% todo_notice() %} Filling a volume via [Procedural Generation](/wiki/procgen). {% end %}
221+
## Next
172222

223+
Next up: Basic world generation!

0 commit comments

Comments
 (0)