/** lineRotation: Which way is the line pointing right now? */ private void AddLineRecursively(Vector2 _pos, float _rot) { Vector2 offset = MathUtils.GetVectorFromDeg(_rot) * 1f; // actually OFFSET it a little bit FORWARD! So I can reflect off a mirror without being unable to escape it. BeamRendererCollision coll = colliderArena.GetBeamRendererCollision(_pos + offset, _rot); // Add this line! lines[numLines] = new Line(_pos, coll.pos); numLines++; // Safety check: If we're somehow out of lines, we can stop here. :) if (numLines >= lines.Length) { return; } // How does this collision end?? switch (coll.collType) { case BeamRendererCollision.Types.End: // We've hit a regular wall? Stop adding! return; //case BeamRendererCollision.Types.Reflect: // Oh, a reflection off a Mirror? Add another point! //AddPointRecursively (collision.exitRotation); //return; case BeamRendererCollision.Types.WarpFlipH: // Warp? Add another line! case BeamRendererCollision.Types.WarpFlipV: AddWarpLineRecursively(coll); return; } }
/// Gets the necessary info for adding a new line via a warp, adds it, and keeps looking. private void AddWarpLineRecursively(BeamRendererCollision coll) { float angleIn = coll.angleIn; Vector2 posIn = coll.pos; float loc = LineUtils.PosToLoc(coll.collLine.line, posIn); // Translate pos/rot in to pos/rot out. float angleOut; switch (coll.collLine.collType) { case BeamRendererCollision.Types.WarpFlipH: angleOut = MathUtils.FlipDegHorz(angleIn); break; case BeamRendererCollision.Types.WarpFlipV: angleOut = MathUtils.FlipDegVert(angleIn); break; default: angleOut = angleIn; break; } Line lineOut = coll.collLine.lineOut; Vector2 posOut = lineOut.LocToPos(loc); AddLineRecursively(posOut, angleOut); }
// ---------------------------------------------------------------- // Getters // ---------------------------------------------------------------- /** beamAngle: in DEGREES. */ public BeamRendererCollision GetBeamRendererCollision(Vector2 beamPos, float beamAngle) { // Make a huge-ass line! Note: I'm doing line-line collision instead of ray-line collision because there's less code and it's easier to understand. Line beamLine = new Line(beamPos, beamPos + MathUtils.GetVectorFromDeg(beamAngle) * 100000); // Get the CLOSEST line-on-line collision! BeamRendererCollision closestColl = new BeamRendererCollision(null, beamLine.end, beamAngle); // default this to the farthest theoretical collision possible. float closestDist = float.PositiveInfinity; Vector2 intPos; foreach (BeamRendererColliderLine collLine in allColliderLines) { bool isIntersection = LineUtils.GetIntersectionLineToLine(out intPos, beamLine, collLine.line); if (isIntersection) // There IS an intersection! { float intDist = Vector2.Distance(intPos, beamLine.start); if (closestDist > intDist) // It's the closest one yet! Update the values I'm gonna return! { closestDist = intDist; closestColl.pos = intPos; closestColl.SetCollLine(collLine); closestColl.angleIn = beamAngle; //float lineAngle = collLine.line.GetAngleDeg(); //closestColl.exitRotation = MathUtils.GetAngleReflection (beamAngle, lineAngle); // Debug.Log ("lineAngle: " + lineAngle + " pos: " + intPos + " closestCollisionDist: " + closestCollisionDist); // Debug.Log ("beamAngle: " + beamAngle + " lineAngle: " + lineAngle + " exitRotation: " + closestCollision.exitRotation); } } } return(closestColl); // // Oh, jeez. SOMEhow we didn't intersect with anything, not even my outer bounds!! This is an error. Just return a made-up intersection at the end of the fake line we used. // Debug.LogWarning ("Oops! A BeamRenderer didn't have a collision with ANYthing! It should at least be hitting the Arena's bounds."); // return new BeamRendererCollision(false, beamAngle, beamLine.end); }