/* This function reflects an animated circle on a static circle. It should first make sure that the animated circle is intersecting with the static one - Parameters - Center0s: The starting position of the animated circle's center - Center0e: The ending position of the animated circle's center - Radius0: The animated circle's radius - Center1: The static circle's center - Radius1: The static circle's radius - Pi: This will be used to store the intersection point's coordinates (In case there's an intersection) - R: Reflected vector R - Returned value: Intersection time t - -1.0f: If there's no intersection - Intersection time: If there's an intersection */ float ReflectAnimatedCircleOnStaticCircle(Vector2D *Center0s, Vector2D *Center0e, float Radius0, Vector2D *Center1, float Radius1, Vector2D *Pi, Vector2D *R) { Vector2D U; //(U is the adjusted normal) Vector2D M; //(M is from Ps to Pi) Vector2D Normal; float UScalar; float IntersectionTime = AnimatedCircleToStaticCircle(Center0s, Center0e, Radius0, Center1, Radius1, Pi); if (IntersectionTime == -1.0f) return -1.0f; // Calculating Normal Vector2DSub(&Normal, Pi, Center1); Vector2DNormalize(&Normal, &Normal); // Calculating Vector M (M is from Ps to Pi) Vector2DSub(&M, Center0s, Pi); //Calculating Vector U (U is the adjusted normal) UScalar = Vector2DDotProduct(&M, &Normal); Vector2DScale(&U, &Normal, UScalar); //Calculating R (R is the reflection Vector) Vector2DScale(&U, &U, 2.0f); Vector2DSub(R, &U, &M); Vector2DNormalize(R, R); return IntersectionTime; }
void CHuman::Update(float fElapsedTime) { CEnemy::Update( fElapsedTime ); m_nCollisionWithStaticObjectsSphere.m_Center = tVector2D(GetPosX(), GetPosY()); for( unsigned int i = 0; i < CGamePlayState::GetInstance()->m_StoreWalls.size(); i++) { Capsule* temp = CGamePlayState::GetInstance()->m_StoreWalls[i]; tVector2D ClosestPoint = ClosestPointOnALine(temp->GetStartPoint(), temp->GetEndPoint(), tVector2D( GetPosX(), GetPosY())); // Create a circle based on clsoest point with capsule radius Circle testCircle; testCircle.m_Center = ClosestPoint; testCircle.m_fRadius = temp->GetRadius(); if( GetSphere()->CheckCollision(testCircle) ) { tVector2D sphere2_to_1 = GetSphere()->m_Center - testCircle.m_Center; sphere2_to_1 = Vector2DNormalize(sphere2_to_1); float dist = GetSphere()->m_fRadius + testCircle.m_fRadius; tVector2D scaler = (sphere2_to_1 * (dist * 0.01f)); tVector2D newpos = GetSphere()->m_Center + scaler; SetPosX(newpos.fX); SetPosY(newpos.fY); } } }
void CAttackState::CalculateAI(float fElapsedTime, CBase* pBase) { CEnemy* pEnemy = (CEnemy*)pBase; pEnemy->GetWeapon()->Update(fElapsedTime); tVector2D distanceToTarget; distanceToTarget.fX = pEnemy->GetTarget()->GetPosX() - pEnemy->GetPosX(); distanceToTarget.fY = pEnemy->GetTarget()->GetPosY() - pEnemy->GetPosY(); if( Vector2DLength(distanceToTarget) > pEnemy->GetWeapon()->GetRange() ) { pEnemy->Walk(); distanceToTarget = Vector2DNormalize(distanceToTarget); distanceToTarget = distanceToTarget * pEnemy->GetSpeed(); pEnemy->SetVelX((distanceToTarget.fX)); pEnemy->SetVelY((distanceToTarget.fY)); } else { pEnemy->Shoot(); // Shoot at the player pEnemy->SetVelX(0.0f); pEnemy->SetVelY(0.0f); pEnemy->GetWeapon()->FireWeapon(pEnemy); } }
float CAI_PlaneSolver::AdjustRegulationWeight( CBaseEntity *pEntity, float weight ) { if ( pEntity->MyNPCPointer() != NULL ) { // @TODO (toml 10-03-02): How to do this with non-NPC entities. Should be using intended solve velocity... Vector2D velOwner = GetNpc()->GetMotor()->GetCurVel().AsVector2D(); Vector2D velBlocker = ((CAI_BaseNPC *)pEntity)->GetMotor()->GetCurVel().AsVector2D(); Vector2D velOwnerNorm = velOwner; Vector2D velBlockerNorm = velBlocker; float speedOwner = Vector2DNormalize( velOwnerNorm ); float speedBlocker = Vector2DNormalize( velBlockerNorm ); float dot = velOwnerNorm.Dot( velBlockerNorm ); if ( speedBlocker > 0 ) { if ( dot > 0 && speedBlocker >= speedOwner * 0.9 ) { if ( dot > 0.86 ) { // @Note (toml 10-10-02): Even in the case of no obstacle, we generate // a suggestion in because we still want to continue sweeping the // search weight = 0; } else if ( dot > 0.7 ) { weight *= sq( weight ); } else weight *= weight; } } } return weight; }
void CGuard::Update(float fElapsedTime) { if(CheckForPlayer()) { ComputeMovement(fElapsedTime); this->addTime(fElapsedTime); CBase::Update(fElapsedTime); } else CEnemy::Update( fElapsedTime ); m_nCollisionWithStaticObjectsSphere.m_Center = tVector2D(GetPosX(), GetPosY()); for( unsigned int i = 0; i < CGamePlayState::GetInstance()->m_StoreWalls.size(); i++) { Capsule* temp = CGamePlayState::GetInstance()->m_StoreWalls[i]; tVector2D ClosestPoint = ClosestPointOnALine(temp->GetStartPoint(), temp->GetEndPoint(), tVector2D( GetPosX(), GetPosY())); // Create a circle based on clsoest point with capsule radius Circle testCircle; testCircle.m_Center = ClosestPoint; testCircle.m_fRadius = temp->GetRadius(); if( GetSphere()->CheckCollision(testCircle) ) { tVector2D sphere2_to_1 = GetSphere()->m_Center - testCircle.m_Center; sphere2_to_1 = Vector2DNormalize(sphere2_to_1); float dist = GetSphere()->m_fRadius + testCircle.m_fRadius; tVector2D scaler = (sphere2_to_1 * (dist * 0.01f)); tVector2D newpos = GetSphere()->m_Center + scaler; SetPosX(newpos.fX); SetPosY(newpos.fY); } } if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_1)) { IsUndead = true; AnimManager::GetInstance()->SetAnimation( GetAnimID(), "Zombie Walking" ); } if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_2)) { IsUndead = false; AnimManager::GetInstance()->SetAnimation( GetAnimID(), "Person Walking" ); } }
void CHeavyInfantry::Update(float fElapsedTime) { if( GetDead() == false ) { // If the unit is either not in a squad or it has been issued the order to attack from the squad if( Attack() == true ) { if( GetCalculate() == true ) { GetState()->CalculateAI(fElapsedTime, this); } if( GetHealth() < GetMaxHealth() * 0.5f ) { SetCalculate(false); tVector2D vectorToPlayer; vectorToPlayer.fX = GetTarget()->GetPosX() - GetPosX(); vectorToPlayer.fY = GetTarget()->GetPosY() - GetPosY(); vectorToPlayer = Vector2DNormalize(vectorToPlayer); SetVelX(vectorToPlayer.fX*(GetSpeed()*2)); SetVelX(vectorToPlayer.fY*(GetSpeed()*2)); } } // Set Facing if( GetVelX() > GetVelY() ) { SetFacing(1.0f,0.0f); } else if( -GetVelX() < -GetVelY() ) { SetFacing(-1.0f,0.0f); } else if( GetVelY() > GetVelX() ) { SetFacing(0.0f,1.0f); } else if( -GetVelY() < -GetVelX() ) { SetFacing(0.0f,-1.0f); } SetPosX(GetPosX()+(GetVelX()*fElapsedTime)); SetPosY(GetPosY()+(GetVelY()*fElapsedTime)); } CEnemy::Update(fElapsedTime); }
int CWeaponCrowbar::WeaponMeleeAttack1Condition( float flDot, float flDist ) { // Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!) CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer(); CBaseEntity *pEnemy = pNPC->GetEnemy(); if (!pEnemy) return COND_NONE; Vector vecVelocity; vecVelocity = pEnemy->GetSmoothedVelocity( ); // Project where the enemy will be in a little while float dt = sk_crowbar_lead_time.GetFloat(); dt += random->RandomFloat( -0.3f, 0.2f ); if ( dt < 0.0f ) dt = 0.0f; Vector vecExtrapolatedPos; VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos ); Vector vecDelta; VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta ); if ( fabs( vecDelta.z ) > 70 ) { return COND_TOO_FAR_TO_ATTACK; } Vector vecForward = pNPC->BodyDirection2D( ); vecDelta.z = 0.0f; float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() ); if ((flDist > 64) && (flExtrapolatedDist > 64)) { return COND_TOO_FAR_TO_ATTACK; } float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() ); if ((flDot < 0.7) && (flExtrapolatedDot < 0.7)) { return COND_NOT_FACING_ATTACK; } return COND_CAN_MELEE_ATTACK1; }
//----------------------------------------------------------------------------- // Animation event handlers //----------------------------------------------------------------------------- void CWeaponCrowbar::HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) { // Trace up or down based on where the enemy is... // But only if we're basically facing that direction Vector vecDirection; AngleVectors( GetAbsAngles(), &vecDirection ); CBaseEntity *pEnemy = pOperator->MyNPCPointer() ? pOperator->MyNPCPointer()->GetEnemy() : NULL; if ( pEnemy ) { Vector vecDelta; VectorSubtract( pEnemy->WorldSpaceCenter(), pOperator->Weapon_ShootPosition(), vecDelta ); VectorNormalize( vecDelta ); Vector2D vecDelta2D = vecDelta.AsVector2D(); Vector2DNormalize( vecDelta2D ); if ( DotProduct2D( vecDelta2D, vecDirection.AsVector2D() ) > 0.8f ) { vecDirection = vecDelta; } } Vector vecEnd; VectorMA( pOperator->Weapon_ShootPosition(), 50, vecDirection, vecEnd ); CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd, Vector(-16,-16,-16), Vector(36,36,36), sk_npc_dmg_crowbar.GetInt(), DMG_CLUB, 0.75 ); // did I hit someone? if ( pHurt ) { // play sound WeaponSound( MELEE_HIT ); // Fake a trace impact, so the effects work out like a player's crowbaw trace_t traceHit; UTIL_TraceLine( pOperator->Weapon_ShootPosition(), pHurt->GetAbsOrigin(), MASK_SHOT_HULL, pOperator, COLLISION_GROUP_NONE, &traceHit ); ImpactEffect( traceHit ); } else { WeaponSound( MELEE_MISS ); } }
void CWeaponIFMSteadyCam::ComputeViewOffset() { // Update 2D spring if ( !m_bInSpringMode ) { m_vecViewOffset = m_vecActualViewOffset; return; } Vector2D dir; Vector2DSubtract( m_vecViewOffset.AsVector2D(), m_vecActualViewOffset.AsVector2D(), dir ); float flDist = Vector2DNormalize( dir ); Vector2D vecForce; Vector2DMultiply( dir, -flDist * ifm_steadycam_2dspringconstant.GetFloat(), vecForce ); Vector2DMA( vecForce, -ifm_steadycam_2ddragconstant.GetFloat(), m_vec2DVelocity.AsVector2D(), vecForce ); Vector2DMA( m_vecViewOffset.AsVector2D(), gpGlobals->frametime, m_vec2DVelocity.AsVector2D(), m_vecViewOffset.AsVector2D() ); Vector2DMA( m_vec2DVelocity.AsVector2D(), gpGlobals->frametime, vecForce, m_vec2DVelocity.AsVector2D() ); }
void CBase::Render(void) { CSGD_TextureManager* pTM = CSGD_TextureManager::GetInstance(); pTM->Draw( GetImageID(), GetPosX() - m_nWidth/2, GetPosY() - m_nHeight/2, 1.0f, 1.0f, NULL, 0.0f, 0.0f, 0.0f, D3DCOLOR_ARGB(128, 255, 255, 255)); CSGD_Direct3D* pD3D = CSGD_Direct3D::GetInstance(); tVector2D tVisualize; tVisualize.fX = GetVelX(); tVisualize.fY = GetVelY(); tVisualize = Vector2DNormalize(tVisualize); tVisualize.fX *= 32.0f; tVisualize.fY *= 32.0f; pD3D->DrawLine(GetPosX(), GetPosY(), GetPosX() + tVisualize.fX, GetPosY() + tVisualize.fY, 255, 0, 0); }
void CHostageState::CalculateAI(float fElapsedTime, CBase* pBase) { CAlly* hostage = (CAlly*)pBase; tVector2D vectorToPlayer; vectorToPlayer.fX = CPlayer::GetInstance()->GetPosX() - hostage->GetPosX(); vectorToPlayer.fY = CPlayer::GetInstance()->GetPosY() - hostage->GetPosY(); if( Vector2DLength(vectorToPlayer) < 100 ) { Vector2DNormalize(vectorToPlayer); vectorToPlayer = vectorToPlayer * (float)hostage->GetSpeed(); hostage->SetVelX(vectorToPlayer.fX); hostage->SetVelY(vectorToPlayer.fY); } else { hostage->SetVelX(0.0f); hostage->SetVelY(0.0f); } }
int CWeaponStunStick::WeaponMeleeAttack1Condition( float flDot, float flDist ) { // Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!) CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer(); CBaseEntity *pEnemy = pNPC->GetEnemy(); if (!pEnemy) return COND_NONE; Vector vecVelocity; AngularImpulse angVelocity; pEnemy->GetVelocity( &vecVelocity, &angVelocity ); // Project where the enemy will be in a little while, add some randomness so he doesn't always hit float dt = sk_crowbar_lead_time.GetFloat(); dt += random->RandomFloat( -0.3f, 0.2f ); if ( dt < 0.0f ) dt = 0.0f; Vector vecExtrapolatedPos; VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos ); Vector vecDelta; VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta ); if ( fabs( vecDelta.z ) > 70 ) { return COND_TOO_FAR_TO_ATTACK; } Vector vecForward = pNPC->BodyDirection2D( ); vecDelta.z = 0.0f; float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() ); if ((flDot < 0.7) && (flExtrapolatedDot < 0.7)) { return COND_NOT_FACING_ATTACK; } float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() ); if( pEnemy->IsPlayer() ) { //Vector vecDir = pEnemy->GetSmoothedVelocity(); //float flSpeed = VectorNormalize( vecDir ); // If player will be in front of me in one-half second, clock his arse. Vector vecProjectEnemy = pEnemy->GetAbsOrigin() + (pEnemy->GetAbsVelocity() * 0.35); Vector vecProjectMe = GetAbsOrigin(); if( (vecProjectMe - vecProjectEnemy).Length2D() <= 48.0f ) { return COND_CAN_MELEE_ATTACK1; } } /* if( metropolice_move_and_melee.GetBool() ) { if( pNPC->IsMoving() ) { flTargetDist *= 1.5f; } } */ float flTargetDist = 48.0f; if ((flDist > flTargetDist) && (flExtrapolatedDist > flTargetDist)) { return COND_TOO_FAR_TO_ATTACK; } return COND_CAN_MELEE_ATTACK1; }
void CWeaponStunStick::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) { switch( pEvent->event ) { case EVENT_WEAPON_MELEE_HIT: { // Trace up or down based on where the enemy is... // But only if we're basically facing that direction Vector vecDirection; AngleVectors( GetAbsAngles(), &vecDirection ); CBaseEntity *pEnemy = pOperator->MyNPCPointer() ? pOperator->MyNPCPointer()->GetEnemy() : NULL; if ( pEnemy ) { Vector vecDelta; VectorSubtract( pEnemy->WorldSpaceCenter(), pOperator->Weapon_ShootPosition(), vecDelta ); VectorNormalize( vecDelta ); Vector2D vecDelta2D = vecDelta.AsVector2D(); Vector2DNormalize( vecDelta2D ); if ( DotProduct2D( vecDelta2D, vecDirection.AsVector2D() ) > 0.8f ) { vecDirection = vecDelta; } } Vector vecEnd; VectorMA( pOperator->Weapon_ShootPosition(), 32, vecDirection, vecEnd ); // Stretch the swing box down to catch low level physics objects CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd, Vector(-16,-16,-40), Vector(16,16,16), GetDamageForActivity( GetActivity() ), DMG_CLUB, 0.5f, false ); // did I hit someone? if ( pHurt ) { // play sound WeaponSound( MELEE_HIT ); CBasePlayer *pPlayer = ToBasePlayer( pHurt ); CNPC_MetroPolice *pCop = dynamic_cast<CNPC_MetroPolice *>(pOperator); bool bFlashed = false; if ( pCop != NULL && pPlayer != NULL ) { // See if we need to knock out this target if ( pCop->ShouldKnockOutTarget( pHurt ) ) { float yawKick = random->RandomFloat( -48, -24 ); //Kick the player angles pPlayer->ViewPunch( QAngle( -16, yawKick, 2 ) ); color32 white = {255,255,255,255}; UTIL_ScreenFade( pPlayer, white, 0.2f, 1.0f, FFADE_OUT|FFADE_PURGE|FFADE_STAYOUT ); bFlashed = true; pCop->KnockOutTarget( pHurt ); break; } else { // Notify that we've stunned a target pCop->StunnedTarget( pHurt ); } } // Punch angles if ( pPlayer != NULL && !(pPlayer->GetFlags() & FL_GODMODE) ) { float yawKick = random->RandomFloat( -48, -24 ); //Kick the player angles pPlayer->ViewPunch( QAngle( -16, yawKick, 2 ) ); Vector dir = pHurt->GetAbsOrigin() - GetAbsOrigin(); // If the player's on my head, don't knock him up if ( pPlayer->GetGroundEntity() == pOperator ) { dir = vecDirection; dir.z = 0; } VectorNormalize(dir); dir *= 500.0f; //If not on ground, then don't make them fly! if ( !(pPlayer->GetFlags() & FL_ONGROUND ) ) dir.z = 0.0f; //Push the target back pHurt->ApplyAbsVelocityImpulse( dir ); if ( !bFlashed ) { color32 red = {128,0,0,128}; UTIL_ScreenFade( pPlayer, red, 0.5f, 0.1f, FFADE_IN ); } // Force the player to drop anyting they were holding pPlayer->ForceDropOfCarriedPhysObjects(); } // do effect? } else { WeaponSound( MELEE_MISS ); } } break; default: BaseClass::Operator_HandleAnimEvent( pEvent, pOperator ); break; } }
void CHL2MP_Player::KickAttack(void) { if (!IsDead()) { CBaseViewModel *vm = GetViewModel(1); if (vm) { int idealSequence = vm->SelectWeightedSequence(ACT_VM_PRIMARYATTACK); if (idealSequence >= 0) { vm->SendViewModelMatchingSequence(idealSequence); m_flNextKickAttack = gpGlobals->curtime + vm->SequenceDuration(idealSequence) - 0.5f; } QAngle recoil = QAngle(random->RandomFloat(1.0f, 2.0f), random->RandomFloat(-1.0f, 1.0f), 0); this->ViewPunch(recoil); // Trace up or down based on where the enemy is... // But only if we're basically facing that direction Vector vecDirection; int kick_maxrange = 120; AngleVectors(QAngle(clamp(EyeAngles().x, 20, kick_maxrange), EyeAngles().y, EyeAngles().z), &vecDirection); CBaseEntity *pEnemy = MyNPCPointer() ? MyNPCPointer()->GetEnemy() : NULL; if (pEnemy) { Vector vecDelta; VectorSubtract(pEnemy->WorldSpaceCenter(), Weapon_ShootPosition(), vecDelta); VectorNormalize(vecDelta); Vector2D vecDelta2D = vecDelta.AsVector2D(); Vector2DNormalize(vecDelta2D); if (DotProduct2D(vecDelta2D, vecDirection.AsVector2D()) > 0.8f) { vecDirection = vecDelta; } } Vector vecEnd; VectorMA(Weapon_ShootPosition(), 50, vecDirection, vecEnd); trace_t tr; UTIL_TraceHull(Weapon_ShootPosition(), vecEnd, Vector(-16, -16, -16), Vector(16, 16, 16), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr); // did I hit someone? float KickDamageMult = 50 + (1 * ((fabs(GetAbsVelocity().x) + fabs(GetAbsVelocity().y) + fabs(GetAbsVelocity().z)) / 48)); float KickThrowForceMult = 20 + (1 * ((fabs(GetAbsVelocity().x) + fabs(GetAbsVelocity().y) + fabs(GetAbsVelocity().z)) / 48)); DevMsg("Kicking at %.2f of damage!\n", KickDamageMult); DevMsg("Kicking at %.2f of force!\n", KickThrowForceMult); if (tr.m_pEnt) { if (!(tr.m_pEnt)) { // return; } else { CBasePropDoor *pDoor = dynamic_cast<CBasePropDoor*>((CBaseEntity*)tr.m_pEnt); if (pDoor) { if (pDoor->HasSpawnFlags(SF_BREAKABLE_BY_PLAYER)) { AngularImpulse angVelocity(random->RandomFloat(0, 45), 18, random->RandomFloat(-45, 45)); pDoor->PlayBreakOpenSound(); pDoor->BreakDoor(Weapon_ShootPosition(), angVelocity); return; } pDoor->PlayBreakFailSound(); pDoor->KickFail(); return; } CBaseEntity *Victim = this->CheckTraceHullAttack(Weapon_ShootPosition(), vecEnd, Vector(-16, -16, -16), Vector(16, 16, 16), KickDamageMult, DMG_CRUSH, KickThrowForceMult, true); if (Victim) { EmitSound("HL2Player.kick_body"); return; } } } UTIL_TraceLine(Weapon_ShootPosition(), vecEnd, MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr);//IF we hit anything else if (tr.DidHit()) { EmitSound("HL2Player.kick_wall"); } else { EmitSound("HL2Player.kick_fire"); } } } }
int main() { Vector2D v1, v2, v3, result; float scale; Matrix2D id, m0, m1; Vector2D u; float d, x, y; long n; long i, j; float radius; v1.x = v1.y = 7.0f; Vector2DZero(&v1); result.x = result.y = 0.0f; printf("Vector2DZero: %s\n", (CompareVector2D(&result, &v1) < EPSILON) ? "Pass" : "Fail"); Vector2DSet(&v1, 1.0f, 2.0f); result.x = 1.0f; result.y = 2.0f; printf("Vector2DSet: %s\n", (CompareVector2D(&result, &v1) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -4.0f; Vector2DNeg(&v2, &v1); result.x = -2.0f; result.y = 4.0f; printf("Vector2DNeg: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -4.0f; v2.x = 1.0f; v2.y = 7.0f; Vector2DAdd(&v3, &v1, &v2); result.x = result.y = 3.0f; printf("Vector2DAdd: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -4.0f; v2.x = 1.0f; v2.y = 7.0f; Vector2DSub(&v3, &v1, &v2); result.x = 1.0f; result.y = -11.0f; printf("Vector2DSub: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail"); v1.x = 3.0f; v1.y = 4.0f; Vector2DNormalize(&v2, &v1); result.x = 0.6f; result.y = 0.8f; printf("Vector2DNormalize: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -5.0f; Vector2DScale(&v2, &v1, 3.0f); result.x = 6.0f; result.y = -15.0f; printf("Vector2DScale: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -5.0f; v2.x = 6.0f; v2.y = 2.0f; scale = 3.0f; Vector2DScaleAdd(&v3, &v1, &v2, scale); result.x = 12.0f; result.y = -13.0f; printf("Vector2DScaleAdd: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail"); Vector2DScaleSub(&v3, &v1, &v2, scale); result.x = 0.f; result.y = -17.f; printf("Vector2DScaleSub: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail"); v1.x = 3.0f; v1.y = -4.0f; printf("Vector2DLength: %s\n", (fabs(Vector2DLength(&v1) - 5.0f) < EPSILON) ? "Pass" : "Fail"); v1.x = 3.0f; v1.y = -4.0f; printf("Vector2DSquareLength: %s\n", (fabs(Vector2DSquareLength(&v1) - 25.0f) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = 3.0f; v2.x = 4.0f; v2.y = -1.0f; printf("Vector2DDistance: %s\n", (fabs(Vector2DDistance(&v1, &v2) - 4.472136) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = 3.0f; v2.x = 4.0f; v2.y = -1.0f; printf("Vector2DSquareDistance: %s\n", (fabs(Vector2DSquareDistance(&v1, &v2) - 20.0f) < EPSILON) ? "Pass" : "Fail"); v1.x = 3.0f; v1.y = 2.0f; v2.x = 4.0f; v2.y = -6.0f; printf("Vector2DDotProduct: %s\n", (fabs(Vector2DDotProduct(&v1, &v2)) < EPSILON) ? "Pass" : "Fail"); printf("\n------Testing StaticPointToStaticCircle------\n\n"); v1.x = 10.f; v1.y = 10.f; v2.x = 11.4f; v2.y = 11.4f; radius = 2.f; printf("StaticPointToStaticCircle Collision: %s\n", (StaticPointToStaticCircle(&v2, &v1, radius)) ? "Pass" : "Fail" ); v2.x = 12.f; v2.y = 12.f; printf("StaticPointToStaticCircle Non Collision: %s\n", (!StaticPointToStaticCircle(&v2, &v1, radius)) ? "Pass" : "Fail" ); printf("\n------Running Matrix Tests------\n\n"); // create an id matrix for reference for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) id.m[j][i] = (i == j) ? 1.0f : 0.0f; // ==================== // test Matrix2DIdentity // ==================== Matrix2DIdentity(&m0); d = CompareMatrix2D(&id, &m0); printf("Matrix2DIdentity : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DTrans // ==================== // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; Matrix2DTranslate(&m0, x, y); m0.m[0][2] -= x; m0.m[1][2] -= y; printf("Matrix2DTranslate: %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DScale // ==================== // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; Matrix2DScale(&m0, x, y); m0.m[0][0] /= x; m0.m[1][1] /= y; printf("Matrix2DScale : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DConcat // ==================== // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; Matrix2DTranslate (&m0, x, y); Matrix2DScale (&m1, x, y); Matrix2DConcat(&m0, &m0, &m1); m0.m[0][2] -= x; m0.m[1][2] -= y; m0.m[0][0] /= x; m0.m[1][1] /= y; printf("Matrix2DConcat 1 : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; Matrix2DTranslate (&m0, x, y); Matrix2DScale (&m1, x, y); Matrix2DConcat(&m0, &m1, &m0); m0.m[0][2] -= x * x; m0.m[1][2] -= y * y; m0.m[0][0] /= x; m0.m[1][1] /= y; printf("Matrix2DConcat 2 : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DRotRad // ==================== n = (rand() % 16) + 15; Matrix2DIdentity(&m0); Matrix2DRotRad (&m1, 2.0f * PI / n); for (i = 0; i < n; i++) Matrix2DConcat(&m0, &m1, &m0); printf("Matrix2DRotRad : %s (%d)\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail", n); // ==================== // test Matrix2DRotDeg // ==================== n = (rand() % 16) + 15; Matrix2DIdentity(&m0); Matrix2DRotDeg (&m1, 360.0f / n); for (i = 0; i < n; i++) Matrix2DConcat(&m0, &m1, &m0); printf("Matrix2DRotDeg : %s (%d)\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail", n); // ==================== // test Matrix2DTranspose // ==================== Matrix2DRotRad (&m0, rand() / (float)(RAND_MAX) * 2.0f * PI); Matrix2DTranspose(&m1, &m0); Matrix2DConcat (&m0, &m1, &m0); printf("Matrix2DTranspose: %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DMultVec // ==================== // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; n = (rand() % 16) + 15; Vector2DSet (&u, x, y); Matrix2DRotRad (&m0, 2.0f * PI / n); for (i = 0; i < n; i++) Matrix2DMultVec(&u, &m0, &u); printf("Matrix2DMultVec : %s\n", ((fabs(u.x - x) + fabs(u.y - y)) < EPSILON) ? "Pass" : "Fail"); // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; n = (rand() % 16) + 15; Vector2DSet (&u, x, y); Matrix2DTranslate (&m0, x, y); for (i = 1; i < n; i++) Matrix2DMultVec(&u, &m0, &u); printf("Matrix2DMultVec : %s\n", ((fabs(u.x - x * n) + fabs(u.y - y * n)) < EPSILON) ? "Pass" : "Fail"); printf("\n------Testing New Collision Functions------\n\n"); //StaticPointToStaticRect Vector2DSet(&v1, 1.f, 1.f); //point Vector2DSet(&v2, 0.f, 0.f); //rect printf("StaticPointToStaticRect Collision: %s\n", (StaticPointToStaticRect(&v1, &v2, 2.f, 2.f) ? "Pass" : "Fail")); printf("StaticPointToStaticRect Non Collision: %s\n\n", (!StaticPointToStaticRect(&v1, &v2, 1.f, 1.f) ? "Pass" : "Fail")); //StaticCircleToStaticCircle Vector2DSet(&v1, 2.f, 0.f); printf("StaticCircleToStaticCircle Collision Touch: %s\n", (StaticCircleToStaticCircle(&v1, 1.f, &v2, 1.f) ? "Pass" : "Fail")); printf("StaticCircleToStaticCircle Collision: %s\n", (StaticCircleToStaticCircle(&v1, 2.f, &v2, 1.f) ? "Pass" : "Fail")); printf("StaticCircleToStaticCircle Non Collision: %s\n\n", (!StaticCircleToStaticCircle(&v1, 0.5f, &v2, 1.f) ? "Pass" : "Fail")); //StaticRectToStaticRect Vector2DSet(&v1, 2.f, 2.f); printf("StaticRectToStaticRect Non Collision: %s\n", (!StaticRectToStaticRect(&v1, 1.f, 1.f, &v2, 1.f, 1.f) ? "Pass" : "Fail")); printf("StaticRectToStaticRect Collision Touch: %s\n", (StaticRectToStaticRect(&v1, 2.f, 2.f, &v2, 2.f, 2.f) ? "Pass" : "Fail")); printf("StaticRectToStaticRect Collision Intersect: %s\n", (StaticRectToStaticRect(&v1, 3.f, 3.f, &v2, 3.f, 3.f) ? "Pass" : "Fail")); return 1; }
vec_t Vector2D::NormalizeInPlace() { return Vector2DNormalize(*this); }