Project: 3d Engine

This is a page from a journal that I used to keep for programming projects:

Date began: 11/28/1995
Date complete: ?

Goals: A 3d engine that is able to immerse the viewer in a pseudo-realistic world.  Supporting objects constructed from trigons in the .vo (vector object) format.  Able to handle, flat, gouraud, and phong illumination models, with the possible addition of texture mapping glass, glenzing, and shadows.  



For Monk := 0 to NumberOfPolygons - 1 do
Begin

{Get the x,y,z coordinates of the current polygon}
  Temp1 := LocalCoords^[Polygons^[Monk].Ref1];
  Temp2 := LocalCoords^[Polygons^[Monk].Ref2];
  Temp3 := LocalCoords^[Polygons^[Monk].Ref3];

{Make the coordinates into two vectors with the same origin}
  MakeVector (Temp2, Temp3, U);
  MakeVector (Temp2, Temp1, V);

{Find the unit vector for each}
  TempMagnitude := Sqrt(U.x*U.x + U.y*U.y + U.z*U.z);

  U1.x := U.x / TempMagnitude;
  U1.y := U.y / TempMagnitude;
  U1.z := U.z / TempMagnitude;

  TempMagnitude := Sqrt(V.x*V.x + V.y*V.y + V.z*V.z);

  V1.x := V.x / TempMagnitude;
  V1.y := V.y / TempMagnitude;
  V1.z := V.z / TempMagnitude;

{Calculate the cross product to get the normal}
  Final.x := (u1.y * v1.z - u1.z * v1.y);
  Final.y := -(u1.x * v1.z - u1.z * v1.x);
  Final.z := (u1.x * v1.y - u1.y * v1.x);

{Find the unit vector of the normal}
  TempMagnitude := Sqrt(Final.x*Final.x + Final.y*Final.y +   Final.z*Final.z);

  Final.x := Final.x / TempMagnitude; test.x := Round(final.x  * 256);
  Final.y := Final.y / TempMagnitude; test.y := Round(final.y  * 256);
  Final.z := Final.z / TempMagnitude; test.z := Round(final.z * 256);

{Save that baby for later}
  Normals^[Monk] := Test;
End;




Well, I never managed to finish the entire 3d engine, but I did get a good start.  This particular project eventually led to an quake .mdl viewer, but I'll talk about that later.  The entire engine ended up being written in Turbo Pascal, with the occasional function written in assembler for speed.  It did, somewhat surprisingly, actually consume the .vo format, which was never very popular.  However, when I used to use IRC all of the time, one of the people that I chatted with, "phred" (Alex Chaflin) had recently written an example reader for the .vo format (a format that he defined by the way).  Anyhow, the .vo format was infinitely easier to parse then .dxf, or .3ds files, so I stuck with it. 

You might notice in the code to the right that the loop variable is 'Monk'.  That might not seem like the most descriptive name that I could have used, and it's not.  But during Programming II in high school, our teacher wrote a test where she misspelled convenient as convent; for the next two years I couldn't write a program without slipping a Monk variable in =-)

If you're curious about what the code to the right is doing, it's pretty simple.  One of the best optimizations that can be done when displaying solid modeled objects, is to remove faces that are 'facing' away from the camera.  In order to make that determination, you need to calculate the normal (the vector that is perpendicular) to each triangle in the object.