KSPModdingLibs/KSPCommunityFixes

Drag cubes are incorrectly calculated with KSPCF 1.24.1

gotmachine opened this issue · 1 comments

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
	}
}

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.