本文整理汇总了C++中float3::SafeNormalize方法的典型用法代码示例。如果您正苦于以下问题:C++ float3::SafeNormalize方法的具体用法?C++ float3::SafeNormalize怎么用?C++ float3::SafeNormalize使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类float3
的用法示例。
在下文中一共展示了float3::SafeNormalize方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Explode
void CWeaponProjectile::Explode(
CUnit* hitUnit,
CFeature* hitFeature,
float3 impactPos,
float3 impactDir
) {
const DamageArray& damageArray = damages->GetDynamicDamages(startPos, impactPos);
const CExplosionParams params = {
impactPos,
impactDir.SafeNormalize(),
damageArray,
weaponDef,
owner(),
hitUnit,
hitFeature,
damages->craterAreaOfEffect,
damages->damageAreaOfEffect,
damages->edgeEffectiveness,
damages->explosionSpeed,
weaponDef->noExplode? 0.3f: 1.0f, // gfxMod
weaponDef->impactOnly,
weaponDef->noExplode || weaponDef->noSelfDamage, // ignoreOwner
true, // damgeGround
static_cast<unsigned int>(id)
};
helper->Explosion(params);
if (!weaponDef->noExplode || TraveledRange()) {
// remove ourselves from the simulation (otherwise
// keep traveling and generating more explosions)
CProjectile::Collision();
}
}
示例2: AdjustTargetVectorLength
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;
}
示例3: FireInternal
void CBeamLaser::FireInternal(float3 dir, bool sweepFire)
{
// fix negative damage when hitting big spheres
float actualRange = range;
float rangeMod = 1.0f;
if (dynamic_cast<CBuilding*>(owner) == NULL) {
// help units fire while chasing
rangeMod = 1.3f;
}
if (owner->fpsControlPlayer != NULL) {
rangeMod = 0.95f;
}
float maxLength = range * rangeMod;
float curLength = 0.0f;
float3 curPos = weaponMuzzlePos;
float3 hitPos;
dir +=
((gs->randVector() * sprayAngle *
(1.0f - owner->limExperience * weaponDef->ownerExpAccWeight)));
dir.SafeNormalize();
bool tryAgain = true;
// increase range if targets are searched for in a cylinder
if (cylinderTargetting > 0.01f) {
const float verticalDist = owner->radius * cylinderTargetting * dir.y;
const float maxLengthModSq = maxLength * maxLength + verticalDist * verticalDist;
maxLength = math::sqrt(maxLengthModSq);
}
// increase range if targetting edge of hitsphere
if (targetType == Target_Unit && targetUnit && targetBorder != 0) {
maxLength += (targetUnit->radius * targetBorder);
}
// unit at the end of the beam
CUnit* hitUnit = NULL;
CFeature* hitFeature = NULL;
CPlasmaRepulser* hitShield = NULL;
for (int tries = 0; tries < 5 && tryAgain; ++tries) {
tryAgain = false;
float length = TraceRay::TraceRay(curPos, dir, maxLength - curLength, collisionFlags, owner, hitUnit, hitFeature);
if (hitUnit && teamHandler->AlliedTeams(hitUnit->team, owner->team) && sweepFire) {
// never damage friendlies with sweepfire
lastFireFrame = 0;
return;
}
float3 newDir;
const float shieldLength = interceptHandler.AddShieldInterceptableBeam(this, curPos, dir, length, newDir, hitShield);
if (shieldLength < length) {
length = shieldLength;
tryAgain = hitShield->BeamIntercepted(this, damageMul); // repulsed
}
hitPos = curPos + dir * length;
const float baseAlpha = weaponDef->intensity * 255.0f;
const float startAlpha = (1.0f - (curLength ) / (range * 1.3f)) * baseAlpha;
const float endAlpha = (1.0f - (curLength + length) / (range * 1.3f)) * baseAlpha;
if (weaponDef->largeBeamLaser) {
new CLargeBeamLaserProjectile(curPos, hitPos, color, weaponDef->visuals.color2, owner, weaponDef);
} else {
new CBeamLaserProjectile(curPos, hitPos, startAlpha, endAlpha, color, owner, weaponDef);
}
curPos = hitPos;
curLength += length;
dir = newDir;
}
if (hitUnit) {
if (hitUnit->unitDef->usePieceCollisionVolumes) {
// getting the actual piece here is probably overdoing it
// TODO change this if we really need propper flanking bonus support
// for beam-lasers
hitUnit->SetLastAttackedPiece(hitUnit->localmodel->GetRoot(), gs->frameNum);
}
if (targetBorder > 0) {
actualRange += hitUnit->radius * targetBorder;
}
}
// make it possible to always hit with some minimal intensity (melee weapons have use for that)
const float hitIntensity = std::max(minIntensity, 1.0f - (curLength) / (actualRange * 2));
//.........这里部分代码省略.........
示例4: FireInternal
void CBeamLaser::FireInternal(float3 curDir)
{
float actualRange = range;
float rangeMod = 1.0f;
if (!owner->unitDef->IsImmobileUnit()) {
// help units fire while chasing
rangeMod = 1.3f;
}
if (owner->UnderFirstPersonControl()) {
rangeMod = 0.95f;
}
bool tryAgain = true;
bool doDamage = true;
float maxLength = range * rangeMod;
float curLength = 0.0f;
float3 curPos = weaponMuzzlePos;
float3 hitPos;
float3 newDir;
// objects at the end of the beam
CUnit* hitUnit = NULL;
CFeature* hitFeature = NULL;
CPlasmaRepulser* hitShield = NULL;
CollisionQuery hitColQuery;
if (!sweepFireState.IsSweepFiring()) {
curDir += (gs->randVector() * SprayAngleExperience());
curDir.SafeNormalize();
// increase range if targets are searched for in a cylinder
if (cylinderTargeting > 0.01f) {
const float verticalDist = owner->radius * cylinderTargeting * curDir.y;
const float maxLengthModSq = maxLength * maxLength + verticalDist * verticalDist;
maxLength = math::sqrt(maxLengthModSq);
}
// adjust range if targetting edge of hitsphere
if (targetType == Target_Unit && targetUnit != NULL && targetBorder != 0.0f) {
maxLength += (targetUnit->radius * targetBorder);
}
} else {
// restrict the range when sweeping
maxLength = std::min(maxLength, sweepFireState.GetTargetDist3D() * 1.125f);
}
for (int tries = 0; tries < 5 && tryAgain; ++tries) {
float beamLength = TraceRay::TraceRay(curPos, curDir, maxLength - curLength, collisionFlags, owner, hitUnit, hitFeature, &hitColQuery);
if (hitUnit != NULL && teamHandler->AlliedTeams(hitUnit->team, owner->team)) {
if (sweepFireState.IsSweepFiring() && !sweepFireState.DamageAllies()) {
doDamage = false; break;
}
}
if (!weaponDef->waterweapon) {
// terminate beam at water surface if necessary
if ((curDir.y < 0.0f) && ((curPos.y + curDir.y * beamLength) <= 0.0f)) {
beamLength = curPos.y / -curDir.y;
}
}
// if the beam gets intercepted, this modifies newDir
//
// we do more than one trace-iteration and set dir to
// newDir only in the case there is a shield in our way
const float shieldLength = interceptHandler.AddShieldInterceptableBeam(this, curPos, curDir, beamLength, newDir, hitShield);
if (shieldLength < beamLength) {
beamLength = shieldLength;
tryAgain = hitShield->BeamIntercepted(this, salvoDamageMult);
} else {
tryAgain = false;
}
// same as hitColQuery.GetHitPos() if no water or shield in way
hitPos = curPos + curDir * beamLength;
{
const float baseAlpha = weaponDef->intensity * 255.0f;
const float startAlpha = (1.0f - (curLength ) / maxLength);
const float endAlpha = (1.0f - (curLength + beamLength) / maxLength);
ProjectileParams pparams = GetProjectileParams();
pparams.pos = curPos;
pparams.end = hitPos;
pparams.ttl = weaponDef->beamLaserTTL;
pparams.startAlpha = Clamp(startAlpha * baseAlpha, 0.0f, 255.0f);
pparams.endAlpha = Clamp(endAlpha * baseAlpha, 0.0f, 255.0f);
WeaponProjectileFactory::LoadProjectile(pparams);
}
curPos = hitPos;
curDir = newDir;
curLength += beamLength;
//.........这里部分代码省略.........