<> <> <> <> <> DIRECTORY CastRays, CSG, IO, SV3d, SVFancyRays, SVModelTypes, SVRayTypes; SVFancyRaysImpl: PROGRAM IMPORTS CastRays, CSG, IO EXPORTS SVFancyRays = BEGIN CSGTree: TYPE = SVRayTypes.CSGTree; LightSource: TYPE = SVModelTypes.LightSource; LightSourceList: TYPE = SVModelTypes.LightSourceList; Point3d: TYPE = SV3d.Point3d; Ray: TYPE = SVRayTypes.Ray; Vector: TYPE = SV3d.Vector; VisibleLights: PUBLIC PROC [allLights: LightSourceList, surfacePoint: Point3d, tree: CSGTree, useBoundSpheres: BOOL, makeStream: BOOL _ FALSE, f: IO.STREAM _ NIL, indent: NAT _ 0] RETURNS [visibleLights: LightSourceList] = { surfaceToLightRay: Ray; lightsource: LightSource; ambient: LightSource; hits: BOOL; t: REAL; IF makeStream THEN f.PutF["\nFinding Visible Lights...\n\n"]; surfaceToLightRay _ CSG.GetRayFromPool[]; visibleLights _ NIL; IF allLights.first.type # ambient THEN ERROR; ambient _ allLights.first; -- CONS on last, so it will be first. FOR l: LightSourceList _ allLights.rest, l.rest UNTIL l = NIL DO lightsource _ l.first; CSG.StuffWorldRayFromPoints[surfaceToLightRay, surfacePoint, lightsource.position]; [hits, t] _ CastRays.FirstHit[surfaceToLightRay, tree, useBoundSpheres, makeStream, f, indent]; IF hits THEN { IF t >=1 THEN visibleLights _ CONS[lightsource, visibleLights] <> } ELSE visibleLights _ CONS[lightsource, visibleLights]; ENDLOOP; CSG.ReturnRayToPool[surfaceToLightRay]; visibleLights _ CONS[ambient, visibleLights]; <> }; END. <> <> <<>> <<>> <<>> <<>>