package NET.worlds.scape; public class BumpEventTemp extends Event { private static Recycler recycler = new Recycler(); public Point3Temp fullPath; public Point3Temp path; public BoundBoxTemp bound; public float fraction; public Room postBumpRoom; public Transform postBumpPosition; public Point3Temp postBumpPath; public Point3Temp sourceAt; public BoundBoxTemp sourceBoxMinus; public Point3Temp bumpNormal; public static BumpEventTemp make(int time, WObject mover, Point3Temp motion) { BumpEventTemp t = (BumpEventTemp)recycler.alloc(); if (t == null) { recycler.recycle(new BumpEventTemp(0, null)); t = (BumpEventTemp)recycler.alloc(); } assert t.source == null; t.time = time; t.source = mover; t.fullPath = Point3Temp.make(motion); t.path = t.fullPath; t.sourceAt = ((WObject)t.source).getWorldPosition(); t.sourceBoxMinus = ((WObject)t.source).getBoundBox(); t.sourceBoxMinus.lo.minus(t.sourceAt); t.sourceBoxMinus.hi.minus(t.sourceAt); t.setPathFraction(1.0F); Room r = mover.getRoom(); if (r.getBumpable()) { r.detectBump(t); } return t; } public void recycle() { this.time = 0; this.source = null; this.target = null; this.receiver = null; this.postBumpRoom = null; this.postBumpPath = null; this.postBumpPosition = null; } private BumpEventTemp(int time, Object source) { super(time, source, null); } public void setPathFraction(float fraction) { this.fraction = fraction; this.path = Point3Temp.make(this.path).times(fraction); this.bound = BoundBoxTemp.make(this.sourceAt, Point3Temp.make(this.sourceAt).plus(this.path)); this.bound.lo.plus(this.sourceBoxMinus.lo); this.bound.hi.plus(this.sourceBoxMinus.hi); } public float isCollision(Point3Temp left, Point3Temp d, Point3Temp start, Point3Temp motion) { double D = (double)motion.x * -d.y + (double)motion.y * d.x; if (D > 0.0) { Point3Temp C = Point3Temp.make(start).minus(left); double betaNum = (double)C.x * d.y - (double)C.y * d.x; double alphaNum = (double)C.x * motion.y - (double)motion.x * C.y; return alphaNum >= 0.0 && alphaNum <= D && betaNum >= 0.0 && betaNum <= D ? (float)(betaNum / D) : -2.0F; } else { return -1.0F; } } public float hitPlane(WObject o, Point3Temp left, Point3Temp d) { float dist = this.isCollision(left, d, this.sourceAt, this.path); if (dist >= 0.0F) { this.target = o; this.setPathFraction(dist); this.bumpNormal = Point3Temp.make(d.y, -d.x, 0.0F).normalize(); this.path.plus(Point3Temp.make(this.path).normalize().times(0.2F)); } return dist; } public boolean hitRegion(WObject o, Point3Temp left, Point3Temp d, Point3Temp extent) { float dist = this.hitPlane(o, left, d); if (dist >= 0.0F) { return true; } else if (dist == -1.0F) { return false; } else { Point3Temp right = Point3Temp.make(left).plus(d); Point3Temp minusD = Point3Temp.make().minus(d); Point3Temp minusExtent = Point3Temp.make().minus(extent); if (this.isCollision(right, minusD, this.sourceAt, minusExtent) > 0.0F) { this.target = o; this.setPathFraction(0.0F); this.bumpNormal = minusExtent; return true; } else { return false; } } } public boolean hitTriRegion(WObject o, Point3Temp left, Point3Temp d, Point3Temp extent) { float dist = this.hitPlane(o, left, d); if (dist >= 0.0F) { return true; } else if (dist == -1.0F) { return false; } else { Point3Temp right = Point3Temp.make(left).plus(d); Point3Temp minusD = Point3Temp.make().minus(d); Point3Temp minusExtent = Point3Temp.make().minus(extent); if (this.isCollision(right, minusD, this.sourceAt, minusExtent) > 0.0F) { float dx = this.sourceAt.x - (left.x + d.x / 2.0F); float dy = this.sourceAt.y - (left.y + d.y / 2.0F); float squaredDistFromMid = dx * dx + dy * dy; dx = this.sourceAt.x - (left.x + extent.x); dy = this.sourceAt.y - (left.y + extent.y); float squaredDistFromA = dx * dx + dy * dy; if (squaredDistFromA < squaredDistFromMid) { return false; } else { dx = this.sourceAt.x - (right.x + extent.x); dy = this.sourceAt.y - (right.y + extent.y); float squaredDistFromB = dx * dx + dy * dy; if (squaredDistFromB < squaredDistFromMid) { return false; } else { this.target = o; this.setPathFraction(0.0F); this.bumpNormal = minusExtent; return true; } } } else { return false; } } } @Override public boolean deliver(Object o) { return o instanceof BumpHandler ? ((BumpHandler)o).handle(this) : false; } }