/// <summary> /// Projects the ghost</summary> private void ProjectGhost(DomNode ghost, Ray3F rayw, HitRecord?hit) { ITransformable xformnode = ghost.Cast <ITransformable>(); IBoundable bnode = ghost.As <IBoundable>(); AABB box = bnode.BoundingBox; Vec3F pt; if (hit.HasValue && hit.Value.hasNormal) { Vec3F rad = box.Radius; Vec3F norm = hit.Value.normal; Vec3F absNorm = Vec3F.Abs(norm); Vec3F offset = Vec3F.ZeroVector; if (absNorm.X > absNorm.Y) { if (absNorm.X > absNorm.Z) { offset.X = norm.X > 0 ? rad.X : -rad.X; } else { offset.Z = norm.Z > 0 ? rad.Z : -rad.Z; } } else { if (absNorm.Y > absNorm.Z) { offset.Y = norm.Y > 0 ? rad.Y : -rad.Y; } else { offset.Z = norm.Z > 0 ? rad.Z : -rad.Z; } } Vec3F localCenter = box.Center - xformnode.Translation; pt = hit.Value.hitPt + (offset - localCenter); } else { float offset = 6.0f * box.Radius.Length; pt = rayw.Origin + offset * rayw.Direction; } if (ViewType == ViewTypes.Front) { pt.Z = 0.0f; } else if (ViewType == ViewTypes.Top) { pt.Y = 0.0f; } else if (ViewType == ViewTypes.Left) { pt.X = 0.0f; } xformnode.Translation = pt; }