Skip to content

Commit 9b95a10

Browse files
committed
Other: Refactor vector math code.
1 parent aeeccdb commit 9b95a10

File tree

3 files changed

+39
-29
lines changed

3 files changed

+39
-29
lines changed

ShaderShrinker/Shrinker.Parser/Optimizations/PerformArithmeticExtension.cs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,7 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
191191
var numberNode = symbolNode.Next;
192192
if (numberNode?.Token is FloatToken)
193193
{
194-
// Number must not be used in a following math operation of a different category.
195-
if (numberNode.Next?.Token is not SymbolOperatorToken nextMath ||
196-
nextMath.GetMathSymbolType() == symbol.GetMathSymbolType() ||
197-
nextMath.GetMathSymbolType() == TokenExtensions.MathSymbolType.AddSubtract)
194+
if (IsSafeToPerformMath(vectorNode, symbol, numberNode))
198195
{
199196
// Perform math on each bracketed value.
200197
var newCsv =
@@ -231,8 +228,7 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
231228
var numberNode = symbolNode.Previous;
232229
if (numberNode?.Token is FloatToken)
233230
{
234-
// Number must not be used in a preceding math operation.
235-
if (numberNode.Previous?.Token is not SymbolOperatorToken nextMath || nextMath.GetMathSymbolType() != TokenExtensions.MathSymbolType.MultiplyDivide)
231+
if (IsSafeToPerformMath(numberNode, symbol, vectorNode))
236232
{
237233
// Perform math on each bracketed value.
238234
var newCsv =
@@ -270,11 +266,7 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
270266
if (rhsVectorNode?.Token is TypeToken t && t.IsVector())
271267
{
272268
var rhsVectorBrackets = rhsVectorNode.Next as RoundBracketSyntaxNode;
273-
274-
// RHS vector must not be used in a following math operation of a different category.
275-
if (rhsVectorBrackets?.Next?.Token is not SymbolOperatorToken nextMath ||
276-
nextMath.GetMathSymbolType() == symbol.GetMathSymbolType() ||
277-
nextMath.GetMathSymbolType() == TokenExtensions.MathSymbolType.AddSubtract)
269+
if (IsSafeToPerformMath(vectorNode, symbol, rhsVectorNode))
278270
{
279271
// Ensure both brackets have the same number of elements.
280272
var lhsCsv = brackets.GetCsv().ToList();
@@ -314,22 +306,10 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
314306
.ToList())
315307
{
316308
var symbolNode = numNodeA.Next;
317-
var symbolType = symbolNode.Token.GetMathSymbolType();
318-
319-
if (symbolType != TokenExtensions.MathSymbolType.MultiplyDivide &&
320-
numNodeA.Previous != null &&
321-
numNodeA.Previous.Token is not CommaToken &&
322-
numNodeA.Previous.Token?.GetMathSymbolType() != symbolType)
323-
{
324-
continue;
325-
}
326-
327309
var numNodeB = symbolNode.Next;
328-
if (numNodeB?.Next?.Token is SymbolOperatorToken &&
329-
numNodeB.Next.Token.GetMathSymbolType() != TokenExtensions.MathSymbolType.AddSubtract)
330-
{
310+
311+
if (!IsSafeToPerformMath(numNodeA, symbolNode.Token as SymbolOperatorToken, numNodeB))
331312
continue;
332-
}
333313

334314
var c = DoNodeMath(numNodeA, symbolNode, numNodeB);
335315

@@ -355,6 +335,32 @@ numNodeA.Previous.Token is not CommaToken &&
355335
return repeatSimplifications;
356336
}
357337

338+
private static bool IsSafeToPerformMath(SyntaxNode lhsNumNode, SymbolOperatorToken symbol, SyntaxNode rhsNumNode)
339+
{
340+
if (lhsNumNode == null || symbol == null || rhsNumNode == null)
341+
return false;
342+
343+
var symbolType = symbol.GetMathSymbolType();
344+
switch (symbolType)
345+
{
346+
case TokenExtensions.MathSymbolType.Unknown:
347+
return false;
348+
349+
// If main symbol is * or /, that's fine - Any further symbols in the expression won't affect things.
350+
case TokenExtensions.MathSymbolType.MultiplyDivide:
351+
return true;
352+
353+
// Only ok to perform math on the two nodes if the surrounding symbols are + or - (or don't exist).
354+
case TokenExtensions.MathSymbolType.AddSubtract:
355+
var prevSymbol = (lhsNumNode.Previous as GenericSyntaxNode)?.Token as SymbolOperatorToken;
356+
var nextSymbol = (rhsNumNode.Next is RoundBracketSyntaxNode ? rhsNumNode.Next.Next : rhsNumNode.Next)?.Token as SymbolOperatorToken;
357+
return new[] { prevSymbol, nextSymbol }.Where(o => o != null).All(o => o.GetMathSymbolType() == symbolType);
358+
359+
default:
360+
throw new ArgumentOutOfRangeException();
361+
}
362+
}
363+
358364
private static double DoNodeMath(SyntaxNode numNodeA, SyntaxNode symbolNode, SyntaxNode numNodeB)
359365
{
360366
var a = double.Parse(numNodeA.Token.Content);

ShaderShrinker/UnitTests/TestFiles/SimplifiedReference/ED209.glsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Processed by 'GLSL Shader Shrinker' (Shrunk by 948 characters)
1+
// Processed by 'GLSL Shader Shrinker' (Shrunk by 950 characters)
22
// (https://github.com/deanthecoder/GLSLShaderShrinker)
33

44
float stretch, gunsUp, gunsForward, edWalk, edTwist, edDown, edShoot, doorOpen, glow;
@@ -85,7 +85,7 @@ void setBodyMaterial(inout MarchData mat) {
8585
mat.specPower = 30.;
8686
}
8787

88-
float legWalkAngle(float f) { return sin(edWalk * 3.141 * 6. * f) * .2; }
88+
float legWalkAngle(float f) { return sin(edWalk * 18.846 * f) * .2; }
8989

9090
float edZ() { return mix(5., -2., edWalk); }
9191

ShaderShrinker/UnitTests/VectorArithmeticTests.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,9 @@ public void CheckArithmeticWithVectorAndVector(
290290
"vec2 f = vec2(1.1, 2.2) * vec2(1, 2) * 2.0;",
291291
"vec2 f = vec2(3) + vec2(4);",
292292
"vec2 f = vec2(3, 4) + vec2(5);",
293-
"vec2 f = vec2(3) + vec2(4, 5);")] string code,
293+
"vec2 f = vec2(3) + vec2(4, 5);",
294+
"vec2 v = vec2(1, 2), f = v * vec2(1.1, 2.2) + vec2(6, 7);",
295+
"vec2 v = vec2(1, 2), f = vec2(1.1, 2.2) + vec2(6, 7) * v;")] string code,
294296
[Values("vec2 f = vec2(2.1, 4.2);",
295297
"vec2 f = vec2(8.1, 11.2);",
296298
"vec2 f = vec2(7.1, 9.2);",
@@ -307,7 +309,9 @@ public void CheckArithmeticWithVectorAndVector(
307309
"vec2 f = vec2(2.2, 8.8);",
308310
"vec2 f = vec2(7);",
309311
"vec2 f = vec2(8, 9);",
310-
"vec2 f = vec2(7, 8);")] string expected)
312+
"vec2 f = vec2(7, 8);",
313+
"vec2 v = vec2(1, 2), f = v * vec2(1.1, 2.2) + vec2(6, 7);",
314+
"vec2 v = vec2(1, 2), f = vec2(1.1, 2.2) + vec2(6, 7) * v;")] string expected)
311315
{
312316
var lexer = new Lexer();
313317
lexer.Load(code);

0 commit comments

Comments
 (0)