1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
--Bent Arc Particle
local parameters = self . parameters
local finalMagnitude = parameters [ "BentArcFinalMagnitude" ]
local velocity = parameters [ "BentArcVelocity" ]
local azimuthStartRadians = parameters [ "BentArcAzimuthStartRadians" ]
local elevationStartRadians = parameters [ "BentArcElevationStartRadians" ]
local azimuthChangeRadians = parameters [ "BentArcAzimuthChangeRadians" ]
local elevationChangeRadians = parameters [ "BentArcElevationChangeRadians" ]
local magnitude
if finalMagnitude then
local magnitudeProgress = progress
end
elseif velocity then
end
local bendProgress = progress
end
local azimuthRadians = zo_lerp ( azimuthStartRadians , azimuthStartRadians + azimuthChangeRadians , bendProgress )
local elevationRadians = zo_lerp ( elevationStartRadians , elevationStartRadians + elevationChangeRadians , bendProgress )
--Spherical coordinates to Cartesian
--X is right, Y is up, Z is toward the screen
return x , y , z
end
end
end
--Control particles expect that Y is down
y = - y
local parameters = self . parameters
if parameters [ "BentArcOrientWithMotion" ] then
--Numerical solution to orient along the spiral. We use the slope between the last two positions to compute the tangent to the spiral. The angle
--to orient the texture's right-middle point to the spiral is the 2*PI - the tangent's angle, or alternately minus the tangent's angle.
if self . lastX then
local offsetRadians = parameters [ "BentArcOrientWithMotionTextureRotationRadians" ] or 0
end
self . lastX = x
self . lastY = y
end
end
end
-- Physics Particle
end
local MAX_ACCELERATIONS = 5
local ACCELERATION_ELEVATION_RADIANS_PARAMETER_NAMES = { }
local ACCELERATION_MAGNITUDE_PARAMETER_NAMES = { }
for accelerationIndex = 1 , MAX_ACCELERATIONS do
table . insert ( ACCELERATION_ELEVATION_RADIANS_PARAMETER_NAMES , "PhysicsAccelerationElevationRadians" .. accelerationIndex )
table . insert ( ACCELERATION_MAGNITUDE_PARAMETER_NAMES , "PhysicsAccelerationMagnitude" .. accelerationIndex )
end
self . velocityX = 0
self . velocityY = 0
local parameters = self . parameters
local initialVelocityElevationRadians = parameters [ "PhysicsInitialVelocityElevationRadians" ]
if initialVelocityElevationRadians then
local initialVelocityMagnitude = parameters [ "PhysicsInitialVelocityMagnitude" ]
if initialVelocityMagnitude then
end
end
local combinedAccelerationX = 0
local combinedAccelerationY = 0
for accelerationIndex = 1 , MAX_ACCELERATIONS do
local accelerationElevationRadians = parameters [ ACCELERATION_ELEVATION_RADIANS_PARAMETER_NAMES [ accelerationIndex ] ]
if not accelerationElevationRadians then
break
end
local accelerationMagnitude = parameters [ ACCELERATION_MAGNITUDE_PARAMETER_NAMES [ accelerationIndex ] ]
if not accelerationMagnitude then
break
end
combinedAccelerationX = combinedAccelerationX + accelerationX
combinedAccelerationY = combinedAccelerationY + accelerationY
end
self . combinedAccelerationX = combinedAccelerationX
self . combinedAccelerationY = combinedAccelerationY
end
--Numerical can do complex calculations like drag, but it does so by doing calculations in intervals, since it's not a simple equation of time
end
do
local DEFAULT_MIN_STEPS_PER_SECOND = 30
local MAX_STEPS_FOR_UPDATE = 10
self . lastUpdateTimeS = self . startTimeS
self . displacementX = 0
self . displacementY = 0
local parameters = self . parameters
local minStepsPerSecond = parameters [ "PhysicsMinStepsPerSecond" ] or DEFAULT_MIN_STEPS_PER_SECOND
self . minStepIntervalS = 1 / minStepsPerSecond
self . maxTimeForMinStepIntervalsS = self . minStepIntervalS * MAX_STEPS_FOR_UPDATE
self . dragMultiplier = parameters [ "PhysicsDragMultiplier" ] or 0
end
local lastUpdateTimeS = self . lastUpdateTimeS
local timeSinceLastUpdateS = timeS - lastUpdateTimeS
local stepsIntervalS = self . minStepIntervalS
if timeSinceLastUpdateS < stepsIntervalS then
stepsIntervalS = timeSinceLastUpdateS
elseif timeSinceLastUpdateS > self . maxTimeForMinStepIntervalsS then
-- If we've hit a long spike since the last update, split the delta into equal intervals looping up to MAX_STEPS_FOR_UPDATE times to catch up
stepsIntervalS = timeSinceLastUpdateS / MAX_STEPS_FOR_UPDATE
end
local displacementX = self . displacementX
local displacementY = self . displacementY
local velocityX = self . velocityX
local velocityY = self . velocityY
local velocityChangePerStepX = self . combinedAccelerationX * stepsIntervalS
local velocityChangePerStepY = self . combinedAccelerationY * stepsIntervalS
local dragMultiplier = self . dragMultiplier
repeat
local dragVelocityChangeX = velocityX * dragMultiplier * stepsIntervalS
local dragVelocityChangeY = velocityY * dragMultiplier * stepsIntervalS
velocityX = velocityX + velocityChangePerStepX - dragVelocityChangeX
velocityY = velocityY + velocityChangePerStepY - dragVelocityChangeY
----------------------------------------------------------------------
displacementX = displacementX + ( velocityX * stepsIntervalS )
displacementY = displacementY + ( velocityY * stepsIntervalS )
lastUpdateTimeS = lastUpdateTimeS + stepsIntervalS
until ( lastUpdateTimeS + stepsIntervalS ) > timeS
self . lastUpdateTimeS = lastUpdateTimeS
self . displacementX = displacementX
self . displacementY = displacementY
self . velocityX = velocityX
self . velocityY = velocityY
--Control particles expect that Y is down
end
end
--Analytical calculates physics as a direct equation of elapsed time. Does not support complex functionality like drag
end
local elapsedTimeS = timeS - self . startTimeS
local velocityChangeX = self . combinedAccelerationX * elapsedTimeS
local velocityChangeY = self . combinedAccelerationY * elapsedTimeS
local x = ( self . velocityX + velocityChangeX ) * elapsedTimeS
local y = ( self . velocityY + velocityChangeY ) * elapsedTimeS
--Control particles expect that Y is down
end
--Stationary Paricle
end
-- Offset is handled in the base update, and SetPosition takes that into consideration
end
--Leaf Particle
--A leaf like motion to the right and down from the origin, based on following sections of a tangent curve. Specify the top and bottom (y-values) and the leaf will move through that
--section of the tangent curve. Descent is a factor on the tangent curve (0, infinity). Higher descents make a steeper curve, while lower descents mean a gentler curve. Fall height is the
--UI space height that the curve will be mapped to. The code that orients the leaf to the direction of travel assumes that the leaf point is a 0 degrees on the unit circle. If that is not true
--it can be corrected by rotating the leaf using LeafTextureRotationRadians.
end
--Inverse of y = -descent * tan(x)
end
local parameters = self . parameters
end
local parameters = self . parameters
end
local sectionTopY = parameters [ "LeafSectionTop" ]
local sectionBottomY = parameters [ "LeafSectionBottom" ]
local descent = parameters [ "LeafDescent" ]
local sectionHeight = sectionTopY - sectionBottomY
local fallHeight = parameters [ "LeafFallHeight" ]
local leafTextureRotationRadians = parameters [ "LeafTextureRotationRadians" ]
--We move linearly from 0 to fallHeight along the Y (This means that the more the curve travels in the X the faster it goes through that section. It is not constant velocity).
local offsetY = fallHeight * progress
--Figure out where we are vertically on the section of the tangent curve
--Find the X the corresponds to that Y
--Convert that to an offset from the starting X value
local sectionOffsetX = sectionX - self . sectionTopX
--Finally, scale this offset to UI coordinates using the correspondence between the section height and the fall height to determine the scaling factor
local offsetX = ( sectionOffsetX / sectionHeight ) * fallHeight
--The derivative of -descent * tan(x) is -descent/cos^2(x). Orient the texture 0 radian point to the direction of travel.
local slope = - descent / ( cosSectionX * cosSectionX )
local tumbleRadians = parameters [ "LeafTumbleRadians" ]
self . textureControl : SetTextureRotation ( math . atan ( slope ) + leafTextureRotationRadians + tumbleRadians * progress )
end
--Flow Particle
--Sends the particle through a series of "posts" that describe a set of vertical ranges. For example:
--
--
-- * * * * * *
-- * * * * * * * * * *
-- * * * * * * * **
-- * * * * *
--
--Particles will be assigned a normalized vertical offset and travel from post to post across where that normalized offset would lie.
--For example, if a particle was assigned 50% it would travel through the middle of each post, interpolating from middle to middle inbetween the posts.
end
end
local parameters = self . parameters
local areaTop = parameters [ "FlowAreaTop" ]
local areaBottom = parameters [ "FlowAreaBottom" ]
local areaLeft = parameters [ "FlowAreaLeft" ]
local areaRight = parameters [ "FlowAreaRight" ]
local normalizedPosts = parameters [ "FlowNormalizedPosts" ]
local numPosts = # normalizedPosts
local temp = progress * ( numPosts - 1 )
local progressBetweenPosts = temp % 1
local previousPost = normalizedPosts [ previousPostIndex ]
--the or handles the case where progress is exactly 1
local nextPost = normalizedPosts [ previousPostIndex + 1 ] or normalizedPosts [ numPosts ]
--index 1 holds the top of the post and index 2 holds the bottom of the post
end |