Skip to content

Commit

Permalink
Fixed organelle models flickering sometimes due to render order (Revo…
Browse files Browse the repository at this point in the history
…lutionary-Games#2756)

* Calculate different RenderPriorities for the HexPositions.

* updated render priority calculation

* added helper function to get scene material

* PR code cleanups

* return null if no scene loaded

* changed string to NodePath

* made positive modulo more readable
  • Loading branch information
takko authored Nov 21, 2021
1 parent afb203f commit 68775a5
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 24 deletions.
5 changes: 5 additions & 0 deletions simulation_parameters/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,11 @@ public static class Constants
/// </summary>
public const string SPECIES_NAME_REGEX = "^(?<genus>[^ ]+) (?<epithet>[^ ]+)$";

/// <summary>
/// Minimum hex distance before the same render priority.
/// </summary>
public const int HEX_RENDER_PRIORITY_DISTANCE = 4;

/// <summary>
/// The duration for which a save is considered recently performed.
/// </summary>
Expand Down
23 changes: 23 additions & 0 deletions src/engine/NodeHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,27 @@ public static void ReParent(this Node node, Node newParent)
node.GetParent().RemoveChild(node);
newParent.AddChild(node);
}

/// <summary>
/// Get the material of this scene's model.
/// </summary>
/// <param name="node">Node to get material from.</param>
/// <param name="modelPath">Path to model within the scene. If null takes scene root as model.</param>
/// <returns>ShaderMaterial of the GeometryInstance.</returns>
public static ShaderMaterial GetMaterial(this Node node, NodePath modelPath = null)
{
GeometryInstance geometry;

// Fetch the actual model from the scene
if (string.IsNullOrEmpty(modelPath))
{
geometry = (GeometryInstance)node;
}
else
{
geometry = node.GetNode<GeometryInstance>(modelPath);
}

return (ShaderMaterial)geometry.MaterialOverride;
}
}
21 changes: 16 additions & 5 deletions src/general/Hex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,19 +231,30 @@ public static Hex FlipHorizontally(Hex hex)
return new Hex(-hex.Q, hex.Q + hex.R);
}

public override bool Equals(object obj)
/// <summary>
/// Returns the RenderPriority for the hex.
/// Between 1 and HEX_RENDER_PRIORITY_DISTANCE^2.
/// </summary>
/// <returns>RenderPriority</returns>
public static int GetRenderPriority(Hex hex)
{
if (!(obj is Hex hex))
return false;

return Equals(hex);
return hex.Q.PositiveModulo(Constants.HEX_RENDER_PRIORITY_DISTANCE) * Constants.HEX_RENDER_PRIORITY_DISTANCE
+ hex.R.PositiveModulo(Constants.HEX_RENDER_PRIORITY_DISTANCE) + 1;
}

public bool Equals(Hex other)
{
return Q == other.Q && R == other.R;
}

public override bool Equals(object obj)
{
if (!(obj is Hex hex))
return false;

return Equals(hex);
}

public override int GetHashCode()
{
var hashCode = -1997189103;
Expand Down
11 changes: 11 additions & 0 deletions src/general/MathUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,15 @@ public static float Lerp(float from, float to, float weight, float tolerance = M

return Mathf.Lerp(from, to, weight);
}

/// <summary>
/// Standard modulo for negative values in C# produces negative results.
/// This function returns modulo values between 0 and mod-1.
/// </summary>
/// <returns>The positive modulo</returns>
public static int PositiveModulo(this int val, int mod)
{
int result = val % mod;
return (result < 0) ? result + mod : result;
}
}
10 changes: 10 additions & 0 deletions src/general/SceneDisplayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ public string Scene
}
}

/// <summary>
/// Get the material of this scene's model.
/// </summary>
/// <param name="modelPath">Path to model within the scene. If null takes scene root as model.</param>
/// <returns>ShaderMaterial of the GeometryInstance. Null if no scene.</returns>
public ShaderMaterial GetMaterial(NodePath modelPath = null)
{
return currentlyShown?.GetMaterial(modelPath);
}

private void LoadNewScene()
{
if (currentlyShown != null)
Expand Down
2 changes: 1 addition & 1 deletion src/microbe_stage/Membrane.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ size = Vector3( 2, 0.539, 2 )

[sub_resource type="ShaderMaterial" id=2]
resource_local_to_scene = true
render_priority = 1
render_priority = 18
shader = ExtResource( 2 )
shader_param/wigglyNess = 1.0
shader_param/movementWigglyNess = 1.0
Expand Down
2 changes: 1 addition & 1 deletion src/microbe_stage/Microbe.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

[sub_resource type="ShaderMaterial" id=1]
resource_local_to_scene = true
render_priority = 1
render_priority = 18
shader = ExtResource( 4 )
shader_param/wigglyNess = 1.0
shader_param/movementWigglyNess = 1.0
Expand Down
18 changes: 4 additions & 14 deletions src/microbe_stage/PlacedOrganelle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -574,26 +574,15 @@ private void SetupOrganelleGraphics()
{
var organelleSceneInstance = (Spatial)Definition.LoadedScene.Instance();

// Store the material of the organelle to be updated
GeometryInstance geometry;

// Fetch the actual model from the scene to get at the material we set the tint on
if (string.IsNullOrEmpty(Definition.DisplaySceneModelPath))
{
geometry = (GeometryInstance)organelleSceneInstance;
}
else
{
geometry = organelleSceneInstance.GetNode<GeometryInstance>(Definition.DisplaySceneModelPath);
}

// Store animation player for later use
if (!string.IsNullOrEmpty(Definition.DisplaySceneAnimation))
{
OrganelleAnimation = organelleSceneInstance.GetNode<AnimationPlayer>(Definition.DisplaySceneAnimation);
}

organelleMaterial = (ShaderMaterial)geometry.MaterialOverride;
// Store the material of the organelle to be updated
organelleMaterial = organelleSceneInstance.GetMaterial(Definition.DisplaySceneModelPath);
organelleMaterial.RenderPriority = Hex.GetRenderPriority(Position);

// There is an intermediate node so that the organelle scene root rotation and scale work
OrganelleGraphics = new Spatial();
Expand All @@ -607,6 +596,7 @@ private void SetupOrganelleGraphics()
// Position the intermediate node relative to origin of cell
var transform = new Transform(Quat.Identity,
Hex.AxialToCartesian(Position) + Definition.CalculateModelOffset());

OrganelleGraphics.Transform = transform;

// For some reason MathUtils.CreateRotationForOrganelle(Orientation) in the above transform doesn't work
Expand Down
13 changes: 10 additions & 3 deletions src/microbe_stage/editor/MicrobeEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1734,7 +1734,8 @@ private void RenderHighlightedOrganelle(int q, int r, int rotation, OrganelleDef

organelleModel.Visible = true;

UpdateOrganellePlaceHolderScene(organelleModel, shownOrganelle.DisplayScene);
UpdateOrganellePlaceHolderScene(organelleModel, shownOrganelle.DisplayScene,
shownOrganelle, Hex.GetRenderPriority(new Hex(q, r)));
}
}

Expand Down Expand Up @@ -2283,7 +2284,7 @@ private void UpdateAlreadyPlacedVisuals()
organelleModel.Visible = !MicrobePreviewMode;

UpdateOrganellePlaceHolderScene(organelleModel,
organelle.Definition.DisplayScene);
organelle.Definition.DisplayScene, organelle.Definition, Hex.GetRenderPriority(organelle.Position));
}
}

Expand All @@ -2304,9 +2305,15 @@ private void UpdateAlreadyPlacedVisuals()
/// <summary>
/// Updates the organelle model displayer to have the specified scene in it
/// </summary>
private void UpdateOrganellePlaceHolderScene(SceneDisplayer organelleModel, string displayScene)
private void UpdateOrganellePlaceHolderScene(SceneDisplayer organelleModel,
string displayScene, OrganelleDefinition definition, int renderPriority)
{
organelleModel.Scene = displayScene;
var material = organelleModel.GetMaterial(definition.DisplaySceneModelPath);
if (material != null)
{
material.RenderPriority = renderPriority;
}
}

[DeserializedCallbackAllowed]
Expand Down

0 comments on commit 68775a5

Please sign in to comment.