public override void draw(Graphics graphics, Camera camera, WorldLights worldLights)
        {
            if (Settings.debug)
            {
                Vector4D centerVector = Vector4D.Zero();

                centerVector.LeftMultiply(StaticMatrices.TranslationMatrix(position));
                centerVector.LeftMultiply(camera.View);

                distanceToCamera = (float)centerVector.getMagnitude();

                centerVector.LeftMultiply(camera.Frustum);
                centerVector.divideByW();
                centerVector.moveOriginToCenterScreen();

                Matrix4 mat = camera.Frustum * camera.View * StaticMatrices.TranslationMatrix(position) * StaticMatrices.ScaleMatrix(new Vector3D(intensity * .0005, intensity * .0005, intensity * .0005));

                Vector4D[] vertices = GameShapes.Tetrahedron();

                for (int i = 0; i < 4; i++)
                {
                    vertices[i].LeftMultiply(mat);
                    vertices[i].divideByW();
                    vertices[i].moveOriginToCenterScreen();
                }

                PointF[] pointsAll = vertices.Select(x => x.getPointXY()).ToArray();
                graphics.DrawLine(new Pen(Color.FromArgb((int)red, (int)green, (int)blue), 2), pointsAll[0], pointsAll[1]);
                graphics.DrawLine(new Pen(Color.FromArgb((int)red, (int)green, (int)blue), 2), pointsAll[0], pointsAll[2]);
                graphics.DrawLine(new Pen(Color.FromArgb((int)red, (int)green, (int)blue), 2), pointsAll[0], pointsAll[3]);
                graphics.DrawLine(new Pen(Color.FromArgb((int)red, (int)green, (int)blue), 2), pointsAll[1], pointsAll[2]);
                graphics.DrawLine(new Pen(Color.FromArgb((int)red, (int)green, (int)blue), 2), pointsAll[1], pointsAll[3]);
                graphics.DrawLine(new Pen(Color.FromArgb((int)red, (int)green, (int)blue), 2), pointsAll[2], pointsAll[3]);

                graphics.DrawString((intensity * .001).ToString() + "K", new Font("Arial", 12), new SolidBrush(Color.White), centerVector.getPointXY());
            }
        }
        /// <summary>
        /// preDraw is called by the graphics engine before object Z-sorting is done.  It get's everything ready for drawing.
        /// </summary>
        /// <param name="graphics">GDI graphics to use</param>
        /// <param name="camera">Camera to use</param>
        /// <param name="worldLights">Set of lights to use</param>
        /// <param name="rotation">Rotation of mesh</param>
        /// <param name="scale">Scale of mesh</param>
        /// <param name="position">Position of mesh</param>
        public void preDraw(Graphics graphics, Camera camera, WorldLights worldLights, Vector3D rotation, Vector3D scale, Vector3D position)
        {
            #region Generate transform matrices

            Matrix4 ViewProjectionMatrix = camera.Frustum * camera.View;
            Matrix4 WorldTransformMatrix = StaticMatrices.TranslationMatrix(position)
                                           * StaticMatrices.RotationMatrixZYX(rotation) * StaticMatrices.ScaleMatrix(scale);

            #endregion

            #region Start with vertices in object (local) space

            for (int i = 0; i < dynamicVertices.Length; i++)
            {
                dynamicVertices[i].setVector(staticVertices[i]);
            }

            #endregion

            #region Transform vertices to world space (combinining the scale, rotation, and position matrices)

            foreach (Vector4D vertex in dynamicVertices)
            {
                vertex.LeftMultiply(WorldTransformMatrix);
            }

            #endregion

            #region Calculate lighting from world lights

            /// Have yet to test whether parallel is actually faster, so leaving original code:

            //foreach (FaceGDI face in faces)
            //    face.calculateWorldLighting(dynamicVertices, worldLights, position);

            Parallel.For(0, faces.Length, i =>
            {
                faces[i].calculateWorldLighting(dynamicVertices, worldLights, position);
            });

            #endregion

            #region Transform vertices to view space (combining camera view and frustum transforms)

            foreach (Vector4D vertex in dynamicVertices)
            {
                /// Transforms vertex into camera space and applies frustum matrix
                vertex.LeftMultiply(ViewProjectionMatrix);

                /// Creates the illusion of perspective, shringing the x, y, and z values based on the original z value, as stored in w.
                vertex.divideByW();

                /// Required to compensate for GDI's upper-left-hand corner origin - could be done elsewhere - maybe doesn't need to be done for each vertex each frame - look into it.
                vertex.moveOriginToCenterScreen();
            }

            #endregion

            // Faces are now ready to draw.  This last bit is for the Z-Sorting and distance read out and stuff.

            #region Calculate render position and distance from camera

            renderPositionGDI.zero();
            renderPositionGDI.LeftMultiply(WorldTransformMatrix);
            renderPositionGDI.LeftMultiply(camera.View);
            distanceFromCamera = (float)renderPositionGDI.getMagnitude();

            if (Settings.debug)
            {
                renderPositionGDI.LeftMultiply(camera.Frustum);
                renderPositionGDI.divideByW();
                renderPositionGDI.moveOriginToCenterScreen();
            }

            #endregion
        }