Let's think about models!

Some time ago, I decided to implement a custom block model format for Experiment801.
Compared to block models, entity models have another complication: they're not static, so you can't just return a list of coordinates and be done with it.
If I weren't a raving lunatic, I'd A more conventional way to do this would be to use Blender or such to create said model, then import it into the client with a library. However, I didn't find this approach to be worthwhile for a few reasons:
  • Using programs such as Blender not only has a steep learning curve, but requires a beefy computer to run it.
  • Even if I mastered the art of 3D modelling, I can't expect everyone to do so.
  • Even if I mastered the art of 3D modelling, creating new models would take lots of effort.
  • Given that this game is already blocky like Minecraft, I don't really need realistic models to satisfy my needs. Even something like this would do.
Here's my initial idea of what to do.
 (sorry for the poor quality; I don't have a scanner nearby and my phone won't turn on anymore, so I had to use my webcam)
This model is composed of a number of rectangular prisms. Each prism has an origin point \(O_i\) specified relative to the centre foot-level point \(O\), and two vectors \(\mathbf{a}_i\) and \(\mathbf{k}_i\). Rotating \(\mathbf{k}_i\) about \(\mathbf{a}_i\) by \(\theta_i\) radians gives \(\mathbf{k}'_i\).
We see that \(\mathbf{a}_i\), \(\mathbf{k}'_i\) and \(\mathbf{u}_i = c \cdot (\mathbf{a}_i \times \mathbf{k}'_i)\) can act as the axes of a cuboid-local coordinate system. In particular, \((x_c, y_c, z_c)\) is equivalent to \(O_i + x_c \cdot \mathbf{a}_i + y_c \cdot \mathbf{k}'_i + z_c \cdot \mathbf{u}_i\). (For convenience, it would be helpful not to supply \(c\) directly, but rather \(|\mathbf{u}_i|\).)
One problem is apparent when we can control only one angle. Suppose we have a head. If we want the head to turn, we can rotate it side to side. If we want it to nod, we can rotate it up and down. But we can't support both of these operations at the same time! Here, each cuboid has three angles to control rotation around \(\mathbf{a}_i\), \(\mathbf{k}'_i\) and \(\mathbf{u}_i\).
Another change I decided to make was for \(O_i\) to not necessarily be at one vertex of the cuboid. Instead, the vertices are at \((c_x^{\pm}, c_y^{\pm}, c_z^{\pm})\).
As you can see here, I have beautiful hands. More importantly, though, this shows that when the cuboid degenerates into a rectangle, we can optimise the model to contain only one quadrilateral. Having it degenerate into a line segment or point would be pointless, so I consider it an error.
In fact, we need not be confined to cuboids or rectangles at all. We can use a bunch of triangles and the basic idea should still work. We can represent the compiled model format using a number of components, each with their own coordinate systems, and for each component storing one or more triangles specified with component-local coordinates. Of course, allowing modellers to specify cuboids and rectangles in the source format would be convenient.
If you want to model limbs, for instance, then \(O_i\) will change for some \(i\). Changing \(O_i\) whenever a parent cuboid rotates would be a pain. It would also be nice to specify for each component \(i\) a parent \(j\) and \(j\)-local coordinates \((x_d, y_d, z_d)\) where \(O_i\) should lie.
Another refinement would be to, instead of using what are called Euler angles, represent orientations as quaternions. This avoids a problem called gimbal lock.

Still, one problem remains.
Suppose we want to model a pyramidal frustum whose faces "point out" at some \(\theta_1\). That is, each side face rectangle when \(\theta_1 = 0\) but a trapezoid when \(\theta_1 > 0\). The side edges of each side face, then, are parallel when \(\theta_1 = 0\) but not when \(\theta_1 > 0\). This shows that we can't rely only on rotations of components to do what we want without changing the component-local coordinates of the vertices themselves. Such figures are useful for modelling clothing and such, so this is not just a theoretical problem.
So far, we've defined a parallel projection linear transformation from \(\mathbb{R}^3\) to \(\mathbb{R}^3\). We need to come up with something more general to solve the problem above.

~~ to be continued in part 2 ~~

Comments

Popular Posts