Ejemplo n.º 1
0
            private void Update()
            {
                double altitude;

                // Altitude is ASL
                altitude = (World.Settings.VerticalExaggeration * this.Alt) + DrawArgs.Camera.WorldRadius;

                this.Position = MathEngine.SphericalToCartesian(this.Lat, this.Lon, altitude);

                this.m_positionD = MathEngine.SphericalToCartesianD(
                    Angle.FromDegrees(this.Lat),
                    Angle.FromDegrees(this.Lon),
                    altitude);
            }
Ejemplo n.º 2
0
        public static Point3d GetGeocentricPosition(System.DateTime utcDateTime)
        {
            if (World.Settings.SunSynchedWithTime)
            {
                // Sun synched with time and date
                double JD = getJulianDay(utcDateTime);
                double T  = (JD - 2451545.0) / 36525; // number of Julian centuries since Jan 1, 2000, 12 UT

                double k  = Math.PI / 180.0;
                double M  = 357.52910 + 35999.05030 * T - 0.0001559 * T * T - 0.00000048 * T * T * T; // mean anomaly, degree
                double L0 = 280.46645 + 36000.76983 * T + 0.0003032 * T * T;                          // mean longitude, degree
                double DL = (1.914600 - 0.004817 * T - 0.000014 * T * T) * Math.Sin(k * M) + (0.019993 - 0.000101 * T) * Math.Sin(k * 2 * M) + 0.000290 * Math.Sin(k * 3 * M);
                double L  = L0 + DL;                                                                  // true longitude, degree
                L = L % 360;
                //		obliquity eps of ecliptic:
                double eps = 23.0 + 26.0 / 60.0 + 21.448 / 3600.0 - (46.8150 * T + 0.00059 * T * T - 0.001813 * T * T * T) / 3600;

                double X = Math.Cos(k * L);
                double Y = Math.Cos(k * eps) * Math.Sin(k * L);
                double Z = Math.Sin(k * eps) * Math.Sin(k * L);

                double R = Math.Sqrt(1.0 - Z * Z);

                double dec = (180 / Math.PI) * Math.Atan(Z / R);                                                                  // in degrees
                double RA  = (24 / Math.PI) * Math.Atan(Y / (X + R));                                                             // in hours

                double theta0 = 280.46061837 + 360.98564736629 * (JD - 2451545.0) + 0.000387933 * T * T - T * T * T / 38710000.0; // Greenwich Sidereal Time

                theta0 = theta0 % 360;
                RA    *= 15; // convert from hours to degrees
                double tau = theta0 - RA;

                Point3d pos = MathEngine.SphericalToCartesianD(
                    Angle.FromDegrees(-dec),
                    Angle.FromDegrees(-(tau - 180)),
                    1);

                return(pos);
            }
            else
            {
                // Fixed sun heading and elevation
                double  worldRadius = 6378137;  // Earth meter
                Vector3 position    = MathEngine.SphericalToCartesian(World.Settings.CameraLatitude, World.Settings.CameraLongitude, worldRadius);
                return(GetGeocentricPosition(position, Angle.FromRadians(World.Settings.SunHeading), Angle.FromRadians(World.Settings.SunElevation), World.Settings.SunDistance));
            }
        }
Ejemplo n.º 3
0
        public virtual void ComputeViewMatrix()
        {
            // Compute camera elevation
            if (World.Settings.ElevateCameraLookatPoint)
            {
                int minStep = 10;
                this.targetCameraElevation = this.TerrainElevation * World.Settings.VerticalExaggeration;
                float stepToTarget = this.targetCameraElevation - this.curCameraElevation;
                if (Math.Abs(stepToTarget) > minStep)
                {
                    float step = 0.05f * stepToTarget;
                    if (Math.Abs(step) < minStep)
                    {
                        step = step > 0 ? minStep : -minStep;
                    }
                    this.curCameraElevation = this.curCameraElevation + step;
                }
                else
                {
                    this.curCameraElevation = this.targetCameraElevation;
                }
            }
            else
            {
                this.curCameraElevation = 0;
            }

            // Absolute matrices
            this.ComputeAbsoluteMatrices();

            // needs to be double precsion
            double radius    = this.WorldRadius + this.curCameraElevation;
            double radCosLat = radius * Math.Cos(this._latitude.Radians);

            LookFrom = new Point3d(radCosLat * Math.Cos(this._longitude.Radians),
                                   radCosLat * Math.Sin(this._longitude.Radians),
                                   radius * Math.Sin(this._latitude.Radians));

            // this constitutes a local tri-frame hovering above the sphere
            Point3d zAxis = LookFrom.normalize(); // on sphere the normal vector and position vector are the same
            Point3d xAxis = Point3d.cross(cameraUpVector, zAxis).normalize();
            Point3d yAxis = Point3d.cross(zAxis, xAxis);

            this.ReferenceCenter = MathEngine.SphericalToCartesianD(
                Angle.FromRadians(Convert.ToSingle(this._latitude.Radians)),
                Angle.FromRadians(Convert.ToSingle(this._longitude.Radians)), this.WorldRadius);

            // Important step !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // In order to use single precsion rendering, we need to define a local frame (i.e. center of center tile, etc.)
            // Vector3d LocalCenter should be defined & initialized in the CameraBase class
            // Each time the camera moves, a new local center could be defined
            // The local center also has to be subtracted from all the terrain vertices!!!!
            relCameraPos = LookFrom - this.ReferenceCenter;

            // Important step: construct the single precision m_ViewMatrix by hand

            // We can build the m_ViewMatrix by hand
            this.m_ViewMatrix.M11 = (float)xAxis.X;
            this.m_ViewMatrix.M21 = (float)xAxis.Y;
            this.m_ViewMatrix.M31 = (float)xAxis.Z;

            this.m_ViewMatrix.M12 = (float)yAxis.X;
            this.m_ViewMatrix.M22 = (float)yAxis.Y;
            this.m_ViewMatrix.M32 = (float)yAxis.Z;

            this.m_ViewMatrix.M13 = (float)zAxis.X;
            this.m_ViewMatrix.M23 = (float)zAxis.Y;
            this.m_ViewMatrix.M33 = (float)zAxis.Z;

            this.m_ViewMatrix.M41 = -(float)(xAxis.X * relCameraPos.X + xAxis.Y * relCameraPos.Y + xAxis.Z * relCameraPos.Z);
            this.m_ViewMatrix.M42 = -(float)(yAxis.X * relCameraPos.X + yAxis.Y * relCameraPos.Y + yAxis.Z * relCameraPos.Z);
            this.m_ViewMatrix.M43 = -(float)(zAxis.X * relCameraPos.X + zAxis.Y * relCameraPos.Y + zAxis.Z * relCameraPos.Z);

            this.m_ViewMatrix.M14 = (float)0.0;
            this.m_ViewMatrix.M24 = (float)0.0;
            this.m_ViewMatrix.M34 = (float)0.0;
            this.m_ViewMatrix.M44 = (float)1.0;

            double cameraDisplacement = this._distance + this._headZoom;

            //if(cameraDisplacement < targetCameraElevation + minimumAltitude)
            //	cameraDisplacement = targetCameraElevation + minimumAltitude;

            this.m_ViewMatrix *= Matrix.RotationYawPitchRoll(
                (float)-(this._swivel.Radians + this._headSwivel.Radians),
                (float)-(this._tilt.Radians + this._headTilt.Radians),
                (float)this._heading.Radians);
            //m_ViewMatrix *= Matrix.Translation(0, 0, (float)(-cameraDisplacement + curCameraElevation));
            this.m_ViewMatrix *= Matrix.Translation(0, 0, (float)(-cameraDisplacement));
            this.m_ViewMatrix *= Matrix.RotationZ((float)this._bank.Radians);

            // Extract camera position
            Matrix cam = Matrix.Invert(this.m_absoluteViewMatrix);

            this._position = new Vector3(cam.M41, cam.M42, cam.M43);
        }
Ejemplo n.º 4
0
        private void finishTesselation(Point3d[] tesselatorList)
        {
            int alpha        = (int)(((double)m_polygonColor.A / 255 * (double)this.Opacity / 255) * 255);
            int polygonColor = System.Drawing.Color.FromArgb(alpha, m_polygonColor.R, m_polygonColor.G, m_polygonColor.B).ToArgb();

            CustomVertex.PositionNormalColored[] vertices = new CustomVertex.PositionNormalColored[tesselatorList.Length];

            // precalculate feature center (at zero elev)
            Point3d center = new Point3d(0, 0, 0);

            for (int i = 0; i < m_outerRing.Points.Length; i++)
            {
                center += MathEngine.SphericalToCartesianD(
                    Angle.FromDegrees(m_outerRing.Points[i].Y),
                    Angle.FromDegrees(m_outerRing.Points[i].X),
                    World.EquatorialRadius
                    );
            }
            center = center * (1.0 / m_outerRing.Points.Length);
            // round off to nearest 10^5.

            center.X = ((int)(center.X / 10000.0)) * 10000.0;
            center.Y = ((int)(center.Y / 10000.0)) * 10000.0;
            center.Z = ((int)(center.Z / 10000.0)) * 10000.0;

            m_localOrigin = center.Vector3;

            for (int i = 0; i < vertices.Length; i++)
            {
                Point3d sphericalPoint = tesselatorList[i];
                //System.Console.WriteLine("Point" + sphericalPoint.X+" "+sphericalPoint.Y+" "+sphericalPoint.Z);

                double terrainHeight = 0;
                if (m_altitudeMode == AltitudeMode.RelativeToGround)
                {
                    if (World.TerrainAccessor != null)
                    {
                        terrainHeight = World.TerrainAccessor.GetElevationAt(
                            sphericalPoint.Y,
                            sphericalPoint.X,
                            (100.0 / DrawArgs.Camera.ViewRange.Degrees)
                            );
                    }
                }

                Point3d xyzPoint = MathEngine.SphericalToCartesianD(
                    Angle.FromDegrees(sphericalPoint.Y),
                    Angle.FromDegrees(sphericalPoint.X),
                    World.EquatorialRadius
                    + m_verticalExaggeration *
                    (m_geographicBoundingBox.MaximumAltitude
                     + m_distanceAboveSurface + terrainHeight));

                //Vector3 xyzVector = (xyzPoint + center).Vector3;

                vertices[i].Color = polygonColor;
                vertices[i].X     = (float)(xyzPoint.X - center.X);
                vertices[i].Y     = (float)(xyzPoint.Y - center.Y);
                vertices[i].Z     = (float)(xyzPoint.Z - center.Z);
                vertices[i].Nx    = 0;
                vertices[i].Ny    = 0;
                vertices[i].Nz    = 0;
            }

            primList.Add(vertices);

            ComputeNormals((PrimitiveType)primTypes[primList.Count - 1], vertices);
        }
Ejemplo n.º 5
0
        private void UpdateTexturedVertices()
        {
            if (m_altitudeMode == AltitudeMode.ClampedToGround)
            {
                if (m_lineString != null)
                {
                    m_lineString.Remove = true;
                    m_lineString        = null;
                }

                m_lineString                  = new LineString();
                m_lineString.Coordinates      = Points;
                m_lineString.Color            = finalLineColor;
                m_lineString.LineWidth        = LineWidth;
                m_lineString.ParentRenderable = this;
                this.World.ProjectedVectorRenderer.Add(m_lineString);

                if (m_wallVertices != null)
                {
                    m_wallVertices = null;
                }

                if (m_colorWallVertices != null)
                {
                    m_colorWallVertices = null;
                }

                return;
            }

            // wall replicates vertices to account for different normal vectors.
            // TODO: would be nice to automatically figure out when NOT to separate
            // triangles (smooth shading) vs. having separate vertices (and thus normals)
            // ('hard' edges). GE doesn't do that, by the way.
            // -stepman
            if (m_extrude || m_altitudeMode != AltitudeMode.ClampedToGround)
            {
                m_wallVertices = new CustomVertex.PositionNormalTextured[m_points.Count * 4 - 2];

                m_colorWallVertices = new CustomVertex.PositionColored[m_points.Count * 4 - 2];
            }

            float textureCoordIncrement = 1.0f / (float)(m_points.Count - 1);

            m_verticalExaggeration = World.Settings.VerticalExaggeration;
            int vertexColor = finalPolygonColor.ToArgb();

            m_topVertices = new CustomVertex.PositionColored[m_points.Count];

            // precalculate feature center (at zero elev)
            Point3d center = new Point3d(0, 0, 0);


            foreach (Point3d point in m_points)
            {
                center += MathEngine.SphericalToCartesianD(
                    Angle.FromDegrees(point.Y),
                    Angle.FromDegrees(point.X),
                    World.EquatorialRadius
                    );
            }
            center = center * (1.0 / m_points.Count);
            // round off to nearest 10^5.
            center.X = ((int)(center.X / 10000.0)) * 10000.0;
            center.Y = ((int)(center.Y / 10000.0)) * 10000.0;
            center.Z = ((int)(center.Z / 10000.0)) * 10000.0;

            m_localOrigin = center.Vector3;

            long i = 0;

            try
            {
                foreach (Point3d point in m_points)
                {
                    double terrainHeight = 0;
                    if (m_altitudeMode == AltitudeMode.RelativeToGround)
                    {
                        if (World.TerrainAccessor != null)
                        {
                            terrainHeight = World.TerrainAccessor.GetElevationAt(
                                point.Y,
                                point.X,
                                (100.0 / DrawArgs.Camera.ViewRange.Degrees)
                                );
                        }
                    }

                    // polygon point
                    Point3d xyzPoint = MathEngine.SphericalToCartesianD(
                        Angle.FromDegrees(point.Y),
                        Angle.FromDegrees(point.X),
                        m_verticalExaggeration * (m_distanceAboveSurface + terrainHeight + point.Z) + World.EquatorialRadius
                        );

                    Vector3 xyzVertex = (xyzPoint - center).Vector3;

                    m_topVertices[i].X     = xyzVertex.X;
                    m_topVertices[i].Y     = xyzVertex.Y;
                    m_topVertices[i].Z     = xyzVertex.Z;
                    m_topVertices[i].Color = finalLineColor.ToArgb();

                    if (m_extrude || m_altitudeMode != AltitudeMode.ClampedToGround)
                    {
                        m_wallVertices[4 * i].X  = xyzVertex.X;
                        m_wallVertices[4 * i].Y  = xyzVertex.Y;
                        m_wallVertices[4 * i].Z  = xyzVertex.Z;
                        m_wallVertices[4 * i].Tu = i * textureCoordIncrement;
                        m_wallVertices[4 * i].Tv = 1.0f;

                        m_wallVertices[4 * i].Normal = new Vector3(0, 0, 0);

                        m_colorWallVertices[4 * i].X     = xyzVertex.X;
                        m_colorWallVertices[4 * i].Y     = xyzVertex.Y;
                        m_colorWallVertices[4 * i].Z     = xyzVertex.Z;
                        m_colorWallVertices[4 * i].Color = vertexColor;

                        // extruded point
                        if (m_extrudeToGround)
                        {
                            xyzPoint = MathEngine.SphericalToCartesianD(
                                Angle.FromDegrees(point.Y),
                                Angle.FromDegrees(point.X),
                                m_verticalExaggeration * (m_distanceAboveSurface + terrainHeight) + World.EquatorialRadius
                                );
                        }
                        else
                        {
                            double extrudeDist = m_extrudeHeight;
                            if (!m_extrudeUpwards)
                            {
                                extrudeDist *= -1;
                            }

                            xyzPoint = MathEngine.SphericalToCartesianD(
                                Angle.FromDegrees(point.Y),
                                Angle.FromDegrees(point.X),
                                m_verticalExaggeration * (m_distanceAboveSurface + terrainHeight + extrudeDist + point.Z) + World.EquatorialRadius
                                );
                        }

                        xyzVertex = (xyzPoint - center).Vector3;


                        m_wallVertices[4 * i + 1].X = xyzVertex.X;
                        m_wallVertices[4 * i + 1].Y = xyzVertex.Y;
                        m_wallVertices[4 * i + 1].Z = xyzVertex.Z;
                        //m_wallVertices[4 * i + 1].Color = vertexColor;
                        m_wallVertices[4 * i + 1].Tu = i * textureCoordIncrement;
                        m_wallVertices[4 * i + 1].Tv = 0.0f;

                        m_wallVertices[4 * i + 1].Normal = new Vector3(0, 0, 0);

                        m_colorWallVertices[4 * i + 1].X     = xyzVertex.X;
                        m_colorWallVertices[4 * i + 1].Y     = xyzVertex.Y;
                        m_colorWallVertices[4 * i + 1].Z     = xyzVertex.Z;
                        m_colorWallVertices[4 * i + 1].Color = vertexColor;

                        // replicate to previous vertex as well
                        if (i > 0)
                        {
                            m_wallVertices[4 * i - 2] = m_wallVertices[4 * i];
                            m_wallVertices[4 * i - 1] = m_wallVertices[4 * i + 1];

                            m_colorWallVertices[4 * i - 2] = m_colorWallVertices[4 * i];
                            m_colorWallVertices[4 * i - 1] = m_colorWallVertices[4 * i + 1];
                        }
                    }
                    i++;
                }
            }
            catch (System.InvalidOperationException ioe)
            {
                Console.WriteLine(ioe.Message);
            }

            // calculate normals
            // -----------------
            // first pass -- accumulate normals
            // we start with the second index because we're looking at (i-1) to calculate normals
            // we also use the same normal for top and bottom vertices...
            for (i = 1; i < m_points.Count && (4 * i - 1) < m_wallVertices.Length; i++)
            {
                Vector3 dir  = m_wallVertices[4 * i - 2].Position - m_wallVertices[4 * i - 3].Position;
                Vector3 up   = m_wallVertices[4 * i - 1].Position - m_wallVertices[4 * i - 2].Position;
                Vector3 norm = Vector3.Normalize(Vector3.Cross(dir, up));
                m_wallVertices[4 * i - 4].Normal += norm;
                m_wallVertices[4 * i - 3].Normal += norm;
                m_wallVertices[4 * i - 2].Normal += norm;
                m_wallVertices[4 * i - 1].Normal += norm;
            }
            // normalize normal vectors.
            if (m_points.Count * 4 <= m_wallVertices.Length)
            {
                for (i = 0; i < m_points.Count; i++)
                {
                    m_wallVertices[4 * i + 0].Normal.Normalize();
                    m_wallVertices[4 * i + 1].Normal.Normalize();
                    m_wallVertices[4 * i + 2].Normal.Normalize();
                    m_wallVertices[4 * i + 3].Normal.Normalize();
                }
            }
        }