Example #1
0
std::vector<CFeature*> CQuadField::GetFeaturesExact(const float3& pos, float radius)
{
    GML_RECMUTEX_LOCK(qnum); // GetFeaturesExact

    const std::vector<int>& quads = GetQuads(pos, radius);
    const int tempNum = gs->tempNum++;

    std::vector<CFeature*> features;
    std::vector<int>::const_iterator qi;
    std::list<CFeature*>::iterator fi;

    for (qi = quads.begin(); qi != quads.end(); ++qi) {
        for (fi = baseQuads[*qi].features.begin(); fi != baseQuads[*qi].features.end(); ++fi) {
            if ((*fi)->tempNum == tempNum) {
                continue;
            }
            if (pos.SqDistance((*fi)->midPos) >= Square(radius + (*fi)->radius)) {
                continue;
            }

            (*fi)->tempNum = tempNum;
            features.push_back(*fi);
        }
    }

    return features;
}
Example #2
0
// should only be used by air
bool CTransportCAI::FindEmptyDropSpots(float3 startpos, float3 endpos, std::list<float3>& dropSpots)
{
	const float gap = 25.5f; // TODO - set tag for this?
	const float3 dir = (endpos - startpos).Normalize();

	float3 nextPos = startpos;

	dropSpots.push_front(nextPos);

	if (dynamic_cast<CHoverAirMoveType*>(owner->moveType) == NULL)
		return false;

	const auto& transportees = static_cast<CTransportUnit*>(owner)->GetTransportedUnits();
	auto ti = transportees.begin();

	// first spot
	if (ti != transportees.end()) {
		nextPos += (dir * (gap + ti->unit->radius));
		++ti;
	}

	// remaining spots
	while (ti != transportees.end() && startpos.SqDistance(nextPos) < startpos.SqDistance(endpos)) {
		nextPos += (dir * (ti->unit->radius));
		nextPos.y = CGround::GetHeightAboveWater(nextPos.x, nextPos.z);

		// check landing spot is ok for landing on
		if (!SpotIsClear(nextPos, ti->unit))
			continue;

		dropSpots.push_front(nextPos);
		nextPos += (dir * (gap + ti->unit->radius));
		++ti;
	}

	return true;
}
Example #3
0
bool CTransportCAI::FindEmptyDropSpots(float3 startpos, float3 endpos, std::list<float3>& dropSpots)
{
	//should only be used by air

	CTransportUnit* transport = static_cast<CTransportUnit*>(owner);
	//dropSpots.clear();
	float gap = 25.5; // TODO - set tag for this?
	float3 dir = endpos - startpos;
	dir.Normalize();

	float3 nextPos = startpos;
	float3 pos;

	std::list<CTransportUnit::TransportedUnit>::const_iterator ti = transport->GetTransportedUnits().begin();
	dropSpots.push_front(nextPos);

	// first spot
	if (ti != transport->GetTransportedUnits().end()) {
		nextPos += dir * (gap + ti->unit->radius);
		++ti;
	}

	// remaining spots
	if (dynamic_cast<CHoverAirMoveType*>(owner->moveType)) {
		while (ti != transport->GetTransportedUnits().end() && startpos.SqDistance(nextPos) < startpos.SqDistance(endpos)) {
			nextPos += dir * (ti->unit->radius);
			nextPos.y = ground->GetHeightAboveWater(nextPos.x, nextPos.z);

			// check landing spot is ok for landing on
			if (!SpotIsClear(nextPos,ti->unit))
				continue;

			dropSpots.push_front(nextPos);
			nextPos += dir * (gap + ti->unit->radius);
			++ti;
		}
		return true;
	}
	return false;
}
Example #4
0
std::vector<CUnit*> CQuadField::GetUnitsExact(const float3& pos, float radius, bool spherical)
{
    GML_RECMUTEX_LOCK(qnum); // GetUnitsExact

    const int tempNum = gs->tempNum++;

    int* begQuad = &tempQuads[0];
    int* endQuad = &tempQuads[0];

    GetQuads(pos, radius, begQuad, endQuad);

    std::vector<CUnit*> units;
    std::list<CUnit*>::iterator ui;

    for (int* a = begQuad; a != endQuad; ++a) {
        Quad& quad = baseQuads[*a];

        for (ui = quad.units.begin(); ui != quad.units.end(); ++ui) {
            if ((*ui)->tempNum == tempNum)
                continue;

            const float totRad       = radius + (*ui)->radius;
            const float totRadSq     = totRad * totRad;
            const float posUnitDstSq = spherical?
                                       pos.SqDistance((*ui)->midPos):
                                       pos.SqDistance2D((*ui)->midPos);

            if (posUnitDstSq >= totRadSq)
                continue;

            (*ui)->tempNum = tempNum;
            units.push_back(*ui);
        }
    }

    return units;
}
Example #5
0
static inline bool equals_distance(const float3& f1, const float3& f2)
{
	return ((f1.x == f2.x) && (f1.y == f2.y) && (f1.z == f2.z))
		|| epscmp2(f1.SqDistance(f2));
}
Example #6
0
// optimization specifically for projectile collisions
void CQuadField::GetUnitsAndFeaturesColVol(
    const float3& pos,
    const float radius,
    std::vector<CUnit*>& units,
    std::vector<CFeature*>& features,
    unsigned int* numUnitsPtr,
    unsigned int* numFeaturesPtr
) {
    GML_RECMUTEX_LOCK(qnum); // GetUnitsAndFeaturesColVol

    const int tempNum = gs->tempNum++;

    // start counting from the previous object-cache sizes
    unsigned int numUnits = (numUnitsPtr == NULL)? 0: (*numUnitsPtr);
    unsigned int numFeatures = (numFeaturesPtr == NULL)? 0: (*numFeaturesPtr);

    int* begQuad = &tempQuads[0];
    int* endQuad = &tempQuads[0];

    // bail early if caches are already full
    if (numUnits >= units.size())
        return;
    if (numFeatures >= features.size())
        return;

    assert(numUnits == 0 || units[numUnits] == NULL);
    assert(numFeatures == 0 || features[numFeatures] == NULL);

    GetQuads(pos, radius, begQuad, endQuad);

    std::list<CUnit*>::const_iterator ui;
    std::list<CFeature*>::const_iterator fi;

    for (int* a = begQuad; a != endQuad; ++a) {
        const Quad& quad = baseQuads[*a];

        for (ui = quad.units.begin(); ui != quad.units.end(); ++ui) {
            CUnit* u = *ui;

            // prevent double adding
            if (u->tempNum == tempNum)
                continue;

            const auto* colvol = u->collisionVolume;
            const float totRad = radius + colvol->GetBoundingRadius();

            if (pos.SqDistance(colvol->GetWorldSpacePos(u)) >= (totRad * totRad))
                continue;

            assert(numUnits < units.size());

            if (numUnits < units.size()) {
                u->tempNum = tempNum;
                units[numUnits++] = u;
            }
        }

        for (fi = quad.features.begin(); fi != quad.features.end(); ++fi) {
            CFeature* f = *fi;

            // prevent double adding
            if (f->tempNum == tempNum)
                continue;

            const auto* colvol = f->collisionVolume;
            const float totRad = radius + colvol->GetBoundingRadius();

            if (pos.SqDistance(colvol->GetWorldSpacePos(f)) >= (totRad * totRad))
                continue;

            assert(numFeatures < features.size());

            if (numFeatures < features.size()) {
                f->tempNum = tempNum;
                features[numFeatures++] = f;
            }
        }
    }

    assert(numUnits < units.size());
    assert(numFeatures < features.size());

    // set end-of-list sentinels
    if (numUnits < units.size())
        units[numUnits] = NULL;
    if (numFeatures < features.size())
        features[numFeatures] = NULL;

    if (numUnitsPtr != NULL) {
        *numUnitsPtr = numUnits;
    }
    if (numFeaturesPtr != NULL) {
        *numFeaturesPtr = numFeatures;
    }
}