コード例 #1
0
        public void Handle(GoToGround message)
        {
            // TODO: assumes planet is at origin
            var planetUnitVector = DoubleVector3.Normalize(_camera.Location);
            var height           = _planet.GetGroundHeight(_camera.Location);

            _camera.Location = planetUnitVector * (height + 2);
        }
コード例 #2
0
        public double GetGroundHeight(DoubleVector3 observerLocation)
        {
            // TODO: should probably delegate this responsibility to the terrain object
            // TODO: what about water?
            var planetUnitVector = DoubleVector3.Normalize(observerLocation - _location);
            var height           = _generator.GetHeight(planetUnitVector, 19, 8000);

            return(_radius + height);
        }
コード例 #3
0
        bool CalculateIsAboveHorizonToCamera(DoubleVector3 cameraLocation, DoubleVector3 planetLocation, DoubleVector3 closestVertex)
        {
            // Taken from http://www.crappycoding.com/2009/04/

            // TODO: This algorithm is poor.  Implement this algorithm instead:
            // http://www.gamedev.net/community/forums/mod/journal/journal.asp?jn=263350&reply_id=3173799

            // TODO: sometimes the mesh is so large and we're so close the surface that none of the sampled
            // vertices are above the horizon.  That causes problems when we want to do early termination
            // when we do a draw walk on the QuadNode tree (see comments there).  Can we add a test here to
            // see if we're inside the mesh's bounding box?

            var planetToCamera = DoubleVector3.Normalize(cameraLocation - planetLocation);
            var planetToMesh   = DoubleVector3.Normalize(closestVertex - planetLocation);

            var horizonAngle = Math.Acos(_planetRadius * 0.99 / DoubleVector3.Distance(planetLocation, cameraLocation));
            var angleToMesh  = Math.Acos(DoubleVector3.Dot(planetToCamera, planetToMesh));

            return(horizonAngle > angleToMesh);
        }
コード例 #4
0
        Matrix GetWorldMatrix(DoubleVector3 location, DoubleVector3 cameraLocation)
        {
            // The mesh stored in the vertex buffer is centered at the origin in order to take it easy on
            // the float number system.  The camera view matrix is also generated as though the camera were
            // at the origin.  In order to correctly render the mesh we translate it away from the origin
            // by the same vector that the mesh (in double space) is displaced from the camera (in double space).

            // We also translate and scale distant meshes to bring them inside the far clipping plane.  For
            // every mesh that's further than the start of the scaled space, we calcuate a new distance
            // using an exponential downscale function to make it fall in the view frustum.  We also scale
            // it down proportionally so that it appears perspective-wise to be identical to the original
            // location.  See the Interactive Visualization paper, page 24.

            Matrix scaleMatrix;
            Matrix translationMatrix;

            var locationRelativeToCamera = location - cameraLocation;
            var distanceFromCamera       = locationRelativeToCamera.Length();
            var unscaledViewSpace        = _settings.FarClippingPlaneDistance * 0.25;

            if (distanceFromCamera > unscaledViewSpace)
            {
                var    scaledViewSpace                = _settings.FarClippingPlaneDistance - unscaledViewSpace;
                double scaledDistanceFromCamera       = unscaledViewSpace + (scaledViewSpace * (1.0 - Math.Exp((scaledViewSpace - distanceFromCamera) / 1000000000)));
                var    scaledLocationRelativeToCamera = DoubleVector3.Normalize(locationRelativeToCamera) * scaledDistanceFromCamera;

                scaleMatrix       = Matrix.CreateScale((float)(scaledDistanceFromCamera / distanceFromCamera));
                translationMatrix = Matrix.CreateTranslation(scaledLocationRelativeToCamera);
            }
            else
            {
                scaleMatrix       = Matrix.Identity;
                translationMatrix = Matrix.CreateTranslation(locationRelativeToCamera);
            }

            return(scaleMatrix * translationMatrix);
        }