Make Camera an Actor and improve performance
#67
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There are quite a few endeavors in this pull request but the main thrust is to designate
Cameraas an actor instead ofWorld, and to takeCameraout ofWorldas a property and instead make it a top-level object in the scene. Moreover, therender()method has been moved out ofWorldand intoCamera, and is now passed an instance of the former into for rendering, as well as being responsible for tracking the progress of a render . Additionally,rayForPixel()has been moved fromWorldtoCamerasince it made more sense forCamerato be generating rays and sending them into aWorldOther related changes:
ScintillaAppandScintillaViewnow have acamerapropertyWorldBuilderno longer needs to worry about being passed aCamerato any of its methods.Worldis no longer an actor so none of its methods need to be designated asasync, and callers no longer need toawaitcalling them, including those in tests suites.rayForPixel()have been moved toCameraTests.swiftIntesectionTests.swiftandWorldTests.swiftno longer have to constuctCameras and so many of those tests were updated.The following changes were made to improve performance:
CSGs now maintain a cache of IDs of right children, rather than relying on the oldfindShape()to navigate down the tree for each ray and intersection. Additionally,Shape,CSG, andGrouphave a new methodgetAllChildIDs()which is called during the initialization of the enclosingWorldto populate the cache in eachCSGinstance.Shape,CSGandGroupall expose a new method,populateParentCache(), that is also only ever called during the initialization process so that the top level instance ofWorldmaintains a new cache of parent objects. The cache replaces the need for a sharedparentIDproperty inSharedShapePropertiesand its proxy property method inShape.World.objectToWorld()andWorld.worldToObjecthas been greatly simplified because it no longer needs to navigate the scene tree upward and instance can consult the cache , viaWorld.parent(of:).intersect()method has been renamed to_intersect()and declared as part of the protocol forShape. The name begins with an underscore to discourage anyone from overriding it, as there is already a default implementation, but it is part of the protocol now so that copies of the implemenation can be localized with anyShapetype.