@@ -37,6 +37,80 @@ static class SkyConstants
3737 public const short skyLevels = 6 ;
3838 }
3939
40+ public class SkySteps
41+ {
42+ // Size of the sun- and moon-position lookup table arrays.
43+ // Must be an integral divisor of 1440 (which is the number of minutes in a day).
44+ public int MaxSteps = 72 ;
45+ public double OldClockTime ;
46+ public int Step1 , Step2 ;
47+
48+ /// <summary>
49+ /// Returns the advance of time in units of 20 mins (1200 seconds).
50+ /// Allows for an offset in hours from a control in the DispatchViewer.
51+ /// This is a user convenience to reveal in daylight what might be hard to see at night.
52+ /// </summary>
53+ /// <returns></returns>
54+ private float CelestialDiff ( double clockTime )
55+ {
56+ var diffS = clockTime - ( OldClockTime - DaylightOffsetS ) ;
57+ return ( float ) diffS / 1200 ;
58+ }
59+
60+ private float DaylightOffsetS
61+ {
62+ get
63+ {
64+ return ( Program . DebugViewer == null ) ? 0f : ( float ) Program . DebugViewer . DaylightOffsetHrs * 60 * 60 ;
65+ }
66+ }
67+
68+ public void SetSunAndMoonDirection ( ref Vector3 solarDirection , ref Vector3 lunarDirection
69+ , ref Vector3 [ ] solarPosArray , ref Vector3 [ ] lunarPosArray
70+ , double clockTime )
71+ {
72+ // Current solar and lunar position are calculated by interpolation in the lookup arrays.
73+ // The arrays have intervals of 1200 secs or 20 mins.
74+ // Using the Lerp() function, so need to calculate the in-between differential
75+ // The rest of this increments/decrements the array indices and checks for overshoot/undershoot.
76+ while ( clockTime >= ( OldClockTime - DaylightOffsetS + 1200 ) ) // Plus key, or normal forward in time; <CSComment> better so in case of fast forward
77+ {
78+ OldClockTime = OldClockTime + 1200 ;
79+ Step1 ++ ;
80+ Step2 ++ ;
81+ if ( Step2 >= MaxSteps ) // Midnight.
82+ {
83+ Step2 = 0 ;
84+ }
85+ if ( Step1 >= MaxSteps ) // Midnight.
86+ {
87+ Step1 = 0 ;
88+ }
89+ }
90+ if ( clockTime <= ( OldClockTime - DaylightOffsetS ) ) // Minus key
91+ {
92+ OldClockTime = OldClockTime - 1200 ;
93+ Step1 -- ;
94+ Step2 -- ;
95+ if ( Step1 < 0 ) // Midnight.
96+ {
97+ Step1 = MaxSteps - 1 ;
98+ }
99+ if ( Step2 < 0 ) // Midnight.
100+ {
101+ Step2 = MaxSteps - 1 ;
102+ }
103+ }
104+ var diff = CelestialDiff ( clockTime ) ;
105+ solarDirection . X = MathHelper . Lerp ( solarPosArray [ Step1 ] . X , solarPosArray [ Step2 ] . X , diff ) ;
106+ solarDirection . Y = MathHelper . Lerp ( solarPosArray [ Step1 ] . Y , solarPosArray [ Step2 ] . Y , diff ) ;
107+ solarDirection . Z = MathHelper . Lerp ( solarPosArray [ Step1 ] . Z , solarPosArray [ Step2 ] . Z , diff ) ;
108+ lunarDirection . X = MathHelper . Lerp ( lunarPosArray [ Step1 ] . X , lunarPosArray [ Step2 ] . X , diff ) ;
109+ lunarDirection . Y = MathHelper . Lerp ( lunarPosArray [ Step1 ] . Y , lunarPosArray [ Step2 ] . Y , diff ) ;
110+ lunarDirection . Z = MathHelper . Lerp ( lunarPosArray [ Step1 ] . Z , lunarPosArray [ Step2 ] . Z , diff ) ;
111+ }
112+ }
113+
40114 public class SkyViewer
41115 {
42116 Viewer Viewer ;
@@ -62,11 +136,9 @@ public struct Date
62136 public int ordinalDate ;
63137 } ;
64138 public Date date ;
65- // Size of the sun- and moon-position lookup table arrays.
66- // Must be an integral divisor of 1440 (which is the number of minutes in a day).
67- private int maxSteps = 72 ;
68- private double oldClockTime ;
69- int step1 , step2 ;
139+
140+ private SkySteps skySteps = new SkySteps ( ) ;
141+
70142 // Phase of the moon
71143 public int moonPhase ;
72144 // Wind speed and direction
@@ -105,10 +177,10 @@ public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
105177 {
106178 // First time around, initialize the following items:
107179 worldLoc = new WorldLatLon ( ) ;
108- oldClockTime = Viewer . Simulator . ClockTime % 86400 ;
109- while ( oldClockTime < 0 ) oldClockTime += 86400 ;
110- step1 = step2 = ( int ) ( oldClockTime / 1200 ) ;
111- step2 = step2 < maxSteps - 1 ? step2 + 1 : 0 ; // limit to max. steps in case activity starts near midnight
180+ skySteps . OldClockTime = Viewer . Simulator . ClockTime % 86400 ;
181+ while ( skySteps . OldClockTime < 0 ) skySteps . OldClockTime += 86400 ;
182+ skySteps . Step1 = skySteps . Step2 = ( int ) ( skySteps . OldClockTime / 1200 ) ;
183+ skySteps . Step2 = skySteps . Step2 < skySteps . MaxSteps - 1 ? skySteps . Step2 + 1 : 0 ; // limit to max. steps in case activity starts near midnight
112184
113185 // Get the current latitude and longitude coordinates
114186 worldLoc . ConvertWTC ( Viewer . Camera . TileX , Viewer . Camera . TileZ , Viewer . Camera . Location , ref latitude , ref longitude ) ;
@@ -122,76 +194,23 @@ public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
122194 date . year = 2017 ;
123195 }
124196 // Fill in the sun- and moon-position lookup tables
125- for ( int i = 0 ; i < maxSteps ; i ++ )
197+ for ( int i = 0 ; i < skySteps . MaxSteps ; i ++ )
126198 {
127- solarPosArray [ i ] = SunMoonPos . SolarAngle ( latitude , longitude , ( ( float ) i / maxSteps ) , date ) ;
128- lunarPosArray [ i ] = SunMoonPos . LunarAngle ( latitude , longitude , ( ( float ) i / maxSteps ) , date ) ;
199+ solarPosArray [ i ] = SunMoonPos . SolarAngle ( latitude , longitude , ( ( float ) i / skySteps . MaxSteps ) , date ) ;
200+ lunarPosArray [ i ] = SunMoonPos . LunarAngle ( latitude , longitude , ( ( float ) i / skySteps . MaxSteps ) , date ) ;
129201 }
130202 // Phase of the moon is generated at random
131203 moonPhase = Viewer . Random . Next ( 8 ) ;
132204 if ( moonPhase == 6 && date . ordinalDate > 45 && date . ordinalDate < 330 )
133205 moonPhase = 3 ; // Moon dog only occurs in winter
134206 }
135207
136-
137- // Current solar and lunar position are calculated by interpolation in the lookup arrays.
138- // The arrays have intervals of 1200 secs or 20 mins.
139- // Using the Lerp() function, so need to calculate the in-between differential
140- float diff = GetCelestialDiff ( ) ;
141- // The rest of this increments/decrements the array indices and checks for overshoot/undershoot.
142- while ( Viewer . Simulator . ClockTime >= ( oldClockTime + 1200 ) ) // Plus key, or normal forward in time; <CSComment> better so in case of fast forward
143- {
144- oldClockTime = oldClockTime + 1200 ;
145- diff = GetCelestialDiff ( ) ;
146- step1 ++ ;
147- step2 ++ ;
148- if ( step2 >= maxSteps ) // Midnight.
149- {
150- step2 = 0 ;
151- }
152- if ( step1 >= maxSteps ) // Midnight.
153- {
154- step1 = 0 ;
155- }
156- }
157- if ( Viewer . Simulator . ClockTime <= ( oldClockTime - 1200 ) ) // Minus key
158- {
159- oldClockTime = Viewer . Simulator . ClockTime ;
160- diff = 0 ;
161- step1 -- ;
162- step2 -- ;
163- if ( step1 < 0 ) // Midnight.
164- {
165- step1 = maxSteps - 1 ;
166- }
167- if ( step2 < 0 ) // Midnight.
168- {
169- step2 = maxSteps - 1 ;
170- }
171- }
172- solarDirection . X = MathHelper . Lerp ( solarPosArray [ step1 ] . X , solarPosArray [ step2 ] . X , diff ) ;
173- solarDirection . Y = MathHelper . Lerp ( solarPosArray [ step1 ] . Y , solarPosArray [ step2 ] . Y , diff ) ;
174- solarDirection . Z = MathHelper . Lerp ( solarPosArray [ step1 ] . Z , solarPosArray [ step2 ] . Z , diff ) ;
175- lunarDirection . X = MathHelper . Lerp ( lunarPosArray [ step1 ] . X , lunarPosArray [ step2 ] . X , diff ) ;
176- lunarDirection . Y = MathHelper . Lerp ( lunarPosArray [ step1 ] . Y , lunarPosArray [ step2 ] . Y , diff ) ;
177- lunarDirection . Z = MathHelper . Lerp ( lunarPosArray [ step1 ] . Z , lunarPosArray [ step2 ] . Z , diff ) ;
208+ skySteps . SetSunAndMoonDirection ( ref solarDirection , ref lunarDirection , ref solarPosArray , ref lunarPosArray ,
209+ Viewer . Simulator . ClockTime ) ;
178210
179211 frame . AddPrimitive ( Material , Primitive , RenderPrimitiveGroup . Sky , ref XNASkyWorldLocation ) ;
180212 }
181213
182- /// <summary>
183- /// Returns the advance of time in seconds in units of 20 mins (1200 seconds).
184- /// Allows for an offset in hours from a control in the DispatchViewer.
185- /// This is a user convenience to reveal in daylight what might be hard to see at night.
186- /// </summary>
187- /// <returns></returns>
188- private float GetCelestialDiff ( )
189- {
190- var diffS = ( Viewer . Simulator . ClockTime - oldClockTime ) ;
191- diffS += ( double ) ( Program . DebugViewer ? . DaylightOffsetHrs ?? 0 ) * 60 * 60 ;
192- return ( float ) diffS / 1200 ;
193- }
194-
195214 public void LoadPrep ( )
196215 {
197216 worldLoc = new WorldLatLon ( ) ;
0 commit comments