@@ -1756,59 +1756,65 @@ async function init(format) {
1756
1756
}
1757
1757
} ;
1758
1758
}
1759
- function traceRay_impl ( getVoxel , px , py , pz , dx , dy , dz , max_d = 64 , hit_pos , hit_norm ) {
1760
- var t = 0.0 , floor = Math . floor , ix = floor ( px ) | 0 , iy = floor ( py ) | 0 , iz = floor ( pz ) | 0 , stepx = dx > 0 ? 1 : - 1 , stepy = dy > 0 ? 1 : - 1 , stepz = dz > 0 ? 1 : - 1 , txDelta = Math . abs ( 1 / dx ) , tyDelta = Math . abs ( 1 / dy ) , tzDelta = Math . abs ( 1 / dz ) , xdist = stepx > 0 ? ix + 1 - px : px - ix , ydist = stepy > 0 ? iy + 1 - py : py - iy , zdist = stepz > 0 ? iz + 1 - pz : pz - iz , txMax = txDelta < Infinity ? txDelta * xdist : Infinity , tyMax = tyDelta < Infinity ? tyDelta * ydist : Infinity , tzMax = tzDelta < Infinity ? tzDelta * zdist : Infinity , steppedIndex = - 1 ;
1761
- while ( t <= max_d ) {
1762
- var b = getVoxel ( ix , iy , iz ) ;
1759
+ function * raycast ( getVoxel , [ px , py , pz ] , [ dx , dy , dz ] , maxDistance = 64 ) {
1760
+ let t = 0 ;
1761
+ let ix = Math . floor ( px ) ;
1762
+ let iy = Math . floor ( py ) ;
1763
+ let iz = Math . floor ( pz ) ;
1764
+ const stepx = Math . sign ( dx ) ;
1765
+ const stepy = Math . sign ( dy ) ;
1766
+ const stepz = Math . sign ( dz ) ;
1767
+ const txDelta = Math . abs ( 1 / dx ) ;
1768
+ const tyDelta = Math . abs ( 1 / dy ) ;
1769
+ const tzDelta = Math . abs ( 1 / dz ) ;
1770
+ let txMax = txDelta < Infinity ? txDelta * ( stepx > 0 ? ix + 1 - px : px - ix ) : Infinity ;
1771
+ let tyMax = tyDelta < Infinity ? tyDelta * ( stepy > 0 ? iy + 1 - py : py - iy ) : Infinity ;
1772
+ let tzMax = tzDelta < Infinity ? tzDelta * ( stepz > 0 ? iz + 1 - pz : pz - iz ) : Infinity ;
1773
+ let steppedIndex = null ;
1774
+ while ( t <= maxDistance ) {
1775
+ const b = getVoxel ( ix , iy , iz ) ;
1763
1776
if ( b ) {
1764
- if ( hit_pos ) {
1765
- hit_pos [ 0 ] = px + t * dx ;
1766
- hit_pos [ 1 ] = py + t * dy ;
1767
- hit_pos [ 2 ] = pz + t * dz ;
1768
- }
1769
- if ( hit_norm ) {
1770
- hit_norm [ 0 ] = hit_norm [ 1 ] = hit_norm [ 2 ] = 0 ;
1771
- if ( steppedIndex === 0 ) hit_norm [ 0 ] = - stepx ;
1772
- if ( steppedIndex === 1 ) hit_norm [ 1 ] = - stepy ;
1773
- if ( steppedIndex === 2 ) hit_norm [ 2 ] = - stepz ;
1774
- }
1775
- return b ;
1777
+ yield {
1778
+ block : [
1779
+ ix ,
1780
+ iy ,
1781
+ iz
1782
+ ] ,
1783
+ position : [
1784
+ px + t * dx ,
1785
+ py + t * dy ,
1786
+ pz + t * dz
1787
+ ] ,
1788
+ normal : [
1789
+ steppedIndex === 'x' ? - stepx : 0 ,
1790
+ steppedIndex === 'y' ? - stepy : 0 ,
1791
+ steppedIndex === 'z' ? - stepz : 0
1792
+ ]
1793
+ } ;
1776
1794
}
1777
- if ( txMax < tyMax ) {
1778
- if ( txMax < tzMax ) {
1795
+ switch ( Math . min ( txMax , tyMax , tzMax ) ) {
1796
+ case txMax :
1779
1797
ix += stepx ;
1780
1798
t = txMax ;
1781
1799
txMax += txDelta ;
1782
- steppedIndex = 0 ;
1783
- } else {
1784
- iz += stepz ;
1785
- t = tzMax ;
1786
- tzMax += tzDelta ;
1787
- steppedIndex = 2 ;
1788
- }
1789
- } else {
1790
- if ( tyMax < tzMax ) {
1800
+ steppedIndex = 'x' ;
1801
+ break ;
1802
+ case tyMax :
1791
1803
iy += stepy ;
1792
1804
t = tyMax ;
1793
1805
tyMax += tyDelta ;
1794
- steppedIndex = 1 ;
1795
- } else {
1806
+ steppedIndex = 'y' ;
1807
+ break ;
1808
+ case tzMax :
1796
1809
iz += stepz ;
1797
1810
t = tzMax ;
1798
1811
tzMax += tzDelta ;
1799
- steppedIndex = 2 ;
1800
- }
1812
+ steppedIndex = 'z' ;
1813
+ break ;
1814
+ default :
1815
+ throw new Error ( 'The minimum is none of these. ??' ) ;
1801
1816
}
1802
1817
}
1803
- if ( hit_pos ) {
1804
- hit_pos [ 0 ] = px + t * dx ;
1805
- hit_pos [ 1 ] = py + t * dy ;
1806
- hit_pos [ 2 ] = pz + t * dz ;
1807
- }
1808
- if ( hit_norm ) {
1809
- hit_norm [ 0 ] = hit_norm [ 1 ] = hit_norm [ 2 ] = 0 ;
1810
- }
1811
- return 0 ;
1812
1818
}
1813
1819
const errorMessages = document . getElementById ( 'error' ) ;
1814
1820
function handleError ( error ) {
@@ -2039,43 +2045,47 @@ function paint() {
2039
2045
} ) ;
2040
2046
frameId = requestAnimationFrame ( paint ) ;
2041
2047
}
2042
- function raycast ( ) {
2043
- const hit_position = [
2044
- 0 ,
2045
- 20 ,
2046
- 0
2047
- ] ;
2048
- const hit_normal = [
2049
- 0 ,
2050
- 20 ,
2051
- 0
2052
- ] ;
2048
+ function doRaycast ( ) {
2053
2049
const [ dx , dy , dz ] = oe . transformMat4Upper3x3 ( [
2054
2050
0 ,
2055
2051
0 ,
2056
2052
- 1
2057
2053
] , ce . rotateZ ( ce . rotateX ( ce . rotationY ( - player . yaw ) , - player . pitch ) , - player . roll ) ) ;
2058
2054
const length = Math . hypot ( dx , dy , dz ) ;
2059
- console . log ( 'dir' , dx / length , dy / length , dz / length ) ;
2060
- const result = traceRay_impl ( ( x , y , z ) => {
2061
- console . log ( 'getblock' , x , y , z , getBlock ( x , y , z ) ) ;
2062
- return isSolid ( getBlock ( x , y , z ) ) ;
2063
- } , player . x , player . y , player . z , dx / length , dy / length , dz / length , 10 , hit_position , hit_normal ) ;
2064
- if ( result ) {
2065
- return {
2066
- hit_position,
2067
- hit_normal
2068
- } ;
2069
- } else {
2070
- return null ;
2071
- }
2055
+ const result = raycast ( ( x , y , z ) => isSolid ( getBlock ( x , y , z ) ) , [
2056
+ player . x ,
2057
+ player . y ,
2058
+ player . z
2059
+ ] , [
2060
+ dx / length ,
2061
+ dy / length ,
2062
+ dz / length
2063
+ ] , 64 ) . next ( ) ;
2064
+ return result . done ? null : result . value ;
2072
2065
}
2073
2066
canvas . addEventListener ( 'mousedown' , ( e ) => {
2074
- if ( e . button === 0 ) {
2075
- const result = raycast ( ) ;
2076
- console . log ( result ) ;
2077
- if ( result ) {
2078
- setBlock ( Math . floor ( result . hit_position [ 0 ] ) , Math . floor ( result . hit_position [ 1 ] ) , Math . floor ( result . hit_position [ 2 ] ) , Block . WHITE ) ;
2067
+ const result = doRaycast ( ) ;
2068
+ if ( result ) {
2069
+ switch ( e . button ) {
2070
+ case 0 :
2071
+ {
2072
+ setBlock ( ...result . block , Block . AIR ) ;
2073
+ break ;
2074
+ }
2075
+ case 1 :
2076
+ {
2077
+ console . log ( getBlock ( ...result . block ) ) ;
2078
+ break ;
2079
+ }
2080
+ case 2 :
2081
+ {
2082
+ const target = oe . add ( result . block , result . normal ) ;
2083
+ if ( getBlock ( target [ 0 ] , target [ 1 ] , target [ 2 ] ) === Block . AIR ) {
2084
+ setBlock ( target [ 0 ] , target [ 1 ] , target [ 2 ] , Block . WHITE ) ;
2085
+ }
2086
+ break ;
2087
+ }
2079
2088
}
2080
2089
}
2090
+ if ( e . button === 0 ) { }
2081
2091
} ) ;
0 commit comments