// 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(); }
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;; }
void Barrier::UpdateMinMax() { Processor::UpdateMinMax(); GetMinMax(m_min,m_max,m_barrier); }
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; }
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); }
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); } }