dkavolis / Ferram-Aerospace-Research

Aerodynamics model for Kerbal Space Program
Other
77 stars 32 forks source link

Occlusion Handler #109

Open DRVeyl opened 3 years ago

DRVeyl commented 3 years ago

Unity Jobs+Burst-based Occlusion Handling for FlightIntegrator

Precompute occlusion from configurable number of directions on a sphere (currently 2000), sample by raycasting over the entire vessel and record per-part dictionary of <direction, area of total raycasts hitting collider>. Limit calculations during FixedUpdate cycle to only those that will be required for physics on that pass. Consume configured number of additional directions during Update() cycle, prioritized by near-ness to current vessel orientation. (That is, attempt to predict which orientations not yet calculated are most likely to be requested next.)

Since it is a physics raycaster, it can only hit colliders. Badly-configured part colliders, or missing colliders, will have an impact. (No collider ala ProcFairings [pre-1.8.3] means no detected surface area/occlusion for thermal processing.)

For testing / to exercise more fully, re-calculates over entire vessel [configurable interval, default 180 seconds] after completion, or whenever voxelization completes. Ideally the precomputation is a one-time cost each time the vessel changes. Part animations, if they move colliders, should trigger a recompute. Things in the environment can also occlude, so decoupling two vessels may lead to one occluding the other, and this state should get re-computed ... some time later. TBD if this is a feature or a bug.

Known issue: Update-cycle jobs cap is per-vessel instead of global. If multiple vessels are in physics range (such as after decoupling a lot of fairingsides) then they will all consume their allotment of raycast jobs. Need to track how many total jobs have been created across all active vessels, not per-instance. Probably should prioritize access by the ActiveVessel in this instance? Does it matter if we starve some vessels of their pre-compute jobs, or should all vessels get a minimum?

Implementation note: Current raycaster is limited to 10,000 rays over entire vessel. Min interval between rays is 0.1m in each dimension. Vessel dimension <10m will cast fewer rays. Vessel dimension > 10m will stretch the interval in that dimension to cast 100 rays along that slice. Not sure if I should keep it this way with the fixed min interval, or configure the raycaster to always shoot 10,000 rays and not have a minimum interval (so a small part/vessel will get a more precise area measurement). Forcing all casts to the fixed size would cost some performance in exchange for some accuracy, not sure if that is needed.