//------------------------------------------------------------------------ void SKillEffect::Activate(EntityId targetId, EntityId ownerId, EntityId weaponId, const char *effect, const char *defaultEffect) { CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(targetId); if (pActor) { //Execute particle effect and kill the actor GameWarning("Explosion effect: %s (Actor)", effect); // TODO: make work in MP... IParticleEffect *pEffect = gEnv->p3DEngine->FindParticleEffect(effect); if (pEffect) { int effectId = 0; effectId = pActor->GetEntity()->LoadParticleEmitter(-1,pEffect); AABB box; pActor->GetEntity()->GetLocalBounds(box); Matrix34 tm = IParticleEffect::ParticleLoc(box.GetCenter()); pActor->GetEntity()->SetSlotLocalTM(effectId, tm); } HitInfo info(ownerId, targetId, weaponId, 1000.0f, 0.0f, 0, 0, 0); g_pGame->GetGameRules()->ServerHit(info); } else if(!pActor && targetId) { // TODO: make work in MP... //No actor, but we have an entity IEntity* pEntity = gEnv->pEntitySystem->GetEntity(targetId); if(pEntity) { //Execute particle effect and kill the actor GameWarning("Explosion effect: %s (Entity)", defaultEffect); IParticleEffect *pEffect = gEnv->p3DEngine->FindParticleEffect(defaultEffect); if (pEffect) { int effectId = 0; effectId = pEntity->LoadParticleEmitter(-1,pEffect); AABB box; pEntity->GetLocalBounds(box); Matrix34 tm = IParticleEffect::ParticleLoc(box.GetCenter()); pEntity->SetSlotLocalTM(effectId, tm); } } } }
void CBoidFish::Physicalize( SBoidContext &bc ) { IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_entity); if (pEntity) { AABB aabb; pEntity->GetLocalBounds(aabb); bc.fBoidRadius = max( (aabb.max-aabb.min).GetLength() * bc.boidScale,0.001f ); bc.fBoidThickness = bc.fBoidRadius*0.5f; } CBoidObject::Physicalize( bc ); }
bool CVTOLVehicleManager::TestEntityInVTOL( const IEntity& entity ) const { AABB aabb; entity.GetLocalBounds(aabb); for(TVTOLList::const_iterator iter=m_vtolList.begin(), end=m_vtolList.end(); iter!=end; ++iter) { if(TestIsInVTOL(iter->second, aabb)) { return true; } } return false; }
//------------------------------------------------------------------------ const AABB & CVehiclePartEntityAttachment::GetLocalBounds() { IEntity* pEntity = GetAttachmentEntity(); if (pEntity) { pEntity->GetLocalBounds(m_bounds); } else { m_bounds.Reset(); } return m_bounds; }
void CStickyProjectile::CalculateLocationForStick( const IEntity& projectile, const Vec3& collPos, const Vec3& collNormal, QuatT& outLocation ) const { if(m_flags&eSF_OrientateToCollNormal) { const float bigz = cry_fabsf(collNormal.z)-cry_fabsf(collNormal.y); const Vec3 temp(0.f,(float)__fsel(bigz,1.f,0.f),(float)__fsel(bigz,0.f,1.f)); outLocation.q = Quat(Matrix33::CreateOrientation( temp.Cross(collNormal), -collNormal, 0)); AABB aabb; projectile.GetLocalBounds(aabb); outLocation.t = collPos + (outLocation.q.GetColumn2() * ((aabb.max.y-aabb.min.y)*0.5f)); } else { outLocation.q = projectile.GetRotation(); outLocation.t = collPos + (outLocation.q.GetColumn1() * 0.1f); } }
void CBaseGrabHandler::UpdatePosVelRot(float frameTime) { IEntity *pGrab = gEnv->pEntitySystem->GetEntity(m_grabStats.grabId); if ( !pGrab) return; IEntity *pEnt = m_pActor->GetEntity(); // NOTE Dez 14, 2006: <pvl> fade away the initial difference between // orientations of grabber and grabbed entities, so that they're // the same finally. m_grabStats.additionalRotation = Quat::CreateSlerp( m_grabStats.additionalRotation, IDENTITY, frameTime * 3.3f ); pGrab->SetRotation(pEnt->GetRotation() * m_grabStats.additionalRotation,ENTITY_XFORM_USER); AABB bbox; pGrab->GetLocalBounds(bbox); Vec3 grabCenter(pGrab->GetWorldTM() * ((bbox.max + bbox.min) * 0.5f)); Vec3 grabWPos(GetGrabWPos()); Vec3 setGrabVel(0,0,0); // TODO Dez 14, 2006: <pvl> if you finally delete this make sure that // BasicActor:DropObject() (in BasicActor.lua) doesn't support its // 'throwDelay' parameter anymore. // NOTE Dez 14, 2006: <pvl> grabCenter is where the grabbed object's // AABB's center is, grabWPos is where it should be. Use physics // to set the grabbed object's speed towards grabWPos. if (pEnt->GetPhysics() && pGrab->GetPhysics()) { pe_status_dynamics dyn; pEnt->GetPhysics()->GetStatus(&dyn); pe_action_set_velocity asv; if (setGrabVel.len2()>0.01f) asv.v = dyn.v + setGrabVel; else asv.v = dyn.v + (grabWPos - grabCenter)*m_grabStats.followSpeed; asv.w.Set(0,0,0); pGrab->GetPhysics()->Action(&asv); } }
bool CIntersectionAssistanceUnit::TestForIntersectionAtLocation(const eTestMethod testMethod, const Matrix34& wMat, EntityId testEntityId, EntityId ignoreEnt, QuatT& outAdjustedResult, const bool bCentreOnFocalEnt /* = false */, bool bRenderOnFail /* = true */, const int index /* = -1*/) { // Build an OOBB that surrounds this entity, test for intersection between that and world IEntity* pEntity = gEnv->pEntitySystem->GetEntity(testEntityId); if(pEntity) { IPhysicalEntity* pPhysical = pEntity->GetPhysics(); if(pPhysical) { OBB entOBB; AABB entAABB; pEntity->GetLocalBounds(entAABB); entOBB.SetOBBfromAABB(Quat(IDENTITY), entAABB); // Do Primitive world intersection primitives::box physBox; physBox.bOriented = 1; // LSpace physBox.center = entOBB.c; physBox.Basis = entOBB.m33; physBox.size.x = entOBB.h.x; physBox.size.y = entOBB.h.y; physBox.size.z = entOBB.h.z; // WSpace physBox.center = wMat.TransformPoint(physBox.center); physBox.Basis *= Matrix33(wMat).GetInverted(); // Optional tweak - We can get away with a little bit of scaling down (if edges are slightly embedded the physics pushes them out easily) physBox.size = physBox.size.scale(kPhysBoxScaleFactor); // adjust Vec3 vAdjustments(0.0f,0.0f,0.0f); if(bCentreOnFocalEnt && m_focalEntityId) { Vec3 vDesiredPos = CalculateTargetAdjustPoint(pEntity, wMat, physBox.center); vAdjustments = (vDesiredPos - physBox.center); physBox.center += vAdjustments; } IEntity* pIgnoreEnt = gEnv->pEntitySystem->GetEntity(ignoreEnt); IPhysicalEntity* pIgnorePhys = pIgnoreEnt ? pIgnoreEnt->GetPhysics() : NULL; // Test if(testMethod == eTM_Immediate #ifndef _RELEASE || g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled >= 1 #endif // #ifndef _RELEASE ) { geom_contact *contacts; intersection_params params; float numHits = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(primitives::box::type, &physBox, Vec3(ZERO), ent_static|ent_terrain, &contacts, 0, 3, ¶ms, 0, 0, &pIgnorePhys, pIgnorePhys ? 1 : 0); // Debug #ifndef _RELEASE if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled) { const bool bIntersect = numHits <= 0.0f ? false : true; if(bRenderOnFail || !bIntersect) { const ColorB colorPositive = ColorB(16, 96, 16); const ColorB colorNegative = ColorB(128, 0, 0); const ColorB colorSelected = ColorB(0,255,0); if(numHits > 0.0f) { gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(contacts->pt, 0.1f, colorPositive); } OBB finalOBB; finalOBB.SetOBB(Matrix33(IDENTITY), physBox.size, Vec3(0.0f,0.0f,0.0f)); Matrix34 drawMat = wMat; drawMat.AddTranslation(physBox.center - wMat.GetTranslation()); if(index != -1 && index == m_currentBestIndex) { gEnv->pRenderer->GetIRenderAuxGeom()->DrawOBB(finalOBB, drawMat, false, colorSelected, eBBD_Faceted); } else { gEnv->pRenderer->GetIRenderAuxGeom()->DrawOBB(finalOBB, drawMat, false, bIntersect ? colorNegative : colorPositive, eBBD_Faceted); } } } #endif //#ifndef RELEASE // If we performed an adjust, make sure we pass out the QuatT representing the FINAL ENTITY POSITION that passed/failed (not the phys box etc) outAdjustedResult.t = wMat.GetTranslation() + vAdjustments; outAdjustedResult.q = Quat(wMat); #ifndef _RELEASE // allow optional debug drawing of last known good positions by retaining non adjusted position if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled == 1) { outAdjustedResult.t = wMat.GetTranslation(); } #endif // #ifndef _RELEASE return (numHits > 0.0f); } else { // QUEUE primitive intersection check outAdjustedResult.t = wMat.GetTranslation() + vAdjustments; outAdjustedResult.q = Quat(wMat); CRY_ASSERT(index >= 0); m_intersectionTester.DoCheck(index,physBox,outAdjustedResult,pIgnorePhys); return false; } } } return false; }
bool CFlock::CreateEntities() { if (!m_e_flocks) return false; SEntitySpawnParams spawnParams; spawnParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Boid"); if (!spawnParams.pClass) return false; spawnParams.nFlags = ENTITY_FLAG_CLIENT_ONLY | ENTITY_FLAG_NO_SAVE | ENTITY_FLAG_NO_PROXIMITY | m_nBoidEntityFlagsAdd; spawnParams.sName = m_boidEntityName; m_modelCgf = PathUtil::ReplaceExtension(m_model,"cgf"); bool bHasCgfFile = gEnv->pCryPak->IsFileExist(m_modelCgf) && m_bc.animationMaxDistanceSq > 0; if(!bHasCgfFile) m_bc.animationMaxDistanceSq = 0; bool bAnyCreated = false; for (Boids::iterator it = m_boids.begin(); it != m_boids.end(); ++it) { CBoidObject *boid = *it;/*m_boids[i]*/; if (boid->m_dead || boid->m_dying) continue; spawnParams.vPosition = boid->m_pos; spawnParams.vScale = Vec3(boid->m_scale,boid->m_scale,boid->m_scale); spawnParams.id = 0; IEntity *pBoidEntity = gEnv->pEntitySystem->SpawnEntity( spawnParams ); if (!pBoidEntity) { //delete boid; //it = m_boids.erase(it); continue; } boid->m_noentity = false; boid->m_entity = pBoidEntity->GetId(); CBoidObjectProxyPtr pBoidObjectProxy = ComponentCreateAndRegister_DeleteWithRelease<CBoidObjectProxy>( IComponent::SComponentInitializer(pBoidEntity), true ); pBoidEntity->SetProxy(ENTITY_PROXY_BOID_OBJECT,pBoidObjectProxy); pBoidObjectProxy->SetBoid(boid); // check if character. if (IsCharacterFile(m_model)) { if(bHasCgfFile) pBoidEntity->LoadGeometry(CBoidObject::eSlot_Cgf, m_modelCgf); pBoidEntity->LoadCharacter( CBoidObject::eSlot_Chr,m_model ); boid->m_object = pBoidEntity->GetCharacter(0); if (!boid->m_object) { gEnv->pEntitySystem->RemoveEntity(boid->m_entity,true); boid->m_entity = 0; //delete boid; //it = m_boids.erase(it); continue; } } else { pBoidEntity->LoadGeometry( 0,m_model ); } bAnyCreated = true; // boid->m_object->GetModel()->AddRef(); AABB aabb; if (boid->m_object) { boid->m_object->SetFlags( CS_FLAG_DRAW_MODEL|CS_FLAG_UPDATE ); boid->PlayAnimation( m_boidDefaultAnimName,true ); aabb = boid->m_object->GetAABB(); } else { pBoidEntity->GetLocalBounds(aabb); } float fBBoxRadius = ((aabb.max-aabb.min).GetLength()/2.0f); m_bc.fBoidRadius = max( fBBoxRadius, 0.001f ); m_bc.fBoidThickness = m_bc.fBoidRadius; if (!m_bc.vEntitySlotOffset.IsZero()) { pBoidEntity->SetSlotLocalTM(0,Matrix34::CreateTranslationMat(m_bc.vEntitySlotOffset*fBBoxRadius)); } boid->Physicalize(m_bc); IEntityRenderProxy *pRenderProxy = (IEntityRenderProxy*)pBoidEntity->GetProxy(ENTITY_PROXY_RENDER); if (pRenderProxy != NULL && m_bc.fBoidRadius > 0) { float r = m_bc.fBoidRadius; AABB box; box.min = Vec3(-r,-r,-r); box.max = Vec3(r,r,r); pRenderProxy->SetLocalBounds( box,true ); } IScriptTable *pScriptTable = pBoidEntity->GetScriptTable(); if (pScriptTable) { pScriptTable->SetValue( "flock_entity",m_pEntity->GetScriptTable() ); } } m_bEntityCreated = true; return bAnyCreated; }
void CAutoAimManager::UpdateTargetInfo(SAutoaimTarget& aaTarget, float fFrameTime) { IEntity * pTargetEntity = gEnv->pEntitySystem->GetEntity(aaTarget.entityId); if(pTargetEntity) { CActorPtr pTargetActor = aaTarget.pActorWeak.lock(); if (pTargetActor) { Vec3 characterPos; Quat characterRot; //Need this because of decouple catch-up movement if (IAnimatedCharacter* pAnimatedCharacter = pTargetActor->GetAnimatedCharacter()) { const QuatT& animationLocation = pAnimatedCharacter->GetAnimLocation(); characterPos = animationLocation.t; characterRot = animationLocation.q; } else { const Matrix34& targetWorldTM = pTargetEntity->GetWorldTM(); //Fallback to entity position characterPos = targetWorldTM.GetTranslation(); characterRot = Quat(targetWorldTM); } Vec3 primaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); Vec3 secondaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); if (aaTarget.primaryBoneId >= 0) { if (pTargetActor->HasBoneID(aaTarget.primaryBoneId)) { primaryOffset = pTargetActor->GetBoneTransform(aaTarget.primaryBoneId).t; } else { GameWarning("CAutoAimManager: Character %s missing primary boneID: %s", pTargetEntity->GetName(), s_BONE_ID_NAME[aaTarget.primaryBoneId]); aaTarget.primaryBoneId = -1; } } if (aaTarget.secondaryBoneId >= 0) { if (pTargetActor->HasBoneID(aaTarget.secondaryBoneId)) { secondaryOffset = pTargetActor->GetBoneTransform(aaTarget.secondaryBoneId).t; } else { GameWarning("CAutoAimManager: Character %s missing secondary boneID: %s", pTargetEntity->GetName(), s_BONE_ID_NAME[aaTarget.secondaryBoneId]); aaTarget.secondaryBoneId = -1; } } aaTarget.primaryAimPosition = characterPos + (characterRot * primaryOffset); aaTarget.secondaryAimPosition = characterPos + (characterRot * secondaryOffset); //Update hostility (changes during gameplay) if (!gEnv->bMultiplayer) { uint8 targetFaction = (aaTarget.aiFaction != IFactionMap::InvalidFactionID) ? aaTarget.aiFaction : GetTargetFaction(*pTargetEntity); if (gEnv->pAISystem->GetFactionMap().GetReaction(GetLocalPlayerFaction(), aaTarget.aiFaction) == IFactionMap::Hostile) { aaTarget.SetFlag(eAATF_AIHostile); } else { aaTarget.RemoveFlag(eAATF_AIHostile); } aaTarget.aiFaction = targetFaction; } } else if(aaTarget.hasSkeleton) { //Not an actor but has a skeleton (and so can use bone offsets) ISkeletonPose* pSkeletonPose = pTargetEntity->GetCharacter(0)->GetISkeletonPose(); const Matrix34& characterMat = pTargetEntity->GetWorldTM(); const Vec3 characterPos = characterMat.GetTranslation(); const Quat characterRot(characterMat); Vec3 primaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); Vec3 secondaryOffset(0.0f, 0.0f, aaTarget.fallbackOffset); if (aaTarget.primaryBoneId >= 0) { primaryOffset = pSkeletonPose->GetAbsJointByID(aaTarget.primaryBoneId).t; } if (aaTarget.secondaryBoneId >= 0) { secondaryOffset = pSkeletonPose->GetAbsJointByID(aaTarget.secondaryBoneId).t; } aaTarget.primaryAimPosition = characterPos + (characterRot * primaryOffset); aaTarget.secondaryAimPosition = characterPos + (characterRot * secondaryOffset); } else { //Must be an object const Matrix34& entityWorldTM = pTargetEntity->GetWorldTM(); Vec3 primaryPosition = entityWorldTM.GetTranslation(); Vec3 secondaryPosition = entityWorldTM.TransformPoint(Vec3(0.0f, 0.0f, 0.5f)); AABB entityLocalBBox; pTargetEntity->GetLocalBounds(entityLocalBBox); if (!entityLocalBBox.IsEmpty()) { const Vec3 offset (0.0f, 0.0f, entityLocalBBox.GetRadius() * 0.2f); const Vec3 objectCenter = entityLocalBBox.GetCenter(); primaryPosition = entityWorldTM.TransformPoint((objectCenter - offset)); secondaryPosition = entityWorldTM.TransformPoint((objectCenter + offset)); } aaTarget.primaryAimPosition = primaryPosition; aaTarget.secondaryAimPosition = secondaryPosition; } //The physics drags the render proxy and entity behind it. If we auto aim at the render position, // we will handicap the console players by failing to let them aim ahead of the target. if(IPhysicalEntity * pPhysicalEntity = pTargetEntity->GetPhysics()) { pe_status_dynamics dyn; if(pPhysicalEntity->GetStatus(&dyn)) { Vec3 lookAhead = (dyn.v * fFrameTime); aaTarget.primaryAimPosition = aaTarget.primaryAimPosition + lookAhead; aaTarget.secondaryAimPosition = aaTarget.secondaryAimPosition + lookAhead; } } } }