|
| 1 | +/* globals cpcBasic */ |
| 2 | + |
| 3 | +"use strict"; |
| 4 | + |
| 5 | +cpcBasic.addItem("", ` |
| 6 | +REM raytrac - Raytracing |
| 7 | +rem |
| 8 | +rem https://cpcwiki.de/forum/index.php/topic,1006.0.html |
| 9 | +rem |
| 10 | +' Screen init |
| 11 | +'SCREEN 8,0:SET PAGE 1,1 |
| 12 | +MODE 0: FOR k=0 TO 15:INK k,round(k*1.7):NEXT:INK 1,26:INK 15,1 |
| 13 | +'CLS |
| 14 | +'_TURBO ON |
| 15 | +' Initialize |
| 16 | +DIM T(9),V(15),O(19,7),S(19,7),RI(3),GI(3),BI(3),Z(3),Y(3) |
| 17 | +FOR I=0 TO 9:READ T(I):NEXT I |
| 18 | +V(0)=T(0):V(1)=T(1):V(2)=T(2) |
| 19 | +V(9)=T(0)-T(3):V(10)=T(1)-T(4):V(11)=T(2)-T(5) |
| 20 | +V1=SQR(V(9)*V(9)+V(10)*V(10)+V(11)*V(11)) |
| 21 | +V(9)=V(9)/V1:V(10)=V(10)/V1:V(11)=V(11)/V1 |
| 22 | +V(6)=-V(9)*V(10):V(7)=1-V(10)*V(10):V(8)=-V(11)*V(10) |
| 23 | +V(3)=-(V(10)*V(8)-V(11)*V(7)):V(4)=-(V(11)*V(6)-V(9)*V(8)) |
| 24 | +V(5)=-(V(9)*V(7)-V(10)*V(6)):V(15)=T(9) |
| 25 | +V(12)=T(6):V(13)=T(7):V(14)=T(8) |
| 26 | +READ MO:FOR I=0 TO MO-1:FOR J=0 TO 7:READ O(I,J):NEXT J:NEXT I |
| 27 | +READ MS:FOR I=0 TO MS-1:FOR J=0 TO 7:READ S(I,J):NEXT J:NEXT I |
| 28 | +MA=1000:MI=0.001:MD=0:PT=4 |
| 29 | +FOR I=1 TO 4 |
| 30 | +V1=SQR(V(I*3+0)*V(I*3+0)+V(I*3+1)*V(I*3+1)+V(I*3+2)*V(I*3+2)) |
| 31 | +V(I*3+0)=V(I*3+0)/V1:V(I*3+1)=V(I*3+1)/V1:V(I*3+2)=V(I*3+2)/V1 |
| 32 | +NEXT I |
| 33 | +' Trace |
| 34 | +FOR SY=0 TO 200 STEP 4:FOR SX=0 TO 320 STEP 4:XD=0:YD=0 |
| 35 | +while yd<4 |
| 36 | +CX=V(0):CY=V(1):CZ=V(2) |
| 37 | +VX=V(3)*(SX+XD-128)/99+V(6)*(106-SY-YD)/99-V(9)*V(15) |
| 38 | +VY=V(4)*(SX+XD-128)/99+V(7)*(106-SY-YD)/99-V(10)*V(15) |
| 39 | +VZ=V(5)*(SX+XD-128)/99+V(8)*(106-SY-YD)/99-V(11)*V(15) |
| 40 | +V1=SQR(VX*VX+VY*VY+VZ*VZ) |
| 41 | +VX=VX/V1:VY=VY/V1:VZ=VZ/V1 |
| 42 | +CR=0:CG=0:CB=0:RN=0:RF=1 |
| 43 | +GOSUB 1760 |
| 44 | +IF CR>=1 THEN CR=0.99 |
| 45 | +IF CG>=1 THEN CG=0.99 |
| 46 | +IF CB>=1 THEN CB=0.99 |
| 47 | +RI(XD)=CR:GI(XD)=CG:BI(XD)=CB |
| 48 | +XD=XD+1 |
| 49 | +if XD>=4 then GOSUB 1470:XD=0:YD=YD+1 |
| 50 | +'TTT IF XD<4 THEN 1250 |
| 51 | +'GOSUB 1470:XD=0 |
| 52 | +'YD=YD+1:'IF YD<4 THEN 1250 |
| 53 | +wend |
| 54 | +IF STRIG(0) THEN STOP 'GOTO 1460 |
| 55 | +NEXT SX |
| 56 | +NEXT SY |
| 57 | +ti=time+300:while TIME<ti AND INKEY$="":WEND |
| 58 | +STOP 'GOTO 1460 |
| 59 | +1470 ' Draw |
| 60 | +'MAKE RGB DATA FOR SCREEN8 AND WRITE IT ON THE SCREEN |
| 61 | +FOR XD=0 TO 3 |
| 62 | +CC1=round((RI(XD)+GI(XD)+BI(XD))/3*15):IF CC1=15 THEN CC1=1 ELSE IF CC1=1 THEN CC1=15 |
| 63 | +PLOT (SX+XD)*2,400-((SY+YD)*2),CC1 |
| 64 | +NEXT XD |
| 65 | +RETURN |
| 66 | +1760 ' Pixel |
| 67 | +f=1 |
| 68 | +while f=1 |
| 69 | +TT=MA |
| 70 | +FOR N=0 TO MO-1 |
| 71 | +GOSUB 1870 |
| 72 | +IF TT>Th AND Th>MI THEN TT=Th:TN=N:LX=NX:LY=NY:LZ=NZ |
| 73 | +NEXT N |
| 74 | +IF TT=MA THEN return '1860 |
| 75 | +CX=CX+TT*VX:CY=CY+TT*VY:CZ=CZ+TT*VZ:N=TN |
| 76 | +GOSUB 2150 |
| 77 | +wend 'IF F=1 THEN GOTO 1760 |
| 78 | +RETURN |
| 79 | +1870 ' Cross |
| 80 | +RX=CX-O(N,0):RY=CY-O(N,1):RZ=CZ-O(N,2) |
| 81 | +A=O(N,3):B=O(N,4):C=O(N,5) |
| 82 | +ON O(N,6)+1 gosub 1920,2030: return 'GOTO 1920,2030 |
| 83 | +gosub 1920 |
| 84 | +return 'GOTO 1920 |
| 85 | +1920 ' Box |
| 86 | +IF VX=0 THEN T1=MA ELSE IF RX<0 THEN T1=-(RX+A)/VX ELSE T1=-(RX-A)/VX |
| 87 | +IF VY=0 THEN T2=MA ELSE IF RY<0 THEN T2=-(RY+B)/VY ELSE T2=-(RY-B)/VY |
| 88 | +IF VZ=0 THEN T3=MA ELSE IF RZ<0 THEN T3=-(RZ+C)/VZ ELSE T3=-(RZ-C)/VZ |
| 89 | +IF ABS(RY+T1*VY)>B OR ABS(RZ+T1*VZ)>C THEN T1=MA |
| 90 | +IF ABS(RZ+T2*VZ)>C OR ABS(RX+T2*VX)>A THEN T2=MA |
| 91 | +IF ABS(RX+T3*VX)>A OR ABS(RY+T3*VY)>B THEN T3=MA |
| 92 | +IF T1<=T2 AND T1<=T3 THEN Th=T1:NX=-VX/ABS(VX):NY=0:NZ=0 |
| 93 | +IF T2<=T3 AND T2<=T1 THEN Th=T2:NY=-VY/ABS(VY):NZ=0:NX=0 |
| 94 | +IF T3<=T1 AND T3<=T2 THEN Th=T3:NZ=-VZ/ABS(VZ):NX=0:NY=0 |
| 95 | +RETURN |
| 96 | +2030 ' Ball |
| 97 | +AA=VX*VX*A+VY*VY*B+VZ*VZ*C |
| 98 | +BB=RX*VX*A+RY*VY*B+RZ*VZ*C |
| 99 | +CC=RX*RX*A+RY*RY*B+RZ*RZ*C-1 |
| 100 | +DD=BB*BB-AA*CC |
| 101 | +IF DD<0 THEN Th=MA:return 'GOTO 2140 |
| 102 | +T1=(-BB-SQR(DD))/AA:T2=(-BB+SQR(DD))/AA |
| 103 | +IF T1<T2 THEN Th=T1 ELSE Th=T2 |
| 104 | +NX=A*(RX+Th*VX):NY=B*(RY+Th*VY):NZ=C*(RZ+Th*VZ) |
| 105 | +M=SQR(NX*NX+NY*NY+NZ*NZ) |
| 106 | +NX=NX/M:NY=NY/M:NZ=NZ/M |
| 107 | +RETURN |
| 108 | +2150 ' Shade |
| 109 | +SH=O(N,7):REM 0=Silber,1=Stahl,2=Rotes Plastik, 3=Graues Plastik, 4=Blaues Plastik,5=Graues Plastik,6=Chrom |
| 110 | +IF SH=-1 THEN PX=INT(ABS(CX+100)/PT-(CX+100<0)) : PY=INT(ABS(CY+100)/PT-(CY+100<0)) : PZ=INT(ABS(CZ+100)/PT-(CZ+100<0)) : SH=(PX+PY+PZ) MOD 2 |
| 111 | +2220 SR=S(SH,0):SG=S(SH,1):SB=S(SH,2) |
| 112 | +SA=S(SH,3):SD=S(SH,4):SF=S(SH,5) |
| 113 | +SP=S(SH,6):SE=S(SH,7) |
| 114 | +JX=V(12)-VX:JY=V(13)-VY:JZ=V(14)-VZ |
| 115 | +JN=SQR(JX*JX+JY*JY+JZ*JZ) |
| 116 | +SM=(LX*JX+LY*JY+LZ*JZ)/JN |
| 117 | +IF SM<0 THEN SM=0 |
| 118 | +FOR P=1 TO SE:SM=SM*SM:NEXT P |
| 119 | +VN=-2*(LX*VX+LY*VY+LZ*VZ) |
| 120 | +WX=VX+VN*LX:WY=VY+VN*LY:WZ=VZ+VN*LZ |
| 121 | +VX=V(12):VY=V(13):VZ=V(14) |
| 122 | +SN=LX*VX+LY*VY+LZ*VZ |
| 123 | +IF SN<0 THEN SN=0 |
| 124 | +FOR N=0 TO MO-1 |
| 125 | +GOSUB 1870 |
| 126 | +IF MA>Th AND Th>MI THEN SN=0:SM=0 |
| 127 | +NEXT N |
| 128 | +CR=CR+(SR*(SA+SD*SN)+SP*SM)*RF |
| 129 | +CG=CG+(SG*(SA+SD*SN)+SP*SM)*RF |
| 130 | +CB=CB+(SB*(SA+SD*SN)+SP*SM)*RF |
| 131 | +IF SF=0 AND RN<4 THEN F=0:return : 'GOTO 2450 |
| 132 | +F=1:RF=RF*SF:RN=RN+1 |
| 133 | +VX=WX:VY=WY:VZ=WZ |
| 134 | +2450 RETURN |
| 135 | +' Picture data |
| 136 | +DATA 20, 40, 20 |
| 137 | +DATA 0, 0, 0 |
| 138 | +DATA -8, 9, -3 |
| 139 | +DATA 6 |
| 140 | +DATA 6 |
| 141 | +DATA 2, 0, 2 |
| 142 | +DATA .2, .2, .2 |
| 143 | +DATA 1, 2:REM Shader lower ball |
| 144 | +DATA -2, 2, 2 |
| 145 | +DATA .2, .2, .2 |
| 146 | +DATA 1, 3:REM Shader left grey ball |
| 147 | +DATA -6, 4, 2 |
| 148 | +DATA .2, .2, .2 |
| 149 | +DATA 1, 4:REM Shader blue ball |
| 150 | +DATA -2, 2, -2 |
| 151 | +DATA .2, .2, .2 |
| 152 | +DATA 1, 5:REM Shader right grey ball |
| 153 | +DATA -6, 4, -6 |
| 154 | +DATA .2, .2, .2 |
| 155 | +DATA 1, 6 |
| 156 | +DATA 0, -2, 0 |
| 157 | +DATA 20, 1, 20 |
| 158 | +DATA 0, -1 |
| 159 | +DATA 7 |
| 160 | +DATA .9, .9, .9 |
| 161 | +DATA .5, .4, .6 |
| 162 | +DATA .7, 6 |
| 163 | +DATA .0, .9, .0 |
| 164 | +DATA .5, .4, .6 |
| 165 | +DATA .7, 6 |
| 166 | +DATA .9, .0, .0 |
| 167 | +DATA .3, .6, 0 |
| 168 | +DATA 0, 0 |
| 169 | +DATA .9, .9, .9 |
| 170 | +DATA .3, .6, 0 |
| 171 | +DATA .6, 8 |
| 172 | +DATA .0, .0, .9 |
| 173 | +DATA .3, .6, 0 |
| 174 | +DATA .6, 8 |
| 175 | +DATA .9, .9, .9 |
| 176 | +DATA .3, .6, 0 |
| 177 | +DATA .6, 6 |
| 178 | +DATA .0, .0, .0 |
| 179 | +DATA .3, .6, 1 |
| 180 | +DATA .9, 8 |
| 181 | +`); |
0 commit comments