void avoid_enemy(world* w, entity* self) { for(auto e : w->entities) { if (e == self) continue; if (e->_flags & EF_DESTROYED) continue; if ((e->_type != ET_PLAYER_BODY) && (e->_type != ET_PLAYER)) continue; vec2 d = self->_pos - e->_pos; float min_l = (self->_radius * 0.5f) + e->_radius; if (length_sq(d) > square(min_l)) continue; float l = length(d); if (l < 0.0001f) d = vec2(1.0f, 0.0f); else d /= l; float force_self = 32.0f; float force_e = 128.0f; self->_vel += d * force_self; if (e->_type == ET_PLAYER_BODY) force_e *= 0.5f; e->_vel -= d * force_e; } }
inline bool line3<T>::is_intersetion_with_sphere(const vec3<T>& sphereCenter, T sphereRadius) const { const vec3<T> q = sphereCenter - start; T c = length_sq(q); T v = dot(q, get_vector_normalized()); T d = sphereRadius * sphereRadius - (c - v*v); return d > 0; }
inline bool line3<T>::get_intersection_with_sphere(const vec3<T>& sphereCenter, T sphereRadius, T& outdistance) const { const vec3<T> q = sphereCenter - start; T c = length_sq(q); T v = dot(q, get_vector_normalized()); T d = sphereRadius * sphereRadius - (c - v*v); if (d < 0.0) return false; outdistance = v - sqrt(d); return true; }
void effect_clouds::draw_obj() { nya_render::set_modelview_matrix(nya_scene::get_camera().get_view_matrix()); nya_render::depth_test::enable(nya_render::depth_test::less); nya_render::zwrite::disable(); nya_render::cull_face::disable(); nya_render::blend::enable(nya_render::blend::src_alpha, nya_render::blend::inv_src_alpha); m_mesh.bind(); m_shader_obj.internal().set(); m_obj_tex.internal().set(); for (uint32_t i = 0; i < m_dist_sort.size(); ++i) { auto cp = nya_scene::get_camera().get_pos(); auto d = m_clouds.obj_clouds[i].second - nya_math::vec2(cp.x,cp.z); m_dist_sort[i].first = d.length_sq(); m_dist_sort[i].second = i; } std::sort(m_dist_sort.rbegin(), m_dist_sort.rend()); const float fade_far = 25000; //ToDo: map params const float height = 1500; //ToDo: map params for (const auto &d: m_dist_sort) { if (d.first > fade_far * fade_far) continue; const auto &o = m_clouds.obj_clouds[d.second]; auto &l = m_obj_levels[d.second % m_obj_levels.size()]; m_shader_obj.internal().set_uniform_value(m_shader_pos, o.second.x, height, o.second.y, 0.0f); m_mesh.draw(l.offset,l.count); } nya_render::blend::disable(); m_obj_tex.internal().unset(); m_shader_obj.internal().unset(); m_mesh.unbind(); }
void avoid_others(game* g, entity* self) { for(auto e : g->_entities) { if (e == self) continue; if (e->_type != ET_BUG) continue; vec2 delta = self->centre() - e->centre(); float dist = 0.25f + 0.25f; if (length_sq(delta) > square(dist)) continue; float l = length(delta); vec2 v = delta / l; if (l < 0.00001f) v = g_game_rand.sv2rand(1.0f); v *= ((dist - l) / dist) * 2.0f; self->_vel += v * DT; //e->_vel -= v * DT; } }
bool separationtTest(int x, int y, int z, int grid[3], const float4x4 &mCameraProj, PointLight* light) { float4 mCameraNearFar;// = float4(viewerCamera->GetFarClip(), viewerCamera->GetNearClip(), 0.0f, 0.0f); GetNearFarFromProjMatr(mCameraProj, mCameraNearFar.y, mCameraNearFar.x); //D3DXMATRIX mCameraProj = *viewerCamera->GetProjMatrix(); // sub-frustrum bounds in view space float minZ = (z - 0) * 1.0f / grid[2] * (mCameraNearFar.y - mCameraNearFar.x) + mCameraNearFar.x; float maxZ = (z + 1) * 1.0f / grid[2] * (mCameraNearFar.y - mCameraNearFar.x) + mCameraNearFar.x; float minZminX = -(1 - 2.0f / grid[0] * (x - 0))*minZ / mCameraProj.r0.x; float minZmaxX = -(1 - 2.0f / grid[0] * (x + 1))*minZ / mCameraProj.r0.x; float minZminY = (1 - 2.0f / grid[1] * (y - 0))*minZ / mCameraProj.r1.y; float minZmaxY = (1 - 2.0f / grid[1] * (y + 1))*minZ / mCameraProj.r1.y; float maxZminX = -(1 - 2.0f / grid[0] * (x - 0))*maxZ / mCameraProj.r0.x; float maxZmaxX = -(1 - 2.0f / grid[0] * (x + 1))*maxZ / mCameraProj.r0.x; float maxZminY = (1 - 2.0f / grid[1] * (y - 0))*maxZ / mCameraProj.r1.y; float maxZmaxY = (1 - 2.0f / grid[1] * (y + 1))*maxZ / mCameraProj.r1.y; // heuristic plane separation test - works pretty well in practice float3 minZcenter = float3((minZminX + minZmaxX) / 2, (minZminY + minZmaxY) / 2, minZ); float3 maxZcenter = float3((maxZminX + maxZmaxX) / 2, (maxZminY + maxZmaxY) / 2, maxZ); float3 center = (minZcenter + maxZcenter) / 2; float3 normal = center - light->positionView; normal /= normal.length(); // compute distance of all corners to the tangent plane, with a few shortcuts (saves 14 muls) float min_d1 = -dot(normal, light->positionView); float min_d2 = min_d1; min_d1 += std::min(normal.x * minZminX, normal.x * minZmaxX); min_d1 += std::min(normal.y * minZminY, normal.y * minZmaxY); min_d1 += normal.z * minZ; min_d2 += std::min(normal.x * maxZminX, normal.x * maxZmaxX); min_d2 += std::min(normal.y * maxZminY, normal.y * maxZmaxY); min_d2 += normal.z * maxZ; float min_d = std::min(min_d1, min_d2); bool separated = min_d > light->attenuationEnd; // exact frustrum-sphere test // gain depends on effectiveness of the plane heuristic: // with very fine-grained clusters, only ~0.5% // with badly balanced (64x32x32) clusters, 5-15% if (false) if (!separated) { // corners of the convex hull float3 corners[8]; corners[0] = float3(minZminX, minZminY, minZ); corners[1] = float3(minZmaxX, minZminY, minZ); corners[2] = float3(minZminX, minZmaxY, minZ); corners[3] = float3(minZmaxX, minZmaxY, minZ); corners[4] = float3(maxZminX, maxZminY, maxZ); corners[5] = float3(maxZmaxX, maxZminY, maxZ); corners[6] = float3(maxZminX, maxZmaxY, maxZ); corners[7] = float3(maxZmaxX, maxZmaxY, maxZ); int min_k = 0; float min_dist = length(corners[0] - light->positionView); for (int k = 1; k < 8; k++) { if (length(corners[k] - light->positionView) < min_dist) { min_dist = length(corners[k] - light->positionView); min_k = k; } } // closest edges float3 nearest_corners[4]; nearest_corners[0] = corners[min_k ^ 0]; nearest_corners[1] = corners[min_k ^ 1]; nearest_corners[2] = corners[min_k ^ 2]; nearest_corners[3] = corners[min_k ^ 4]; float dot_a = dot(light->positionView - nearest_corners[0], nearest_corners[1] - nearest_corners[0]); float dot_b = dot(light->positionView - nearest_corners[0], nearest_corners[2] - nearest_corners[0]); float dot_c = dot(light->positionView - nearest_corners[0], nearest_corners[3] - nearest_corners[0]); if (dot_a < 0 && dot_b < 0 && dot_c < 0) { // point-sphere } else if (dot_a < 0 && dot_b < 0) { // edge-sphere float dot = dot_c; float norm = length(nearest_corners[3] - nearest_corners[0]); min_dist = sqrtf(min_dist*min_dist - dot*dot / (norm*norm)); } else if (dot_a < 0 && dot_c < 0) { // edge-sphere float dot = dot_b; float norm = length(nearest_corners[2] - nearest_corners[0]); min_dist = sqrtf(min_dist*min_dist - dot*dot / (norm*norm)); } else if (dot_b < 0 && dot_c < 0) { // edge-sphere float dot = dot_a; float norm = length(nearest_corners[1] - nearest_corners[0]); min_dist = sqrtf(min_dist*min_dist - dot*dot / (norm*norm)); } else if (dot_a < 0 || dot_b < 0 || dot_c < 0) { // plane-sphere float dot_xp; float dot_yp; float dot_xx; float dot_yy; float dot_xy; if (dot_c < 0) { dot_xp = dot_a; dot_yp = dot_b; dot_xx = length_sq(nearest_corners[1] - nearest_corners[0]); dot_yy = length_sq(nearest_corners[2] - nearest_corners[0]); dot_xy = dot(nearest_corners[1] - nearest_corners[0], nearest_corners[2] - nearest_corners[0]); } else if (dot_b < 0) { dot_xp = dot_a; dot_yp = dot_c; dot_xx = length_sq(nearest_corners[1] - nearest_corners[0]); dot_yy = length_sq(nearest_corners[3] - nearest_corners[0]); dot_xy = dot(nearest_corners[1] - nearest_corners[0], nearest_corners[3] - nearest_corners[0]); } else if (dot_a < 0) { dot_xp = dot_b; dot_yp = dot_c; dot_xx = length_sq(nearest_corners[2] - nearest_corners[0]); dot_yy = length_sq(nearest_corners[3] - nearest_corners[0]); dot_xy = dot(nearest_corners[2] - nearest_corners[0], nearest_corners[3] - nearest_corners[0]); } // 2x2 matrix solve => get coordinates in plane float inv_det = 1 / (dot_xx*dot_yy - dot_xy*dot_xy); float mu_x = inv_det*(dot_yy*dot_xp - dot_xy*dot_yp); float mu_y = inv_det*(-dot_xy*dot_xp + dot_xx*dot_yp); float3 pp; if (dot_c < 0) pp = mu_x*(nearest_corners[1] - nearest_corners[0]) + mu_y*(nearest_corners[2] - nearest_corners[0]); if (dot_b < 0) pp = mu_x*(nearest_corners[1] - nearest_corners[0]) + mu_y*(nearest_corners[3] - nearest_corners[0]); if (dot_a < 0) pp = mu_x*(nearest_corners[2] - nearest_corners[0]) + mu_y*(nearest_corners[3] - nearest_corners[0]); float dot_xpp = 0, dot_ypp = 0; if (dot_c < 0) dot_xpp = dot(pp, nearest_corners[1] - nearest_corners[0]); if (dot_c < 0) dot_ypp = dot(pp, nearest_corners[2] - nearest_corners[0]); if (dot_b < 0) dot_xpp = dot(pp, nearest_corners[1] - nearest_corners[0]); if (dot_b < 0) dot_ypp = dot(pp, nearest_corners[3] - nearest_corners[0]); if (dot_a < 0) dot_xpp = dot(pp, nearest_corners[2] - nearest_corners[0]); if (dot_a < 0) dot_ypp = dot(pp, nearest_corners[3] - nearest_corners[0]); assert(abs(dot_xpp - dot_xp) < 0.001f); assert(abs(dot_ypp - dot_yp) < 0.001f); float dot_pp = mu_x*mu_x*dot_xx + mu_y*mu_y*dot_yy + 2 * mu_x*mu_y*dot_xy; min_dist = sqrtf(min_dist*min_dist - dot_pp); } else { // inside min_dist = 0; } if (min_dist > light->attenuationEnd) separated = true; } return separated; }
COMP_T length( vecn<N, COMP_T> const& v) { return std::sqrt(length_sq(v)); }
T aabb2<T>::get_radius_sq() const { return length_sq(get_extent()) * 0.25f; }
T aabb2<T>::get_radius_fast() const { float radiusSq = length_sq(get_extent()) * 0.25f; return sqrt(radiusSq); }
inline bool line3<T>::is_between_points(const vec3<T>& point, const vec3<T>& begin, const vec3<T>& stop) const { const T f = length_sq(stop - begin); return distance_sq(point, begin) <= f && distance_sq(point, stop) <= f; }
void game_hack::p_physics(float dt) { LE_UNUSED_VAR(dt); auto * game_space = get_owning_entity()->get_owning_space(); // Quick and dirty hack until actual physics is in place. std::vector<entity *> curr_ents; curr_ents.reserve(game_space->entity_num()); for(auto physics_comp_it = game_space->engine_component_begin<physics_component>(); physics_comp_it != game_space->engine_component_end<physics_component>(); ++physics_comp_it) { curr_ents.emplace_back((*physics_comp_it)->get_owning_entity()); } // n^2 collision detection using circles based on pos/scale for(auto ent_outer_it = curr_ents.begin(); ent_outer_it != curr_ents.end(); ++ent_outer_it) { // Don't consider this object or ones before it for testing (they've already been tested). for(auto ent_inner_it = ent_outer_it + 1; ent_inner_it != curr_ents.end(); ++ent_inner_it) { auto ent_outer = (*ent_outer_it); auto ent_inner = (*ent_inner_it); auto * ent_outer_t = ent_outer->get_component<transform_component>(); auto * ent_inner_t = ent_inner->get_component<transform_component>(); auto * ent_outer_sprite = ent_outer->get_component<sprite_component>(); auto * ent_inner_sprite = ent_inner->get_component<sprite_component>(); if(!ent_outer_sprite || !ent_inner_sprite) { continue; } float const ent_outer_radius = ent_outer_t->get_scale_x() * ent_outer_sprite->get_dimensions().x() * 0.5f; float const ent_inner_radius = ent_inner_t->get_scale_x() * ent_inner_sprite->get_dimensions().x() * 0.5f; float const dist_sq = length_sq(ent_inner_t->get_pos() - ent_outer_t->get_pos()); float const r_sum = ent_outer_radius + ent_inner_radius; float r_sum_sq = r_sum * r_sum; if(dist_sq <= r_sum_sq) { entity * ents[2] = { ent_outer, ent_inner }; // No collision messages implemented, the results of a collision are acted upon here for // now for(int ent_check_it = 0; ent_check_it < 2; ++ent_check_it) { // Kill non-enemies that collide with enemies if(ents[ent_check_it]->get_component<enemy_damage>()) { // Enemies don't kill other enemies if(ents[!ent_check_it]->get_component<enemy_damage>() == false) { ents[!ent_check_it]->kill(); } } // Kill enemies that collide with bullts if(ents[ent_check_it]->get_component<bullet_damage>()) { // Don't kill on collision with shooter or other bullets if(ents[ent_check_it]->get_component<bullet_damage>()->get_shooter_id() != ents[!ent_check_it]->get_id().value() && ents[!ent_check_it]->get_component<bullet_damage>() == nullptr) { ents[0]->kill(); ents[1]->kill(); } } } } } } }
inline bool is_normal(const unsigned short *from) { const auto n = half3_as_vec3(from); const float l = n.length_sq(); return l == 0 || fabsf(l - 1.0f) < 0.05f; }
bool within(entity* a, entity* b, float d) { return a && b && (length_sq(a->_pos - b->_pos) < square(d)); }
T triangle3<T>::get_area_sq() const { return length_sq(cross((pointB - pointA),pointC - pointA)) * 0.25f; }
inline bool line3<T>::get_intersection_with_line(const line3<T>& other, vec3<T>& intersection) const { //handle the case of being parallel separately vec3<T> dir = get_vector().normalize(); vec3<T> otherDir = other.getVector().normalize(); T dotf = dot(dir, otherDir); if(equals(abs(dotf - 1.0f), 0.0f)) { //std::cout<<"getIntersection(): is parallel\n"; //the lines are parallel, special case if(!is_point_on_line(other.start)) { //std::cout<<"doesn't lie on infinite line\n"; return false; } //there are multiple intersection points //we don't try to figure out which one the user wants, //and just give him the first one we find if(is_point_between_start_and_end(other.start)) { intersection = other.start; return true; } if(is_point_between_start_and_end(other.end)) { intersection = other.end; return true; } if(other.isPointBetweenStartAndEnd(start)) { intersection = start; return true; } //std::cout<<"none were between start and end\n"; return false; } else { T A = length_sq(get_vector()); T B = 2*(dot(get_vector(), start) - dot(get_vector(), other.start)); T C = 2*(dot(get_vector(), other.getVector())); T D = 2*(dot(other.getVector(), other.start) - dot(other.getVector(), start)); T E = length_sq(other.getVector()); T s = (2*A*D+B*C) / (C*C-4*A*E); T t=(C*s-B)/(2*A); vec3<T> point1 = start + get_vector() * t; vec3<T> point2 = other.start + other.getVector() * s; //std::cout<<"points are "<<point1<<", "<<point2<<"\n"; if(equals(point1, point2)) { if(is_point_between_start_and_end(point1) && other.isPointBetweenStartAndEnd(point1)) { intersection = point1; return true; } return false; } else { return false; } } }
inline float length( const Vector& v ) { return sqrtf( length_sq( v ) ); }
inline typename detail::element_type_of< T_ >::type length( T_ const& r ) { return std::sqrt( length_sq( r ) ); }