예제 #1
0
 public void Update(DoubleVector3 cameraLocation, DoubleVector3 planetLocation, ClippingPlanes clippingPlanes)
 {
     foreach (var face in _faces)
     {
         face.Update(cameraLocation, planetLocation, clippingPlanes);
     }
 }
예제 #2
0
        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();
        }
예제 #3
0
 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;
         }
     }
 }
예제 #4
0
        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);
        }
예제 #5
0
        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;
            });
        }
예제 #6
0
        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);
                }
            }
        }