Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- DECLARE FUNCTION lerp! (a!, b!, t!)
- DEFINT A-Z
- '----------------------------------------
- ' Elevator Shaft Simulation!
- ' aka. How camera tilting works in a ray surfer
- '----------------------------------------
- ' Created by Dan McKinnon (dan@danmckinnon.net)
- '
- ' In a classic ray-casting algorithm you normally
- ' only cast vertical lines from the bottom of the
- ' screen to the top. When you attempt to tilt
- ' your camera (thus spreading out the rays) this
- ' produces an inaccurate sheering effect limiting
- ' the range of movement and distorting the view.
- '
- ' To overcome this limitation we switch to
- ' projecting non-vertical lines.
- '
- ' I've spread the rays for demonstration purposes:
- ' - Vertical lines = FORWARD
- ' - Converging lines = DOWN
- '
- ' Think of it like you're looking down a really
- ' long elevator shaft
- '
- '
- ' Enjoy
- ' Note: The range of angles is limited to 90
- ' degrees. If we wanted to overcome this we'd
- ' divide pitch angles into four 90 degree
- ' quadrants and swizzle the axes. It's
- ' important to note that once you tilt
- ' by 45 degrees it becomes more efficient
- ' to swizzle the algorithm so that down
- ' becomes forward, forward becomes up, etc.
- '
- '----------------------------------------
- 'Universal constants
- CONST TAU = 6.283183
- CONST PI = TAU / 2!
- CONST DegToRad = TAU / 360!
- 'Graphics mode constants
- CONST ScreenWidth = 320
- CONST ScreenHeight = 200
- 'Algorithm constants
- CONST HalfScreenHeight = ScreenHeight / 2
- CONST nadirX = ScreenWidth / 2
- CONST MinPitch = 0!
- CONST MaxPitch = TAU / 4
- '-------------------- Our Preferences --------------------
- CONST PitchStep = 5! * DegToRad
- CONST RaySpacingMax = 12
- CONST RaySpacingMin = 6
- '-------------------- vec2 --------------------
- 'Single Precision 2D Vector
- TYPE vec2
- x AS SINGLE
- y AS SINGLE
- END TYPE
- DIM pitch AS SINGLE
- pitch = 0!
- SCREEN 7, , 0, 1
- '-------------------- Main Loop --------------------
- DO
- 'Switch to draw back buffer
- SCREEN 7, , 1
- CLS
- '-------------------- Calculate --------------------
- 'nadir is perpendicular to the vanishing point
- sinValue! = SIN(pitch)
- 'Calculate the nadirY (use y! as a temporary single because nadirY is integer)
- s! = 1 / sinValue!
- y! = (HalfScreenHeight * s!)
- 'Interpolate the ray spacing
- raySpacing = CINT(lerp!(RaySpacingMin, RaySpacingMax, sinValue!))
- 'A hack for when we approach zero with our pitch, sometimes it
- 'seems QBASIC's line function hits more edge cases without this
- IF y! > 32767! THEN nadirY = 32767! ELSE nadirY = CINT(y!)
- 'Calculate the ray spacing for the vertical direction
- y! = raySpacing / sinValue!
- verticalStep = CINT(y!)
- 'Draw lines from the Nadir to the top of the screen (if necessary)
- IF nadirY > 0 THEN
- FOR x = 0 TO ScreenWidth - 1 STEP raySpacing
- LINE (nadirX, nadirY)-(x, 0), 12
- NEXT x
- END IF
- 'Draw lines from the Nadir to the bottom of the screen (if necessary)
- IF nadirY < ScreenHeight AND nadirY > 0 THEN
- FOR x = 0 TO ScreenWidth - 1 STEP raySpacing
- LINE (nadirX, nadirY)-(x, ScreenHeight - 1), 1
- NEXT x
- END IF
- 'Draw lines from the nadir to the left of the screen
- FOR y = 0 TO ScreenHeight - 1 STEP verticalStep
- LINE (nadirX, nadirY)-(0, y), 14
- NEXT y
- 'Draw lines from the nadir to the right of the screen
- FOR y = 0 TO ScreenHeight - 1 STEP verticalStep
- LINE (nadirX, nadirY)-(ScreenWidth - 1, y), 13
- NEXT y
- '-------------------- Handle Input --------------------
- DO
- k$ = INKEY$
- LOOP UNTIL k$ <> ""
- SELECT CASE k$
- CASE CHR$(0) + "H":
- IF pitch > MinPitch THEN pitch = pitch - PitchStep ELSE pitch = MinPitch
- CASE CHR$(0) + "P":
- IF pitch < MaxPitch THEN pitch = pitch + PitchStep ELSE pitch = MaxPitch
- END SELECT
- '-------------------- VSync --------------------
- WAIT &H3DA, 8
- SCREEN 7, , 0, 1
- LOOP UNTIL k$ = CHR$(27)
- FUNCTION lerp! (a!, b!, t!)
- lerp! = (b! - a!) * t! + a!
- END FUNCTION
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement