The math package
The Layercake project comes with a rudimentary math package. It implements the vector math required for the project and flat vector lists. It does not aim to be a complete vector math library.
The package was written to prevent a dependency on a larger external library.
There is nothing special about its design and changing the code to make use of another vector math implementation should be easy.
For example, Layercake’s Vec3f
and libGDX’s Vector3
classes should be, for the most part, interchangeable.
Mutable vectors
The vector implementations are mutable. This means that the value of a vector can change during its lifetime. Furthermore, all operations reuse vector instances whenever possible.
The reason for this is that Java’s memory model relies on garbage collection. Under certain conditions creating many small short-lived objects can result in a lot of garbage and thus a lot of work for the collector. A mutable design allows to keep the number of such objects low.
In practice, the only thing you have to keep in mind is that whenever an operation returns a vector, it does not create a copy.
Instead, a self-reference is returned.
For example, the variable c
in the following snippet points to the same vector as the variable a
:
Vec3f a = new Vec3f(1f, 2f, 3f);
Vec3f b = new Vec3f(5f, 5f, 5f);
Vec3f c = a.add(b);
System.out.println(a); // (6.000, 7.000, 8.000)
System.out.println(b); // (5.000, 5.000, 5.000)
System.out.println(c); // (6.000, 7.000, 8.000)
You might wonder why return any reference at all? To allow for chaining of operations:
float distance = a.sub(b).len();
Flat lists
The math
package comes with its own specialized implementations of vector lists.
They do not add any notable functionality.
Their only purpose is to keep the memory footprint low.
Java of course comes with builtin list implementations.
The most commons being the ArrayList
which as its name suggests is backed by a simple array.
So why not just use that?
The problem with an ArrayList<Vec3f>
with let’s say 1000 entries is that it does not store the values of the 1000 vectors in a single array.
Instead, it maintains an array with references to 1000 separate Vec3f
instances.
That is a lot of overhead for storing 3000 float values.
By know you probably have guessed what Layercake’s Vec3fList
is doing under the hood.
Just as an ArrayList
it is backed by a single array.
But instead of storing references to Vec3f
instances, it stores their values.
A Vec3fList
with 1000 entries is basically a wrapper around a single float
array with 3000 items.
Iterating over an Vec3fList
requires only a single Vec3f
instance.
For example, given a list of vertices
, you can either pass it in as parameter:
Vec3f vertex = new Vec3f();
for (int i = 0; i < vertices.size(); i++) {
vertex = vertices.get(i, vertex);
// do something with the vertex
}
Or make use of an iterator which internally maintains a single Vec3f
instance:
for (Vec3f vertex: vertices) {
// do something with the vertex
}