I've broken model
design down into a few steps that make it easier for me to build a
model. This is by no means the only way; it's just the way I do
things. I've learned the hard way that these steps are
important. You'll need the following:
- Graph paper
- Regular pencil
- Red pencil
- Ruler/Straight edge (Optional, though helpful)
- Eraser (for fixing mistakes)
- Computer (duh!)
These are the steps I follow:
- Draw the outline of the model using only dots
- Connect the dots using the pencil and straight edge
- Fill in one or more inner outlines, similiar to a topographical
map for different height levels
- Draw lines between the various outlines, forming triangles or
quads (quad strips, triangle fans and triangle strips are problematic)
- Begin laying down the vertices in code; I suggest laying out the
model in sections corresponding to the segments you want to name
- As you put each polygon in code, fill it in with the red pencil,
so you know what you've done already
- Apply transformations via VertexUtil to fix mistakes and/or
duplicate portions of the model for parts that look the same
- Name segments. You can safely ignore this if you wish to
only use a texture, but I suggest filling in this data anyway; future
users of your model will appreciate you for it.
- Setup Colorations. You can safely ignore this if you wish
to only use a texture.
- Perfrom the aura test occasionally (see below, under notes).
- Decide if you want the model to have a faceted apperance (don't
call Model.calcNormals() on it) or a smooth appearance (call
Model.calcNormals() on it)
- Decide if you want your model to have a texture. If so,
you'll have to provide texture coordinates. With the default
settings, colorations and textures are combined. The texture
provides surface features for the Model and the the coloration acts
like paint. If you change the settings various different things
are possible. The default settings are (in my opinion) the most
useful.
Suggestions/Notes:
Build your models using Triangles objects; even
though the vertex count is higher than for a Quads, Triangles seems to
be the most accelerated OpenGL primitive; I get about three time the
performance when using textured models. Even if your model has
already been built, you can use the
VertexUtil.quadsToTriangles(float[][]) and
VertexUtil.quadsToTriangles(float[][], float[][]) methods to convert
from quads.
Texturing a model always darkens it some. You
may wish to plan accordingly when texturing and coloring your model.
Be aware of where the light source is. Make
sure highlights are where they're supposed to be.
Use a standard green Coloration object while
building the model; the human eye is most sensitive to green, so you'll
be able to see your model's features best if they're highlighted in
green.
Test your model every few polygons you add to
it.
Build polygons counter-clockwise when facing them
from the outside of the model; this is important for building proper
surface normals.
Build your models with twosidedness turned
off. This will allow you to properly see if the normals for your
model are facing the right direction (based on light source highlights).
If you want to test to see if the model has been
built with
properly facing normals, use the AuraTest.java file from the models
directory.
Change the source file it loads to your model and it will generate and
display an alpha-blended aura along with your model. If the aura
intersects your model or is not visible, then the normals aren't facing
correctly and you may have to invert one or more of the MeshElements.
If you accidentally build your model inside out, you
can fix it with a simple scale transformation via the VertexUtil class.
Use variables for height values, so you can modify
the height of your model by simply changing one value. In fact,
using variables wherever possible is helpful, but don't go crazy.
Declaring more than about 256 variables in the same method will cause
compilation to fail (I've done this before when building models).
Build your model from a single MeshElement if
possible. This should make rendering most efficient.
Declare the vertices in the array declaration
itself, like models\AlienBroadWing.java does. Use white space to
seperate polygons.
Use VertexUtil.reduce(float[][]) to reduce the
memory load of your MeshElement objects if you're concerned about
saving the most memory; this is an expensive operation, however.
Don't be afraid to use transformations to give your
model a unique look, say by sweeping wings back or by pushing them
down. For an example of this, check out
models\AlienBroadWing.java.
The warp method in that file is how I did
that. I started by building it as a flat model, similiar to
models\Fighter.java. After it was done, it just didn't look right
and I wanted to keep it, so I tried putting a bit of a z-axis curve
into it's body along the x-axis. It turned out nice and I didn't
have to throw away my work. The funny part is, I was trying to
build something that looked like a certain bat-themed hero's jet.
Sometimes things don't turn out the way we plan.
Use Trigonometry when it's helpful; it's handy for
approximating curved surfaces (and use vertex normals to make the
curves actually
look curved). The equations for circles (and spheres) are
especially handy. For some novel approaches to generating spheres
and cylinders, see the source code for the VertexUtil class. I
build cylinders and spheres from planes without ever touching GLU or
GLUT. The Sphere class, however still uses GLU.
Hosting for this project generously
provided by: