Beispiel #1
0
// Returns true if there is no collision, and false if there is a collision.
bool TestSAT(AABB a, AABB b)
{
	// Since these are AABB collisions, we can easily determine the normals. That said, this was left this way for understanding and future implementation.
	// The first step is to get the normals for the two colliding objects, as these will be the axes on which we test for collisions.
	std::vector<glm::vec3> aNormals = GetNormals(a);
	std::vector<glm::vec3> bNormals = GetNormals(b);
	
	// A quick method that exists for getting the points of the AABB. In a regular implementation, we might instead pass in the actual points to this algorithm, skipping
	// this step.
	std::vector<glm::vec3> aPoints = GetPoints(a);
	std::vector<glm::vec3> bPoints = GetPoints(b);

	// This boolean gets returned, and will be true if there is no collision.
	bool isSeparated = false;

	// For each normal
	for (int i = 0; i < aNormals.size(); i++)
	{
		// Get the Min and Max projections for each object along the normal.
		float aMin, aMax;
		GetMinMax(aPoints, aNormals[i], aMin, aMax);

		float bMin, bMax;
		GetMinMax(bPoints, aNormals[i], bMin, bMax);

		// If the maximum projection of one of the objects is less than the minimum projection of the other object, then we can determine that there is a separation 
		// along this axis. Thus, we set isSeparated to true and break out of the for loop.
		isSeparated = aMax < bMin || bMax < aMin;
		if (isSeparated) break;
	}

	// This only runs if we still haven't proven that there is a separation between the two objects.
	// SAT is an optimistic algorithm in that it will stop the moment it determines there isn't a collision, and as such the less collisions there are the faster it will run.
	if (!isSeparated)
	{
		// Loop through the normals for the second object.
		// Note that since this is an AABB, the normals will be the same as the previous object. Again, this is left for future implementation and understanding.
		// The process below is exactly the same as above, only with object b's normals instead of object a.
		for (int i = 0; i < bNormals.size(); i++)
		{
			float aMin, aMax;
			GetMinMax(aPoints, bNormals[i], aMin, aMax);

			float bMin, bMax;
			GetMinMax(bPoints, bNormals[i], bMin, bMax);

			isSeparated = aMax < bMin || bMax < aMin;
			if (isSeparated) break;
		}
	}

	// At this point, isSeparated has been tested against each normal. If it has been set to true, then there is a separation. If it is false, that means none of the axes 
	// were separated, and there is a collision.
	return isSeparated;
}
void Collider::calculateAABB()
{	
	if (type == ColliderType::Sphere) {
		alignedSize = vector3(1) * transform->GetScale();
	}
	else {
		CalculateOBB();

		GetMinMax(min, max, obb.verts);
		alignedSize.x = max.x - min.x;
		alignedSize.y = max.y - min.y;
		alignedSize.z = max.z - min.z;
	}
}
//The big 3
Collider::Collider(std::vector<vector3> a_lVectorList, GOTransform* transform)
{
	this->transform = transform;
	GetMinMax(min, max, a_lVectorList);
	centroid = (min + max) / 2.0f;

	radius = glm::distance(centroid, max);

	size.x = max.x - min.x;
	size.y = max.y - min.y;
	size.z = max.z - min.z;
	alignedSize = size;

	CalculateOBB();
}
Beispiel #4
0
bool FLYCALL FlyEngine_Core::Geometry_Load(vector<const wchar_t*> resourcesToLoad, vector<Entity*>* objects)
{
	std::vector<ImportedObjectData> raw;
	if(!ResourceImporter::ImportObject(resourcesToLoad , &raw))
		return false;
	
	for (int i = 0; i < (int)raw.size(); i++)
	{
		for (int k = 0; k < (int)raw[i].objects.size(); k++)
		{
			BoundingBox bb;
			bb.minPoint = vec3((*raw[i].objects[k].vertex)[0].position.x, (*raw[i].objects[k].vertex)[0].position.y, (*raw[i].objects[k].vertex)[0].position.z);
			bb.maxPoint = bb.minPoint;
			for (int j = 0; j < (int)raw[i].objects[k].vertex->size(); j++)
			{
				GetMinMax(bb, (*raw[i].objects[k].vertex)[j].position);
			}
			BoundingSphere* bs = new BoundingSphere();
			bs->radius = D3DXVec3Length(&(bb.maxPoint - bb.minPoint)) * 0.5f;
			bs->center = (bb.maxPoint + bb.minPoint) * 0.5f;

			FlyMesh::OBJECT_DESC d;
			d.device = D3DShell::self()->getDevice();
			d.deviceContext = D3DShell::self()->getDeviceContext();
			d.material_id = raw[i].objects[k].material;
			d.name = raw[i].name;
			d.shader = 0;
			d.vCount = (int)raw[i].objects[k].vertex->size();
			d.vertecies = raw[i].objects[k].vertex;
			d.boundingSphere = bs;

			FlyMesh *obj = new FlyMesh();
			if(!obj->Initialize(d))
				return false;
			objects->push_back(obj);
		}
	}

	return true;;
}
Beispiel #5
0
void Barrier::UpdateMinMax()
{
	Processor::UpdateMinMax();
	GetMinMax(m_min,m_max,m_barrier);
}
Beispiel #6
0
bool FLYCALL FlyEngine_Core::Geometry_Load(const wchar_t* path, vector<Entity*>* objects, FlyEngineGeometry special)
{
	ImportedObjectData raw;
	if(!ResourceImporter::ImportObject(path, &raw))
		return false;

	if(special == FlyGeometry_Terrain)
	{
		for (int i = 0; i < (int)raw.objects.size(); i++)
		{
			BoundingBox bb;
			bb.minPoint = vec3((*raw.objects[i].vertex)[0].position.x, (*raw.objects[i].vertex)[0].position.y, (*raw.objects[i].vertex)[0].position.z);
			bb.maxPoint = bb.minPoint;
			for (int k = 0; k < (int)raw.objects[i].vertex->size(); k++)
			{
				GetMinMax(bb, (*raw.objects[i].vertex)[k].position);
			}
			BoundingSphere* bs = new BoundingSphere();
			bs->radius = D3DXVec3Length(&(bb.maxPoint - bb.minPoint)) * 0.5f;
			bs->center = (bb.maxPoint + bb.minPoint) * 0.5f;


			FlyMesh::OBJECT_DESC d;
			d.device = D3DShell::self()->getDevice();
			d.deviceContext = D3DShell::self()->getDeviceContext();
			d.material_id = raw.objects[i].material;
			d.name = raw.name;
			d.shader = 0;
			d.vCount = (int)raw.objects[i].vertex->size();
			d.vertecies = raw.objects[i].vertex;
			d.boundingSphere = bs;

			Terrain *obj = new Terrain();
			if(!obj->Initialize(d))
				return false;
			objects->push_back(obj);
		}
	}
	else if(special == FlyGeometry_AnimatedMesh)
	{

		ImportedObjectData raw;
		if(!ResourceImporter::ImportObject(path, &raw))
			return false;

		SmartPtrStd<std::vector<BoundingSphere>> boundingSpheres; 
		boundingSpheres = new vector<BoundingSphere>; 
		SmartPtrStd<std::vector<std::vector<FrameData>>> frames; 
		frames  = new vector<vector<FrameData>>; 
		SmartPtrStd<std::vector<std::vector<VERTEX::VertexPNT>>> vert; 
		vert = new vector<vector<VERTEX::VertexPNT>>;

		for (int i = 0; i < (int)raw.objects.size(); i++)
		{
			BoundingBox bb;
			bb.minPoint = vec3((*raw.objects[i].vertex)[0].position.x, (*raw.objects[i].vertex)[0].position.y, (*raw.objects[i].vertex)[0].position.z);
			bb.maxPoint = bb.minPoint;
			for (int k = 0; k < (int)raw.objects[i].vertex->size(); k++)
			{
				GetMinMax(bb, (*raw.objects[i].vertex)[k].position);
			}
			BoundingSphere bs;
			bs.radius = D3DXVec3Length(&(bb.maxPoint - bb.minPoint)) * 0.5f;
			bs.center = (bb.maxPoint + bb.minPoint) * 0.5f;
			(*boundingSpheres).push_back(bs);
			
		
			std::vector<VERTEX::VertexPNT> tempVector;
			tempVector.resize(raw.objects[i].vertex->size());

			for(int k =0;k<(int)raw.objects[i].vertex->size(); k++)
			{
				tempVector.at(k) = raw.objects[i].vertex->at(k);
			}
			(*vert).push_back(tempVector);
			
		}
		(*frames).resize(raw.animations.size());
		for(int i = 0; i<(int)raw.animations.size(); i++)
		{
			for(int k = 0; k<(int)raw.animations.at(i).frames.size(); k++)
			{
				(*frames).at(i).push_back(raw.animations.at(i).frames.at(k));
			}
		}

		
		FlyMeshAnimated::ANIM_OBJECT_DESC d;
		d.device = D3DShell::self()->getDevice();
		d.deviceContext = D3DShell::self()->getDeviceContext();
		d.material_id = raw.objects[0].material;
		d.name = raw.name;
		d.shader = 0;
		d.vCount = (int)raw.objects[0].vertex->size();
		d.vertecies = vert;
		d.boundingSphere = boundingSpheres;
		d.frames =  frames;

		FlyMeshAnimated *obj = new FlyMeshAnimated();
		if(!obj->Initialize(d))
			return false;
		objects->push_back(obj);

		(*boundingSpheres).clear();
		(*frames).clear(); 
		(*vert).clear(); 
	}

	return true;
}
Beispiel #7
0
void
TrailRenderer::Draw(Canvas &canvas, const TraceComputer &trace_computer,
                    const WindowProjection &projection, unsigned min_time,
                    bool enable_traildrift, const RasterPoint pos,
                    const NMEAInfo &basic, const DerivedInfo &calculated,
                    const TrailSettings &settings)
{
  if (settings.length == TrailSettings::Length::OFF)
    return;

  if (!LoadTrace(trace_computer, min_time, projection))
    return;

  if (!calculated.wind_available)
    enable_traildrift = false;

  GeoPoint traildrift;
  if (enable_traildrift) {
    GeoPoint tp1 = FindLatitudeLongitude(basic.location,
                                         calculated.wind.bearing,
                                         calculated.wind.norm);
    traildrift = basic.location - tp1;
  }

  auto minmax = GetMinMax(settings.type, trace);
  auto value_min = minmax.first;
  auto value_max = minmax.second;

  bool scaled_trail = settings.scaling_enabled &&
                      projection.GetMapScale() <= 6000;

  const GeoBounds bounds = projection.GetScreenBounds().Scale(4);

  RasterPoint last_point = RasterPoint(0, 0);
  bool last_valid = false;
  for (auto it = trace.begin(), end = trace.end(); it != end; ++it) {
    const GeoPoint gp = enable_traildrift
      ? it->GetLocation().Parametric(traildrift,
                                     it->CalculateDrift(basic.time))
      : it->GetLocation();
    if (!bounds.IsInside(gp)) {
      /* the point is outside of the MapWindow; don't paint it */
      last_valid = false;
      continue;
    }

    RasterPoint pt = projection.GeoToScreen(gp);

    if (last_valid) {
      if (settings.type == TrailSettings::Type::ALTITUDE) {
        unsigned index = GetAltitudeColorIndex(it->GetAltitude(),
                                               value_min, value_max);
        canvas.Select(look.trail_pens[index]);
        canvas.DrawLinePiece(last_point, pt);
      } else {
        unsigned color_index = GetSnailColorIndex(it->GetVario(),
                                                  value_min, value_max);
        if (it->GetVario() < 0 &&
            (settings.type == TrailSettings::Type::VARIO_1_DOTS ||
             settings.type == TrailSettings::Type::VARIO_2_DOTS ||
             settings.type == TrailSettings::Type::VARIO_DOTS_AND_LINES)) {
          canvas.SelectNullPen();
          canvas.Select(look.trail_brushes[color_index]);
          canvas.DrawCircle((pt.x + last_point.x) / 2, (pt.y + last_point.y) / 2,
                            look.trail_widths[color_index]);
        } else {
          // positive vario case

          if (settings.type == TrailSettings::Type::VARIO_DOTS_AND_LINES) {
            canvas.Select(look.trail_brushes[color_index]);
            canvas.Select(look.trail_pens[color_index]); //fixed-width pen
            canvas.DrawCircle((pt.x + last_point.x) / 2, (pt.y + last_point.y) / 2,
                              look.trail_widths[color_index]);
          } else if (scaled_trail)
            // width scaled to vario
            canvas.Select(look.scaled_trail_pens[color_index]);
          else
            // fixed-width pen
            canvas.Select(look.trail_pens[color_index]);

          canvas.DrawLinePiece(last_point, pt);
        }
      }
    }
    last_point = pt;
    last_valid = true;
  }

  if (last_valid)
    canvas.DrawLine(last_point, pos);
}
Beispiel #8
0
void CGUIDialogMediaFilter::GetRange(const Filter &filter, int &min, int &interval, int &max)
{
  if (filter.field == FieldUserRating &&
     (m_mediaType == "movies" || m_mediaType == "tvshows" || m_mediaType == "episodes"|| m_mediaType == "musicvideos" || m_mediaType == "albums" || m_mediaType == "songs"))
  {
    min = 0;
    interval = 1;
    max = 10;
  }
  else if (filter.field == FieldYear)
  {
    min = 0;
    interval = 1;
    max = 0;

    if (m_mediaType == "movies" || m_mediaType == "tvshows" || m_mediaType == "musicvideos")
    {
      std::string table;
      std::string year;
      if (m_mediaType == "movies")
      {
        table = "movie_view";
        year = DatabaseUtils::GetField(FieldYear, MediaTypeMovie, DatabaseQueryPartWhere);
      }
      else if (m_mediaType == "tvshows")
      {
        table = "tvshow_view";
        year = StringUtils::Format("strftime(\"%%Y\", %s)", DatabaseUtils::GetField(FieldYear, MediaTypeTvShow, DatabaseQueryPartWhere).c_str());
      }
      else if (m_mediaType == "musicvideos")
      {
        table = "musicvideo_view";
        year = DatabaseUtils::GetField(FieldYear, MediaTypeMusicVideo, DatabaseQueryPartWhere);
      }

      CDatabase::Filter filter;
      filter.where = year + " > 0";
      GetMinMax(table, year, min, max, filter);
    }
    else if (m_mediaType == "albums" || m_mediaType == "songs")
    {
      std::string table;
      if (m_mediaType == "albums")
        table = "albumview";
      else if (m_mediaType == "songs")
        table = "songview";
      else
        return;

      CDatabase::Filter filter;
      filter.where = DatabaseUtils::GetField(FieldYear, CMediaTypes::FromString(m_mediaType), DatabaseQueryPartWhere) + " > 0";
      GetMinMax(table, DatabaseUtils::GetField(FieldYear, CMediaTypes::FromString(m_mediaType), DatabaseQueryPartSelect), min, max, filter);
    }
  }
  else if (filter.field == FieldAirDate)
  {
    min = 0;
    interval = 1;
    max = 0;

    if (m_mediaType == "episodes")
    {
      std::string field = StringUtils::Format("CAST(strftime(\"%%s\", c%02d) AS INTEGER)", VIDEODB_ID_EPISODE_AIRED);
      
      GetMinMax("episode_view", field, min, max);
      interval = 60 * 60 * 24 * 7; // 1 week
    }
  }
  else if (filter.field == FieldTime)
  {
    min = 0;
    interval = 10;
    max = 0;

    if (m_mediaType == "songs")
      GetMinMax("songview", "iDuration", min, max);
  }
  else if (filter.field == FieldPlaycount)
  {
    min = 0;
    interval = 1;
    max = 0;

    if (m_mediaType == "songs")
      GetMinMax("songview", "iTimesPlayed", min, max);
  }
}