KSPModdingLibs / KSPCommunityFixes

Community patches for bugs in the KSP codebase
49 stars 17 forks source link

Drag cubes are incorrectly calculated with KSPCF 1.24.1 #114

Closed gotmachine closed 1 year ago

gotmachine commented 1 year ago

Initially reported on the forums

The FastLoader patch cause drag cubes to be semi-randomly wrongly generated. Specifically, this seems to happen on all parts having multiple drag cubes defined, this include parachutes, but also animated parts such as the inflatable heatshield, deployable antennas, landing gears, etc.

The FastLoader patch alter the part compilation to decouple it from framerate, but it seems some part of the drag cube computations actually require a frame to skipped.

The required frame skip could be either setting the part animation at the desired position for each drag cube, or the aero texture not being updated immediately, this require further investigation. In any case, it seems to be necessary to reimplement at least some of the frame skips (yield return null) defined in DragCubeSystem.RenderDragCubes().

The reason it's semi-random is likely because the FastLoader patch still skip a frame occasionally to maintain ~30 FPS while loading, so depending on CPU/GPU speed as well as "data alignment", this doesn't reproduce on the same drag cubes every time, and sometimes not at all.

A few examples :

// ORIGINAL :
PART
{
    url = Squad/Parts/Aero/InflatableHeatShield/HeatShield/InflatableHeatShield
    DRAG_CUBE
    {
        cube = A, 19.07,0.4872,8.728, 19.07,0.4871,8.728, 72.75,0.8279,2.352, 71.74,0.8437,2.415, 18.75,0.4822,9.129, 18.75,0.5195,9.129, -4.768E-07,0.9913,4.768E-07, 8.528,3.025,9.074
        cube = B, 5.042,0.7795,4.677, 5.042,0.7795,4.677, 4.271,0.8684,4.235, 3.585,0.6972,0.9259, 5.008,0.7754,4.212, 5.008,0.7758,4.212, -4.768E-07,2.057,0, 6.815,4.172,5.902
    }
}
// GENERATED :
PART
{
    url = Squad/Parts/Aero/InflatableHeatShield/HeatShield/InflatableHeatShield
    DRAG_CUBE
    {
        cube = A, 5.042,0.7795,4.677, 5.042,0.7795,4.677, 4.271,0.8684,4.235, 3.585,0.6972,0.9259, 5.008,0.7754,4.212, 5.008,0.7758,4.212, -4.768E-07,2.057,0, 6.815,4.172,5.902
        cube = B, 5.042,0.7795,4.677, 5.042,0.7795,4.677, 4.271,0.8684,4.235, 3.585,0.6972,0.9259, 5.008,0.7754,4.212, 5.008,0.7758,4.212, -4.768E-07,2.057,0, 6.815,4.172,5.902
    }
}
// ORIGINAL :
PART
{
    url = Squad/Parts/Electrical/1x6SolarPanels/1x6SolarPanels/solarPanels4
    DRAG_CUBE
    {
        cube = RETRACTED, 0.1941,0.9914,0.299, 0.1941,0.9573,0.244, 0.05756,0.9133,0.3041, 0.05756,0.8735,0.5156, 0.06437,0.9507,0.4989, 0.06437,0.9518,0.4189, -0.03427,-0.1231,-1.851E-05, 0.2383,0.5386,0.4
        cube = EXTENDED_A, 0.07373,0.9491,2.729, 0.07373,0.7227,2.651, 0.9936,0.9921,0.2336, 0.9936,0.9941,0.2723, 0.07135,0.9598,0.2894, 0.07135,0.9606,0.2894, -1.235,0,5.454E-06, 2.64,0.2924,0.4
        cube = EXTENDED_B, 0.07123,0.9683,2.729, 0.07123,0.7177,2.651, 0.062,0.9603,0.2824, 0.062,0.9603,0.2824, 1.003,0.9918,0.2324, 1.003,0.9923,0.2121, -1.235,0.02947,-7.451E-09, 2.64,0.4,0.2326
    }
}
// GENERATED :
PART
{
    url = Squad/Parts/Electrical/1x6SolarPanels/1x6SolarPanels/solarPanels4
    DRAG_CUBE
    {
        cube = RETRACTED, 0.1323,0.9912,0.2713, 0.1323,0.9454,0.2161, 0.04206,0.9165,0.275, 0.04206,0.8853,0.4296, 0.0476,0.9542,0.257, 0.0476,0.9552,0.257, -0.0365,-0.1006,4.47E-08, 0.2023,0.4679,0.3161
        cube = EXTENDED_A, 0.1323,0.9912,0.2713, 0.1323,0.9454,0.2161, 0.04206,0.9165,0.275, 0.04206,0.8853,0.4296, 0.0476,0.9542,0.257, 0.0476,0.9552,0.257, -0.0365,-0.1006,4.47E-08, 0.2023,0.4679,0.3161
        cube = EXTENDED_B, 0.0579,0.9862,2.166, 0.0579,0.7354,2.086, 0.04493,0.9582,0.2489, 0.04493,0.9582,0.2489, 0.6585,0.9911,0.2199, 0.6585,0.9879,0.2021, -0.972,-4.515E-06,-7.451E-09, 2.073,0.3161,0.2122
    }
}
// ORIGINAL :
PART
{
    url = Squad/Parts/Utility/parachuteMk1/parachuteMk1/parachuteSingle
    DRAG_CUBE
    {
        cube = PACKED, 0.1569,0.6558,0.4137, 0.1569,0.6558,0.4137, 0.2765,0.6424,0.3861, 0.2765,0.8647,0.1765, 0.1612,0.6492,0.6308, 0.1612,0.6764,0.669, 6.735E-06,0.1034,0.01848, 0.6307,0.3626,0.6124
        cube = SEMIDEPLOYED, 7.477,0.2764,0.5794, 7.477,0.2764,0.5794, 0.5275,1.225,4.172, 0.5275,1.124,14.99, 7.54,0.2754,0.5646, 7.54,0.2744,0.5325, 6.557E-07,8.838,1.147E-05, 0.826,17.83,0.821
        cube = DEPLOYED, 72.79,7.569,4.943, 72.79,7.568,4.943, 52.78,8.568,4.172, 52.78,6.533,14.99, 73.5,7.509,4.551, 73.5,7.474,4.551, 6.676E-06,8.838,0.0001245, 8.26,17.83,8.21
    }
}
// GENERATED :
PART
{
    url = Squad/Parts/Utility/parachuteMk1/parachuteMk1/parachuteSingle
    DRAG_CUBE
    {
        cube = PACKED, 0.1571,0.6559,0.4137, 0.1571,0.656,0.4137, 0.2765,0.6424,0.3861, 0.2765,0.8647,0.1765, 0.1614,0.6493,0.6308, 0.1614,0.6765,0.669, 6.735E-06,0.1034,0.01848, 0.6307,0.3626,0.6124
        cube = SEMIDEPLOYED, 7.477,0.2764,0.5794, 7.477,0.2764,0.5794, 0.5275,1.225,4.172, 0.5275,1.124,14.99, 7.54,0.2754,0.5646, 7.54,0.2744,0.5325, 6.557E-07,8.838,1.147E-05, 0.826,17.83,0.821
        cube = DEPLOYED, 7.477,2.653,0.5794, 7.477,2.653,0.5794, 0.5275,11.76,4.172, 0.5275,10.79,14.99, 7.54,2.644,0.5646, 7.54,2.634,0.5325, 6.557E-07,8.838,1.147E-05, 0.826,17.83,0.821
    }
}
gotmachine commented 1 year ago

For reference, the needed frame skip was after calls to IMultipleDragCube.AssumeDragCubePosition(), which is logical in hindsight as this usually calls Animation.Play(), a deferred unity call. Actual animation processing occurs in the animation update in between frames.

This was fixed by adding a static flag flip in a DragCubeSystem.RenderDragCubes() transpiler, after the call to IMultipleDragCube.AssumeDragCubePosition(), then skipping an additional frame from the FastLoader coroutine wrapper if the flag is set.