コード例 #1
0
ファイル: GameHelper.cpp プロジェクト: javaphoon/spring
void CGameHelper::DoExplosionDamage(CFeature* feature,
                                    const float3& expPos, float expRad, CUnit* owner, const DamageArray& damages)
{
    CollisionVolume* cv = feature->collisionVolume;

    if (cv) {
        float3 dif = (feature->midPos + cv->GetOffsets()) - expPos;
        float expDist = std::max(dif.Length(), 0.1f);
        float expMod = (expRad - expDist) / expRad;

        // always do some damage with explosive stuff
        // (DDM wreckage etc. is too big to normally
        // be damaged otherwise, even by BB shells)
        // NOTE: this will also be only approximate
        // for non-spherical volumes
        if ((expRad > 8.0f) && (expDist < (cv->GetBoundingRadius() * 1.1f)) && (expMod < 0.1f)) {
            expMod = 0.1f;
        }
        if (expMod > 0.0f) {
            feature->DoDamage(damages * expMod, owner,
                              dif * (damages.impulseFactor * expMod / expDist *
                                     (damages[0] + damages.impulseBoost)));
        }
    }
}
コード例 #2
0
void	PhysicsSystem::NarrowPhaseCollisions() {
	for (int i = 0; i < allNodes.size(); i++) {
		PhysicsNode& first = *allNodes[i];
		CollisionVolume* fv = first.GetCollisionVolume();
		if (!fv) continue;
		for (int j = i + 1; j < allNodes.size(); j++) {
			PhysicsNode& second = *allNodes[j];
			CollisionVolume* sv = second.GetCollisionVolume();
			if (!sv) continue;

			switch(fv->GetType()) {
			case COLLISION_VOL_SPHERE:
				switch(sv->GetType()) {
				case COLLISION_VOL_SPHERE:
					CollisionData data;
					if (CollisionHelper::SphereSphereCollision(first, second, &data)) {
						CollisionHelper::AddCollisionImpulse(first, second, data);
					}
					continue;
				}
			case COLLISION_VOL_PLANE:
				switch(sv->GetType()) {
				case COLLISION_VOL_SPHERE:
					CollisionData data;
					if (CollisionHelper::PlaneSphereCollision(first, second, &data)) {
						CollisionHelper::AddCollisionImpulse(first, second, data);
					}
					continue;
				}
			}
		
		}
	}
}
コード例 #3
0
ファイル: TreeBuilder.cpp プロジェクト: frobro98/RADEngine
CollisionVolume* TreeBuilder::recConstructTree(Model* const model, BoundingBox* const box, int level)
{
	if(level == 0)
	{
		return 0;
	}
	else
	{
		CollisionVolume* rootVolume = box;
		if(this->type == OCT)
		{
			for(int i = 0; i < 8; ++i)
			{
				BoxQuadrent loc = (BoxQuadrent)(TOP_FRONT_LEFT + i);
				PartialBoundingBox* subQuad = buildSubQuadrent(model, box->getLocalCorners(), loc);
				//Visualizer::showSphere(subQuad->getCenter(), subQuad->getRadius());
				if(triangleInSphere(model, subQuad))
				{
					//BoundingSphere* octSphere = boxToSphere(model, subQuad);
					rootVolume->setChild(subQuad);
					subQuad->setChild(recConstructTree(model, subQuad, level-1));
				}
			}
		}
		else if(this->type == QUAD)
		{
			

		}
		return (CollisionVolume*)rootVolume->getChild();
	}
}
コード例 #4
0
bool CWeapon::AdjustTargetVectorLength(
	CUnit* targetUnit,
	float3& targetPos,
	float3& targetVec,
	float3& targetDir)
const {
	bool retCode = false;
	const float tbScale = math::fabsf(targetBorder);

	CollisionVolume* cvOld = targetUnit->collisionVolume;
	CollisionVolume  cvNew = CollisionVolume(targetUnit->collisionVolume);
	CollisionQuery   cq;

	// test for "collision" with a temporarily volume
	// (scaled uniformly by the absolute target-border
	// factor)
	cvNew.RescaleAxes(tbScale, tbScale, tbScale);
	cvNew.SetTestType(CollisionVolume::COLVOL_HITTEST_DISC);

	targetUnit->collisionVolume = &cvNew;

	if (CCollisionHandler::DetectHit(targetUnit, weaponMuzzlePos, ZeroVector, NULL)) {
		// our weapon muzzle is inside the target unit's volume; this
		// means we do not need to make any adjustments to targetVec
		targetVec = ZeroVector;
	} else {
		targetDir.SafeNormalize();

		// otherwise, perform a raytrace to find the proper length correction
		// factor for non-spherical coldet volumes based on the ray's ingress
		// (for positive TB values) or egress (for negative TB values) position;
		// this either increases or decreases the length of <targetVec> but does
		// not change its direction
		cvNew.SetTestType(CollisionVolume::COLVOL_HITTEST_CONT);

		// make the ray-segment long enough so it can reach the far side of the
		// scaled collision volume (helps to ensure a ray-intersection is found)
		//
		// note: ray-intersection is NOT guaranteed if the volume itself has a
		// non-zero offset, since here we are "shooting" at the target UNIT's
		// midpoint
		const float3 targetOffset = targetDir * (cvNew.GetBoundingRadius() * 2.0f);
		const float3 targetRayPos = targetPos + targetOffset;

		if (CCollisionHandler::DetectHit(targetUnit, weaponMuzzlePos, targetRayPos, &cq)) {
			if (targetBorder > 0.0f) { targetVec -= (targetDir * ((targetPos - cq.p0).Length())); }
			if (targetBorder < 0.0f) { targetVec += (targetDir * ((cq.p1 - targetPos).Length())); }
		}

		retCode = true;
	}

	targetUnit->collisionVolume = cvOld;

	// true indicates we took the else-branch and targetDir is now normalized
	return retCode;
}
コード例 #5
0
ファイル: GameHelper.cpp プロジェクト: javaphoon/spring
float CGameHelper::GuiTraceRayFeature(const float3& start, const float3& dir, float length, CFeature*& feature)
{
    float nearHit = length;

    GML_RECMUTEX_LOCK(quad); // GuiTraceRayFeature

    std::vector<int> quads = qf->GetQuadsOnRay(start, dir, length);
    std::vector<int>::iterator qi;

    for (qi = quads.begin(); qi != quads.end(); ++qi) {
        const CQuadField::Quad& quad = qf->GetQuad(*qi);
        std::list<CFeature*>::const_iterator ui;

        // NOTE: switch this to custom volumes fully?
        // (not used for any LOF checks, maybe wasteful)
        for (ui = quad.features.begin(); ui != quad.features.end(); ++ui) {
            CFeature* f = *ui;

            if (!gu->spectatingFullView && !f->IsInLosForAllyTeam(gu->myAllyTeam)) {
                continue;
            }
            if (f->noSelect) {
                continue;
            }

            CollisionVolume* cv = f->collisionVolume;
            const float3& midPosOffset = cv? cv->GetOffsets(): ZeroVector;
            const float3 dif = (f->midPos + midPosOffset) - start;
            float closeLength = dif.dot(dir);

            if (closeLength < 0)
                continue;
            if (closeLength > nearHit)
                continue;

            float3 closeVect = dif - dir * closeLength;
            if (closeVect.SqLength() < f->sqRadius) {
                nearHit = closeLength;
                feature = f;
            }
        }
    }

    return nearHit;
}
コード例 #6
0
ファイル: PathCache.cpp プロジェクト: FriedRice/spring
static void GetRectangleCollisionVolume(const SRectangle& r, CollisionVolume& v, float3& rm) {
	float3 vScales;

	// rectangle dimensions (WS)
	vScales.x = WS(r.x2 - r.x1);
	vScales.z = WS(r.z2 - r.z1);
	vScales.y = 1.0f;

	// rectangle mid-point (WS)
	rm.x = WS(r.x1 + r.x2) >> 1;
	rm.z = WS(r.z1 + r.z2) >> 1;
	rm.y = 0.0f;

	#define CV CollisionVolume
	v.Init(vScales, ZeroVector, CV::COLVOL_TYPE_BOX, CV::COLVOL_HITTEST_CONT, CV::COLVOL_AXIS_Y);
	#undef CV
}