Beispiel #1
0
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;
    }
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #4
0
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();
}
Beispiel #5
0
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;
}
Beispiel #7
0
COMP_T
length(
  vecn<N, COMP_T> const& v)
{
  return std::sqrt(length_sq(v));
}
Beispiel #8
0
T aabb2<T>::get_radius_sq() const
{
	return length_sq(get_extent()) * 0.25f;
}
Beispiel #9
0
T aabb2<T>::get_radius_fast() const
{
	float radiusSq = length_sq(get_extent()) * 0.25f;
	return sqrt(radiusSq);
}
Beispiel #10
0
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;
}
Beispiel #11
0
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;
}
Beispiel #13
0
bool within(entity* a, entity* b, float d) {
    return a && b && (length_sq(a->_pos - b->_pos) < square(d));
}
Beispiel #14
0
T triangle3<T>::get_area_sq() const
{
	return length_sq(cross((pointB - pointA),pointC - pointA)) * 0.25f;
}
Beispiel #15
0
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;
		}
	}
}
Beispiel #16
0
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 ) );
}