float DistanceToQuad(const vec3& p, const vec3& v1, const vec3& v2, const vec3& v3, const vec3& v4, const vec3& n) { float flPlaneDistance = DistanceToPlane(p, v1, n); if (PointInTriangle(p, v1, v2, v3)) return flPlaneDistance; if (PointInTriangle(p, v1, v3, v4)) return flPlaneDistance; float flClosestPointSqr = (v1 - p).LengthSqr(); float flV2Sqr = (v2 - p).LengthSqr(); float flV3Sqr = (v3 - p).LengthSqr(); float flV4Sqr = (v4 - p).LengthSqr(); flClosestPointSqr = smaller(flClosestPointSqr, smaller(flV2Sqr, smaller(flV3Sqr, flV4Sqr))); float flClosestPoint = sqrt(flClosestPointSqr); float flV12 = DistanceToLineSegment(p, v1, v2); float flV23 = DistanceToLineSegment(p, v2, v3); float flV34 = DistanceToLineSegment(p, v3, v4); float flV41 = DistanceToLineSegment(p, v4, v1); flClosestPoint = smaller(flClosestPoint, smaller(flV12, smaller(flV23, smaller(flV34, flV41)))); return flClosestPoint; }
void CDigitanksEntity::InterceptSupplyLines() { // Haha... no. if (dynamic_cast<CSupplyLine*>(this)) return; if (!GetPlayerOwner()) return; for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++) { CBaseEntity* pEntity = CBaseEntity::GetEntity(i); if (!pEntity) continue; CSupplyLine* pSupplyLine = dynamic_cast<CSupplyLine*>(pEntity); if (!pSupplyLine) continue; if (pSupplyLine->GetPlayerOwner() == GetPlayerOwner()) continue; if (!pSupplyLine->GetPlayerOwner()) continue; if (!pSupplyLine->GetSupplier() || !pSupplyLine->GetEntity()) continue; Vector vecEntity = GetGlobalOrigin(); vecEntity.z = 0; Vector vecSupplier = pSupplyLine->GetSupplier()->GetGlobalOrigin(); vecSupplier.z = 0; Vector vecUnit = pSupplyLine->GetEntity()->GetGlobalOrigin(); vecUnit.z = 0; if (DistanceToLineSegment(vecEntity, vecSupplier, vecUnit) > GetBoundingRadius()+4) continue; bool bFound = false; for (size_t j = 0; j < m_ahSupplyLinesIntercepted.size(); j++) { if (pSupplyLine == m_ahSupplyLinesIntercepted[j]) { bFound = true; break; } } if (!bFound) { pSupplyLine->Intercept(0.2f); m_ahSupplyLinesIntercepted.push_back(pSupplyLine); } } }
float DistanceToPolygon(const vec3& p, tvector<vec3>& v, vec3 n) { float flPlaneDistance = DistanceToPlane(p, v[0], n); size_t i; bool bFoundPoint = false; for (i = 0; i < v.size()-2; i++) { if (PointInTriangle(p, v[0], v[i+1], v[i+2])) { bFoundPoint = true; break; } } if (bFoundPoint) return flPlaneDistance; float flClosestPoint = -1; for (i = 0; i < v.size(); i++) { float flPointDistance = (v[i] - p).Length(); if (flClosestPoint == -1 || (flPointDistance < flClosestPoint)) flClosestPoint = flPointDistance; float flLineDistance; if (i == v.size() - 1) flLineDistance = DistanceToLineSegment(p, v[i], v[0]); else flLineDistance = DistanceToLineSegment(p, v[i], v[i+1]); if (flClosestPoint == -1 || (flLineDistance < flClosestPoint)) flClosestPoint = flLineDistance; } return flClosestPoint; }
float CSupplyLine::Distance(Vector vecSpot) const { if (!m_hSupplier || !m_hEntity) return BaseClass::Distance(vecSpot); Vector vecSupplier = m_hSupplier->GetGlobalOrigin(); Vector vecEntity = m_hEntity->GetGlobalOrigin(); Vector vecSupplierFlat = vecSupplier; Vector vecEntityFlat = vecEntity; Vector vecSpotFlat = vecSpot; vecSupplierFlat.z = 0; vecEntityFlat.z = 0; vecSpotFlat.z = 0; Vector vecIntersection; float flDistance = DistanceToLineSegment(vecSpotFlat, vecSupplierFlat, vecEntityFlat, &vecIntersection); vecIntersection = DigitanksGame()->GetTerrain()->GetPointHeight(vecIntersection); return vecSpot.Distance(vecIntersection); }