List <Task <IQuadNode> > CreateBackgroundSplitTasks(DoubleVector3 cameraLocation, DoubleVector3 planetLocation) { // TODO: there's a problem with this algorithm. If we need to split very deeply because for example // the camera is teleported to the surface, we only split one level at a time and wait for that level // to finish and for the next update sweep to occur before queuing splits for the next level. There // may be wasted time in there (not clear yet). We also spend time generating meshes for quads that // we know we don't need. Ideally we'd jump straight to rendering meshes for the new leaves and worry // about rendering meshes for the intermediate nodes later when we need them. This means we need a // general way to delay completing a merge (continuing to render its children in the meantime) until // a mesh is rendered for that node. Once we have that behavior // we can maybe throw away the vertex buffers for all non-leaf meshes to save memory and regenerate them // as needed. That would take more CPU overall but it's not time sensitive because we'd just keep // rendering the child nodes until we got around to it. That would be a problem only if we end up // overloading the GPU but in many cases that wouldn't happen because the merging nodes would be behind // the camera as it travels and thus not rendered. // Potential problem: we don't know for sure if a node needs to be split until after we generate its mesh. _splitInProgress = true; var subextents = _extents.Split(); return(subextents.Select(extent => Task <IQuadNode> .Factory.StartNew(() => { var node = _quadNodeFactory.Create(); node.Initialize(_planetRadius, _planeNormalVector, _uVector, _vVector, extent, Level + 1); node.Update(cameraLocation, planetLocation); return node; }, _cancellationTokenSource.Token, TaskCreationOptions.None, _taskSchedulerFactory.CreateForLevel(Level))).ToList()); }
private IQuadNode CreateFace(double planetRadius, Vector3 normalVector) { var face = _quadNodeFactory.Create(); var orientationVectors = _faceOrientations[normalVector]; var u = orientationVectors[0]; var v = orientationVectors[1]; face.Initialize(planetRadius, normalVector, u, v, new QuadNodeExtents(-1.0, 1.0, -1.0, 1.0), 0); return(face); }