//------------------------------------------------------------------------ void CItem::UpdateFPPosition(float frameTime) { CActor* pActor = GetOwnerActor(); if (!pActor) return; SPlayerStats *pStats = static_cast<SPlayerStats *>(pActor->GetActorStats()); if (!pStats) return; Matrix34 tm = Matrix33::CreateRotationXYZ(pStats->FPWeaponAngles); Vec3 offset(0.0f,0.0f,0.0f); float right(g_pGameCVars->i_offset_right); float front(g_pGameCVars->i_offset_front); float up(g_pGameCVars->i_offset_up); if (front!=0.0f || up!=0.0f || right!=0.0f) { offset += tm.GetColumn(0).GetNormalized() * right; offset += tm.GetColumn(1).GetNormalized() * front; offset += tm.GetColumn(2).GetNormalized() * up; } tm.SetTranslation(pStats->FPWeaponPos + offset); GetEntity()->SetWorldTM(tm); //CryLogAlways("weaponpos: %.3f,%.3f,%.3f // weaponrot: %.3f,%.3f,%.3f", tm.GetTranslation().x,tm.GetTranslation().y,tm.GetTranslation().z, pStats->FPWeaponAngles.x, pStats->FPWeaponAngles.y, pStats->FPWeaponAngles.z); }
//------------------------------------------------------------------------ void CItem::PostFilterView(struct SViewParams &viewParams) { if (m_camerastats.animating && !m_camerastats.follow) { const Matrix34 tm = GetEntity()->GetSlotWorldTM(eIGS_FirstPerson); Vec3 offset(0.0f,0.0f,0.0f); offset += tm.GetColumn(0).GetNormalized()*m_camerastats.pos.x; offset += tm.GetColumn(1).GetNormalized()*m_camerastats.pos.y; offset += tm.GetColumn(2).GetNormalized()*m_camerastats.pos.z; viewParams.position+=offset; viewParams.rotation*=m_camerastats.rot; viewParams.blend=true; viewParams.viewID=5; } if (m_camerastats.animating && m_stats.mounted && !m_camerastats.helper.empty() && IsOwnerFP()) { viewParams.position = GetSlotHelperPos(eIGS_FirstPerson, m_camerastats.helper, true); viewParams.rotation = Quat(GetSlotHelperRotation(eIGS_FirstPerson, m_camerastats.helper, true)); viewParams.blend = true; viewParams.viewID=5; viewParams.nearplane = 0.1f; } }
//------------------------------------------------------------------------ bool CItem::FilterView(struct SViewParams &viewParams) { if (m_camerastats.animating && m_camerastats.follow) { const Matrix34 tm = GetEntity()->GetSlotWorldTM(eIGS_FirstPerson); Vec3 offset(0.0f,0.0f,0.0f); offset += tm.GetColumn(0).GetNormalized()*m_camerastats.pos.x; offset += tm.GetColumn(1).GetNormalized()*m_camerastats.pos.y; offset += tm.GetColumn(2).GetNormalized()*m_camerastats.pos.z; viewParams.position+=offset; viewParams.rotation*=m_camerastats.rot; viewParams.blend=true; viewParams.viewID=5; } return m_camerastats.reorient; }
void CVehicleMovementAerodynamic::UpdateWing(SWing *_pWing,float _fAngle,float _fDeltaTime) { Matrix34 matWing = m_pEntity->GetWorldTM() * Matrix33::CreateRotationXYZ(Ang3(DEG2RAD(_pWing->fAngleX), DEG2RAD(_pWing->fAngleY), DEG2RAD(_pWing->fAngleZ))).GetInverted(); Vec3 vRight = matWing.GetColumn(0); Vec3 vLook = matWing.GetColumn(1); Vec3 vUp = matWing.GetColumn(2); pe_status_dynamics StatusDynamics; GetPhysics()->GetStatus(&StatusDynamics); // v(relativepoint) = v + w^(relativepoint-center) Vec3 vVelocity = StatusDynamics.v + StatusDynamics.w.Cross(m_pEntity->GetWorldTM().TransformVector(_pWing->vPos)); Vec3 vVelocityNormalized = vVelocity.GetNormalizedSafe(vLook); // TODO: float fAngleOfAttack = RAD2DEG(asin(vRight.Dot(vVelocityNormalized.Cross(vLook)))); DumpText("AoA=%f",fAngleOfAttack); fAngleOfAttack += _fAngle; float Cl = GetCoefficient(_pWing->pLiftPointsMap,fAngleOfAttack) * _pWing->fCl; float Cd = GetCoefficient(_pWing->pDragPointsMap,fAngleOfAttack) * _pWing->fCd; Vec3 vVelocityNormal = vRight.Cross(vVelocityNormalized).GetNormalized(); float fVelocitySquared = vVelocity.len2(); const float c_fDynamicPressure = 1.293f; float fLift = 0.5f * c_fDynamicPressure * _pWing->fSurface * Cl * fVelocitySquared * _fDeltaTime; float fDrag = 0.5f * c_fDynamicPressure * _pWing->fSurface * Cd * fVelocitySquared * _fDeltaTime; Vec3 vLiftImpulse = +fLift * vVelocityNormal; Vec3 vDragImpulse = -fDrag * vVelocityNormalized; AddForce(&vLiftImpulse,&_pWing->vPos,ColorF(0,1,0,1)); AddForce(&vDragImpulse,&_pWing->vPos,ColorF(1,0,1,1)); }
bool CTornado::Reset() { //Initialize default values before (in case ScriptTable fails) m_wanderSpeed = 10.0f; m_cloudHeight = 376.0f; m_radius = 300.0f; m_spinImpulse = 9.0f; m_attractionImpulse = 13.0f; m_upImpulse = 18.0f; const char* funnelEffect = 0; SmartScriptTable props; IScriptTable* pScriptTable = GetEntity()->GetScriptTable(); if(!pScriptTable || !pScriptTable->GetValue("Properties", props)) return false; props->GetValue("fWanderSpeed", m_wanderSpeed); props->GetValue("fCloudHeight", m_cloudHeight); props->GetValue("Radius", m_radius); props->GetValue("fSpinImpulse", m_spinImpulse); props->GetValue("fAttractionImpulse", m_attractionImpulse); props->GetValue("fUpImpulse", m_upImpulse); props->GetValue("FunnelEffect", funnelEffect); if (!UseFunnelEffect(funnelEffect)) return false; Matrix34 m = GetEntity()->GetWorldTM(); m_wanderDir = m.GetColumn(1)*0.414214f; m_isOnWater = false; m_isInAir = false; m_nextEntitiesCheck = 0; Vec3 pos = GetEntity()->GetWorldPos(); gEnv->pLog->Log("TORNADO INIT POS: %f %f %f", pos.x, pos.y, pos.z); m_points[0] = pos; m_points[1] = pos + Vec3(0,0,m_cloudHeight/8.0f); m_points[2] = pos + Vec3(0,0,m_cloudHeight/2.0f); m_points[3] = pos + Vec3(0,0,m_cloudHeight); for (int i=0; i<4; ++i) m_oldPoints[i] = m_points[i]; m_currentPos = GetEntity()->GetWorldPos(); CHANGED_NETWORK_STATE(this, POSITION_ASPECT); UpdateTornadoSpline(); return true; }
//------------------------------------------------------------------------ void CTornado::Update(SEntityUpdateContext &ctx, int updateSlot) { if (g_pGame->GetIGameFramework()->IsEditing()) return; // wandering Matrix34 m = GetEntity()->GetWorldTM(); Vec3 dir(m.GetColumn(1)); Vec3 pos(GetEntity()->GetWorldPos()); if(!gEnv->bServer) pos = m_currentPos; Vec3 wanderPos(dir * 1.414214f); float wanderStrength(1.0f); float wanderRate(0.6f); Vec3 wanderOffset; wanderOffset.SetRandomDirection(); wanderOffset.z = 0.0f; wanderOffset.NormalizeSafe(Vec3(1,0,0)); m_wanderDir += wanderOffset * wanderRate + (m_wanderDir - wanderPos) * wanderStrength; m_wanderDir = (m_wanderDir - wanderPos).GetNormalized() + wanderPos; Vec3 wanderSteer = (dir + m_wanderDir * gEnv->pTimer->GetFrameTime()); wanderSteer.z = 0; wanderSteer.NormalizeSafe(Vec3(1,0,0)); Vec3 targetSteer(0,0,0); // go to target if (m_pTargetEntity) { Vec3 target = m_pTargetEntity->GetWorldPos() - pos; if (target.GetLength() < 10.0f) { // emit target reached event SEntityEvent event( ENTITY_EVENT_SCRIPT_EVENT ); event.nParam[0] = (INT_PTR)"TargetReached"; event.nParam[1] = IEntityClass::EVT_BOOL; bool bValue = true; event.nParam[2] = (INT_PTR)&bValue; GetEntity()->SendEvent( event ); if (m_pTargetCallback) m_pTargetCallback->Done(); m_pTargetEntity = 0; m_pTargetCallback = 0; } targetSteer = (target - dir); targetSteer.z = 0; targetSteer.NormalizeSafe(Vec3(1,0,0)); } Vec3 steerDir = (0.4f * wanderSteer + 0.6f * targetSteer).GetNormalized(); Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(steerDir)); pos = pos + steerDir * gEnv->pTimer->GetFrameTime() * m_wanderSpeed; pos.z = gEnv->p3DEngine->GetTerrainElevation(pos.x, pos.y); float waterLevel = gEnv->p3DEngine->GetWaterLevel(&pos); bool prevIsOnWater = m_isOnWater; m_isOnWater = (pos.z < waterLevel); if (m_isOnWater) { pos.z = waterLevel; } // raycast does not work for oceans if (prevIsOnWater != m_isOnWater && m_isOnWater) { m_pGroundEffect->SetParticleEffect("weather.tornado.water"); } else if (!m_isOnWater) { IMaterialEffects *mfx = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects(); Vec3 down = Vec3(0,0,-1.0f); int matID = mfx->GetDefaultSurfaceIndex(); static const int objTypes = ent_all; static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; ray_hit hit; int col = gEnv->pPhysicalWorld->RayWorldIntersection(pos, (down * 5.0f), objTypes, flags, &hit, 1, GetEntity()->GetPhysics()); if (col) { matID = hit.surface_idx; } if (m_curMatID != matID) { TMFXEffectId effectId = mfx->GetEffectId("tornado", matID); SMFXResourceListPtr pList = mfx->GetResources(effectId); if (pList && pList->m_particleList) { m_pGroundEffect->SetParticleEffect(pList->m_particleList->m_particleParams.name); } m_curMatID = matID; } } if(gEnv->bServer) { tm.SetTranslation(pos); m_currentPos = pos; CHANGED_NETWORK_STATE(this, POSITION_ASPECT); GetEntity()->SetWorldTM(tm); } else { tm.SetTranslation(m_currentPos); GetEntity()->SetWorldTM(tm); } UpdateParticleEmitters(); UpdateTornadoSpline(); UpdateFlow(); }