Example #1
0
/*
Request a new multipath, store the result and return a handle-id to it.
*/
unsigned int CPathManager::RequestPath(
	CSolidObject* caller,
	const MoveDef* moveDef,
	float3 startPos,
	float3 goalPos,
	float goalRadius,
	bool synced
) {
	if (!IsFinalized())
		return 0;

	// in misc since it is called from many points
	SCOPED_TIMER("Misc::Path::RequestPath");
	startPos.ClampInBounds();
	goalPos.ClampInBounds();

	// Create an estimator definition.
	goalRadius = std::max<float>(goalRadius, PATH_NODE_SPACING * SQUARE_SIZE); //FIXME do on a per PE & PF level?
	assert(moveDef == moveDefHandler->GetMoveDefByPathType(moveDef->pathType));

	MultiPath newPath = MultiPath(moveDef, startPos, goalPos, goalRadius);
	newPath.finalGoal = goalPos;
	newPath.caller = caller;
	newPath.peDef.synced = synced;

	if (caller != nullptr)
		caller->UnBlock();

	const IPath::SearchResult result = ArrangePath(&newPath, moveDef, startPos, goalPos, caller);

	unsigned int pathID = 0;

	if (result != IPath::Error) {
		if (newPath.maxResPath.path.empty()) {
			if (result != IPath::CantGetCloser) {
				LowRes2MedRes(newPath, startPos, caller, synced);
				MedRes2MaxRes(newPath, startPos, caller, synced);
			} else {
				// add one dummy waypoint so that the calling MoveType
				// does not consider this request a failure, which can
				// happen when startPos is very close to goalPos
				//
				// otherwise, code relying on MoveType::progressState
				// (eg. BuilderCAI::MoveInBuildRange) would misbehave
				// (eg. reject build orders)
				newPath.maxResPath.path.push_back(startPos);
				newPath.maxResPath.squares.push_back(int2(startPos.x / SQUARE_SIZE, startPos.z / SQUARE_SIZE));
			}
		}

		FinalizePath(&newPath, startPos, goalPos, result == IPath::CantGetCloser);
		newPath.searchResult = result;
		pathID = Store(newPath);
	}

	if (caller != nullptr)
		caller->Block();

	return pathID;
}
Example #2
0
unsigned int CQuadField::GetQuads(float3 pos, float radius, int*& begQuad, int*& endQuad) const
{
    pos.ClampInBounds();
    pos.AssertNaNs();

    assert(begQuad == &tempQuads[0]);
    assert(endQuad == &tempQuads[0]);

    const int maxx = std::min((int(pos.x + radius)) / quadSizeX + 1, numQuadsX - 1);
    const int maxz = std::min((int(pos.z + radius)) / quadSizeZ + 1, numQuadsZ - 1);

    const int minx = std::max((int(pos.x - radius)) / quadSizeX, 0);
    const int minz = std::max((int(pos.z - radius)) / quadSizeZ, 0);

    if (maxz < minz || maxx < minx) {
        return 0;
    }

    // qsx and qsz are always equal
    const float maxSqLength = (radius + quadSizeX * 0.72f) * (radius + quadSizeZ * 0.72f);

    for (int z = minz; z <= maxz; ++z) {
        for (int x = minx; x <= maxx; ++x) {
            const float3 quadCenterPos = float3(x * quadSizeX + quadSizeX * 0.5f, 0, z * quadSizeZ + quadSizeZ * 0.5f);

            if ((pos - quadCenterPos).SqLength2D() < maxSqLength) {
                *endQuad = z * numQuadsX + x;
                ++endQuad;
            }
        }
    }

    return (endQuad - begQuad);
}
Example #3
0
std::vector<int> CQuadField::GetQuads(float3 pos, float radius) const
{
    pos.ClampInBounds();
    pos.AssertNaNs();

    std::vector<int> ret;

    // qsx and qsz are always equal
    const float maxSqLength = (radius + quadSizeX * 0.72f) * (radius + quadSizeZ * 0.72f);

    const int maxx = std::min((int(pos.x + radius)) / quadSizeX + 1, numQuadsX - 1);
    const int maxz = std::min((int(pos.z + radius)) / quadSizeZ + 1, numQuadsZ - 1);

    const int minx = std::max((int(pos.x - radius)) / quadSizeX, 0);
    const int minz = std::max((int(pos.z - radius)) / quadSizeZ, 0);

    if (maxz < minz || maxx < minx) {
        return ret;
    }

    ret.reserve((maxz - minz) * (maxx - minx));

    for (int z = minz; z <= maxz; ++z) {
        for (int x = minx; x <= maxx; ++x) {
            if ((pos - float3(x * quadSizeX + quadSizeX * 0.5f, 0, z * quadSizeZ + quadSizeZ * 0.5f)).SqLength2D() < maxSqLength) {
                ret.push_back(z * numQuadsX + x);
            }
        }
    }

    return ret;
}
Example #4
0
IPath::SearchResult IPathFinder::GetPath(
	const MoveDef& moveDef,
	const CPathFinderDef& pfDef,
	const CSolidObject* owner,
	float3 startPos,
	IPath::Path& path,
	const unsigned int maxNodes
) {
	startPos.ClampInBounds();

	// Clear the path
	path.path.clear();
	path.squares.clear();
	path.pathCost = PATHCOST_INFINITY;

	// initial calculations
	if (isEstimator) {
		maxBlocksToBeSearched = std::min(MAX_SEARCHED_NODES_PE - 8U, maxNodes);
	} else {
		maxBlocksToBeSearched = std::min(MAX_SEARCHED_NODES_PF - 8U, maxNodes);
	}
	mStartBlock.x  = startPos.x / BLOCK_PIXEL_SIZE;
	mStartBlock.y  = startPos.z / BLOCK_PIXEL_SIZE;
	mStartBlockIdx = BlockPosToIdx(mStartBlock);
	assert((unsigned)mStartBlock.x < nbrOfBlocks.x && (unsigned)mStartBlock.y < nbrOfBlocks.y);

	// Check cache (when there is one)
	int2 goalBlock;
	goalBlock.x = pfDef.goalSquareX / BLOCK_SIZE;
	goalBlock.y = pfDef.goalSquareZ / BLOCK_SIZE;
	const CPathCache::CacheItem* ci = GetCache(mStartBlock, goalBlock, pfDef.sqGoalRadius, moveDef.pathType, pfDef.synced);
	if (ci != nullptr) {
		path = ci->path;
		return ci->result;
	}

	// Start up a new search
	IPath::SearchResult result = InitSearch(moveDef, pfDef, owner);

	// If search was successful, generate new path
	if (result == IPath::Ok || result == IPath::GoalOutOfRange) {
		FinishSearch(moveDef, pfDef, path);

		// Save to cache
		AddCache(&path, result, mStartBlock, goalBlock, pfDef.sqGoalRadius, moveDef.pathType, pfDef.synced);

		if (LOG_IS_ENABLED(L_DEBUG)) {
			LOG_L(L_DEBUG, "==== %s: Search completed ====", (isEstimator) ? "PE" : "PF");
			LOG_L(L_DEBUG, "Tested blocks: %u", testedBlocks);
			LOG_L(L_DEBUG, "Open blocks: %u", openBlockBuffer.GetSize());
			LOG_L(L_DEBUG, "Path length: " _STPF_, path.path.size());
			LOG_L(L_DEBUG, "Path cost: %f", path.pathCost);
			LOG_L(L_DEBUG, "==============================");
		}
	} else {
		if (LOG_IS_ENABLED(L_DEBUG)) {
			LOG_L(L_DEBUG, "==== %s: Search failed! ====", (isEstimator) ? "PE" : "PF");
			LOG_L(L_DEBUG, "Tested blocks: %u", testedBlocks);
			LOG_L(L_DEBUG, "Open blocks: %u", openBlockBuffer.GetSize());
			LOG_L(L_DEBUG, "============================");
		}
	}

	return result;
}
Example #5
0
void CFeature::Initialize(const float3& _pos, const FeatureDef* _def, short int _heading,
	int facing, int _team, int _allyteam, const UnitDef* _udef, const float3& speed, int _smokeTime)
{
	def = _def;
	udef = _udef;
	defName = def->myName;
	heading = _heading;
	buildFacing = facing;
	team = _team;
	allyteam = _allyteam;
	emitSmokeTime = _smokeTime;

	mass = def->mass;
	crushResistance = def->crushResistance;

	health   = def->maxHealth;
	blocking = def->blocking;

	xsize    = ((facing & 1) == 0) ? def->xsize : def->zsize;
	zsize    = ((facing & 1) == 1) ? def->xsize : def->zsize;

	noSelect = def->noSelect;

	float fRadius = 1.0f;
	float fHeight = 0.0f;

	if (def->drawType == DRAWTYPE_MODEL) {
		model = def->LoadModel();

		if (!model) {
			LOG_L(L_ERROR, "Features: Couldn't load model for %s", defName.c_str());
		} else {
			relMidPos = model->relMidPos;
			fRadius = model->radius;
			fHeight = model->height;

			// note: gets deleted in ~CSolidObject
			collisionVolume = new CollisionVolume(def->collisionVolume, fRadius);
		}
	}
	else if (def->drawType >= DRAWTYPE_TREE) {
		relMidPos = UpVector * TREE_RADIUS;
		fRadius = TREE_RADIUS;
		fHeight = fRadius * 2.0f;

		// LoadFeaturesFromMap() doesn't set a scale for trees
		// note: gets deleted in ~CSolidObject
		collisionVolume = new CollisionVolume(def->collisionVolume, fRadius);
	}

	Move3D(_pos.ClampInBounds(), false);
	SetRadiusAndHeight(fRadius, fHeight);
	UpdateMidPos();
	CalculateTransform();

	featureHandler->AddFeature(this);
	qf->AddFeature(this);

	// maybe should not be here, but it prevents crashes caused by team = -1
	ChangeTeam(team);

	if (blocking) {
		Block();
	}

	if (def->floating) {
		finalHeight = ground->GetHeightAboveWater(pos.x, pos.z);
	} else {
		finalHeight = ground->GetHeightReal(pos.x, pos.z);
	}

	if (speed != ZeroVector) {
		deathSpeed = speed;
	}

	reachedFinalPos = (speed == ZeroVector && pos.y == finalHeight);
}