Ejemplo n.º 1
0
        // The main method of the engine that re-compute each vertex projection
        // during each frame
        public static void RenderInto(RenderState state, params Mesh[] meshes)
        {
            Vector3f   buffv      = new Vector3f();
            GeoPolar3d polarA     = new GeoPolar3d();
            GeoPolar3d polarB     = new GeoPolar3d();
            GeoPolar3d polarC     = new GeoPolar3d();
            Vector3f   midAB      = new Vector3f();
            Vector3f   midAC      = new Vector3f();
            Vector3f   midBC      = new Vector3f();
            GeoPolar3d polarMidAB = new GeoPolar3d();
            GeoPolar3d polarMidAC = new GeoPolar3d();
            GeoPolar3d polarMidBC = new GeoPolar3d();

            foreach (Mesh mesh in meshes)
            {
                for (int faceIndex = 0; faceIndex < mesh.Faces.Length; faceIndex++)
                {
                    var face = mesh.Faces[faceIndex];

                    state.TransformToPolar(ref mesh.Vertices[face.A].Coordinates, ref polarA);
                    state.TransformToPolar(ref mesh.Vertices[face.B].Coordinates, ref polarB);
                    state.TransformToPolar(ref mesh.Vertices[face.C].Coordinates, ref polarC);

                    // TODO: Skip this triangle if it contains the point we are at?

                    // Also need to maintain the triangle topology that can be distrupted by
                    // discontinuities in arctan.

                    Vector3f.Avg(ref mesh.Vertices[face.A].Coordinates, ref mesh.Vertices[face.B].Coordinates, ref midAB);
                    Vector3f.Avg(ref mesh.Vertices[face.A].Coordinates, ref mesh.Vertices[face.C].Coordinates, ref midAC);
                    Vector3f.Avg(ref mesh.Vertices[face.B].Coordinates, ref mesh.Vertices[face.C].Coordinates, ref midBC);
                    state.TransformToPolar(ref midAB, ref polarMidAB);
                    state.TransformToPolar(ref midAC, ref polarMidAC);
                    state.TransformToPolar(ref midBC, ref polarMidBC);

                    bool abOK = CheckBetween(polarA.Lat, polarMidAB.Lat, polarB.Lat);
                    bool acOK = CheckBetween(polarA.Lat, polarMidAC.Lat, polarC.Lat);
                    bool bcOK = CheckBetween(polarB.Lat, polarMidBC.Lat, polarC.Lat);
                    if (!(abOK && acOK && bcOK))
                    {
                        if (abOK)
                        {
                            polarC.Lat += (polarC.Lat < polarA.Lat ? 1 : -1) * 2 * Math.PI;
                        }
                        if (acOK)
                        {
                            polarB.Lat += (polarB.Lat < polarA.Lat ? 1 : -1) * 2 * Math.PI;
                        }
                        if (bcOK)
                        {
                            polarA.Lat += (polarA.Lat < polarC.Lat ? 1 : -1) * 2 * Math.PI;
                        }
                    }

                    // Now check if any triangles need to be shifted by multiple of 2Pi to move into view
                    // First, shift neg
                    while (
                        polarA.Lat - 2 * Math.PI >= state.Camera.MinAngleRad ||
                        polarB.Lat - 2 * Math.PI >= state.Camera.MinAngleRad ||
                        polarC.Lat - 2 * Math.PI >= state.Camera.MinAngleRad)
                    {
                        polarC.Lat -= 2 * Math.PI;
                        polarB.Lat -= 2 * Math.PI;
                        polarA.Lat -= 2 * Math.PI;
                    }

                    while (
                        polarA.Lat <= state.Camera.MaxAngleRad ||
                        polarB.Lat <= state.Camera.MaxAngleRad ||
                        polarC.Lat <= state.Camera.MaxAngleRad)
                    {
                        var pixelA = state.Project(ref mesh.Vertices[face.A], ref polarA);
                        var pixelB = state.Project(ref mesh.Vertices[face.B], ref polarB);
                        var pixelC = state.Project(ref mesh.Vertices[face.C], ref polarC);

                        DrawTriangle(state, ref pixelA, ref pixelB, ref pixelC, mesh.Texture, ref buffv);

                        polarC.Lat += 2 * Math.PI;
                        polarB.Lat += 2 * Math.PI;
                        polarA.Lat += 2 * Math.PI;
                    }
                }
            }
        }