1717# If a cell is invisible, its value is set to -1
1818INVISIBLE = - 1
1919
20+ CAMERA_HEIGHT = 10000
21+
2022
2123@nb .cuda .jit
22- def _generate_primary_rays_kernel (data , x_coords , y_coords , H , W ):
24+ def _generate_primary_rays_kernel (data , H , W ):
2325 """
2426 A GPU kernel that given a set of x and y discrete coordinates on a raster
2527 terrain generates in @data a list of parallel rays that represent camera
2628 rays generated from an orthographic camera that is looking straight down
27- at the surface from an origin height 10000 .
29+ at the surface from an origin height CAMERA_HEIGHT .
2830 """
2931 i , j = nb .cuda .grid (2 )
3032 if i >= 0 and i < H and j >= 0 and j < W :
3133 if (j == W - 1 ):
32- data [i , j , 0 ] = x_coords [ j ] - 1e-3
34+ data [i , j , 0 ] = j - 1e-3
3335 else :
34- data [i , j , 0 ] = x_coords [ j ] + 1e-3
36+ data [i , j , 0 ] = j + 1e-3
3537
3638 if (i == H - 1 ):
37- data [i , j , 1 ] = y_coords [ i ] - 1e-3
39+ data [i , j , 1 ] = i - 1e-3
3840 else :
39- data [i , j , 1 ] = y_coords [ i ] + 1e-3
41+ data [i , j , 1 ] = i + 1e-3
4042
41- data [i , j , 2 ] = 10000 # Location of the camera (height)
43+ data [i , j , 2 ] = CAMERA_HEIGHT # Location of the camera (height)
4244 data [i , j , 3 ] = 1e-3
4345 data [i , j , 4 ] = 0
4446 data [i , j , 5 ] = 0
4547 data [i , j , 6 ] = - 1
4648 data [i , j , 7 ] = np .inf
4749
4850
49- def _generate_primary_rays (rays , x_coords , y_coords , H , W ):
51+ def _generate_primary_rays (rays , H , W ):
5052 griddim , blockdim = calc_cuda_dims ((H , W ))
51- d_y_coords = cupy .array (y_coords )
52- d_x_coords = cupy .array (x_coords )
53- _generate_primary_rays_kernel [griddim , blockdim ](
54- rays , d_x_coords , d_y_coords , H , W )
53+ _generate_primary_rays_kernel [griddim , blockdim ](rays , H , W )
5554 return 0
5655
5756
@@ -94,6 +93,8 @@ def _generate_viewshed_rays_kernel(
9493 ray_dir = make_float3 (camera_ray , 4 )
9594 # calculate intersection point
9695 hit_p = add (ray_origin , mul (ray_dir , dist ))
96+
97+ surfaceHit = hit_p
9798 # generate new ray origin, and a little offset to avoid
9899 # self-intersection
99100 new_origin = add (hit_p , mul (norm , 1e-3 ))
@@ -117,7 +118,7 @@ def _generate_viewshed_rays_kernel(
117118 viewshed_point = add (hit_p , float3 (0 , 0 , observer_elev ))
118119
119120 # calculate vector from SurfaceHit to VP
120- new_dir = diff (viewshed_point , new_origin )
121+ new_dir = diff (viewshed_point , surfaceHit )
121122 # calculate distance from surface to VP
122123 length = math .sqrt (dot (new_dir , new_dir ))
123124 # normalize the direction (vector v)
@@ -188,7 +189,7 @@ def _viewshed_rt(
188189 d_visgrid = cupy .empty ((H , W ), np .float32 )
189190 d_vsrays = cupy .empty ((H , W , 8 ), np .float32 )
190191
191- _generate_primary_rays (d_rays , x_coords , y_coords , H , W )
192+ _generate_primary_rays (d_rays , H , W )
192193 device = cupy .cuda .Device (0 )
193194 device .synchronize ()
194195 res = optix .trace (d_rays , d_hits , W * H )
@@ -230,6 +231,6 @@ def viewshed_gpu(
230231 raise TypeError ("raster.data must be a cupy array" )
231232
232233 optix = RTX ()
233- create_triangulation (raster , optix )
234+ scale = create_triangulation (raster , optix )
234235
235- return _viewshed_rt (raster , optix , x , y , observer_elev , target_elev )
236+ return _viewshed_rt (raster , optix , x , y , observer_elev * scale , target_elev * scale )
0 commit comments