In which you abstract away the complexities of managing a 3D model.
Triangular meshes are made of several arrays upon which you need to execute various operations. They warrant an abstraction that draws together the otherwise scattered state and behaviors into a single entity. You need a Trimesh
class.
A possible interface for the Trimesh
class is described below. It assumes that your mesh uses indexed geometry.
The Trimesh
class binds together at least these three arrays.
Vector3
or Vector4
instead of as a flat array or an array of arrays. By storing them as vectors, you can perform vector operations on the positions.Vector3
or Vector4
.[
[0, 1, 3], // triangle 0
[0, 3, 2], // triangle 1
// ...
]
There are some other pieces of state you might consider storing. Perhaps you need color information like albedo or shininess. These could be uniform across the mesh or defined on a per-vertex basis. Perhaps you want to track the number of vertices and faces in properties instead of computing them from the arrays.
At this point in the development of your graphics library, your class needs only a few behaviors.
The constructor receives the positions, normals, and indices and hangs on to them for later use.
The GPU cares little for your abstraction. It wants flat arrays of raw numbers to put in the VBOs. Each of your arrays needs a getter that returns a flattened representation of the array. Consider using JavaScript's flatMap
and flat
methods to do most of the labor.
The OBJ parser that you write needs a home. If JavaScript supported overloading, you could add a second constructor that took in the OBJ string. But it doesn't. That's okay, because you can write a static method named fromObj
that receives the text and returns a Trimesh
instance. Such a method is sometimes is called a named constructor.