Just another status update.
I've changed the method used to calculate which plane to clip a polygon edge against. Instead of turning the fractions 16-bit fixed point values and then comparing them, I am now directly comparing the fractions. Surprisingly, this turns out to be not just more accurate, but actually faster in the most common cases. The only time it will be (marginally) slower is when you are getting up-close and personal with the objects, so that the camera is basically penetrating the object.
While working on my documentation generator, I also hit upon a cool idea. I've been worrying about how to actually create objects. A model editor/importer is not really ideal. Due to the fact that we need to squeeze every cycle we can out of this, there is no way a computer is going to be able to generate the best solution for any particular model. That's why we code in assembler when we want speed, and the same is true here. So I've decided to try a simple modelling language.
Internally, the engine already uses a tokenized language for defining models, so it only makes sense to make a compiler for it.
I am designing the language while simultaneously writing the compiler, so things are a bit all over the place, but if gives me a good way of quickly seeing what is going to work and what isn't.
This is an example of the way I am going with it. This is a short program to create a cube. The exclamation mark is the
mirror operator. When used in a
transform, it will mirror the vertex across the specified axis'. When used after a
vertex identifier, it is used to select a particular mirrored vertex. This way, the example can use
v1 to refer to all 8 vertices which were generated in the
transform statement.
The mirror can also appear after a
face, which will mirror all vertices in the face - hence we only need to define 3 sides of the cube.
Code: Select all
begin
transform[0..7]!xyz begin // this will create 8 vertices at indices 0 - 7
vertex v1(64, 64, 64)
end
normals(clockwise)
face f1(v1, v1!y, v1!yz, v1!z) // x-plane ("right" face)
face f2(v1, v1!z, v1!zx, v1!x) // y-plane ("top" face)
face f3(v1, v1!x, v1!xy, v1!y) // z-plane ("far" face)
// Note: It is also possible to declare a mirrored face: face f4(f1!x).
/* with each face pair, if the first is front-facing, the
second can't be, so we won't even bother testing it. */
if not backfacing(f1) draw(f1, alPattern08)
else if not backfacing(f1!x) draw(f1!x, alPattern28)
if not backfacing(f2) draw(f2, alPattern48)
else if not backfacing(f2!y) draw(f2!y, alPattern48)
if not backfacing(f3) draw(f3, alPattern68)
else if not backfacing(f3!z) draw(f3!z, alPattern88)
end
It's a little bit unsightly, but is makes the job easier while still giving you complete control over how the model is drawn. BSP trees are sure gonna get ugly, though!
"I don't know why a refrigerator is now involved, but put that aside for now". - Jim e on unitedti.org
avatar courtesy of driesguldolf.