The refactoring is done. It should now be more robust and I can start adding matrix support.
Expressions like (v2 - v1) dot v3 are not fully supported yet. They may actually become worse ATM, but I'm planning to add support for creating anonymous vectors for expressions that are used multiple times. Here are some examples:
Code:
// Original
val v: org.villane.vecmath.Vector2 = v1.-(v2).×(-2.0);
// Optimized
val v$x: Float = v1.y.-(v2.y).*(-2.0);
val v$y: Float = v1.x.-(v2.x).*(-2.0.unary_-); // -(-2) should be optimized later anyway before bytecode generation
// Original
var vd = Preamble.floatToFloatExtensions(v2.-(v1).dot(v3)).*(new Vector2(1.0, 3.0));
var vx = Preamble.floatToFloatExtensions(v2.-(v1).cross(v3)).*(new Vector2(1.0, 3.0));
vx.-(vd)
// "Optimized" (actually at least v2 - v1 should be cached!!!)
var vd$x: Float = v2.x.-(v1.x).*(v3.x).+(v2.y.-(v1.y).*(v3.y)).*(1.0);
var vd$y: Float = v2.x.-(v1.x).*(v3.x).+(v2.y.-(v1.y).*(v3.y)).*(3.0);
var vx$x: Float = v2.x.-(v1.x).*(v3.y).-(v2.y.-(v1.y).*(v3.x)).*(1.0);
var vx$y: Float = v2.x.-(v1.x).*(v3.y).-(v2.y.-(v1.y).*(v3.x)).*(3.0);
new org.villane.vecmath.Vector2(vx$x.-(vd$x), vx$y.-(vd$y))
The previous example had an error I missed (normalize call was not transformed), but now it works (even expanding the If-Then expression into a block as needed when a temporary variable is added):
Code:
--- ORIGINAL SOURCE ---
@org.villane.vecmath.optimizer.sr def testSegment(segment: org.villane.box2d.shapes.Segment, maxLambda: Float): org.villane.box2d.shapes.SegmentCollide = {
val s: org.villane.vecmath.Vector2 = segment.p1;
val r: org.villane.vecmath.Vector2 = segment.p2.-(s);
val d: org.villane.vecmath.Vector2 = Segment.this.p2.-(Segment.this.p1);
val n: org.villane.vecmath.Vector2 = d.cross(1.0);
val slop: Float = 100.0.*(Settings.Epsilon);
val denom: Float = r.dot(n).unary_-;
if (denom.>(slop))
{
val b: org.villane.vecmath.Vector2 = s.-(Segment.this.p1);
val a: Float = b.dot(n);
if (0.0.<=(a).&&(a.<=(maxLambda.*(denom))))
{
val mu2: Float = b.cross(r);
if (slop.unary_-.*(denom).<=(mu2).&&(mu2.<=(denom.*(1.0.+(slop)))))
return SegmentCollide.hit(a./(denom), n.normalize)
}
};
SegmentCollide.Miss
}
--- OPTIMIZED SOURCE ---
@org.villane.vecmath.optimizer.sr def testSegment(segment: org.villane.box2d.shapes.Segment, maxLambda: Float): org.villane.box2d.shapes.SegmentCollide = {
val s$x: Float = segment.p1.x;
val s$y: Float = segment.p1.y;
val r$x: Float = segment.p2.x.-(s$x);
val r$y: Float = segment.p2.y.-(s$y);
val d$x: Float = Segment.this.p2.x.-(Segment.this.p1.x);
val d$y: Float = Segment.this.p2.y.-(Segment.this.p1.y);
val n$x: Float = d$y.*(1.0);
val n$y: Float = d$x.*(1.0.unary_-);
val slop: Float = 100.0.*(Settings.Epsilon);
val denom: Float = r$x.*(n$x).+(r$y.*(n$y)).unary_-;
if (denom.>(slop))
{
val b$x: Float = s$x.-(Segment.this.p1.x);
val b$y: Float = s$y.-(Segment.this.p1.y);
val a: Float = b$x.*(n$x).+(b$y.*(n$y));
if (0.0.<=(a).&&(a.<=(maxLambda.*(denom))))
{
val mu2: Float = b$x.*(r$y).-(b$y.*(r$x));
if (slop.unary_-.*(denom).<=(mu2).&&(mu2.<=(denom.*(1.0.+(slop)))))
{
val n$length: Float = Preamble.sqrt(n$x.*(n$x).+(n$y.*(n$y)));
return SegmentCollide.hit(a./(denom), new org.villane.vecmath.Vector2(n$x./(n$length), n$y./(n$length)))
}
}
};
SegmentCollide.Miss
}