Post by Rod on Feb 13, 2023 7:47:39 GMT -5
Pulled this out the drawer and made a few improvements. Not sure it is fast enough to spend any more time on but it is pretty cool. It takes a 256 color bmp and uses that as a 2d map of height. Dark is low white is high. I then set up a camera that can move and cast a few rays about the bmp mapping the view to screen and plotting the height. The color fades as the distance to the height increases. Net result, almost a 3d undersea view.
You will need to copy this bmp to the .bas folder and name it bump.bmp
If thats all too much, here is a static frame, it looks alot cooler moving.
You will need to copy this bmp to the .bas folder and name it bump.bmp
nomainwin
'open full screen graphics
open "3D Height Mapping" for graphics_fs as #1
#1 "trapclose [quit]"
#1 "down"
'divide the screen into 800x320 blocks
w=(DisplayWidth/800)
h=(DisplayHeight/320)
'set our initial camera position
eyeX=150
eyeZ=150
eyeA=90
fov=30
eyeL=eyeA-fov
eyeR=eyeA+fov
'get our height map
dim hmap(320,320)
open "bump1.bmp" for binary as #bmp
x=1
y=1
seek #bmp,1078
for y=320 to 1 step -1
for x= 1 to 320
n$ = INPUT$(#bmp, 1)
hmap(x,y)=asc(n$)
next
next
close #bmp
'set up our events
#1 "when characterInput [keyboardinterrupt]"
#1 "setfocus"
[drawit]
'for every angle/block in the X field of view
for scrx=0 to 800 step 10
a=eyeL+60/800*scrx
'Calculate Sine and Cosine of angle only once thanks for the tip Andya
aRad = a * 0.01745329251994329576923690768489
sinA = Sin(aRad)
cosA = Cos(aRad)
ly=0
'cast a ray in the z distance
for z=0 to 100 step 5
'calculate viewing vector using Andya's sin/cos
sX=eyeX+(z*sinA)
sZ=eyeZ+(z*cosA)
'step through the viewing line rolling round the bmp if required
vX=sX
vZ=sZ
if sX<0 then vX=sX+320
if sX>320 then vX=sX-320
if sZ<0 then vZ=sZ+320
if sZ>320 then vZ=sZ-320
'get the height for that point on the bmp
y = hmap(int(vX),int(vZ))
'reduce the height by distance close = low so starting point is always low ie we are at that height
y = y - (100-z)
'only draw new higher blocks
if y >=ly then
#1 "color 0 0 ";255-z*2;" ; backcolor 0 0 ";255-z*2
#1 "place ";scrx*w;" ";DisplayHeight-ly*h;" ; boxfilled ";(scrx+10)*w;" ";DisplayHeight-y*h
ly=y
end if
next
'fill in the remainder
#1 "discard ; color 0 0 20 ; backcolor 0 0 20"
#1 "place ";scrx*w;" ";DisplayHeight-ly*h;" ; boxfilled ";(scrx+10)*w;" ";0
next
'rem out this block to restore keyboard input
eyeX=eyeX+(5*sin(eyeA/57.29577951))
eyeZ=eyeZ+(5*cos(eyeA/57.29577951))
if eyeX>320 then eyeX=eyeX-320
if eyeZ<0 then eyeZ=eyeZ+320
if eyeX<0 then eyeX=eyeX+320
if eyeZ>320 then eyeZ=eyeZ-320
scan
goto [drawit]
'********************************************
#1 "when characterInput [keyboardinterrupt]"
#1 "setfocus"
wait
[keyboardinterrupt]
'this loop gets called every time a key is pressed
#1 "when characterInput "
k=asc(right$(Inkey$,1))
if k=37 then eyeA=eyeA-1 'left
if eyeA<0 then eyeA=eyeA+360
if k=38 then 'up
eyeX=eyeX+(5*sin(eyeA/57.29577951))
eyeZ=eyeZ+(5*cos(eyeA/57.29577951))
end if
if k=39 then eyeA=eyeA+1 'right
if eyeA>360 then eyeA=eyeA-360
if k=40 then 'down
eyeX=eyeX-(5*sin(eyeA/57.29577951))
eyeZ=eyeZ-(5*cos(eyeA/57.29577951))
end if
'roll round 320x320 map
if eyeX>320 then eyeX=eyeX-320
if eyeZ<0 then eyeZ=eyeZ+320
if eyeX<0 then eyeX=eyeX+320
if eyeZ>320 then eyeZ=eyeZ-320
eyeL=eyeA-fov
eyeR=eyeA+fov
goto [drawit]
[quit]
close #1
end
If thats all too much, here is a static frame, it looks alot cooler moving.