public override bool getGuidance(Vector3D pos, ref Vector3D guide, ref float weight, float height) { if (!base.getGuidance(pos, ref guide, ref weight, height)) { return(false); } // size: 5x2x1, meaning 12.5 x 5 x 2.5 // approximated by y = -(x+6.25)^2*0.008, see http://tinyurl.com/gnm5akr // for X flip, see below var localCoords = Vector3D.Transform(pos, this.cubeBlock.WorldMatrixNormalizedInv); localCoords.X = -localCoords.X; // just mirror, todo redo the equation if (localCoords.Z < -1.25 || localCoords.Z > 1.25) { return(false); } localCoords.Y -= height; // guide height above rail -- so we track the actual slope // closest point to a poly is not entirely trivial and I cba solving it manually, so resort to the laziest approach possible: BINARY SEARCH. double x = 0.0; bool success = MinSearch.find_smallest(ref x, xpar => distance(localCoords.X, localCoords.Y, xpar), localCoords.X, -6.25, 6.25, 10); // MyLog.Default.WriteLine(String.Format("success {0} finding x {1} which has guidefn {2} at {3}", success, x, guidefn(x), localCoords)); if (!success) { return(false); } var localGuidepoint = new Vector3D(-x, guidefn(x) + height, 0); var worldGuidepoint = Vector3D.Transform(localGuidepoint, this.cubeBlock.WorldMatrix); guide += worldGuidepoint; weight += 1; return(true); }
public override bool getGuidance(Vector3D pos, ref Vector3D guide, ref float weight, float height) { if (!base.getGuidance(pos, ref guide, ref weight, height)) { return(false); } // size: 5x1x1, meaning 12.5 x 2.5 x 2.5 // approximated by y = (x+6.25)^2*0.008-2.5, see http://tinyurl.com/j9q6fc4 // except with flipped x because whyy var localCoords = Vector3D.Transform(pos, this.cubeBlock.WorldMatrixNormalizedInv); localCoords.X = -localCoords.X; // just mirror, todo redo the equation if (localCoords.Z < -1.25 || localCoords.Z > 1.25) { return(false); } // "rail coords" localCoords.Y -= height; // see above double x = 0.0; bool success = MinSearch.find_smallest(ref x, xpar => distance(localCoords.X, localCoords.Y, xpar), localCoords.X, -6.25, 6.25, 10); if (!success) { return(false); } var localGuidepoint = new Vector3D(-x, railfn(x) + height, 0); var worldGuidepoint = Vector3D.Transform(localGuidepoint, this.cubeBlock.WorldMatrix); guide += worldGuidepoint; weight += 1; return(true); }