<> <> <> <> <> DIRECTORY AtomButtonsTypes, SVCastRays, SVRay, Feedback, SV3d, SVFancyRays, SVModelTypes, SVRayTypes; SVFancyRaysImpl: CEDAR PROGRAM IMPORTS SVCastRays, SVRay, Feedback EXPORTS SVFancyRays = BEGIN CSGTree: TYPE = SVRayTypes.CSGTree; FeedbackData: TYPE = AtomButtonsTypes.FeedbackData; LightSource: TYPE = SVModelTypes.LightSource; LightSourceList: TYPE = SVModelTypes.LightSourceList; Point3d: TYPE = SV3d.Point3d; Ray: TYPE = SVRayTypes.Ray; Vector3d: TYPE = SV3d.Vector3d; VisibleLights: PUBLIC PROC [allLights: LightSourceList, surfacePoint: Point3d, tree: CSGTree, useBoundSpheres: BOOL, feedback: FeedbackData, makeStream: BOOL _ FALSE, indent: NAT _ 0] RETURNS [visibleLights: LightSourceList] = { surfaceToLightRay: Ray; lightsource: LightSource; ambient: LightSource; hits: BOOL; t: REAL; IF makeStream THEN Feedback.PutFTypescript[feedback, oneLiner, "\nFinding Visible Lights...\n\n"]; surfaceToLightRay _ SVRay.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; SVRay.StuffWorldRayFromPoints[surfaceToLightRay, surfacePoint, lightsource.position]; [hits, t] _ SVCastRays.FirstHit[surfaceToLightRay, tree, useBoundSpheres, feedback, makeStream, indent]; IF hits THEN { IF t >=1 THEN visibleLights _ CONS[lightsource, visibleLights] <> } ELSE visibleLights _ CONS[lightsource, visibleLights]; ENDLOOP; IF makeStream THEN { lightCount: NAT _ CountLights[visibleLights]; Feedback.PutF[feedback, oneLiner, "\n%g Visible Lights found.\n\n", [integer[lightCount]]]; }; SVRay.ReturnRayToPool[surfaceToLightRay]; visibleLights _ CONS[ambient, visibleLights]; <> }; CountLights: PROC [lights: LightSourceList] RETURNS [count: NAT] = { count _ 0; FOR list: LightSourceList _ lights, list.rest UNTIL list = NIL DO count _ count + 1; ENDLOOP; }; END. <> <> <<>> <<>> <<>> <<>>