# File ../lib/roller/CWRP.rb, line 834 def height_at(x, y) cell_size = terrain_cell_size.to_f # Ensure we don't go out of bounds. x = [x, map_size - cell_size].min y = [y, map_size - cell_size].min x_offset = x.modulo(cell_size) / cell_size y_offset = y.modulo(cell_size) / cell_size x_cell = x / cell_size y_cell = y / cell_size if (x_offset == 0) and (y_offset == 0) # Just read straight out of the grid. height = @terrain_height[y_cell][x_cell] else # Interpolate to work out the actual height player will see. x_min = (x_cell).floor x_max = (x_cell).ceil y_min = (y_cell).floor y_max = (y_cell).ceil # Depending in which of two triangles that the point is in, we choose # a corner to start from. # B--- # | /| # |/ | # 0--B # if x_offset > y_offset # base_height = @terrain_height[y_min][x_max] # bottom right corner/triangle. # x_offset = 1 - x_offset # x_diff = @terrain_height[y_min][x_min] - base_height # BL # y_diff = @terrain_height[y_max][x_max] - base_height # TR # else # base_height = @terrain_height[y_max][x_min] # top left corner/triangle. # y_offset = 1 - y_offset # x_diff = @terrain_height[y_max][x_min] - base_height # TL # y_diff = @terrain_height[y_min][x_min] - base_height # BR # end # A single square cell is made up of two triangles. O is the origin [0, 0] # TL--TR # |\ | # | \| # O--BL # First, work out which triangle we are in and get the "base height" of # the outside corner (O or TR). Then work out the height difference to # each of TL and BL and interpolate the action height of the point. # Note: This algorithm is probably not as efficient as solving the planar # equation, but I am both too ignorant and too lazy to bother doing it # properly! if (x_offset + y_offset) > 1 # Top right triangle. base_height = @terrain_height[y_max][x_max] # TR y_offset = 1 - y_offset # Going left from TR to TL x_offset = 1 - x_offset # Going down from TL to O x_diff = @terrain_height[y_max][x_min] - base_height # TL y_diff = @terrain_height[y_min][x_max] - base_height # BR else # Bottom left triangle. base_height = @terrain_height[y_min][x_min] # O x_diff = @terrain_height[y_min][x_max] - base_height # BL y_diff = @terrain_height[y_max][x_min] - base_height # TR end height = base_height + (x_diff * x_offset) + (y_diff * y_offset) end height end