Oryginalny kod
public override Intersection GetIntersection(Ray a_ray) { float denom = Normal * a_ray.Dir; if (OneSide) { if (denom > 0) return Scene.NoIntersection; } if (a_ray.PrevHit == this) return Scene.NoIntersection; if (!denom.IsZero()) { float dist = ((Normal * a_ray.Start) - Distance) / (-denom); if (dist <= 0) return Scene.NoIntersection; else { bool backHit = (denom > 0); if (backHit && OneSide) return Scene.NoIntersection; else { return new Intersection() { SceneObject = this, SourceRay = a_ray, Dist = dist, Scene = Scene, BackHit = backHit, Pos = a_ray.HitPoint(dist) }; } } } else return Scene.NoIntersection; }Zmieniony kod:
public override Intersection GetIntersection(Ray a_ray) { Ray ray_local = a_ray.Transform(WorldToLocal); bool backHit = false; float dist; if (ray_local.PrevHit == this) { if (ray_local.PrevBackHit) { backHit = true; if (OneSide) return Scene.NoIntersection; else { float v = -(ray_local.Start * ray_local.Dir); float m2 = Radius * Radius - (ray_local.Start.SqrLen - v * v); dist = v + (float)Math.Sqrt(m2); } } else return Scene.NoIntersection; } else { float c2 = ray_local.Start.SqrLen; float r2 = Radius * Radius; if (c2 > r2) { float v = -(ray_local.Start * ray_local.Dir); if (v <= 0) return Scene.NoIntersection; else { float m2 = r2 - (c2 - v * v); if (m2 < 0) return Scene.NoIntersection; else dist = v - (float)Math.Sqrt(m2); } } else { backHit = true; if (OneSide) return Scene.NoIntersection; else { float v = -(ray_local.Start * ray_local.Dir); float m2 = r2 - (c2 - v * v); dist = v + (float)Math.Sqrt(m2); } } } var pos = ray_local.Start + ray_local.Dir * dist; pos = LocalToWorld * pos; dist = (pos - a_ray.Start).Length; return new Intersection() { SceneObject = this, SourceRay = a_ray, Dist = dist, Scene = Scene, BackHit = backHit, Pos = pos }; }Zmiany polegały na dodaniu transformacji promienia z współrzędnych świata do lokalnego na początku i policzeniu punktu uderzenia i dystansu w współrzędnych świata na końcu. Dodatkowo w układzie lokalnym płaszczyzna leży (w moim przypadku) w płaszczyźnie XZ, tak więc normalna do wersor Y, zaś dystans płaszczyzny do środka układu współrzędnych to 0. To pozwala nam trochę uprościć kod.
Brak komentarzy:
Prześlij komentarz