Skip to content

Commit

Permalink
Merge Jeff's changes
Browse files Browse the repository at this point in the history
  • Loading branch information
linuxgurugamer committed Jul 9, 2018
2 parents 8ce188b + b994db3 commit 1dea032
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 174 deletions.
12 changes: 12 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
1.9.3
Thanks to github & forum user @jefftimlin for this fix:
The BiomeFilter class attempted to generate a clean biome texture for the purposes of more accurate biome detection,
however it's expensive and complicated. Completely removed all of the complex code from this class to avoid the threading
issue entirely, and just made it use the ScienceUtil.GetExperimentBiome function, which seems to work well.
It makes the code faster, simpler, and safer.
Fixed an array index out of bounds problem in RequiresCrew.cs, which I found while debugging, which would intermittently
produce errors in the logs.
Added Collect All button to collect all science into any/all containers



1.9.2.3
Official release

Expand Down
180 changes: 11 additions & 169 deletions Source/ScienceAlert.Experiments/BiomeFilter.cs
Original file line number Diff line number Diff line change
@@ -1,45 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
using ReeperCommon;
using UnityEngine;

namespace ScienceAlert.Experiments
{
public class BiomeFilter : MonoBehaviour
{
private const int HALF_SEARCH_DIMENSIONS = 2; // box around the point on the biome map to

private CelestialBody current; // which CelestialBody we've got a cached biome map texture for
private Texture2D projectedMap; // this is the cleaned biome map of the current CelestialBody
private const float COLOR_THRESHOLD = 0.005f; // Maximum color difference for two colors to be considered the same
private Queue<Action> actions = new Queue<Action>(); // Actions to be performed during Update
private Thread worker; // Worker thread for ReprojectMap

void Start()
{
GameEvents.onDominantBodyChange.Add(OnDominantBodyChanged);
GameEvents.onVesselChange.Add(OnVesselChanged);
ReprojectBiomeMap(FlightGlobals.currentMainBody);
}

void OnDestroy()
{
GameEvents.onVesselChange.Remove(OnVesselChanged);
GameEvents.onDominantBodyChange.Remove(OnDominantBodyChanged);
}

public void Update()
{
lock(actions)
{
while (actions.Count > 0)
{
actions.Dequeue()();
}
}
}

public bool GetCurrentBiome(out string biome)
{
biome = "N/A";
Expand All @@ -48,159 +13,36 @@ public bool GetCurrentBiome(out string biome)

string possibleBiome = string.Empty;

if (GetBiome(FlightGlobals.ActiveVessel.latitude * Mathf.Deg2Rad, FlightGlobals.ActiveVessel.longitude * Mathf.Deg2Rad, out possibleBiome))
if (GetBiome(FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude, out possibleBiome))
{
// the biome we got is most likely good
biome = possibleBiome;
return true;
}
// the biome we got is not very accurate (e.g. polar ice caps in middle of kerbin grasslands and
// such, due to the way the biome map is filtered).
biome = possibleBiome;
return false;
else
{
return false;
}
}

public bool GetBiome(double latRad, double lonRad, out string biome)
public bool GetBiome(double lat, double lon, out string biome)
{
biome = string.Empty;
var vessel = FlightGlobals.ActiveVessel;

if (vessel == null || vessel.mainBody.BiomeMap == null || vessel.mainBody.BiomeMap.MapName == null)
return true;
if (vessel == null || vessel.mainBody.BiomeMap == null || vessel.mainBody.BiomeMap.MapName == null || vessel.mainBody.BiomeMap.Attributes.Length == 0)
{
return false;
}

if (!string.IsNullOrEmpty(vessel.landedAt))
{
biome = Vessel.GetLandedAtString(vessel.landedAt);
return true;
}

var possibleBiome = vessel.mainBody.BiomeMap.GetAtt(latRad, lonRad);

if (!IsBusy)
{
if (!VerifyBiomeResult(latRad, lonRad, possibleBiome)) return false;
biome = possibleBiome.name;
return true;
}
biome = ScienceUtil.GetExperimentBiome(vessel.mainBody, lat, lon);

biome = possibleBiome.name;
return true;
}

private bool Similar(Color first, Color second)
{
return Mathf.Abs(first.r - second.r) < COLOR_THRESHOLD && Mathf.Abs(first.g - second.g) < COLOR_THRESHOLD && Mathf.Abs(first.b - second.b) < COLOR_THRESHOLD;
}

private bool VerifyBiomeResult(double lat, double lon, CBAttributeMapSO.MapAttribute target)
{
if (projectedMap == null) return true; // we'll have to assume it's accurate since we can't prove otherwise
if (target == null || target.mapColor == null) return true; // this shouldn't happen

lon -= Mathf.PI * 0.5f;
if (lon < 0d) lon += Mathf.PI * 2d;
lon %= Mathf.PI * 2d;

int x_center = (int)Math.Round(projectedMap.width * (float)(lon / (Mathf.PI * 2)), 0);
int y_center = (int)Math.Round(projectedMap.height * ((float)(lat / Mathf.PI) + 0.5f), 0);

for (int y = y_center - HALF_SEARCH_DIMENSIONS; y < y_center + HALF_SEARCH_DIMENSIONS; ++y)
for (int x = x_center - HALF_SEARCH_DIMENSIONS; x < x_center + HALF_SEARCH_DIMENSIONS; ++x)
{
Color c = projectedMap.GetPixel(x, y);
if (Similar(c, target.mapColor))
return true; // we have a match, no need to look further
}
return false;
}

private void ReprojectBiomeMap(CelestialBody newBody)
{
ReprojectMap(newBody);
}

private void ReprojectMap(CelestialBody newBody)
{
if (current == newBody)
{
return;
}

if (newBody == null)
{
current = null;
return;
}

current = null;

if (newBody.BiomeMap == null || newBody.BiomeMap.MapName == null)
{
projectedMap = null;
return;
}

Texture2D projection = new Texture2D(newBody.BiomeMap.Width, newBody.BiomeMap.Height, TextureFormat.ARGB32, false);
projection.filterMode = FilterMode.Point;

float timer = Time.realtimeSinceStartup;
Color32[] pixels = projection.GetPixels32();

if (worker != null)
{
worker.Abort();
}

var projectionWidth = projection.width;
var projectionHeight = projection.height;

worker = new Thread(() =>
{
for (int y = 0; y < projectionHeight; ++y)
{
for (int x = 0; x < projectionWidth; ++x)
{
// convert x and y into uv coordinates
float u = (float)x / projectionWidth;
float v = (float)y / projectionHeight;
// convert uv coordinates into latitude and longitude
double lat = Math.PI * v - Math.PI * 0.5;
double lon = 2d * Math.PI * u + Math.PI * 0.5;
// set biome color in our clean texture
pixels[y * projectionWidth + x] = (Color32)newBody.BiomeMap.GetAtt(lat, lon).mapColor;
}
}
lock (actions)
{
actions.Enqueue(() =>
{
projection.SetPixels32(pixels);
projection.Apply();
current = newBody;
projectedMap = projection;
worker = null;
});
}
});
worker.IsBackground = true;
worker.Start();
}

private void OnDominantBodyChanged(GameEvents.FromToAction<CelestialBody, CelestialBody> bodies)
{
ReprojectBiomeMap(bodies.to);
}

private void OnVesselChanged(Vessel v)
{
ReprojectBiomeMap(v.mainBody);
}

public bool IsBusy => worker != null;
}
}
2 changes: 1 addition & 1 deletion Source/ScienceAlert.Experiments/ExperimentObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public virtual bool UpdateStatus(ExperimentSituations experimentSituation, out b
// biome matters; check to make sure we have biome data available
if (scanInterface.HaveScanData(vessel.latitude, vessel.longitude, vessel.mainBody))
{
if (biomeFilter.GetBiome(vessel.latitude * Mathf.Deg2Rad, vessel.longitude * Mathf.Deg2Rad,
if (biomeFilter.GetBiome(vessel.latitude, vessel.longitude,
out biome))
{
lastBiomeQuery = biome;
Expand Down
2 changes: 1 addition & 1 deletion Source/ScienceAlert.Experiments/RequiresCrew.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public override bool IsReadyOnboard
{
get
{
for (int i = crewableParts.Count - 1; i >= 0; i++)
for (int i = crewableParts.Count - 1; i >= 0; i--)
{
if (crewableParts[i].protoModuleCrew.Count > 0)
return true;
Expand Down
23 changes: 20 additions & 3 deletions Source/ScienceAlert.Windows/DraggableExperimentList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,23 @@ protected override void DrawUI()
doAll = true;
noEva = true;
}
if (GUILayout.Button("Collect All", Settings.Skin.button))
{
var parts = FlightGlobals.ActiveVessel.Parts.FindAll(p => p.Modules.Contains("ModuleScienceContainer"));

foreach (var part in parts)
{
var m = part.Modules["ModuleScienceContainer"];

if (m.Events["CollectAllEvent"].active)
{
//((ModuleScienceContainer)m).CollectAllEvent();

ModuleScienceContainer msc = m as ModuleScienceContainer;
msc.CollectAllEvent();
}
}
}

//-----------------------------------------------------
// Experiment list
Expand Down Expand Up @@ -136,9 +153,9 @@ protected override void DrawUI()
}
GUILayout.EndVertical();
}
string lblGreenColor = "00ff00";
string lblDrkGreenColor = "ff9d00";
string lblBlueColor = "3DB1FF";
//string lblGreenColor = "00ff00";
//string lblDrkGreenColor = "ff9d00";
//string lblBlueColor = "3DB1FF";
string lblYellowColor = "FFD966";
string lblRedColor = "f90000";

Expand Down
8 changes: 8 additions & 0 deletions Source/ScienceAlert.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,18 @@
<PropertyGroup>
<PostBuildEvent>"..\..\..\..\pdb2mdb.exe" "$(TargetPath)"



start /D D:\Users\jbb\github\ScienceAlert /WAIT deploy.bat $(TargetDir) $(TargetFileName)



if $(ConfigurationName) == Release (


start /D D:\Users\jbb\github\ScienceAlert /WAIT buildRelease.bat $(TargetDir) $(TargetFileName)


)
</PostBuildEvent>
</PropertyGroup>
Expand Down

0 comments on commit 1dea032

Please sign in to comment.