void CVehicleSeatActionRotateTurret::MaintainPartRotationWorldSpace(EVehicleTurretRotationType eType) { CVehiclePartBase* pPart = m_rotations[eType].m_pPart; IVehiclePart* pParent = pPart->GetParent(); IActor* pActor = m_pSeat->GetPassengerActor(); bool remote = m_pSeat->GetCurrentTransition() == IVehicleSeat::eVT_RemoteUsage; bool worldSpace = m_rotations[eType].m_worldSpace && VehicleCVars().v_independentMountedGuns != 0; if (worldSpace && pParent && pActor && pActor->IsClient() && !remote) { // we want to keep the old worldspace rotation // therefore we're updating the local transform from it // NB: there is no need to clamp here, its done later Matrix34 localTM = pParent->GetWorldTM().GetInverted() * Matrix34(m_rotations[eType].m_prevWorldQuat); localTM.OrthonormalizeFast(); // precision issue const Matrix34 &baseTM = pPart->GetLocalBaseTM(); if (!Matrix34::IsEquivalent(baseTM,localTM)) { Ang3 anglesCurr(baseTM); Ang3 angles(localTM); if (eType == eVTRT_Pitch) { angles.y = anglesCurr.y; angles.z = anglesCurr.z; } else if (eType == eVTRT_Yaw) { angles.x = anglesCurr.x; angles.y = anglesCurr.y; } localTM.SetRotationXYZ(angles); localTM.SetTranslation(baseTM.GetTranslation()); pPart->SetLocalBaseTM(localTM); m_pSeat->ChangedNetworkState(CVehicle::ASPECT_PART_MATRIX); } #if ENABLE_VEHICLE_DEBUG if (VehicleCVars().v_debugdraw == eVDB_Parts) { float color[] = {1,1,1,1}; Ang3 a(localTM), aBase(baseTM); gEnv->pRenderer->Draw2dLabel(200,200,1.4f,color,false,"localAng: %.1f (real: %.1f)", RAD2DEG(a.z), RAD2DEG(aBase.z)); } #endif } }
bool CIntersectionAssistanceUnit::TestForIntersection(const eTestMethod testMethod, const QuatT& qWOrient, const Quat& qRotOffset, const bool bCentreOnFocalEnt, int index ) { QuatT temp = qWOrient; temp.q *= qRotOffset; Matrix34 finalMatrix = Matrix34(temp); QuatT outAdjustedResult; if(!TestForIntersectionAtLocation(testMethod, finalMatrix, m_subjectEntityId, m_focalEntityId, outAdjustedResult,bCentreOnFocalEnt, false, index)) { if(testMethod == eTM_Immediate) { m_lastKnownGoodPositions[index] = outAdjustedResult; } return false; } #ifndef _RELEASE else if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled == 1) { const QuatT& qLastKnownGood =m_lastKnownGoodPositions[index]; if(IsPositionWithinAcceptedLimits(qLastKnownGood.t, finalMatrix.GetTranslation(), 1.5f)) { QuatT dummyTest; TestForIntersectionAtLocation(eTM_Immediate, Matrix34(qLastKnownGood), m_subjectEntityId, m_focalEntityId, dummyTest, bCentreOnFocalEnt, true, index); } } #endif // #ifndef _RELEASE return true; }
//------------------------------------------------------------------------ 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 SAmmoParams::LoadGeometry(const XmlNodeRef& ammoParamsNode) { CGameXmlParamReader reader(ammoParamsNode); XmlNodeRef geometryNode = reader.FindFilteredChild("geometry"); if (!geometryNode) return; CGameXmlParamReader geometryReader(geometryNode); XmlNodeRef firstpersonNode = geometryReader.FindFilteredChild("firstperson"); if (firstpersonNode) { const char *modelName = firstpersonNode->getAttr("name"); if (modelName && modelName[0]) { Ang3 angles(0,0,0); Vec3 position(0,0,0); float scale=1.0f; firstpersonNode->getAttr("position", position); firstpersonNode->getAttr("angles", angles); firstpersonNode->getAttr("scale", scale); fpLocalTM = Matrix34(Matrix33::CreateRotationXYZ(DEG2RAD(angles))); fpLocalTM.ScaleColumn(Vec3(scale, scale, scale)); fpLocalTM.SetTranslation(position); fpGeometryName = modelName; } } }
void SAmmoParams::LoadGeometry() { const IItemParamsNode *geometry = pItemParams->GetChild("geometry"); if (!geometry) { return; } const IItemParamsNode *firstperson = geometry->GetChild("firstperson"); if (firstperson) { const char *modelName = firstperson->GetAttribute("name"); if (modelName && modelName[0]) { Ang3 angles(0, 0, 0); Vec3 position(0, 0, 0); float scale = 1.0f; firstperson->GetAttribute("position", position); firstperson->GetAttribute("angles", angles); firstperson->GetAttribute("scale", scale); fpLocalTM = Matrix34(Matrix33::CreateRotationXYZ(DEG2RAD(angles))); fpLocalTM.Scale(Vec3(scale, scale, scale)); fpLocalTM.SetTranslation(position); fpGeometryName = modelName; } } }
int CScriptBind_Actor::GetClosestAttachment(IFunctionHandler *pH, int characterSlot, Vec3 testPos, float maxDistance, const char* suffix) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); IEntity* pEntity = pActor->GetEntity(); ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot); if (!pChar) return pH->EndFunction(); //fallback: use nearest attachment float minDiff = maxDistance*maxDistance; IAttachment* pClosestAtt = 0; IAttachmentManager* pMan = pChar->GetIAttachmentManager(); int count = pMan->GetAttachmentCount(); for (int i=0; i<count; ++i) { IAttachment* pAtt = pMan->GetInterfaceByIndex(i); if (pAtt->IsAttachmentHidden() || !pAtt->GetIAttachmentObject()) continue; AABB bbox(AABB::CreateTransformedAABB(Matrix34(pAtt->GetAttWorldAbsolute()),pAtt->GetIAttachmentObject()->GetAABB())); //gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB(bbox,false,ColorB(255,0,0,100),eBBD_Faceted); //float diff = (testPos - pAtt->GetWMatrix().GetTranslation()).len2(); float diff((testPos - bbox.GetCenter()).len2()); if (diff < minDiff) { //CryLogAlways("%s distance: %.1f", pAtt->GetName(), sqrt(diff)); if (suffix[0] && !strstr(pAtt->GetName(), suffix)) continue; minDiff = diff; pClosestAtt = pAtt; } } if (!pClosestAtt) return pH->EndFunction(); //FIXME FIXME: E3 workaround char attachmentName[64]; strncpy(attachmentName,pClosestAtt->GetName(),63); attachmentName[63] = 0; char *pDotChar = strstr(attachmentName,"."); if (pDotChar) *pDotChar = 0; strlwr(attachmentName); // return pH->EndFunction(attachmentName); }
void CVehicleMovementMPVTOL::SnapToPathLoc( const SVTOLPathPosParams& data ) { QuatT transform(IDENTITY); if(m_pathing.SnapTo(data, transform)) { m_pVehicle->GetEntity()->SetWorldTM(Matrix34(transform)); } }
//------------------------------------------------------------------------ void CVehicleHelper::GetWorldTM(Matrix34& worldTM) const { FUNCTION_PROFILER( gEnv->pSystem, PROFILE_ACTION ); const Matrix34& partWorldTM = m_pParentPart->GetWorldTM(); worldTM = Matrix34(Matrix33(partWorldTM) * Matrix33(m_localTM)); worldTM.SetTranslation((partWorldTM * m_localTM).GetTranslation()); }
bool CMFXParticleEffect::AttachToCharacter( IEntity& targetEntity, const SMFXParticleEntry& particleParams, const SMFXRunTimeEffectParams& params, const Vec3& dir, float scale ) { if (params.partID >= 0) { //Assume character is loaded in first slot //We could iterate through all available slots, but first one should be good enough ICharacterInstance* pCharacterInstace = targetEntity.GetCharacter(0); ISkeletonPose* pSkeletonPose = pCharacterInstace ? pCharacterInstace->GetISkeletonPose() : NULL; if (pSkeletonPose) { IDefaultSkeleton& rIDefaultSkeleton = pCharacterInstace->GetIDefaultSkeleton(); //It hit the character, but probably in a physicalized attached part, like armor plates, etc if (params.partID >= rIDefaultSkeleton.GetJointCount()) { return false; } //It hit some valid joint, create an attachment const char* boneName = rIDefaultSkeleton.GetJointNameByID(params.partID); TAttachmentName attachmentName; GetNextCharacterAttachmentName(attachmentName); IAttachmentManager* pAttachmentManager = pCharacterInstace->GetIAttachmentManager(); CRY_ASSERT(pAttachmentManager); //Remove the attachment first (in case was created before) pAttachmentManager->RemoveAttachmentByName(attachmentName.c_str()); //Create attachment on nearest hit bone IAttachment* pAttachment = pAttachmentManager->CreateAttachment(attachmentName.c_str(), CA_BONE, boneName, false); if (pAttachment) { //Apply relative offsets const QuatT boneLocation = pSkeletonPose->GetAbsJointByID(params.partID); Matrix34 inverseJointTM = targetEntity.GetWorldTM() * Matrix34(boneLocation); inverseJointTM.Invert(); Vec3 attachmentOffsetPosition = inverseJointTM * params.pos; Quat attachmentOffsetRotation = Quat(inverseJointTM) * targetEntity.GetRotation(); CRY_ASSERT(attachmentOffsetPosition.IsValid()); //CRY_ASSERT(attachmentOffsetRotation.IsUnit()); pAttachment->SetAttRelativeDefault(QuatT(attachmentOffsetRotation, attachmentOffsetPosition)); //Finally attach the effect CEffectAttachment* pEffectAttachment = new CEffectAttachment(particleParams.name.c_str(), Vec3(0,0,0), dir, scale); pAttachment->AddBinding(pEffectAttachment); return true; } } } return false; }
//------------------------------------------------------------------------ void CItem::SetCharacterAttachmentWorldTM(int slot, const char *name, const Matrix34 &tm) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot); if(IAttachment * pAttachment = GetCharacterAttachment(pCharacter, name)) { Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) * Matrix34(pCharacter->GetISkeletonPose()->GetAbsJointByID(pAttachment->GetBoneID()) ); Matrix34 localAttachmentMatrix = (boneWorldMatrix.GetInverted()*tm); pAttachment->SetAttRelativeDefault(QuatT(localAttachmentMatrix)); } }
//------------------------------------------------------------------------ Matrix34 CItem::GetCharacterAttachmentLocalTM(int slot, const char *name) { if(IAttachment * pAttachment = GetCharacterAttachment(GetEntity()->GetCharacter(slot), name)) { return Matrix34(pAttachment->GetAttRelativeDefault()); } else { return Matrix34::CreateIdentity(); } }
//------------------------------------------------------------------------ Matrix34 CItem::GetCharacterAttachmentWorldTM(int slot, const char *name) { if(IAttachment * pAttachment = GetCharacterAttachment(GetEntity()->GetCharacter(slot), name)) { return Matrix34(pAttachment->GetAttWorldAbsolute()); } else { return Matrix34::CreateIdentity(); } }
//------------------------------------------------------------------------ void CVehicleHelper::GetReflectedWorldTM(Matrix34 &reflectedWorldTM) const { FUNCTION_PROFILER( gEnv->pSystem, PROFILE_ACTION ); Matrix34 tempMatrix = m_localTM; tempMatrix.m03 = -tempMatrix.m03; // negate x coord of translation const Matrix34& partWorldTM = m_pParentPart->GetWorldTM(); reflectedWorldTM = Matrix34(Matrix33(partWorldTM) * Matrix33(tempMatrix)); reflectedWorldTM.SetTranslation((partWorldTM * tempMatrix).GetTranslation()); }
LUALIB_FUNCTION(_G, ParticleEmitter) { auto mat = Matrix34(); mat.Set(my->ToVec3(1, Vec3(0,0,0)), my->ToQuat(2, Quat(Ang3(0,0,0))), my->ToVec3(3, Vec3(1,1,1))); auto params = ParticleParams(); auto self = gEnv->p3DEngine->GetParticleManager()->CreateEmitter(mat, params); my->Push(self); return 1; }
//------------------------------------------------------------------------ Matrix34 CItem::GetCharacterAttachmentWorldTM(int slot, const char *name) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot); if (!pCharacter) return Matrix34::CreateIdentity(); IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(name); if (!pAttachment) { GameWarning("Item '%s' trying to get local TM on attachment '%s' which does not exist!", GetEntity()->GetName(), name); return Matrix34::CreateIdentity(); } return Matrix34(pAttachment->GetAttWorldAbsolute()); }
void CVehicleWeaponPulseC::Update(SEntityUpdateContext& ctx, int update) { if(!m_vehicleId && GetEntity()->GetParent()) { m_vehicleId = GetEntity()->GetParent()->GetId(); CRY_ASSERT(gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId) && "Using VehicleWeapons on non-vehicles may lead to unexpected behavior."); } IVehicle* pVehicle = GetVehicle(); if(pVehicle) { IVehiclePart* pPart = pVehicle->GetWeaponParentPart(GetEntityId()); if(pPart) { const Matrix34& partWorldTM = pPart->GetWorldTM(); const Vec3 partDirection = partWorldTM.GetColumn1(); const Vec3 partPosition = partWorldTM.GetTranslation(); //ColorB col(255, 0, 0); //gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(partPosition, col, partPosition + 100.0f * partDirection, col, 2.0f); //ok, ok, i'll optimise this later Matrix34 mat = pVehicle->GetEntity()->GetWorldTM(); Matrix33 matO(mat); matO.Invert(); const Vec3 diff = (m_TargetPos - partPosition).GetNormalized(); m_destination.SetLerp(partDirection, diff, ctx.fFrameTime); Quat quat1; //quat1.SetRotationVDir(diff, 0.0f); quat1.SetRotationVDir(m_destination.GetNormalized(), 0.0f); Matrix33 mat2(quat1); mat2 = matO * mat2; m_destination = m_destination * 10000.0f + partPosition; m_targetPosition = m_destination; m_aimPosition = m_destination; pPart->SetLocalTM(Matrix34(mat2, pPart->GetLocalTM(true, true).GetTranslation())); } } Base::Update(ctx, update); }
bool CStickyProjectile::StickToStatic( const SStickParams& stickParams ) { m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity(); QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); pProjectileEntity->SetWorldTM(Matrix34(loc)); m_stuckPos = loc.t; m_stuckRot = loc.q; AttachTo(stickParams.m_pProjectile, NULL); m_childId = pProjectileEntity->GetId(); m_flags |= eSF_IsStuck; return true; }
//------------------------------------------------------------------------ void CItem::SetCharacterAttachmentWorldTM(int slot, const char *name, const Matrix34 &tm) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot); if (!pCharacter) return; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(name); if (!pAttachment) { GameWarning("Item '%s' trying to set world TM on attachment '%s' which does not exist!", GetEntity()->GetName(), name); return; } // Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) * pCharacter->GetISkeleton()->GetAbsJMatrixByID(pAttachment->GetBoneID()); Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) * Matrix34(pCharacter->GetISkeletonPose()->GetAbsJointByID(pAttachment->GetBoneID()) ); Matrix34 localAttachmentMatrix = (boneWorldMatrix.GetInverted()*tm); pAttachment->SetAttRelativeDefault(QuatT(localAttachmentMatrix)); }
void CDialogActorContext::UpdateAuxProxyPosition() { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity == 0) return; IEntityAudioProxy* pActorAudioProxy = m_pSession->GetEntityAudioProxy(pActorEntity); if (pActorAudioProxy == 0) return; ICharacterInstance* const pCharacter = pActorEntity->GetCharacter(0); //cache some IDs if (m_VoiceAttachmentIndex == DIALOG_VOICE_POSITION_NEEDS_UPDATE && pCharacter) { const IAttachmentManager* pAttachmentManager = pCharacter->GetIAttachmentManager(); if (pAttachmentManager) { m_VoiceAttachmentIndex = pAttachmentManager->GetIndexByName("voice"); //First prio: get the "voice" attachment position if (m_VoiceAttachmentIndex == -1) { // There's no attachment so let's try to find the head bone. IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton(); m_BoneHeadJointID = rIDefaultSkeleton.GetJointIDByName("Bip01 Head"); //Second prio: use the Bip01 head bone position if (m_BoneHeadJointID == -1) { // Has it been named differently? m_BoneHeadJointID = rIDefaultSkeleton.GetJointIDByName("def_head"); //third prio: use the Bip01 head bone position } } } } Matrix34 tmHead; //try to get a position close to the "mouth" of our actor if(m_VoiceAttachmentIndex > 0 && pCharacter) { const IAttachmentManager* pAttachmentManager = pCharacter->GetIAttachmentManager(); const IAttachment* pAttachment = pAttachmentManager->GetInterfaceByIndex(m_VoiceAttachmentIndex); if (pAttachment) { tmHead = Matrix34(pAttachment->GetAttModelRelative()); } } else if (m_BoneHeadJointID > 0 && pCharacter) { // re-query SkeletonPose to prevent crash on removed Character if (ISkeletonPose* const pSkeletonPose = pCharacter->GetISkeletonPose()) { tmHead = Matrix34(pSkeletonPose->GetAbsJointByID(m_BoneHeadJointID)); } } else { //last-resort: if we could not find a head attachment point or a head-bone: Lets just assume the head is 1.80m above the feet tmHead = Matrix34(IDENTITY, Vec3(0.0f, 1.80f, 0.0f)); } pActorAudioProxy->SetAuxAudioProxyOffset(tmHead, m_SpeechAuxProxy); }
void CIntersectionAssistanceUnit::DebugUpdate() const { if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_subjectEntityId); if(pEntity) { IPhysicalEntity *pPhysical = pEntity->GetPhysics(); if(pPhysical) { const float fFontSize = 1.2f; float drawColor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; string sMsg(string().Format(" Entity ID: [%d]", m_subjectEntityId)); sMsg += string().Format("\n Entity Name: [%s]", pEntity->GetName()); sMsg += string().Format("\n EmbedTimer: [%.3f]", m_embedTimer); sMsg += string().Format("\n EmbedState: [%s]",(m_embedState == eES_None) ? "NONE" : (m_embedState == eES_Evaluating) ? "EVALUATING" : (m_embedState == eES_ReEvaluating) ? "REEVALUATING" : (m_embedState == eES_NotEmbedded) ? "NOT EMBEDDED" : (m_embedState == eES_Embedded) ? "EMBEDDED" : "UNKNOWN"); Vec3 vCurrTrans = m_entityStartingWPos - pEntity->GetWorldPos(); sMsg += string().Format("\n Translation: < %.3f, %.3f, %.3f >", vCurrTrans.x, vCurrTrans.y, vCurrTrans.z ); sMsg += string().Format("\n Trans magnitude: < %.3f >", vCurrTrans.GetLength() ); sMsg += string().Format("\n Trans per sec: < %.3f >", vCurrTrans.GetLength() / g_pGameCVars->pl_pickAndThrow.intersectionAssistTimePeriod ); sMsg += string().Format("\n Collision count: %u", m_collisionCount ); // RENDER Vec3 vDrawPos = pEntity->GetWorldPos() + Vec3(0.0f,0.0f,0.6f); gEnv->pRenderer->DrawLabelEx(vDrawPos, fFontSize, drawColor, true, true, sMsg.c_str()); // Box pe_params_bbox bbox; if(pPhysical->GetParams(&bbox)) { ColorB colDefault = ColorB( 127,127,127 ); ColorB embedded = ColorB(255, 0, 0); ColorB notEmbedded = ColorB(0, 255, 0); gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB( AABB(bbox.BBox[0],bbox.BBox[1]), Matrix34(IDENTITY), false, (m_embedState == eES_Embedded) ? embedded : (m_embedState == eES_NotEmbedded) ? notEmbedded : colDefault, eBBD_Faceted); } } } } }
//------------------------------------------------------------------------ void CProjectile::Launch(const Vec3 &pos, const Vec3 &dir, const Vec3 &velocity, float speedScale) { Matrix34 worldTM=Matrix34(Matrix33::CreateRotationVDir(dir.GetNormalizedSafe())); worldTM.SetTranslation(pos); GetEntity()->SetWorldTM(worldTM); //Must set velocity after position, if not velocity could be reseted for PE_RIGID SetVelocity(pos, dir, velocity, speedScale); m_initial_pos = pos; m_initial_dir = dir; m_initial_vel = velocity; m_last = pos; // Attach effect when fired (not first update) if (m_trailEffectId<0) TrailEffect(true); IAIObject* pAI = 0; if ((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE) { IEntity *pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId); if (pOwnerEntity && pOwnerEntity->GetAI()) { pe_status_dynamics dyn; pe_status_dynamics dynProj; if (pOwnerEntity->GetAI()->GetProxy() && pOwnerEntity->GetPhysics() && pOwnerEntity->GetPhysics()->GetStatus(&dyn) && GetEntity()->GetPhysics()->GetStatus(&dynProj)) { Vec3 ownerVel( dyn.v); Vec3 grenadeDir(dynProj.v.GetNormalizedSafe()); // Trigger the signal at the predicted landing position. Vec3 predictedPos = pos; float dummySpeed; if (GetWeapon()) GetWeapon()->PredictProjectileHit(pOwnerEntity->GetPhysics(), pos, dir, velocity, speedScale * m_pAmmoParams->speed, predictedPos, dummySpeed); /* bool res = pOwnerEntity->GetAI()->GetProxy()->GetSecWeapon()->PredictProjectileHit( pOwnerEntity->GetPhysics(), GetEntity()->GetPos(), grenadeDir, ownerVel, 1, predictedPos, speed);*/ gEnv->pAISystem->GrenadeEvent(predictedPos, 0.0f, AIGE_GRENADE_THROWN, GetEntity(), pOwnerEntity); // Inform the AI that sees the throw /* IAIObject* pOwnerAI = pOwnerEntity->GetAI(); AutoAIObjectIter it(gEnv->pAISystem->GetFirstAIObjectInRange(IAISystem::OBJFILTER_TYPE, AIOBJECT_PUPPET, predictedPos, 20.0f, false)); for(; it->GetObject(); it->Next()) { IAIObject* pAI = it->GetObject(); if (!pAI->IsEnabled()) continue; if (pOwnerAI && !pOwnerAI->IsHostile(pAI,false)) continue; // Only sense grenades that are on front of the AI and visible when thrown. // Another signal is sent when the grenade hits the ground. Vec3 delta = GetEntity()->GetPos() - pAI->GetPos(); // grenade to AI float dist = delta.NormalizeSafe(); const float thr = cosf(DEG2RAD(160.0f)); if (delta.Dot(pAI->GetViewDir()) > thr) { ray_hit hit; static const int objTypes = ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid; static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; int res = gEnv->pPhysicalWorld->RayWorldIntersection(pAI->GetPos(), delta*dist, objTypes, flags, &hit, 1); if (!res || hit.dist > dist*0.9f) { IAISignalExtraData* pEData = gEnv->pAISystem->CreateSignalExtraData(); // no leak - this will be deleted inside SendAnonymousSignal pEData->point = predictedPos; pEData->nID = pOwnerEntity->GetId(); pEData->iValue = 1; gEnv->pAISystem->SendSignal(SIGNALFILTER_SENDER, 1, "OnGrenadeDanger", pAI, pEData); } } } */ } } } }
//------------------------------------------------------------------------ void CProjectile::Launch(const Vec3 &pos, const Vec3 &dir, const Vec3 &velocity, float speedScale) { m_destroying = false; GetGameObject()->EnablePhysicsEvent(true, eEPE_OnCollisionLogged); // Only for bullets m_hitPoints = m_pAmmoParams->hitPoints; m_hitListener = false; if(m_hitPoints>0) { //Only projectiles with hit points are hit listeners g_pGame->GetGameRules()->AddHitListener(this); m_hitListener = true; m_noBulletHits = m_pAmmoParams->noBulletHits; } Matrix34 worldTM=Matrix34(Matrix33::CreateRotationVDir(dir.GetNormalizedSafe())); worldTM.SetTranslation(pos); GetEntity()->SetWorldTM(worldTM); //Must set velocity after position, if not velocity could be reseted for PE_RIGID SetVelocity(pos, dir, velocity, speedScale); m_initial_pos = pos; m_initial_dir = dir; m_initial_vel = velocity; m_last = pos; // Attach effect when fired (not first update) if(m_trailEffectId<0) TrailEffect(true); IAIObject *pAI = 0; if((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE) { IEntity *pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId); pe_status_dynamics dyn; pe_status_dynamics dynProj; if(pOwnerEntity->GetPhysics() && pOwnerEntity->GetPhysics()->GetStatus(&dyn) && GetEntity()->GetPhysics()->GetStatus(&dynProj)) { // Vec3 ownerVel(dyn.v); Vec3 grenadeDir(dynProj.v.GetNormalizedSafe()); // Trigger the signal at the predicted landing position. Vec3 predictedPos = pos; float dummySpeed; if(GetWeapon()) GetWeapon()->PredictProjectileHit(pOwnerEntity->GetPhysics(), pos, dir, velocity, speedScale * m_pAmmoParams->speed, predictedPos, dummySpeed); // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = pOwnerEntity->GetId(); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if(pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_THROWN, ownerId, GetEntityId(), predictedPos, ZERO, 20.0f); gEnv->pAISystem->RegisterStimulus(stim); } } }
//------------------------------------------------------------------------ void CItem::SpawnEffect(int slot, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale) { if (m_stats.mounted) slot=eIGS_FirstPerson; Vec3 position(0,0,0); Vec3 finalOffset = offset; SEntitySlotInfo slotInfo; if (GetEntity()->GetSlotInfo(slot, slotInfo)) { if (slotInfo.pStatObj) // entity slot { // get helper position IStatObj *pStatsObj = slotInfo.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotWorldTM(slot).TransformPoint(position); } else if (slotInfo.pCharacter) // bone attachment { ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if (pAttachment) { const Matrix34 m = Matrix34(pAttachment->GetAttWorldAbsolute()); position = m.GetTranslation(); } else { int16 id = pCharacter->GetISkeletonPose()->GetJointIDByName(helper); if (id>=0) position = pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t; position = GetEntity()->GetSlotWorldTM(slot).TransformPoint(position); } } } else if(m_stats.mounted && !m_stats.fp) { if(GetIWeapon()) { // if no helper specified, try getting pos from firing locator IWeaponFiringLocator *pLocator = GetIWeapon()->GetFiringLocator(); if (pLocator) { if(!pLocator->GetFiringPos(GetEntityId(), NULL, position)) position.Set(0.0f,0.0f,0.0f); else finalOffset = GetEntity()->GetWorldTM().TransformVector(finalOffset); } } } position += finalOffset; IParticleEffect *pParticleEffect = gEnv->pParticleManager->FindEffect(effectName); if (pParticleEffect) pParticleEffect->Spawn(true, IParticleEffect::ParticleLoc(position, dir, scale)); }
//------------------------------------------------------------------------ //Above function is almost the same, just some special stuff for flashlight //------------------------------------------------------------------------ uint32 CItem::AttachLightEx(int slot, uint32 id, bool attach, bool fakeLight /*= false */, bool castShadows /*= false*/, IRenderNode* pCasterException, float radius, const Vec3 &color, const float fSpecularMult, const char *projectTexture, float projectFov, const char *helper, const Vec3 &offset, const Vec3 &dir, const char* material, float fHDRDynamic) { if (m_stats.mounted) slot=eIGS_FirstPerson; if (radius<0.1f) return 0; if (attach) { CDLight light; light.SetLightColor(ColorF(color.x, color.y, color.z, 1.0f)); light.SetSpecularMult( fSpecularMult ); light.m_nLightStyle = 0; light.m_fLightFrustumAngle = 45.0f; light.m_fRadius = radius; light.m_fLightFrustumAngle = projectFov*0.5f; light.m_fHDRDynamic = fHDRDynamic; if(fakeLight) light.m_Flags |= DLF_FAKE; //Only on hight/very hight spec if(castShadows && (g_pGameCVars->i_lighteffects!=0)) light.m_Flags |= DLF_CASTSHADOW_MAPS; if (projectTexture && projectTexture[0]) { int flags = 0; light.m_pLightImage = gEnv->pRenderer->EF_LoadTexture(projectTexture, flags); if (!light.m_pLightImage || !light.m_pLightImage->IsTextureLoaded()) { GameWarning("Item '%s' failed to load projecting light texture '%s'!", GetEntity()->GetName(), projectTexture); return 0; } } if (light.m_fLightFrustumAngle && (light.m_pLightImage != NULL) && light.m_pLightImage->IsTextureLoaded()) light.m_Flags |= DLF_PROJECT; else { if (light.m_pLightImage) light.m_pLightImage->Release(); light.m_pLightImage = 0; light.m_Flags |= DLF_POINT; } IMaterial* pMaterial = 0; if (material && material[0]) pMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(material); // generate id ++m_effectGenId; while (!m_effectGenId || (m_effects.find(m_effectGenId) != m_effects.end())) ++m_effectGenId; SEntitySlotInfo slotInfo; SEffectInfo effectInfo; effectInfo.slot = -1; bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj); if (!validSlot || slotInfo.pStatObj) { // get helper position Vec3 position(0,0,0); if (validSlot) { IStatObj *pStatsObj = slotInfo.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } position+=offset; // find a free slot SEntitySlotInfo dummy; int i=0; while (GetEntity()->GetSlotInfo(eIGS_Last+i, dummy)) i++; // move light slot to the helper position+offset effectInfo.helper = helper; effectInfo.slot = GetEntity()->LoadLight(eIGS_Last+i, &light); if (effectInfo.slot != -1 && pMaterial) GetEntity()->SetSlotMaterial(effectInfo.slot, pMaterial); Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(position); GetEntity()->SetSlotLocalTM(effectInfo.slot, tm); } else if (slotInfo.pCharacter) // bone attachment { effectInfo.helper = helper; effectInfo.characterSlot = slot; ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if (!pAttachment) { GameWarning("Item '%s' trying to attach light to attachment '%s' which does not exist!", GetEntity()->GetName(), helper); return 0; } CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); if (pMaterial) { if (ILightSource* pLightSource = pLightAttachment->GetLightSource()) pLightSource->SetMaterial(pMaterial); } if(light.m_Flags&DLF_CASTSHADOW_MAPS) { if (ILightSource* pLightSource = pLightAttachment->GetLightSource()) pLightSource->SetCastingException(pCasterException); } Matrix34 tm =Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(offset); pAttachment->AddBinding(pLightAttachment); pAttachment->SetAttRelativeDefault(QuatT(tm)); } m_effects.insert(TEffectInfoMap::value_type(m_effectGenId, effectInfo)); return m_effectGenId; } else if (id) { TEffectInfoMap::iterator it = m_effects.find(id); if (it == m_effects.end()) return 0; SEffectInfo &info = it->second; if (info.slot>-1) { GetEntity()->FreeSlot(info.slot); } else { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(info.characterSlot); if (pCharacter) { IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(info.helper.c_str()); pAttachment->ClearBinding(); } } m_effects.erase(it); } return 0; }
//------------------------------------------------------------------------ uint32 CItem::AttachEffect(int slot, uint32 id, bool attach, const char *effectName, const char *helper, const Vec3 &offset, const Vec3 &dir, float scale, bool prime) { if (m_stats.mounted) slot=eIGS_FirstPerson; if (attach) { if (!g_pGameCVars->i_particleeffects) return 0; IParticleEffect *pParticleEffect = gEnv->pParticleManager->FindEffect(effectName); if (!pParticleEffect) return 0; // generate id ++m_effectGenId; while (!m_effectGenId || (m_effects.find(m_effectGenId) != m_effects.end())) ++m_effectGenId; SEntitySlotInfo slotInfo; SEffectInfo effectInfo; bool validSlot = GetEntity()->GetSlotInfo(slot, slotInfo) && (slotInfo.pCharacter || slotInfo.pStatObj); if (!validSlot || slotInfo.pStatObj || (!helper || !helper[0])) { // get helper position Vec3 position(0,0,0); if (validSlot && helper && helper[0]) { IStatObj *pStatsObj = slotInfo.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } position+=offset; // find a free slot SEntitySlotInfo dummy; int i=0; while (GetEntity()->GetSlotInfo(eIGS_Last+i, dummy)) i++; // move particle slot to the helper position+offset effectInfo.helper = helper; effectInfo.slot = GetEntity()->LoadParticleEmitter(eIGS_Last+i, pParticleEffect, 0, prime, true); Matrix34 tm = IParticleEffect::ParticleLoc(position, dir, scale); GetEntity()->SetSlotLocalTM(effectInfo.slot, tm); } else if (slotInfo.pCharacter) // bone attachment { effectInfo.helper = helper; effectInfo.characterSlot = slot; ICharacterInstance *pCharacter = slotInfo.pCharacter; IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helper); if (!pAttachment) { GameWarning("Item '%s' trying to attach effect '%s' to attachment '%s' which does not exist!", GetEntity()->GetName(), effectName, helper); return 0; } CEffectAttachment *pEffectAttachment = new CEffectAttachment(effectName, Vec3(0,0,0), Vec3(0,1,0), scale); Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(dir)); tm.SetTranslation(offset); pAttachment->AddBinding(pEffectAttachment); pAttachment->SetAttRelativeDefault(QuatT(tm)); pEffectAttachment->UpdateAttachment(pAttachment); if (pEffectAttachment->GetEmitter()) { if (prime) pEffectAttachment->GetEmitter()->Prime(); } } m_effects.insert(TEffectInfoMap::value_type(m_effectGenId, effectInfo)); return m_effectGenId; } else if (id) { TEffectInfoMap::iterator it = m_effects.find(id); if (it == m_effects.end()) return 0; SEffectInfo &info = it->second; if (info.slot>-1) { GetEntity()->FreeSlot(info.slot); } else { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(info.characterSlot); if (pCharacter) { IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(info.helper.c_str()); if(pAttachment) pAttachment->ClearBinding(); } } m_effects.erase(it); } return 0; }
void CPersistantDebug::Update( float frameTime ) { if (m_objects.empty()) return; IRenderAuxGeom * pAux = gEnv->pRenderer->GetIRenderAuxGeom(); static const int flags3D = e_Mode3D | e_AlphaBlended | e_DrawInFrontOff | e_FillModeSolid | e_CullModeBack | e_DepthWriteOn | e_DepthTestOn; static const int flags2D = e_Mode2D | e_AlphaBlended; std::vector<ListObj::iterator> toClear; std::vector<MapListObj::iterator> toClearMap; for (MapListObj::iterator iterMap = m_objects.begin(); iterMap != m_objects.end(); ++iterMap) { toClear.resize(0); for (ListObj::iterator iterList = iterMap->second.begin(); iterList != iterMap->second.end(); ++iterList) { iterList->timeRemaining -= frameTime; if (iterList->timeRemaining <= 0.0f && !(iterList->obj == eOT_EntityTag && iterList->columns.size() > 1)) toClear.push_back(iterList); else { ColorF clr = iterList->clr; clr.a *= iterList->timeRemaining / iterList->totalTime; switch (iterList->obj) { case eOT_Sphere: pAux->SetRenderFlags( flags3D ); pAux->DrawSphere( iterList->pos, iterList->radius, clr ); break; case eOT_Quat: pAux->SetRenderFlags( flags3D ); { float r = iterList->radius; Vec3 x = r * iterList->q.GetColumn0(); Vec3 y = r * iterList->q.GetColumn1(); Vec3 z = r * iterList->q.GetColumn2(); Vec3 p = iterList->pos; OBB obb = OBB::CreateOBB( Matrix33::CreateIdentity(), Vec3(0.05f,0.05f,0.05f), ZERO ); pAux->DrawOBB( obb, p, false, clr, eBBD_Extremes_Color_Encoded ); pAux->DrawLine( p, ColorF(1,0,0,clr.a), p+x, ColorF(1,0,0,clr.a) ); pAux->DrawLine( p, ColorF(0,1,0,clr.a), p+y, ColorF(0,1,0,clr.a) ); pAux->DrawLine( p, ColorF(0,0,1,clr.a), p+z, ColorF(0,0,1,clr.a) ); } break; case eOT_Arrow: pAux->SetRenderFlags( flags3D ); pAux->DrawLine( iterList->pos - iterList->dir * iterList->radius, clr, iterList->pos + iterList->dir * iterList->radius, clr ); pAux->DrawCone( iterList->pos + iterList->dir * iterList->radius, iterList->dir, 0.1f * iterList->radius, 0.3f * iterList->radius, clr ); break; case eOT_Line: pAux->SetRenderFlags( flags3D ); pAux->DrawLine( iterList->pos, clr, iterList->pos + iterList->dir, clr ); break; case eOT_Cone: pAux->SetRenderFlags( flags3D ); pAux->DrawCone( iterList->pos, iterList->dir, iterList->radius, iterList->radius2, clr ); break; case eOT_Cylinder: pAux->SetRenderFlags( flags3D ); pAux->DrawCylinder( iterList->pos, iterList->dir, iterList->radius, iterList->radius2, clr ); break; case eOT_AABB: pAux->SetRenderFlags( flags3D ); pAux->DrawAABB( AABB(iterList->pos,iterList->dir), Matrix34(IDENTITY), false, clr, eBBD_Faceted ); break; case eOT_Line2D: pAux->SetRenderFlags( flags2D ); pAux->DrawLine( iterList->pos, clr, iterList->dir, clr ); break; case eOT_Text: { float clrAry[4] = {clr.r, clr.g, clr.b, clr.a}; gEnv->pRenderer->Draw2dLabel( iterList->pos.x, iterList->pos.y, iterList->radius, clrAry, false, "%s", iterList->text.c_str() ); } break; case eOT_Disc: { pAux->SetRenderFlags( flags3D ); vtx_idx indTriQuad[ 6 ] = { 0, 2, 1, 0, 3, 2 }; vtx_idx indTriTri[ 3 ] = { 0, 1, 2 }; int steps = (int)(10 * iterList->radius2); steps = std::max(steps, 10); float angStep = gf_PI2 / steps; for (int i=0; i<steps; i++) { float a0 = angStep*i; float a1 = angStep*(i+1); float c0 = cosf( a0 ); float c1 = cosf( a1 ); float s0 = sinf( a0 ); float s1 = sinf( a1 ); Vec3 pts[4]; int n, n2; vtx_idx * indTri; if (iterList->radius) { n = 4; n2 = 6; pts[0] = iterList->pos + iterList->radius * Vec3( c0, s0, 0 ); pts[1] = iterList->pos + iterList->radius * Vec3( c1, s1, 0 ); pts[2] = iterList->pos + iterList->radius2 * Vec3( c1, s1, 0 ); pts[3] = iterList->pos + iterList->radius2 * Vec3( c0, s0, 0 ); indTri = indTriQuad; } else { n = 3; n2 = 3; pts[0] = iterList->pos; pts[1] = pts[0] + iterList->radius2 * Vec3( c0, s0, 0 ); pts[2] = pts[0] + iterList->radius2 * Vec3( c1, s1, 0 ); indTri = indTriTri; } pAux->DrawTriangles( pts, n, indTri, n2, clr ); } } break; case eOT_EntityTag: { UpdateTags(frameTime, *iterList); } break; } } } while (!toClear.empty()) { iterMap->second.erase(toClear.back()); toClear.pop_back(); } if (iterMap->second.empty()) toClearMap.push_back(iterMap); } while (!toClearMap.empty()) { m_objects.erase(toClearMap.back()); toClearMap.pop_back(); } }
ICVar* CVar::pHitCharacters = NULL; ICVar* CVar::pHitDeadBodies = NULL; ICVar* CVar::pCharZOffsetSpeed = NULL; ICVar* CVar::pEnableFullScriptSave = NULL; ICVar* CVar::pLogCollisions = NULL; ICVar* CVar::pNotSeenTimeout = NULL; ICVar* CVar::pDebugNotSeenTimeout = NULL; ICVar* CVar::pDrawAreas = NULL; ICVar* CVar::pDrawAreaGrid = NULL; ICVar* CVar::pDrawAreaDebug = NULL; ICVar* CVar::pDrawAudioProxyZRay = NULL; ICVar* CVar::pMotionBlur = NULL; ICVar* CVar::pSysSpecLight = NULL; Matrix34 CVar::audioListenerOffset = Matrix34(ZERO); int CVar::es_DebugTimers = 0; int CVar::es_DebugFindEntity = 0; int CVar::es_UsePhysVisibilityChecks = 1; float CVar::es_MaxPhysDist; float CVar::es_MaxPhysDistInvisible; float CVar::es_MaxPhysDistCloth; float CVar::es_FarPhysTimeout; int CVar::es_DebugEvents = 0; int CVar::es_SortUpdatesByClass = 0; int CVar::es_debugEntityLifetime = 0; int CVar::es_DisableTriggers = 0; int CVar::es_DrawProximityTriggers = 0; int CVar::es_DebugEntityUsage = 0; const char* CVar::es_DebugEntityUsageFilter = "";
//------------------------------------------------------------------------ void CVehiclePartAnimated::InitGeometry() { if (!m_pSharedParameters->m_filename.empty()) { m_slot = GetEntity()->LoadCharacter(m_slot, m_pSharedParameters->m_filename.c_str()); m_pCharInstance = GetEntity()->GetCharacter(m_slot); if (m_pCharInstance) { if (m_pCharInstance->GetIMaterial() && !GetEntity()->GetMaterial()) { SetMaterial(m_pCharInstance->GetIMaterial()); } ISkeletonAnim* pSkeletonAnim = m_pCharInstance->GetISkeletonAnim(); ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); if (pSkeletonAnim) pSkeletonAnim->StopAnimationsAllLayers(); if (m_hideCount == 0) GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) | ENTITY_SLOT_RENDER); else GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) & ~(ENTITY_SLOT_RENDER | ENTITY_SLOT_RENDER_NEAREST)); #if ENABLE_VEHICLE_DEBUG if (IsDebugParts()) { CryLog("joint transformations for %s", m_pCharInstance->GetFilePath()); for (int i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i) { VehicleUtils::LogMatrix(rIDefaultSkeleton.GetJointNameByID(i), Matrix34(pSkeletonPose->GetRelJointByID(i))); } } #endif } if (!m_pCharInstanceDestroyed && !m_pSharedParameters->m_filenameDestroyed.empty()) m_pCharInstanceDestroyed = gEnv->pCharacterManager->CreateInstance(m_pSharedParameters->m_filenameDestroyed.c_str()); if (m_pCharInstanceDestroyed) { m_pCharInstanceDestroyed->AddRef(); #if ENABLE_VEHICLE_DEBUG if (IsDebugParts()) { CryLog("joint transformations for %s", m_pCharInstanceDestroyed->GetFilePath()); ISkeletonPose* pSkeletonDestroyed = m_pCharInstanceDestroyed->GetISkeletonPose(); IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstanceDestroyed->GetIDefaultSkeleton(); for (int i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i) { VehicleUtils::LogMatrix(rIDefaultSkeleton.GetJointNameByID(i), Matrix34(pSkeletonDestroyed->GetRelJointByID(i))); } } #endif } } if (m_pSharedParameters->m_isPhysicalized && m_slot > -1) GetEntity()->UnphysicalizeSlot(m_slot); if (m_pCharInstance) { m_pCharInstance->GetISkeletonAnim()->StopAnimationsAllLayers(); if (m_hideCount == 0) GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) | ENTITY_SLOT_RENDER); else GetEntity()->SetSlotFlags(m_slot, GetEntity()->GetSlotFlags(m_slot) & ~(ENTITY_SLOT_RENDER | ENTITY_SLOT_RENDER_NEAREST)); } // Disable hand-placed (static) decals on vehicles GetEntity()->SetFlags(GetEntity()->GetFlags() | ENTITY_FLAG_NO_DECALNODE_DECALS); }
TAttachedEffectId CEffectsController::AttachLight(const int targetSlot, const char *helperName, const SLightAttachParams &attachParams) { CRY_ASSERT(m_pOwnerEntity); CDLight light; light.SetLightColor(ColorF(attachParams.color.x * attachParams.diffuseMultiplier, attachParams.color.y * attachParams.diffuseMultiplier, attachParams.color.z * attachParams.diffuseMultiplier, 1.0f)); light.SetSpecularMult( (float)__fsel( -attachParams.diffuseMultiplier, attachParams.specularMultiplier, (attachParams.specularMultiplier / (attachParams.diffuseMultiplier + FLT_EPSILON)) ) ); light.m_nLightStyle = attachParams.style; light.SetAnimSpeed(attachParams.animSpeed); light.m_fLightFrustumAngle = 45.0f; light.m_fRadius = attachParams.radius; light.m_fLightFrustumAngle = attachParams.projectFov * 0.5f; light.m_fHDRDynamic = attachParams.hdrDynamic; light.m_Flags |= attachParams.deferred ? DLF_DEFERRED_LIGHT : 0; light.m_Flags |= attachParams.castShadows ? DLF_CASTSHADOW_MAPS : 0; light.m_nEntityId = m_pOwnerEntity->GetId(); if (attachParams.projectTexture && attachParams.projectTexture[0]) { light.m_pLightImage = gEnv->pRenderer->EF_LoadTexture(attachParams.projectTexture); if (!light.m_pLightImage || !light.m_pLightImage->IsTextureLoaded()) { GameWarning("[EntityEffects] Entity '%s' failed to load projecting light texture '%s'!", m_pOwnerEntity->GetName(), attachParams.projectTexture); return 0; } } if ((light.m_pLightImage != NULL) && light.m_pLightImage->IsTextureLoaded()) { light.m_Flags |= DLF_PROJECT; } else { if (light.m_pLightImage) { light.m_pLightImage->Release(); } light.m_pLightImage = NULL; light.m_Flags |= DLF_POINT; } IMaterial* pMaterial = NULL; if (attachParams.material && attachParams.material[0]) { pMaterial = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(attachParams.material); } SEntitySlotInfo slotInfo; SEffectInfo effectInfo; const bool validSlot = m_pOwnerEntity->GetSlotInfo(targetSlot, slotInfo); if (!validSlot || slotInfo.pStatObj) { //Get helper position on static object (if any) Vec3 helperPos(ZERO); Vec3 localHelperPosition = attachParams.offset; if (validSlot) { helperPos = slotInfo.pStatObj->GetHelperPos(helperName); if (helperPos.IsZero()) { const int childCount = m_pOwnerEntity->GetChildCount(); for (int i=0;i<childCount;++i) { if (IEntity* pChild = m_pOwnerEntity->GetChild(i)) { if (IStatObj* statObj = pChild->GetStatObj(targetSlot)) { helperPos = statObj->GetHelperPos(helperName); if (!helperPos.IsZero()) { helperPos += pChild->GetPos(); break; } } } } } localHelperPosition = helperPos + attachParams.offset; localHelperPosition = m_pOwnerEntity->GetSlotLocalTM(targetSlot, false).TransformPoint(localHelperPosition); } int attachSlot = FindSafeSlot(attachParams.firstSafeSlot); ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.entityEffectSlot = m_pOwnerEntity->LoadLight(attachSlot, &light); if ((effectInfo.entityEffectSlot >= 0) && pMaterial) { m_pOwnerEntity->SetSlotMaterial(effectInfo.entityEffectSlot, pMaterial); } Matrix34 localEffectMtx = Matrix34(Matrix33::CreateRotationVDir(attachParams.direction)); localEffectMtx.SetTranslation(localHelperPosition); m_pOwnerEntity->SetSlotLocalTM(effectInfo.entityEffectSlot, localEffectMtx); m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } else if (slotInfo.pCharacter) { IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helperName); if (pAttachment) { CLightAttachment *pLightAttachment = new CLightAttachment(); pLightAttachment->LoadLight(light); ILightSource* pLightSource = pLightAttachment->GetLightSource(); if (pLightSource) { pLightSource->SetMaterial(pMaterial); pLightSource->SetCastingException(attachParams.pCasterException); } pAttachment->AddBinding(pLightAttachment); const bool customOffset = (attachParams.offset != Vec3Constants<float>::fVec3_Zero) || (attachParams.direction != Vec3Constants<float>::fVec3_OneY); if (customOffset) { pAttachment->SetAttRelativeDefault(QuatT(Quat::CreateRotationVDir(attachParams.direction), attachParams.offset)); } } else { GameWarning("[EntityEffects] Entity '%s' trying to attach light to attachment '%s' which does not exist!", m_pOwnerEntity->GetName(), helperName); return 0; } ++m_effectGeneratorId; effectInfo.id = m_effectGeneratorId; effectInfo.helperName = helperName; effectInfo.characterEffectSlot = targetSlot; m_attachedEffects.push_back(effectInfo); return m_effectGeneratorId; } return 0; }
//------------------------------------------------------------------------ IStatObj* CVehiclePartAnimated::GetSubGeometry(CVehiclePartBase* pPart, EVehiclePartState state, Matrix34 &localTM, bool removeFromParent) { ICharacterInstance* pCharInstance = 0; string jointName; pPart->GetGeometryName(state, jointName); int jointId = -1; if (state == eVGS_Destroyed) { pCharInstance = m_pCharInstanceDestroyed; if (pCharInstance) jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str()); } else { // lookup first on intact, then on destroyed model pCharInstance = m_pCharInstance; if (pCharInstance) jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str()); if (jointId == -1) { pCharInstance = m_pCharInstanceDestroyed; if (pCharInstance) jointId = pCharInstance->GetIDefaultSkeleton().GetJointIDByName(jointName.c_str()); } } if (jointId != -1) { if (ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose()) { localTM = Matrix34(pCharInstance->GetISkeletonPose()->GetAbsJointByID(jointId)); if (IStatObj* pStatObj = pSkeletonPose->GetStatObjOnJoint(jointId)) { if (removeFromParent && (pCharInstance != m_pCharInstanceDestroyed)) { if (m_intactStatObjs.find(pPart->GetName()) == m_intactStatObjs.end()) { m_intactStatObjs.insert(TStringStatObjMap::value_type(pPart->GetName(), pStatObj)); } SetCGASlot(jointId, NULL); } if (pPart) { m_jointParts.insert(TStringVehiclePartMap::value_type(pPart->GetName(), pPart)); } return pStatObj; } else if ((state == eVGS_Default) && (pPart->GetState() != eVGS_Default)) { TStringStatObjMap::const_iterator it = m_intactStatObjs.find(pPart->GetName()); if (it != m_intactStatObjs.end()) { return it->second; } } } } return NULL; }