Last active
February 25, 2021 18:48
-
-
Save gnalvesteffer/d56d6af2c966a76fc3d1a96a7a4547fa to your computer and use it in GitHub Desktop.
Teardown | Actively Awaken Bodies Near Player
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function init() | |
-- configuration | |
bodies_to_process_per_tick = 10 -- bodies to process per tick | |
chunk_refresh_interval = 10 -- the interval (in seconds) to refresh the chunk (only if current chunk has finished processing) | |
is_debug = true | |
-- chunk state | |
chunk_position = GetPlayerTransform().pos | |
chunk_bodies = {} | |
chunk_size = 50 | |
chunk_tick = 0 | |
chunk_last_refresh_time = 0 | |
-- set up initial chunk | |
set_up_new_chunk() | |
end | |
function is_body_floating(body) | |
local min_bound, max_bound = GetBodyBounds(body) | |
local center_bottom_point = VecLerp(Vec(min_bound[1], min_bound[2], min_bound[3]), Vec(max_bound[1], min_bound[2], max_bound[3]), 0.5) | |
local did_ray_hit = QueryRaycast(center_bottom_point, Vec(0, -1, 0), 1) | |
return not did_ray_hit | |
end | |
function try_make_body_fall(body) | |
if not IsBodyDynamic(body) or not is_body_floating(body) then | |
return | |
end | |
local velocity = GetBodyVelocity(body) | |
local speed = VecLength(velocity) | |
if speed < 0.001 then | |
if is_debug then | |
DrawBodyOutline(body, 1) | |
end | |
SetBodyVelocity(body, VecAdd(velocity, Vec(0, -0.001, 0))) | |
end | |
end | |
function get_bodies_near_position(position, radius) | |
local min_point = VecAdd(position, Vec(-radius, -radius, -radius)) | |
local max_point = VecAdd(position, Vec(radius, radius, radius)) | |
return QueryAabbBodies(min_point, max_point) | |
end | |
function refresh_chunk_bodies() | |
chunk_last_refresh_time = GetTime() | |
chunk_bodies = {} | |
local bodies = get_bodies_near_position(chunk_position, chunk_size) | |
for i, body in ipairs(bodies) do | |
chunk_bodies[i] = body | |
end | |
end | |
function has_processed_all_bodies_and_requires_refresh() | |
local total_processed_bodies = math.min(chunk_tick * bodies_to_process_per_tick, #chunk_bodies) | |
return total_processed_bodies == #chunk_bodies and GetTime() - chunk_last_refresh_time >= chunk_refresh_interval | |
end | |
function needs_to_set_up_new_chunk() | |
local player_position = GetPlayerTransform().pos | |
local player_distance_from_current_chunk = VecLength(VecSub(player_position, chunk_position)) | |
return player_distance_from_current_chunk >= chunk_size or has_processed_all_bodies_and_requires_refresh() | |
end | |
function set_up_new_chunk() | |
chunk_tick = 0 | |
chunk_position = GetPlayerTransform().pos | |
refresh_chunk_bodies() | |
end | |
function process_chunk_bodies() | |
for i = chunk_tick * bodies_to_process_per_tick, math.min((chunk_tick + 1) * bodies_to_process_per_tick, #chunk_bodies) do | |
try_make_body_fall(chunk_bodies[i]) | |
end | |
end | |
function update_current_chunk() | |
process_chunk_bodies() | |
chunk_tick = chunk_tick + 1 | |
end | |
function tick(delta_time) | |
if needs_to_set_up_new_chunk() then | |
set_up_new_chunk() | |
else | |
update_current_chunk() | |
end | |
if is_debug then | |
DebugWatch("Total Chunk Bodies", #chunk_bodies) | |
-- highlight body/shape looked at | |
local hit, distance, normal, shape = QueryRaycast(GetCameraTransform().pos, TransformToParentVec(GetCameraTransform(), Vec(0, 0, -1)), 100) | |
if hit then | |
DrawBodyOutline(GetShapeBody(shape), 1, 0, 0, 0.5) | |
DrawShapeOutline(shape, 0, 1, 1, 0.5) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment