diff options
Diffstat (limited to 'src/environment.cpp')
-rw-r--r-- | src/environment.cpp | 223 |
1 files changed, 118 insertions, 105 deletions
diff --git a/src/environment.cpp b/src/environment.cpp index 7acad313e..0a08a1d68 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -26,14 +26,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "daynightratio.h" #include "emerge.h" - -Environment::Environment(IGameDef *gamedef): - m_time_of_day_speed(0.0f), - m_day_count(0), - m_gamedef(gamedef) +Environment::Environment(IGameDef *gamedef) : + m_time_of_day_speed(0.0f), m_day_count(0), m_gamedef(gamedef) { m_cache_enable_shaders = g_settings->getBool("enable_shaders"); - m_cache_active_block_mgmt_interval = g_settings->getFloat("active_block_mgmt_interval"); + m_cache_active_block_mgmt_interval = + g_settings->getFloat("active_block_mgmt_interval"); m_cache_abm_interval = g_settings->getFloat("abm_interval"); m_cache_nodetimer_interval = g_settings->getFloat("nodetimer_interval"); @@ -105,14 +103,15 @@ bool Environment::line_of_sight(v3f pos1, v3f pos2, v3s16 *p) /* Check if a node is pointable */ -inline static bool isPointableNode(const MapNode &n, - const NodeDefManager *nodedef , bool liquids_pointable, bool nodes_pointable) +inline static bool isPointableNode(const MapNode &n, const NodeDefManager *nodedef, + bool liquids_pointable, bool nodes_pointable) { - if (! nodes_pointable) + if (!nodes_pointable) return false; const ContentFeatures &features = nodedef->get(n); return features.pointable || - ((liquids_pointable || g_settings->getBool("point_liquids")) && features.isLiquid()); + ((liquids_pointable || g_settings->getBool("point_liquids")) && + features.isLiquid()); } void Environment::continueRaycast(RaycastState *state, PointedThing *result) @@ -140,7 +139,7 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result) s16 lastIndex = state->m_iterator.m_last_index; if (!state->m_found.empty()) { lastIndex = state->m_iterator.getIndex( - floatToInt(state->m_found.top().intersection_point, BS)); + floatToInt(state->m_found.top().intersection_point, BS)); } Map &map = getMap(); @@ -156,8 +155,8 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result) new_nodes.MaxEdge += state->m_iterator.m_current_node_pos; // Only check new nodes - v3s16 delta = state->m_iterator.m_current_node_pos - - state->m_previous_node; + v3s16 delta = state->m_iterator.m_current_node_pos - + state->m_previous_node; if (delta.X > 0) { new_nodes.MinEdge.X = new_nodes.MaxEdge.X; } else if (delta.X < 0) { @@ -174,99 +173,113 @@ void Environment::continueRaycast(RaycastState *state, PointedThing *result) // For each untested node for (s16 x = new_nodes.MinEdge.X; x <= new_nodes.MaxEdge.X; x++) - for (s16 y = new_nodes.MinEdge.Y; y <= new_nodes.MaxEdge.Y; y++) - for (s16 z = new_nodes.MinEdge.Z; z <= new_nodes.MaxEdge.Z; z++) { - MapNode n; - v3s16 np(x, y, z); - bool is_valid_position; - - n = map.getNode(np, &is_valid_position); - if (!(is_valid_position && isPointableNode(n, nodedef, - state->m_liquids_pointable, state->m_nodes_pointable))) { - continue; - } - - PointedThing result; - - std::vector<aabb3f> boxes; - n.getSelectionBoxes(nodedef, &boxes, - n.getNeighbors(np, &map)); - - // Is there a collision with a selection box? - bool is_colliding = false; - // Minimal distance of all collisions - float min_distance_sq = 10000000; - // ID of the current box (loop counter) - u16 id = 0; - - v3f npf = intToFloat(np, BS); - // This loop translates the boxes to their in-world place. - for (aabb3f &box : boxes) { - box.MinEdge += npf; - box.MaxEdge += npf; - - v3f intersection_point; - v3s16 intersection_normal; - if (!boxLineCollision(box, state->m_shootline.start, - state->m_shootline.getVector(), &intersection_point, - &intersection_normal)) { - ++id; - continue; + for (s16 y = new_nodes.MinEdge.Y; y <= new_nodes.MaxEdge.Y; y++) + for (s16 z = new_nodes.MinEdge.Z; + z <= new_nodes.MaxEdge.Z; z++) { + MapNode n; + v3s16 np(x, y, z); + bool is_valid_position; + + n = map.getNode(np, &is_valid_position); + if (!(is_valid_position && + isPointableNode(n, nodedef, + state->m_liquids_pointable, + state->m_nodes_pointable))) { + continue; + } + + PointedThing result; + + std::vector<aabb3f> boxes; + n.getSelectionBoxes(nodedef, &boxes, + n.getNeighbors(np, &map)); + + // Is there a collision with a selection box? + bool is_colliding = false; + // Minimal distance of all collisions + float min_distance_sq = 10000000; + // ID of the current box (loop counter) + u16 id = 0; + + v3f npf = intToFloat(np, BS); + // This loop translates the boxes to their + // in-world place. + for (aabb3f &box : boxes) { + box.MinEdge += npf; + box.MaxEdge += npf; + + v3f intersection_point; + v3s16 intersection_normal; + if (!boxLineCollision(box, + state->m_shootline + .start, + state->m_shootline + .getVector(), + &intersection_point, + &intersection_normal)) { + ++id; + continue; + } + + f32 distanceSq = (intersection_point - + state->m_shootline + .start) + .getLengthSQ(); + // If this is the nearest collision, save + // it + if (min_distance_sq > distanceSq) { + min_distance_sq = distanceSq; + result.intersection_point = + intersection_point; + result.intersection_normal = + intersection_normal; + result.box_id = id; + found_boxcenter = box.getCenter(); + is_colliding = true; + } + ++id; + } + // If there wasn't a collision, stop + if (!is_colliding) { + continue; + } + result.type = POINTEDTHING_NODE; + result.node_undersurface = np; + result.distanceSq = min_distance_sq; + // Set undersurface and abovesurface nodes + f32 d = 0.002 * BS; + v3f fake_intersection = result.intersection_point; + // Move intersection towards its source block. + if (fake_intersection.X < found_boxcenter.X) { + fake_intersection.X += d; + } else { + fake_intersection.X -= d; + } + if (fake_intersection.Y < found_boxcenter.Y) { + fake_intersection.Y += d; + } else { + fake_intersection.Y -= d; + } + if (fake_intersection.Z < found_boxcenter.Z) { + fake_intersection.Z += d; + } else { + fake_intersection.Z -= d; + } + result.node_real_undersurface = + floatToInt(fake_intersection, BS); + result.node_abovesurface = + result.node_real_undersurface + + result.intersection_normal; + // Push found PointedThing + state->m_found.push(result); + // If this is nearer than the old nearest object, + // the search can be shorter + s16 newIndex = state->m_iterator.getIndex( + result.node_real_undersurface); + if (newIndex < lastIndex) { + lastIndex = newIndex; + } } - - f32 distanceSq = (intersection_point - - state->m_shootline.start).getLengthSQ(); - // If this is the nearest collision, save it - if (min_distance_sq > distanceSq) { - min_distance_sq = distanceSq; - result.intersection_point = intersection_point; - result.intersection_normal = intersection_normal; - result.box_id = id; - found_boxcenter = box.getCenter(); - is_colliding = true; - } - ++id; - } - // If there wasn't a collision, stop - if (!is_colliding) { - continue; - } - result.type = POINTEDTHING_NODE; - result.node_undersurface = np; - result.distanceSq = min_distance_sq; - // Set undersurface and abovesurface nodes - f32 d = 0.002 * BS; - v3f fake_intersection = result.intersection_point; - // Move intersection towards its source block. - if (fake_intersection.X < found_boxcenter.X) { - fake_intersection.X += d; - } else { - fake_intersection.X -= d; - } - if (fake_intersection.Y < found_boxcenter.Y) { - fake_intersection.Y += d; - } else { - fake_intersection.Y -= d; - } - if (fake_intersection.Z < found_boxcenter.Z) { - fake_intersection.Z += d; - } else { - fake_intersection.Z -= d; - } - result.node_real_undersurface = floatToInt( - fake_intersection, BS); - result.node_abovesurface = result.node_real_undersurface - + result.intersection_normal; - // Push found PointedThing - state->m_found.push(result); - // If this is nearer than the old nearest object, - // the search can be shorter - s16 newIndex = state->m_iterator.getIndex( - result.node_real_undersurface); - if (newIndex < lastIndex) { - lastIndex = newIndex; - } - } // Next node state->m_previous_node = state->m_iterator.m_current_node_pos; state->m_iterator.next(); |