Example #1
0
            public void TransformToPolar(ref Vector3f p, ref GeoPolar3d delta)
            {
                // Figure out angle in x-y plane.
                delta.Lat = Math.Atan2(p.X, p.Y);
                // Then the "height" angle.
                var xy = p.Y * p.Y + p.X * p.X;
                var dZ = p.Z - Camera.HeightOffset;

                delta.Lon    = Math.Atan2(dZ, Math.Sqrt(xy));
                delta.Height = Math.Sqrt(xy + dZ * dZ);
            }
Example #2
0
 // Project takes some 3D coordinates and transform them
 // in 2D coordinates using the transformation matrix
 // It also transform the same coordinates and the normal to the vertex
 // in the 3D world
 public VertexProj Project(ref Vertex vertex, ref GeoPolar3d polar)
 {
     return(new VertexProj
     {
         Coordinates = new Vector3fProj(
             GetXIndexFromLatRad(polar.Lat),
             GetYIndexFromLonRad(polar.Lon),
             (float)polar.Height),
         Normal = vertex.Normal,
         WorldCoordinates = vertex.Coordinates,
         TextureCoordinates = vertex.TextureCoordinates
     });
 }
Example #3
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;
                    }
                }
            }
        }