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