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); }
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); }
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); }
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); }