Skip to content

Commit

Permalink
Element: Temporary hack to bypass inability for constraint matching o…
Browse files Browse the repository at this point in the history
…n bools, updates to standard library (fixed vector cross product, plane functions, minor matrix updates, renaming)
  • Loading branch information
TheMunro committed Oct 21, 2020
1 parent eeeb7f5 commit 63d4245
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 96 deletions.
4 changes: 2 additions & 2 deletions ContentFiles/ElementPackages/StandardLibrary/Line.ele
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ struct Line2(direction:Vector2, offset:Vector2)
distanceFromPoint(line:Line2, point:Vector2):Num
{
w = point.sub(line.offset)
l = line.direction.normalize
l = line.direction.normalise
return = w.sub(l.mul(w.dot(l))).magnitude
}
}
Expand All @@ -15,7 +15,7 @@ struct Line3(direction:Vector3, offset:Vector3)
distanceFromPoint(line:Line3, point:Vector3):Num
{
w = point.sub(line.offset)
l = line.direction.normalize
l = line.direction.normalise
return = w.sub(l.mul(w.dot(l))).magnitude
}
}
2 changes: 1 addition & 1 deletion ContentFiles/ElementPackages/StandardLibrary/Math.ele
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ random(seed:Num):Num
return = t4.rem(E).div(E)
}

#

#ellipse(a:Num, b:Num):Num
#{
# l = a.div(b);
Expand Down
74 changes: 29 additions & 45 deletions ContentFiles/ElementPackages/StandardLibrary/Matrices.ele
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
#column-major 2x2 coordinate matrix for representing linear transformations - INCOMPLETE
struct Matrix2x2(x:Vector2, y:Vector2)
{
xRow(a:Matrix2x2) = Vector2(a.x.x, a.y.x)
yRow(a:Matrix2x2) = Vector2(a.x.y, a.y.y)

transpose(m:Matrix2x2):Matrix2x2 = Matrix2x2(m.xRow, m.yRow)

determinant(m:Matrix2x2):Num
{
return = m.x.x.mul(m.y.y).sub(m.x.y.mul(m.y.x))
}
}



#column-major 3x3 coordinate matrix for representing linear transformations - INCOMPLETE
struct Matrix3x3(x:Vector3, y:Vector3, z:Vector3)
{
xRow(a:Matrix3x3) = Vector3(a.x.x, a.y.x, a.z.x)
yRow(a:Matrix3x3) = Vector3(a.x.y, a.y.y, a.z.y)
zRow(a:Matrix3x3) = Vector3(a.x.z, a.y.z, a.z.z)

transpose(m:Matrix4x4):Matrix3x3 = Matrix3x3(m.xRow, m.yRow, m.zRow)
transpose(m:Matrix3x3):Matrix3x3 = Matrix3x3(m.xRow, m.yRow, m.zRow)

#UNTESTED
determinant(m:Matrix3x3):Num
{
component_x = m.x.x.mul(m.y.y.mul(m.z.z).sub(m.y.z.mul(m.z.y)))
component_y = m.y.x.mul(m.y.y.mul(m.z.z).sub(m.y.z.mul(m.z.y)))
component_z = m.z.x.mul(m.y.y.mul(m.z.z).sub(m.y.z.mul(m.z.y)))
a = m.x.x.mul(m.y.y.mul(m.z.z).sub(m.y.z.mul(m.z.y)))
b = m.y.x.mul(m.x.x.mul(m.z.z).sub(m.x.z.mul(m.z.x)))
c = m.z.x.mul(m.x.x.mul(m.y.y).sub(m.x.y.mul(m.x.y)))

return = component_x.add(component_y).add(component_z)
return = a.sub(b).add(c)
}
}



#column-major 4x4 homogeneous coordinate matrix for representing affine transformations
struct Matrix4x4(x:Vector4, y:Vector4, z:Vector4, w:Vector4)
{
Expand All @@ -38,10 +54,10 @@ struct Matrix4x4(x:Vector4, y:Vector4, z:Vector4, w:Vector4)

position(m:Matrix4x4):Vector3 = Vector3(m.w.x, m.w.y, m.w.z)

rotation_submatrix(m:Matrix4x4):Matrix3x3 = Matrix3x3(
Vector3(m.x.x, m.y.x, m.z.x),
Vector3(m.x.y, m.y.y, m.z.y),
Vector3(m.x.z, m.y.z, m.z.z))
rotation(m:Matrix4x4):Matrix3x3 = Matrix3x3(
Vector3(m.x.x, m.y.x, m.z.x),
Vector3(m.x.y, m.y.y, m.z.y),
Vector3(m.x.z, m.y.z, m.z.z))

#this makes the assumption that Matrix4x4 is affine
hasInverse(a:Matrix4x4):Bool = a.rotation_submatrix.determinant.neq(0)
Expand All @@ -53,12 +69,12 @@ struct Matrix4x4(x:Vector4, y:Vector4, z:Vector4, w:Vector4)
Vector4(0, 0, 1, 0),
Vector4(translation.x, translation.y, translation.z, 1))

rotation(axis:Vector3, angle:Num):Matrix4x4
fromAxisAngle(axis:Vector3, angle:Num):Matrix4x4
{
c = Num.cos(angle)
s = Num.sin(angle)
t = 1.sub(c)
a = axis.normalize
a = axis.normalise

m_00 = t.mul(a.x).mul(a.x).add(c)
m_11 = t.mul(a.y).mul(a.y).add(c)
Expand Down Expand Up @@ -127,36 +143,4 @@ struct Matrix4x4(x:Vector4, y:Vector4, z:Vector4, w:Vector4)
Vector4(a.z.add(b.z)),
Vector4(a.w.add(b.w)))
}
}






#check these produce the same output
#memberwise is important... spot the typo in this mess... hopefully I didn't make any, but...
#multiply(a:Matrix4x4, b:Matrix4x4) {
#
# x = Vector4(a.x.x.mul(b.x.x).add(a.y.x.mul(b.x.y)).add(a.z.x.mul(b.x.z)).add(a.w.x.mul(b.x.w)),
# a.x.x.mul(b.y.x).add(a.y.x.mul(b.y.y)).add(a.z.x.mul(b.y.z)).add(a.w.x.mul(b.y.w)),
# a.x.x.mul(b.z.x).add(a.y.x.mul(b.z.y)).add(a.z.x.mul(b.z.z)).add(a.w.x.mul(b.z.w)),
# a.x.x.mul(b.w.x).add(a.y.x.mul(b.w.y)).add(a.z.x.mul(b.w.z)).add(a.w.x.mul(b.w.w)))
#
# y = Vector4(a.x.y.mul(b.x.x).add(a.y.y.mul(b.x.y)).add(a.z.y.mul(b.x.z)).add(a.w.y.mul(b.x.w)),
# a.x.y.mul(b.y.x).add(a.y.y.mul(b.y.y)).add(a.z.y.mul(b.y.z)).add(a.w.y.mul(b.y.w)),
# a.x.y.mul(b.z.x).add(a.y.y.mul(b.z.y)).add(a.z.y.mul(b.z.z)).add(a.w.y.mul(b.z.w)),
# a.x.y.mul(b.w.x).add(a.y.y.mul(b.w.y)).add(a.z.y.mul(b.w.z)).add(a.w.y.mul(b.w.w)))
#
# z = Vector4(a.x.z.mul(b.x.x).add(a.y.z.mul(b.x.y)).add(a.z.z.mul(b.x.z)).add(a.w.z.mul(b.x.w)),
# a.x.z.mul(b.y.x).add(a.y.z.mul(b.y.y)).add(a.z.z.mul(b.y.z)).add(a.w.z.mul(b.y.w)),
# a.x.z.mul(b.z.x).add(a.y.z.mul(b.z.y)).add(a.z.z.mul(b.z.z)).add(a.w.z.mul(b.z.w)),
# a.x.z.mul(b.w.x).add(a.y.z.mul(b.w.y)).add(a.z.z.mul(b.w.z)).add(a.w.z.mul(b.w.w)))
#
# w = Vector4(a.x.w.mul(b.x.x).add(a.y.w.mul(b.x.y)).add(a.z.w.mul(b.x.z)).add(a.w.w.mul(b.x.w)),
# a.x.w.mul(b.y.x).add(a.y.w.mul(b.y.y)).add(a.z.w.mul(b.y.z)).add(a.w.w.mul(b.y.w)),
# a.x.w.mul(b.z.x).add(a.y.w.mul(b.z.y)).add(a.z.w.mul(b.z.z)).add(a.w.w.mul(b.z.w)),
# a.x.w.mul(b.w.x).add(a.y.w.mul(b.w.y)).add(a.z.w.mul(b.w.z)).add(a.w.w.mul(b.w.w)))
#
# return = Matrix4x4(x, y, z, w)
#}
}
67 changes: 35 additions & 32 deletions ContentFiles/ElementPackages/StandardLibrary/Plane.ele
Original file line number Diff line number Diff line change
@@ -1,40 +1,43 @@
struct Plane(normal:Vector3, distance:Num)
{
#UNTESTED
#fromVertices(a:Vector3, b:Vector3, c:Vector3):Plane
#{
# ba = b.sub(a)
# ca = c.sub(a)
#
# n = ba.cross(ca)
# normal = n.normalize
# d = normal.dot(a).negate
#
# return = Plane(normal, d)
#}
#
##UNTESTED
#signedDistanceFromPoint(plane:Plane, point:Vector3):Num
#{
# closestPointOnPlane = plane.normal.mul(plane.distance)
# projectedPoint = point.sub(closestPointOnPlane)
# return = projectedPoint.dot(planeNormal)
#}

#UNTESTED
intersection(a:Plane, b:Plane):Line3
fromVertices(a:Vector3, b:Vector3, c:Vector3):Plane
{
direction = a.normal.Cross(b.normal)

perpendicularVector = b.normal.Cross(direction)
denominator = a.normal.Dot(perpendicularVector)
planeAPosition = a.normal.mul(a.distance)
planeBPosition = b.normal.mul(b.distance)
ba = b.sub(a)
ca = c.sub(a)

n = ba.cross(ca)
normal = n.normalise
d = normal.dot(a).negate

return = Plane(normal, d)
}

planePositionDifference = planeAPosition.sub(planeBPosition)
t = a.normal.dot(planePositionDifference).div(denominator)
point = planeBPosition.add(perpendicularVector.mul(t))
intersection(a:Plane, b:Plane):Line3
{
#http://geomalgorithms.com/a05-_intersect-1.html

#sanity check on normals
d1 = a.distance
n1 = a.normal.normalise

d2 = b.distance
n2 = b.normal.normalise

direction = n1.cross(n2)

difference = n1.mul(d2).sub(n2.mul(d1))
point = direction.cross(difference).div(direction.magnitudeSquared)

return = Line3(direction, point)
}

signedDistanceFromPoint(plane:Plane, point:Vector3):Num
{
#creates a position vector from the origin to the nearest point on the plane
closestPointOnPlane = plane.normal.mul(plane.distance)
#creates a position vector from point on plane to target point
projectedPoint = point.sub(closestPointOnPlane)
#projects position vector onto normal to determine distance from the plane
return = projectedPoint.dot(plane.normal)
}
}
8 changes: 4 additions & 4 deletions ContentFiles/ElementPackages/StandardLibrary/Vectors.ele
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct Vector2(x:Num, y:Num)
#operations
opposite(v:Vector2):Vector2 = Zero.sub(v)

normalize(v:Vector2):Vector2
normalise(v:Vector2):Vector2
{
#return zero vector if len = 0
len = magnitude(v)
Expand Down Expand Up @@ -96,7 +96,7 @@ struct Vector3(x:Num, y:Num, z:Num)
#operations
opposite(v:Vector3):Vector3 = Zero.sub(v)

normalize(v:Vector3):Vector3
normalise(v:Vector3):Vector3
{
#return zero vector if len = 0
len = magnitude(v)
Expand Down Expand Up @@ -154,7 +154,7 @@ struct Vector3(x:Num, y:Num, z:Num)
ax_by = a.x.mul(b.y)
ay_bx = a.y.mul(b.x)

return = Vector3(ay_bz.sub(az_by), az_bx.sub(ax_bz), az_by.sub(ay_bx))
return = Vector3(ay_bz.sub(az_by), az_bx.sub(ax_bz), ax_by.sub(ay_bx))
}

transformPosition(a:Vector3, matrix:Matrix4x4):Vector3
Expand Down Expand Up @@ -182,7 +182,7 @@ struct Vector4(x:Num, y:Num, z:Num, w:Num)
#operations
opposite(v:Vector4):Vector4 = Zero.sub(v)

normalize(v:Vector4):Vector4
normalise(v:Vector4):Vector4
{
#return zero vector if len = 0
len = magnitude(v)
Expand Down
15 changes: 12 additions & 3 deletions Element.NET/!3-Instructions/Instruction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,18 @@ public override Result<IValue> Index(Identifier id, Context context) =>
public override Result<IValue> Deserialize(Func<Instruction> nextValue, Context context)
{
var result = nextValue();
return result.StructImplementation == StructImplementation
? new Result<IValue>(result)
: context.Trace(EleMessageCode.SerializationError, $"'{result}' deserialized to incorrect type: is '{result.StructImplementation}' - expected '{StructImplementation}'");

//HACK: REMOVE THIS WHEN BUG IS FIXED, TEMPORARILY REQUIRED FOR INITIAL IMPLEMENTATION OF FORCEFIELD
if (StructImplementation is BoolStruct && result.StructImplementation is NumStruct)
{
return new Result<IValue>(result);
}

if (result.StructImplementation == StructImplementation)
return new Result<IValue>(result);
else
return context.Trace(EleMessageCode.SerializationError,
$"'{result}' deserialized to incorrect type: is '{result.StructImplementation}' - expected '{StructImplementation}'");
}
}

Expand Down
6 changes: 3 additions & 3 deletions Laboratory/Tests/L4-Standard-Library/Vector2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public void Opposite(string expression, string expected) =>
AssertApproxEqual(ValidatedCompilerInput, expected, expression);

[
TestCase("Vector2(0, 0).normalize", "Vector2(Num.NaN, Num.NaN)"),
TestCase("Vector2(1, 1).normalize", "Vector2(1.div(2.sqrt), 1.div(2.sqrt))"),
TestCase("Vector2(3, 4).normalize", "Vector2(3.div(5), 4.div(5))"),
TestCase("Vector2(0, 0).normalise", "Vector2(Num.NaN, Num.NaN)"),
TestCase("Vector2(1, 1).normalise", "Vector2(1.div(2.sqrt), 1.div(2.sqrt))"),
TestCase("Vector2(3, 4).normalise", "Vector2(3.div(5), 4.div(5))"),
]
public void Normalize(string expression, string expected) =>
AssertApproxEqual(ValidatedCompilerInput, expected, expression);
Expand Down
6 changes: 3 additions & 3 deletions Laboratory/Tests/L4-Standard-Library/Vector3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ public void Opposite(string expression, string expected) =>
AssertApproxEqual(ValidatedCompilerInput, expected, expression);

[
TestCase("Vector3(0, 0, 0).normalize", "Vector3(Num.NaN, Num.NaN, Num.NaN)"),
TestCase("Vector3(1, 1, 1).normalize", "Vector3(1.div(3.sqrt), 1.div(3.sqrt), 1.div(3.sqrt))"),
TestCase("Vector3(1, 2, 2).normalize", "Vector3(1.div(3), 2.div(3), 2.div(3))"),
TestCase("Vector3(0, 0, 0).normalise", "Vector3(Num.NaN, Num.NaN, Num.NaN)"),
TestCase("Vector3(1, 1, 1).normalise", "Vector3(1.div(3.sqrt), 1.div(3.sqrt), 1.div(3.sqrt))"),
TestCase("Vector3(1, 2, 2).normalise", "Vector3(1.div(3), 2.div(3), 2.div(3))"),
]
public void Normalize(string expression, string expected) =>
AssertApproxEqual(ValidatedCompilerInput, expected, expression);
Expand Down
6 changes: 3 additions & 3 deletions Laboratory/Tests/L4-Standard-Library/Vector4.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ public void Opposite(string expression, string expected) =>
AssertApproxEqual(ValidatedCompilerInput, expected, expression);

[
TestCase("Vector4(0, 0, 0, 0).normalize", "Vector4(Num.NaN, Num.NaN, Num.NaN, Num.NaN)"),
TestCase("Vector4(1, 1, 1, 1).normalize", "Vector4(1.div(2), 1.div(2), 1.div(2), 1.div(2))"),
TestCase("Vector4(2, 2, 4, 5).normalize", "Vector4(2.div(7), 2.div(7), 4.div(7), 5.div(7))"),
TestCase("Vector4(0, 0, 0, 0).normalise", "Vector4(Num.NaN, Num.NaN, Num.NaN, Num.NaN)"),
TestCase("Vector4(1, 1, 1, 1).normalise", "Vector4(1.div(2), 1.div(2), 1.div(2), 1.div(2))"),
TestCase("Vector4(2, 2, 4, 5).normalise", "Vector4(2.div(7), 2.div(7), 4.div(7), 5.div(7))"),
]
public void Normalize(string expression, string expected) =>
AssertApproxEqual(ValidatedCompilerInput, expected, expression);
Expand Down

0 comments on commit 63d4245

Please sign in to comment.