//------------------------------------------------------------------------ void CTracer::Reset(const Vec3 &pos, const Vec3 &dest) { m_pos.zero(); m_dest.zero(); m_startingPos=pos; m_age=0.0f; m_lifeTime=1.5f; m_tracerFlags &= ~kTracerFlag_scaleToDistance; m_startFadeOutTime = 0.0f; m_slideFrac = 0.f; if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity(m_entityId)) { pEntity->FreeSlot(TRACER_GEOM_SLOT); pEntity->FreeSlot(TRACER_FX_SLOT); Vec3 dir = dest - pos; dir.Normalize(); Matrix34 tm; tm.SetIdentity(); if(!dir.IsZero()) { tm = Matrix33::CreateRotationVDir(dir); } tm.AddTranslation(pos); pEntity->SetWorldTM(tm); } }
void CLaserBeam::UpdateLaserGeometry( IEntity& laserEntity ) { // Scale the laser based on the distance. const float assetLengthInv = 0.5f; const float bias = g_pGameCVars->i_laser_hitPosOffset; const float finalLaserLen = m_hasHitData ? max(0.f, m_lastLaserUpdatePosition.GetDistance(GetLastHit()) - bias) : 0.001f; const float scale = finalLaserLen * assetLengthInv; const float thickness = m_pLaserParams->laser_thickness[GetIndexFromGeometrySlot()]; const Quat inverseWorldQuat(laserEntity.GetWorldRotation().GetInverted()); Vec3 localSpaceDirection = inverseWorldQuat * m_lastLaserUpdateDirection; const Vec3 finalHitPos = localSpaceDirection * finalLaserLen; const Matrix34 localLaserMatrix = Matrix33::CreateOrientation(localSpaceDirection, Vec3(0.f, 0.f, 1.f), 0.f) * Matrix34::CreateScale(Vec3(thickness, scale, thickness)); laserEntity.SetSlotLocalTM(m_laserGeometrySlot, localLaserMatrix); // Set Dot matrix if (m_hitSolid) { const Matrix34 mt = Matrix34::CreateTranslationMat(finalHitPos); laserEntity.SetSlotLocalTM(m_laserDotSlot, mt); } else { Matrix34 scaleMatrix; scaleMatrix.SetIdentity(); scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f)); laserEntity.SetSlotLocalTM(m_laserDotSlot, scaleMatrix); } }
//------------------------------------------------------------------------ Matrix34 CVehiclePartAnimated::GetDestroyedGeometryTM(const char* pJointName, unsigned int index) { if (pJointName[0] && m_pCharInstanceDestroyed) { IDefaultSkeleton &rICharacterModelSkeletonDestroyed = m_pCharInstanceDestroyed->GetIDefaultSkeleton(); ISkeletonPose* pSkeletonDestroyed = m_pCharInstanceDestroyed->GetISkeletonPose(); CRY_ASSERT(pSkeletonDestroyed); char buffer[256]; const char* pSuffix = !m_pSharedParameters->m_destroyedSuffix.empty() ? m_pSharedParameters->m_destroyedSuffix.c_str() : GetDestroyedGeometrySuffix(eVGS_Destroyed); if (index == 0) { cry_sprintf(buffer, "%s%s", pJointName, pSuffix); } else { cry_sprintf(buffer, "%s_debris_%u", pJointName, index); } buffer[sizeof(buffer) - 1] = '\0'; int16 jointIdForDestroyed = rICharacterModelSkeletonDestroyed.GetJointIDByName(buffer); if (jointIdForDestroyed > -1) return Matrix34(pSkeletonDestroyed->GetAbsJointByID(jointIdForDestroyed)); } Matrix34 identTM; identTM.SetIdentity(); return identTM; }
//------------------------------------------------------------------- void CLam::UpdateLaserScale(float scaleLenght,IEntity* pLaserEntity) { if(pLaserEntity) { Matrix34 tm; tm.SetIdentity(); tm.SetScale(Vec3(1.0f,scaleLenght,1.0f)); pLaserEntity->SetLocalTM(tm); } }
void CBurnEffectManager::SpawnImpactEffect(const EventPhysCollision& pCollision, const char* effectName) { Vec3 surfaceNormal = pCollision.n; Vec3 surfacePosition = pCollision.pt; CItemParticleEffectCache& particleCache = g_pGame->GetGameSharedParametersStorage()->GetItemResourceCache().GetParticleEffectCache(); IParticleEffect* pParticleEffect = particleCache.GetCachedParticle(effectName); if (pParticleEffect) { Matrix34 loc; loc.SetIdentity(); loc.SetTranslation(surfacePosition); loc.SetRotation33(OrthoNormalVector(surfaceNormal)); pParticleEffect->Spawn(false, loc); } }
//------------------------------------------------------------------------ void CVehicleActionDeployRope::AttachOnRope(IEntity *pEntity) { assert(pEntity); if(!pEntity) return; IRopeRenderNode *pRopeUpper = GetRopeRenderNode(m_ropeUpperId); if(!pRopeUpper) return; assert(pRopeUpper->GetPointsCount() >= 2); IPhysicalEntity *pRopePhys = pRopeUpper->GetPhysics(); assert(pRopePhys); typedef std::vector <Vec3> TVec3Vector; TVec3Vector points; int pointCount; pe_status_rope ropeStatus; if(pRopePhys->GetStatus(&ropeStatus)) pointCount = ropeStatus.nSegments + 1; else pointCount = 0; if(pointCount < 2) return; points.resize(pointCount); ropeStatus.pPoints = &points[0]; if(pRopePhys->GetStatus(&ropeStatus)) { Matrix34 worldTM; worldTM.SetIdentity(); worldTM = Matrix33(m_pVehicle->GetEntity()->GetWorldTM()); worldTM.SetTranslation(ropeStatus.pPoints[1]); pEntity->SetWorldTM(worldTM); } pRopeUpper->LinkEndEntities(m_pVehicle->GetEntity()->GetPhysics(), pEntity->GetPhysics()); }
void CBurnEffectManager::CreateBurnEffect(const EventPhysCollision& pCollision, CBurnEffectManager::SBurnPoint* pBurnPoint) { Vec3 surfaceNormal = pCollision.n; Vec3 hitDir(ZERO); if (pCollision.vloc[0].GetLengthSquared() > 1e-6f) { hitDir = pCollision.vloc[0].GetNormalized(); } Vec3 surfacePosition = pCollision.pt; Vec3 halfVector = (surfaceNormal + (-hitDir)).GetNormalized(); CItemParticleEffectCache& particleCache = g_pGame->GetGameSharedParametersStorage()->GetItemResourceCache().GetParticleEffectCache(); IParticleEffect* pParticleEffect = particleCache.GetCachedParticle(pBurnPoint->m_pBurnParams->m_effectName); if (pParticleEffect) { Matrix34 loc; loc.SetIdentity(); loc.SetTranslation(surfacePosition); loc.SetRotation33(OrthoNormalVector(surfaceNormal)); IParticleEmitter* pEffect = pParticleEffect->Spawn(false, loc); if(pEffect) { pEffect->AddRef(); pBurnPoint->m_effect = pEffect; const ParticleParams& particleParams = pParticleEffect->GetParticleParams(); pBurnPoint->m_attachType = particleParams.eAttachType; pBurnPoint->m_attachForm = particleParams.eAttachForm; } UpdateBurnEffect(pBurnPoint); } UpdateBurnEffect(pBurnPoint); }
void CBoidObject::CreateArticulatedCharacter(SBoidContext &bc,const Vec3 &size,float mass) { Vec3 orgVelocity = m_speed*m_heading; if(m_pPhysics && m_pPhysics->GetType() == PE_PARTICLE) { pe_params_particle pparams; m_pPhysics->GetParams(&pparams); orgVelocity = pparams.velocity*pparams.heading; } if(m_pPhysics) { m_pPhysics = 0; } IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity); if(!pEntity) return; Quat q(IDENTITY); CalcOrientation(q); pe_params_pos bodypos; bodypos.pos = m_pos; bodypos.q = q; bodypos.scale = m_scale; bodypos.iSimClass = 2; SEntityPhysicalizeParams entityPhysParams; entityPhysParams.type = PE_ARTICULATED; entityPhysParams.nSlot = 0; entityPhysParams.mass = mass; entityPhysParams.nLod = 1; pEntity->Physicalize(entityPhysParams); // After physicalization reset entity slot matrix if present. if(!bc.vEntitySlotOffset.IsZero()) { Matrix34 tmIdent; tmIdent.SetIdentity(); pEntity->SetSlotLocalTM(0,tmIdent); } m_pPhysics = pEntity->GetPhysics(); if(!m_pPhysics) return; m_pPhysics->SetParams(&bodypos); //m_pPhysics = m_object->RelinquishCharacterPhysics(); pe_params_flags pf; pf.flagsOR = pef_never_affect_triggers|pef_never_break; m_pPhysics->SetParams(&pf); pe_params_articulated_body pab; pab.bGrounded = 0; pab.bCheckCollisions = 1; pab.bCollisionResp = 1; m_pPhysics->SetParams(&pab); pe_simulation_params symparams; symparams.damping = 0.3f; symparams.dampingFreefall = 0.2f; m_pPhysics->SetParams(&symparams); pe_params_buoyancy pb; pb.waterDensity = 1000.0f; pb.waterDamping = 1; pb.waterResistance = 1000; pb.waterPlane.n.Set(0,0,1); //pb.waterPlane.origin.set(0,0,gEnv->p3DEngine->GetWaterLevel(&m_center)); pb.waterPlane.origin.Set(0,0,bc.waterLevel); m_pPhysics->SetParams(&pb); // Set original velocity on ragdoll. pe_action_set_velocity psetvel; psetvel.v = orgVelocity; m_pPhysics->Action(&psetvel); pe_params_part pp; pp.flagsColliderOR=pp.flagsColliderAND = geom_colltype_debris; pp.flagsAND = ~(geom_colltype_vehicle|geom_colltype6); m_pPhysics->SetParams(&pp); }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { if (!pActInfo->pEntity) return; if (event == eFE_Activate && IsPortActive(pActInfo, IN_ACTIVATE)) { pe_action_impulse action; int ipart = GetPortInt( pActInfo, IN_PARTINDEX ); if (ipart>0) action.ipart = ipart-1; IEntity* pEntity = pActInfo->pEntity; ECoordSys coordSys = (ECoordSys)GetPortInt( pActInfo, IN_COORDSYS ); if (coordSys==CS_PARENT && !pEntity->GetParent()) coordSys = CS_WORLD; // When a "zero point" is set in the node, the value is left undefined and physics assume it is the CM of the object. // but when the entity has a parent (is linked), then we have to use a real world coordinate for the point, because we have to apply the impulse to the highest entity // on the hierarchy and physics will use the position of that entity instead of the position of the entity assigned to the node bool bHaveToUseTransformedZeroPoint = false; Vec3 transformedZeroPoint; Matrix34 transMat; switch (coordSys) { case CS_WORLD: default: { transMat.SetIdentity(); bHaveToUseTransformedZeroPoint = pEntity->GetParent()!=NULL; transformedZeroPoint = pEntity->GetWorldPos(); break; } case CS_PARENT: { transMat = pEntity->GetParent()->GetWorldTM(); bHaveToUseTransformedZeroPoint = pEntity->GetParent()->GetParent()!=NULL; transformedZeroPoint = pEntity->GetParent()->GetWorldPos(); break; } case CS_LOCAL: { transMat = pEntity->GetWorldTM(); bHaveToUseTransformedZeroPoint = pEntity->GetParent()!=NULL; transformedZeroPoint = pEntity->GetWorldPos(); break; } } action.impulse = GetPortVec3( pActInfo, IN_IMPULSE ); action.impulse = transMat.TransformVector( action.impulse ); Vec3 angImpulse = GetPortVec3( pActInfo, IN_ANGIMPULSE ); if (!angImpulse.IsZero()) action.angImpulse = transMat.TransformVector( angImpulse ); Vec3 pointApplication = GetPortVec3( pActInfo, IN_POINT ); if (!pointApplication.IsZero()) action.point = transMat.TransformPoint( pointApplication ); else { if (bHaveToUseTransformedZeroPoint) action.point = transformedZeroPoint; } // the impulse has to be applied to the highest entity in the hierarchy. This comes from how physics manage linked entities. IEntity* pEntityImpulse = pEntity; while (pEntityImpulse->GetParent()) { pEntityImpulse = pEntityImpulse->GetParent(); } IPhysicalEntity * pPhysEntity = pEntityImpulse->GetPhysics(); if (pPhysEntity) pPhysEntity->Action( &action ); } }
//------------------------------------------------------------------ void CLam::UpdateTPLaser(float frameTime, CItem* parent) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); const int frameId = gEnv->pRenderer->GetFrameID(); if (s_lastUpdateFrameId != frameId) { // Check how many LAMs to update this frame. float dt = frameTime; // + s_laserUpdateTimeError; const int n = s_lasers.size(); int nActive = 0; for (int i = 0; i < n; ++i) { if (!s_lasers[i]->IsLaserActivated() && !s_lasers[i]->IsLightActivated()) continue; nActive++; } float updatedPerSecond = (nActive / LASER_UPDATE_TIME) + s_laserUpdateTimeError; int updateCount = (int)floorf(updatedPerSecond * dt); if(dt==0.0f) s_laserUpdateTimeError = 0.0f; else s_laserUpdateTimeError = updatedPerSecond - updateCount/dt; s_curLaser %= n; for (int i = 0, j = 0; i < n && j < updateCount ; ++i) { s_curLaser = (s_curLaser + 1) % n; if (!s_lasers[s_curLaser]->IsLaserActivated() && !s_lasers[s_curLaser]->IsLightActivated()) continue; s_lasers[s_curLaser]->SetAllowUpdate(); ++j; } s_lastUpdateFrameId = frameId; } IEntity* pRootEnt = GetEntity(); if (!pRootEnt) return; IEntity *pLaserEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId); // if(!pLaserEntity) // return; const CCamera& camera = gEnv->pRenderer->GetCamera(); Vec3 lamPos = pRootEnt->GetWorldPos(); //pLaserEntity->GetParent()->GetWorldPos(); Vec3 dir = pRootEnt->GetWorldRotation().GetColumn1(); //pLaserEntity->GetParent()->GetWorldRotation().GetColumn1(); bool charNotVisible = false; float dsg1Scale = 1.0f; //If character not visible, laser is not correctly updated if(parent) { if(CActor* pOwner = parent->GetOwnerActor()) { ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0); if(pCharacter && !pCharacter->IsCharacterVisible()) charNotVisible = true; } if(parent->GetEntity()->GetClass()==CItem::sDSG1Class) dsg1Scale = 3.0f; } // if (!pLaserEntity->GetParent()) // return; Vec3 hitPos(0,0,0); float laserLength = 0.0f; // HACK??: Use player movement controller locations, or else the laser // pops all over the place when character out of the screen. CActor *pActor = parent->GetOwnerActor(); if (pActor && (!pActor->IsPlayer() || charNotVisible)) { if (IMovementController* pMC = pActor->GetMovementController()) { SMovementState state; pMC->GetMovementState(state); if(!charNotVisible) lamPos = state.weaponPosition; else { float oldZPos = lamPos.z; lamPos = state.weaponPosition; if(m_lastZPos>0.0f) lamPos.z = m_lastZPos; //Stabilize somehow z position (even if not accurate) else lamPos.z = oldZPos; } const float angleMin = DEG2RAD(3.0f); const float angleMax = DEG2RAD(7.0f); const float thr = cosf(angleMax); float dot = dir.Dot(state.aimDirection); if (dot > thr) { float a = acos_tpl(dot); float u = 1.0f - clamp((a - angleMin) / (angleMax - angleMin), 0.0f, 1.0f); dir = dir + u * (state.aimDirection - dir); dir.Normalize(); } } } if(!charNotVisible) m_lastZPos = lamPos.z; lamPos += (dir*0.10f); if (m_allowUpdate) { m_allowUpdate = false; IPhysicalEntity* pSkipEntity = NULL; if(parent->GetOwner()) pSkipEntity = parent->GetOwner()->GetPhysics(); const float range = m_lamparams.laser_range[eIGS_ThirdPerson]*dsg1Scale; // Use the same flags as the AI system uses for visbility. const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); ray_hit hit; if (gEnv->pPhysicalWorld->RayWorldIntersection(lamPos, dir*range, objects, flags, &hit, 1, &pSkipEntity, pSkipEntity ? 1 : 0)) { laserLength = hit.dist; m_lastLaserHitPt = hit.pt; m_lastLaserHitSolid = true; } else { m_lastLaserHitSolid = false; m_lastLaserHitPt = lamPos + dir * range; laserLength = range + 0.1f; } // Hit near plane if (dir.Dot(camera.GetViewdir()) < 0.0f) { Plane nearPlane; nearPlane.SetPlane(camera.GetViewdir(), camera.GetPosition()); nearPlane.d -= camera.GetNearPlane()+0.15f; Ray ray(lamPos, dir); Vec3 out; m_lastLaserHitViewPlane = false; if (Intersect::Ray_Plane(ray, nearPlane, out)) { float dist = Distance::Point_Point(lamPos, out); if (dist < laserLength) { laserLength = dist; m_lastLaserHitPt = out; m_lastLaserHitSolid = true; m_lastLaserHitViewPlane = true; } } } hitPos = m_lastLaserHitPt; } else { laserLength = Distance::Point_Point(m_lastLaserHitPt, lamPos); hitPos = lamPos + dir * laserLength; } if (m_smoothLaserLength < 0.0f) m_smoothLaserLength = laserLength; else { if (laserLength < m_smoothLaserLength) m_smoothLaserLength = laserLength; else m_smoothLaserLength += (laserLength - m_smoothLaserLength) * min(1.0f, 10.0f * frameTime); } float laserAIRange = 0.0f; if (m_laserActivated && pLaserEntity) { // Orient the laser towards the point point. Matrix34 parentTMInv; parentTMInv = pRootEnt->GetWorldTM().GetInverted(); Vec3 localDir = parentTMInv.TransformPoint(hitPos); float finalLaserLen = localDir.NormalizeSafe(); Matrix33 rot; rot.SetIdentity(); rot.SetRotationVDir(localDir); pLaserEntity->SetLocalTM(rot); laserAIRange = finalLaserLen; const float assetLength = 2.0f; finalLaserLen = CLAMP(finalLaserLen,0.01f,m_lamparams.laser_max_len*dsg1Scale); float scale = finalLaserLen / assetLength; // Scale the laser based on the distance. if (m_laserEffectSlot >= 0) { Matrix33 scl; scl.SetIdentity(); scl.SetScale(Vec3(1,scale,1)); pLaserEntity->SetSlotLocalTM(m_laserEffectSlot, scl); } if (m_dotEffectSlot >= 0) { if (m_lastLaserHitSolid) { Matrix34 mt = Matrix34::CreateTranslationMat(Vec3(0,finalLaserLen,0)); if(m_lastLaserHitViewPlane) mt.Scale(Vec3(0.2f,0.2f,0.2f)); pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, mt); } else { Matrix34 scaleMatrix; scaleMatrix.SetIdentity(); scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f)); pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix); } } } float lightAIRange = 0.0f; if (m_lightActivated) { float range = clamp(m_smoothLaserLength, 0.5f, m_lamparams.light_range[eIGS_ThirdPerson]); lightAIRange = range * 1.5f; if (m_lightID[eIGS_ThirdPerson] && m_smoothLaserLength > 0.0f) { CItem* pLightEffect = this; if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId())) pLightEffect = (CItem *)pOwnerItem; pLightEffect->SetLightRadius(range, m_lightID[eIGS_ThirdPerson]); } } if (laserAIRange > 0.0001f || lightAIRange > 0.0001f) UpdateAILightAndLaser(lamPos, dir, lightAIRange, m_lamparams.light_fov[eIGS_ThirdPerson], laserAIRange); }
void CSmokeManager::Update(float dt) { PrefetchLine(m_smokeInstances, 0); PrefetchLine(m_smokeInstances, 128); const int kInitialNumActiveSmokeInstances = m_numActiveSmokeInstances; //Update all smoke instances for(int i = 0; i < kInitialNumActiveSmokeInstances; i++) { SSmokeInstance& smokeInstance = m_smokeInstances[i]; PrefetchLine(&smokeInstance, 128); UpdateSmokeInstance(smokeInstance, dt); } #ifndef _RELEASE DrawSmokeDebugSpheres(); #endif //Remove any smoke instances marked for deletion int iNumActiveSmokeInstances = kInitialNumActiveSmokeInstances; for(int i = 0; i < iNumActiveSmokeInstances; i++) { SSmokeInstance& smokeInstance = m_smokeInstances[i]; //If this item is marked for deletion, copy the last element of the array // over it if(smokeInstance.state == eSIS_ForDeletion) { smokeInstance.RemoveObstructionObject(); const int iLastIndex = iNumActiveSmokeInstances - 1; m_smokeInstances[i] = m_smokeInstances[iLastIndex]; m_smokeInstances[iLastIndex].state = eSIS_Unassigned; m_smokeInstances[iLastIndex].pObstructObject = NULL; iNumActiveSmokeInstances--; i--; } } m_numActiveSmokeInstances = iNumActiveSmokeInstances; //Update smoke soundmood and screen effects for client float insideSmokeFactor = 0.0f; const bool clientInsideSmoke = ClientInsideSmoke(insideSmokeFactor); SetSmokeSoundmood(clientInsideSmoke); SetBlurredVision(insideSmokeFactor, dt); if(clientInsideSmoke) { if(m_pInsideSmokeEmitter == NULL) { // Start smoke Matrix34 spawnLocation; spawnLocation.SetIdentity(); if (m_pInsideSmokeParticleEffect) { m_pInsideSmokeEmitter = m_pInsideSmokeParticleEffect->Spawn(false,spawnLocation); if(m_pInsideSmokeEmitter) { m_pInsideSmokeEmitter->AddRef(); EntityId localActorId = g_pGame->GetIGameFramework()->GetClientActorId(); IEntity* pLocalActorEntity = gEnv->pEntitySystem->GetEntity(localActorId); if(pLocalActorEntity) { m_pInsideSmokeEmitter->SetEntity(pLocalActorEntity,0); } } } } if(m_pInsideSmokeEmitter && !m_pInsideSmokeEmitter->IsAlive()) { m_pInsideSmokeEmitter->Activate(true); } } else { if(m_pInsideSmokeEmitter && m_pInsideSmokeEmitter->IsAlive()) { m_pInsideSmokeEmitter->SetEntity(NULL,0); m_pInsideSmokeEmitter->Activate(false); } } }
//-------------------------------------------------------------------------------------------------- // Name: CalculateGlassBounds // Desc: Calculates glass bounds from physics geometry //-------------------------------------------------------------------------------------------------- void CBreakableGlassSystem::CalculateGlassBounds(const phys_geometry* const pPhysGeom, Vec3& size, Matrix34& matrix) { // Find thinnest axis of physics geometry primitives::box bbox; pPhysGeom->pGeom->GetBBox(&bbox); Matrix33 basis = bbox.Basis.T(); Vec3 halfSize = bbox.size; Vec3 center = bbox.center; const uint thinAxis = idxmin3(&halfSize.x); // Need to rotate so Z is our thin axis if (thinAxis < 2) { float tempSize; Matrix33 tempMat; tempMat.SetIdentity(); // Calculate the rotation based on current facing dir const Vec3 axes[2] = { Vec3Constants<float>::fVec3_OneX, Vec3Constants<float>::fVec3_OneY }; const Vec3& thinRow = bbox.Basis.GetRow(thinAxis); const Vec3 localAxis = bbox.Basis.TransformVector(axes[thinAxis]); float rot = (thinRow.Dot(localAxis) >= 0.0f) ? -gf_PI*0.5f : gf_PI*0.5f; if (thinAxis == 0) { tempSize = halfSize.x; halfSize.x = halfSize.z; tempMat.SetRotationY(rot); } else { tempSize = halfSize.y; halfSize.y = halfSize.z; tempMat.SetRotationX(rot); } // Apply rotation to matrix and vectors basis = basis * tempMat; halfSize.z = tempSize; } // Assert minimum thickness const float halfMinThickness = 0.004f; halfSize.z = max(halfSize.z, halfMinThickness); size = halfSize * 2.0f; // Calculate locally offset bounds matrix.SetIdentity(); matrix.SetTranslation(-halfSize); matrix = basis * matrix; matrix.AddTranslation(center); }//-------------------------------------------------------------------------------------------------
//----------------------------------------------- //This function is only executed on the server void CC4Projectile::Stick(EventPhysCollision *pCollision) { assert(pCollision); int trgId = 1; IPhysicalEntity *pTarget = pCollision->pEntity[trgId]; if(pTarget == GetEntity()->GetPhysics()) { trgId = 0; pTarget = pCollision->pEntity[trgId]; } //Do not stick to breakable glass if(ISurfaceType *pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(pCollision->idmat[trgId])) { if(pSurfaceType->GetBreakability()==1) { m_notStick = true; return; } } IEntity *pTargetEntity = pTarget ? gEnv->pEntitySystem->GetEntityFromPhysics(pTarget) : 0; if(pTarget && (!pTargetEntity || (pTargetEntity->GetId() != m_ownerId))) { //Special cases if(pTargetEntity) { //Stick to actors using a character attachment CActor *pActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId())); //Not in MP if(pActor && gEnv->bMultiplayer) { m_notStick = true; return; } if(pActor && pActor->GetHealth()>0) { if(pActor->GetActorSpecies()!=eGCT_HUMAN) { m_notStick = true; return; } if(StickToCharacter(true,pTargetEntity)) { GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None); m_stuck = true; } m_notStick = true; return; } //Do not stick to small objects... if(!pActor) { pe_params_part pPart; pPart.ipart = 0; if(pTarget->GetParams(&pPart) && pPart.pPhysGeom && pPart.pPhysGeom->V<0.15f) { m_notStick = true; return; } } } else if(pTarget->GetType()==PE_LIVING) { m_notStick = true; return; } if(!pTargetEntity) StickToStaticObject(pCollision,pTarget); else { //Do not attach to items if(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pTargetEntity->GetId())) { m_notStick = true; return; } Matrix34 mat = pTargetEntity->GetWorldTM(); mat.Invert(); Vec3 pos = mat.TransformPoint(pCollision->pt); mat.SetIdentity(); mat.SetRotation33(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI)); mat.SetTranslation(pos); //Dephysicalize and stick GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None); StickToEntity(pTargetEntity,mat); if(gEnv->bMultiplayer) { Quat rot(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI*0.5f)); GetGameObject()->InvokeRMI(CC4Projectile::ClStickToEntity(),ProjectileStickToEntity(pTargetEntity->GetId(),pos,rot),eRMI_ToAllClients); } } m_stuck = true; } }
//---------------------------------------------------- void CRocketLauncher::UpdateTPLaser(float frameTime) { m_lastUpdate -= frameTime; bool allowUpdate = true; if(m_lastUpdate<=0.0f) m_lastUpdate = m_Timeout; else allowUpdate = false; const CCamera& camera = gEnv->pRenderer->GetCamera(); //If character not visible, laser is not correctly updated if(CActor* pOwner = GetOwnerActor()) { ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0); if(pCharacter && !pCharacter->IsCharacterVisible()) return; } Vec3 offset(-0.06f,0.28f,0.115f); //To match scope position in TP LAW model Vec3 pos = GetEntity()->GetWorldTM().TransformPoint(offset); Vec3 dir = GetEntity()->GetWorldRotation().GetColumn1(); Vec3 hitPos(0,0,0); float laserLength = 0.0f; if(allowUpdate) { IPhysicalEntity* pSkipEntity = NULL; if(GetOwner()) pSkipEntity = GetOwner()->GetPhysics(); const float range = m_LaserRangeTP; // Use the same flags as the AI system uses for visibility. const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); ray_hit hit; if (gEnv->pPhysicalWorld->RayWorldIntersection(pos, dir*range, objects, flags, &hit, 1, &pSkipEntity, pSkipEntity ? 1 : 0)) { laserLength = hit.dist; m_lastLaserHitPt = hit.pt; m_lastLaserHitSolid = true; } else { m_lastLaserHitSolid = false; m_lastLaserHitPt = pos + dir * range; laserLength = range + 0.1f; } // Hit near plane if (dir.Dot(camera.GetViewdir()) < 0.0f) { Plane nearPlane; nearPlane.SetPlane(camera.GetViewdir(), camera.GetPosition()); nearPlane.d -= camera.GetNearPlane()+0.15f; Ray ray(pos, dir); Vec3 out; m_lastLaserHitViewPlane = false; if (Intersect::Ray_Plane(ray, nearPlane, out)) { float dist = Distance::Point_Point(pos, out); if (dist < laserLength) { laserLength = dist; m_lastLaserHitPt = out; m_lastLaserHitSolid = true; m_lastLaserHitViewPlane = true; } } } hitPos = m_lastLaserHitPt; } else { laserLength = Distance::Point_Point(m_lastLaserHitPt, pos); hitPos = pos + dir * laserLength; } if (m_smoothLaserLength < 0.0f) m_smoothLaserLength = laserLength; else { if (laserLength < m_smoothLaserLength) m_smoothLaserLength = laserLength; else m_smoothLaserLength += (laserLength - m_smoothLaserLength) * min(1.0f, 10.0f * frameTime); } const float assetLength = 2.0f; m_smoothLaserLength = CLAMP(m_smoothLaserLength,0.01f,m_LaserRangeTP); float scale = m_smoothLaserLength / assetLength; // Scale the laser based on the distance. Matrix34 scl; scl.SetIdentity(); scl.SetScale(Vec3(1,scale,1)); scl.SetTranslation(offset); GetEntity()->SetSlotLocalTM( eIGS_Aux1, scl); if (m_dotEffectSlot >= 0) { if (m_lastLaserHitSolid) { Matrix34 dotMatrix = Matrix34::CreateTranslationMat(Vec3(0,m_smoothLaserLength,0)); dotMatrix.AddTranslation(offset); if(m_lastLaserHitViewPlane) dotMatrix.Scale(Vec3(0.2f,0.2f,0.2f)); GetEntity()->SetSlotLocalTM(m_dotEffectSlot,dotMatrix); } else { Matrix34 scaleMatrix; scaleMatrix.SetIdentity(); scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f)); GetEntity()->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix); } } }
//------------------------------------------------------------------------ void CVehicleMovementStdBoat::UpdateSurfaceEffects(const float deltaTime) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); if (0 == g_pGameCVars->v_pa_surface) { ResetParticles(); return; } IEntity* pEntity = m_pVehicle->GetEntity(); const Matrix34& worldTM = pEntity->GetWorldTM(); float distSq = worldTM.GetTranslation().GetSquaredDistance(gEnv->pRenderer->GetCamera().GetPosition()); if (distSq > sqr(300.f) || (distSq > sqr(50.f) && !m_pVehicle->GetGameObject()->IsProbablyVisible())) return; Matrix34 worldTMInv = worldTM.GetInverted(); const SVehicleStatus& status = m_pVehicle->GetStatus(); float velDot = status.vel * worldTM.GetColumn1(); float powerNorm = min(abs(m_movementAction.power), 1.f); SEnvironmentParticles* envParams = m_pPaParams->GetEnvironmentParticles(); SEnvParticleStatus::TEnvEmitters::iterator end = m_paStats.envStats.emitters.end(); for (SEnvParticleStatus::TEnvEmitters::iterator emitterIt = m_paStats.envStats.emitters.begin(); emitterIt!=end; ++emitterIt) { if (emitterIt->layer < 0) { assert(0); continue; } const SEnvironmentLayer& layer = envParams->GetLayer(emitterIt->layer); SEntitySlotInfo info; info.pParticleEmitter = 0; pEntity->GetSlotInfo(emitterIt->slot, info); float countScale = 1.f; float sizeScale = 1.f; float speedScale = 1.f; float speed = 0.f; // check if helper position is beneath water level Vec3 emitterWorldPos = worldTM * emitterIt->quatT.t; float waterLevel = gEnv->p3DEngine->GetWaterLevel(&emitterWorldPos); int matId = 0; if (emitterWorldPos.z <= waterLevel+0.1f && m_physStatus[k_mainThread].submergedFraction<0.999f) { matId = gEnv->pPhysicalWorld->GetWaterMat(); speed = status.speed; bool spray = !strcmp(layer.GetName(), "spray"); if (spray) { // slip based speed -= abs(velDot); } GetParticleScale(layer, speed, powerNorm, countScale, sizeScale, speedScale); } else { countScale = 0.f; } if (matId && matId != emitterIt->matId) { // change effect IParticleEffect* pEff = 0; const char* effect = GetEffectByIndex( matId, layer.GetName() ); if (effect && (pEff = gEnv->pParticleManager->FindEffect(effect))) { #if ENABLE_VEHICLE_DEBUG if (DebugParticles()) CryLog("%s changes water sfx to %s (slot %i)", pEntity->GetName(), effect, emitterIt->slot); #endif if (info.pParticleEmitter) { info.pParticleEmitter->Activate(false); pEntity->FreeSlot(emitterIt->slot); } emitterIt->slot = pEntity->LoadParticleEmitter(emitterIt->slot, pEff); if (emitterIt->slot != -1) pEntity->SetSlotLocalTM(emitterIt->slot, Matrix34(emitterIt->quatT)); info.pParticleEmitter = 0; pEntity->GetSlotInfo(emitterIt->slot, info); } else countScale = 0.f; } if (matId) emitterIt->matId = matId; if (info.pParticleEmitter) { SpawnParams sp; sp.fSizeScale = sizeScale; sp.fCountScale = countScale; sp.fSpeedScale = speedScale; info.pParticleEmitter->SetSpawnParams(sp); if (layer.alignToWater && countScale > 0.f) { Vec3 worldPos(emitterWorldPos.x, emitterWorldPos.y, waterLevel+0.05f); Matrix34 localTM(emitterIt->quatT); localTM.SetTranslation(worldTMInv * worldPos); pEntity->SetSlotLocalTM(emitterIt->slot, localTM); } } #if ENABLE_VEHICLE_DEBUG if (DebugParticles() && m_pVehicle->IsPlayerDriving()) { float color[] = {1,1,1,1}; ColorB red(255,0,0,255); IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); const char* effect = info.pParticleEmitter ? info.pParticleEmitter->GetName() : ""; const Matrix34& slotTM = m_pEntity->GetSlotWorldTM(emitterIt->slot); Vec3 ppos = slotTM.GetTranslation(); pAuxGeom->DrawSphere(ppos, 0.2f, red); pAuxGeom->DrawCone(ppos, slotTM.GetColumn1(), 0.1f, 0.5f, red); gEnv->pRenderer->Draw2dLabel(50.f, (float)(400+10*emitterIt->slot), 1.2f, color, false, "<%s> water fx: slot %i [%s], speed %.1f, sizeScale %.2f, countScale %.2f (pos %.0f,%0.f,%0.f)", pEntity->GetName(), emitterIt->slot, effect, speed, sizeScale, countScale, ppos.x, ppos.y, ppos.z); } #endif } // generate water splashes Vec3 wakePos; if(m_pSplashPos) { wakePos = m_pSplashPos->GetWorldSpaceTranslation(); } else { wakePos = worldTM.GetTranslation(); } float wakeWaterLevel = gEnv->p3DEngine->GetWaterLevel(&wakePos); const Vec3& localW = m_localSpeed; if (localW.x >= 0.f) m_diving = false; if (!m_diving && localW.x < -0.03f && status.speed > 10.f && wakePos.z < m_lastWakePos.z && wakeWaterLevel+0.1f >= wakePos.z) { float speedRatio = min(1.f, status.speed/(m_maxSpeed*m_factorMaxSpeed)); m_diving = true; if (m_pWaveEffect) { if (IParticleEmitter* pEmitter = pEntity->GetParticleEmitter(m_wakeSlot)) { pEmitter->Activate(false); pEntity->FreeSlot(m_wakeSlot); m_wakeSlot = -1; } SpawnParams spawnParams; spawnParams.fSizeScale = spawnParams.fCountScale = 0.5f + 0.25f*speedRatio; spawnParams.fSizeScale += 0.4f*m_waveRandomMult; spawnParams.fCountScale += cry_random(0.0f, 0.4f); m_wakeSlot = pEntity->LoadParticleEmitter(m_wakeSlot, m_pWaveEffect, &spawnParams); } // handle splash sound ExecuteTrigger(eSID_Splash); SetSoundParam(eSID_Splash, "intensity", 0.2f*speedRatio + 0.5f*m_waveRandomMult); if (m_rpmPitchDir == 0) { m_rpmPitchDir = -1; m_waveSoundPitch = 0.f; m_waveSoundAmount = 0.02f + m_waveRandomMult*0.08f; } } if (m_wakeSlot != -1) { // update emitter local pos to short above waterlevel Matrix34 tm; if(m_pSplashPos) m_pSplashPos->GetVehicleTM(tm); else tm.SetIdentity(); Vec3 pos = tm.GetTranslation(); pos.z = worldTMInv.TransformPoint(Vec3(wakePos.x,wakePos.y,wakeWaterLevel)).z + 0.2f; tm.SetTranslation(pos); pEntity->SetSlotLocalTM(m_wakeSlot, tm); #if ENABLE_VEHICLE_DEBUG if (IsProfilingMovement()) { Vec3 wPos = worldTM * tm.GetTranslation(); ColorB col(128, 128, 0, 200); gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(wPos, 0.4f, col); gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(wPos, col, wPos+Vec3(0,0,1.5f), col); } #endif } m_lastWakePos = wakePos; }
//------------------------------------------------------------------------ void CViewSystem::Update(float frameTime) { FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION); if (gEnv->IsDedicated()) return; CView* const __restrict pActiveView = static_cast<CView*>(GetActiveView()); TViewMap::const_iterator Iter(m_views.begin()); TViewMap::const_iterator const IterEnd(m_views.end()); for (; Iter != IterEnd; ++Iter) { CView* const __restrict pView = Iter->second; bool const bIsActive = (pView == pActiveView); pView->Update(frameTime, bIsActive); if (bIsActive) { CCamera &rCamera = pView->GetCamera(); pView->UpdateAudioListener(rCamera.GetMatrix()); SViewParams currentParams = *(pView->GetCurrentParams()); rCamera.SetJustActivated(currentParams.justActivated); currentParams.justActivated = false; pView->SetCurrentParams(currentParams); if (m_bOverridenCameraRotation) { // When camera rotation is overridden. Vec3 pos = rCamera.GetMatrix().GetTranslation(); Matrix34 camTM(m_overridenCameraRotation); camTM.SetTranslation(pos); rCamera.SetMatrix(camTM); } else { // Normal setting of the camera if (m_fCameraNoise > 0) { Matrix33 m = Matrix33(rCamera.GetMatrix()); m.OrthonormalizeFast(); Ang3 aAng1 = Ang3::GetAnglesXYZ(m); //Ang3 aAng2 = RAD2DEG(aAng1); Matrix34 camTM = rCamera.GetMatrix(); Vec3 pos = camTM.GetTranslation(); camTM.SetIdentity(); const float fScale = 0.1f; CPNoise3* pNoise = m_pSystem->GetNoiseGen(); float fRes = pNoise->Noise1D(gEnv->pTimer->GetCurrTime() * m_fCameraNoiseFrequency); aAng1.x += fRes * m_fCameraNoise * fScale; pos.z -= fRes * m_fCameraNoise * fScale; fRes = pNoise->Noise1D(17 + gEnv->pTimer->GetCurrTime() * m_fCameraNoiseFrequency); aAng1.y -= fRes * m_fCameraNoise * fScale; //aAng1.z+=fRes*0.025f; // left / right movement should be much less visible camTM.SetRotationXYZ(aAng1); camTM.SetTranslation(pos); rCamera.SetMatrix(camTM); } } m_pSystem->SetViewCamera(rCamera); } } // Display debug info on screen if (m_nViewSystemDebug) { DebugDraw(); } // perform dynamic color grading // Beni - Commented for console demo stuff /****************************************************************************************** if (!IsPlayingCutScene() && gEnv->pAISystem) { SAIDetectionLevels detection; gEnv->pAISystem->GetDetectionLevels(nullptr, detection); float factor = detection.puppetThreat; // marcok: magic numbers taken from Maciej's tweaked values (final - initial) { float percentage = (0.0851411f - 0.0509998f)/0.0509998f * factor; float amount = 0.0f; gEnv->p3DEngine->GetPostEffectParam("ColorGrading_GrainAmount", amount); gEnv->p3DEngine->SetPostEffectParam("ColorGrading_GrainAmount_Offset", amount*percentage); } { float percentage = (0.405521f - 0.256739f)/0.256739f * factor; float amount = 0.0f; gEnv->p3DEngine->GetPostEffectParam("ColorGrading_SharpenAmount", amount); //gEnv->p3DEngine->SetPostEffectParam("ColorGrading_SharpenAmount_Offset", amount*percentage); } { float percentage = (0.14f - 0.11f)/0.11f * factor; float amount = 0.0f; gEnv->p3DEngine->GetPostEffectParam("ColorGrading_PhotoFilterColorDensity", amount); gEnv->p3DEngine->SetPostEffectParam("ColorGrading_PhotoFilterColorDensity_Offset", amount*percentage); } { float percentage = (234.984f - 244.983f)/244.983f * factor; float amount = 0.0f; gEnv->p3DEngine->GetPostEffectParam("ColorGrading_maxInput", amount); //gEnv->p3DEngine->SetPostEffectParam("ColorGrading_maxInput_Offset", amount*percentage); } { float percentage = (239.984f - 247.209f)/247.209f * factor; float amount = 0.0f; gEnv->p3DEngine->GetPostEffectParam("ColorGrading_maxOutput", amount); //gEnv->p3DEngine->SetPostEffectParam("ColorGrading_maxOutput_Offset", amount*percentage); } { Vec4 dest(0.0f/255.0f, 22.0f/255.0f, 33.0f/255.0f, 1.0f); Vec4 initial(2.0f/255.0f, 154.0f/255.0f, 226.0f/255.0f, 1.0f); Vec4 percentage = (dest - initial)/initial * factor; Vec4 amount; gEnv->p3DEngine->GetPostEffectParamVec4("clr_ColorGrading_SelectiveColor", amount); //gEnv->p3DEngine->SetPostEffectParamVec4("clr_ColorGrading_SelectiveColor_Offset", amount*percentage); } { float percentage = (-5.0083 - -1.99999)/-1.99999 * factor; float amount = 0.0f; gEnv->p3DEngine->GetPostEffectParam("ColorGrading_SelectiveColorCyans", amount); //gEnv->p3DEngine->SetPostEffectParam("ColorGrading_SelectiveColorCyans_Offset", amount*percentage); } { float percentage = (10.0166 - -5.99999)/-5.99999 * factor; float amount = 0.0f; gEnv->p3DEngine->GetPostEffectParam("ColorGrading_SelectiveColorMagentas", amount); //gEnv->p3DEngine->SetPostEffectParam("ColorGrading_SelectiveColorMagentas_Offset", amount*percentage); } { float percentage = (10.0166 - 1.99999)/1.99999 * factor; float amount = 0.0f; gEnv->p3DEngine->GetPostEffectParam("ColorGrading_SelectiveColorYellows", amount); //gEnv->p3DEngine->SetPostEffectParam("ColorGrading_SelectiveColorYellows_Offset", amount*percentage); } } ********************************************************************************************/ }