public void Update(DoubleVector3 cameraLocation, DoubleVector3 planetLocation, ClippingPlanes clippingPlanes) { foreach (var face in _faces) { face.Update(cameraLocation, planetLocation, clippingPlanes); } }
public Planet(DoubleVector3 location, double radius, ITerrain terrain, IPlanetRenderer renderer, IHeightfieldGenerator generator, Statistics statistics) { _location = location; _radius = radius; _terrain = terrain; _renderer = renderer; _generator = generator; _statistics = statistics; _clippingPlanes = new ClippingPlanes(); }
void SetClippingPlanes(MeshDistance meshDistance, ClippingPlanes clippingPlanes) { if (IsVisibleToCamera) { if (clippingPlanes.Near > meshDistance.ClosestDistance) { clippingPlanes.Near = meshDistance.ClosestDistance; } if (clippingPlanes.Far < meshDistance.FurthestDistance) { clippingPlanes.Far = meshDistance.FurthestDistance; } } }
public void Update(DoubleVector3 cameraLocation, DoubleVector3 planetLocation, ClippingPlanes clippingPlanes) { // TODO: I don't like this class's public member design. In order to get properties like IsVisibleToCamera, // you must first call Update with appropriate information. Internally, a lot of stuff is also // order-dependent. However, this seems to be the most performant design at the moment. var meshDistance = GetDistanceFrom(cameraLocation); var distanceFromCamera = meshDistance.ClosestDistance; CameraDistanceToWidthRatio = distanceFromCamera / WidthInRealSpaceUnits(); IsVisibleToCamera = CalculateVisibility(cameraLocation, planetLocation, meshDistance.ClosestVertex); SetClippingPlanes(meshDistance, clippingPlanes); }
private void Split(DoubleVector3 cameraLocation, DoubleVector3 planetLocation, ClippingPlanes clippingPlanes) { _splitInProgress = true; var subextents = _extents.Split(); // TODO: refactor // TODO: should we bother to write specs for the threading behavior? var tasks = new List<Task<IQuadNode>>(); foreach (var subextent in subextents) { var capturedExtent = subextent; var task = Task<IQuadNode>.Factory.StartNew(() => { var node = _quadNodeFactory.Create(); node.Initialize(_planetRadius, _planeNormalVector, _uVector, _vVector, capturedExtent, Level + 1); node.Update(cameraLocation, planetLocation, clippingPlanes); return node; }); tasks.Add(task); } _backgroundSplitTask = Task.Factory.ContinueWhenAll(tasks.ToArray(), finishedTasks => { foreach (var task in finishedTasks) { _subnodes.Add(task.Result); } _hasSubnodes = true; _splitInProgress = false; }); }
public void Update(DoubleVector3 cameraLocation, DoubleVector3 planetLocation, ClippingPlanes clippingPlanes) { _mesh.Update(cameraLocation, planetLocation, clippingPlanes); // TODO: This algorithm could be improved to optimize the number of triangles that are drawn if (_mesh.IsVisibleToCamera && _mesh.CameraDistanceToWidthRatio < 1 && !_hasSubnodes && !_splitInProgress && !_mergeInProgress && Level < _settings.MaximumQuadNodeLevel) { Split(cameraLocation, planetLocation, clippingPlanes); } else if (_mesh.CameraDistanceToWidthRatio > 1.2 && _hasSubnodes && !_mergeInProgress && !_splitInProgress) { Merge(); } if (_hasSubnodes) { foreach (var subnode in _subnodes) { subnode.Update(cameraLocation, planetLocation, clippingPlanes); } } }