//------------------------------------------------------------------------ void CVehiclePartAnimated::Reset() { CVehiclePartBase::Reset(); SetDrivingProxy(false); if (m_slot > -1 && m_pCharInstance) { ISkeletonAnim* pSkeletonAnim = m_pCharInstance->GetISkeletonAnim(); CRY_ASSERT(pSkeletonAnim); ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); CRY_ASSERT(pSkeletonPose); IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); pSkeletonAnim->StopAnimationsAllLayers(); pSkeletonPose->SetDefaultPose(); pSkeletonPose->SetForceSkeletonUpdate(0); for (int i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i) { pSkeletonPose->SetMaterialOnJoint(i, NULL); } } m_iRotChangedFrameId = 0; }
//------------------------------------------------------------------------ bool CVehiclePartAnimated::ChangeChildState(CVehiclePartAnimatedJoint* pPart, EVehiclePartState state, int flags) { // only handle range between intact and destroyed if (state > pPart->GetState() && (state < eVGS_Damaged1 || state >= eVGS_Destroyed)) return false; if (state < pPart->GetState() && pPart->GetState() >= eVGS_Destroyed) return false; int jointId = pPart->GetJointId(); if (pPart->GetState() == eVGS_Default) { ISkeletonPose* pSkeletonPose = m_pCharInstance ? m_pCharInstance->GetISkeletonPose() : NULL; if (IStatObj* pStatObjIntact = pSkeletonPose ? pSkeletonPose->GetStatObjOnJoint(jointId) : NULL) { IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); const char* jointName = rIDefaultSkeleton.GetJointNameByID(jointId); if (m_intactStatObjs.find(CONST_TEMP_STRING(jointName)) == m_intactStatObjs.end()) m_intactStatObjs.insert(TStringStatObjMap::value_type(jointName, pStatObjIntact)); } } if (m_jointParts.find(pPart->GetName()) == m_jointParts.end()) m_jointParts.insert(TStringVehiclePartMap::value_type(pPart->GetName(), pPart)); IStatObj* pStatObj = GetGeometryForState(pPart, state); if (pStatObj) SetCGASlot(jointId, pStatObj, (flags & eVPSF_Physicalize) != 0); return true; }
void CLivingEntitySample::ResetCharacterModel() { IEntity* pEntity = GetEntity(); const int slot = 0; const char* modelFilename = DEFAULT_MODEL_NAME; pEntity->LoadCharacter( slot, modelFilename ); ICharacterInstance* pCharacterInstance = pEntity->GetCharacter( slot ); if ( pCharacterInstance == NULL ) { return; } ISkeletonAnim* pSkeletonAnim = pCharacterInstance->GetISkeletonAnim(); if ( pSkeletonAnim == NULL ) { return; } ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose(); if ( pSkeletonPose == NULL ) { return; } pSkeletonPose->SetFootAnchoring( 1 ); pSkeletonAnim->SetAnimationDrivenMotion( 1 ); // We will want to set motion parameters directly ourselves for this sample: pSkeletonAnim->SetCharEditMode( 1 ); }
//------------------------------------------------------------------------ IStatObj* CVehiclePartAnimated::GetDestroyedGeometry(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) _snprintf(buffer, sizeof(buffer), "%s%s", pJointName, pSuffix); else _snprintf(buffer, sizeof(buffer), "%s_debris_%d", pJointName, index); buffer[sizeof(buffer)-1] = '\0'; int16 jointIdForDestroyed = rICharacterModelSkeletonDestroyed.GetJointIDByName(buffer); if (jointIdForDestroyed > -1) { return pSkeletonDestroyed->GetStatObjOnJoint(jointIdForDestroyed); } } return NULL; }
//------------------------------------------------------------------------ int CCannonBall::GetRopeBoneId(const EventPhysCollision& collision, IEntity& target, IPhysicalEntity* pRopePhysicalEntity) const { int boneId = -1; ICharacterInstance* pCharacterInstance = target.GetCharacter(0); if (!pCharacterInstance) return boneId; ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose(); if (!pSkeletonPose) return boneId; int auxPhys = 0; while (IPhysicalEntity* pPhysicalEntity = pSkeletonPose->GetCharacterPhysics(auxPhys)) { if (pRopePhysicalEntity == pPhysicalEntity) { boneId = pSkeletonPose->GetAuxPhysicsBoneId(auxPhys, collision.partid[1]); break; } ++auxPhys; } return boneId; }
bool CTransformationPinning::Execute(const SAnimationPoseModifierParams& params) { if (m_factor == 0.0f) return false; CRY_ASSERT(m_source && (m_jointID > 0.0f)); if (!m_jointsInitialised) { Init(params); } ISkeletonPose* pSkeletonPose = params.pCharacterInstance->GetISkeletonPose(); int sourceJoints = m_source->GetJointCount(); CRY_ASSERT(sourceJoints == pSkeletonPose->GetJointCount()); for (int i=0; i<sourceJoints; i++) { const QuatT &sourceJoint = m_source->GetAbsJointByID(i); const QuatT &relSourceJoint = m_source->GetRelJointByID(i); CRY_ASSERT(params.pPoseData->GetJointAbsolute(i).IsValid()); CRY_ASSERT(sourceJoint.IsValid()); switch (m_jointTypes[i]) { case TransformationPinJoint::Copy: if (m_factor < 1.0f) { QuatT diff = params.pPoseData->GetJointAbsolute(i).GetInverted() * sourceJoint; params.pPoseData->SetJointAbsolute(i, params.pPoseData->GetJointAbsolute(i) * diff.GetScaled(m_factor)); diff = params.pPoseData->GetJointRelative(i).GetInverted() * relSourceJoint; params.pPoseData->SetJointRelative(i, params.pPoseData->GetJointRelative(i) * diff.GetScaled(m_factor)); } else { params.pPoseData->SetJointAbsolute(i, sourceJoint); params.pPoseData->SetJointRelative(i, relSourceJoint); } break; case TransformationPinJoint::Feather: { int16 parent = m_source->GetParentIDByID(i); QuatT invParent = params.pPoseData->GetJointAbsolute(parent).GetInverted(); params.pPoseData->SetJointRelative(i, invParent * params.pPoseData->GetJointAbsolute(i)); QuatT thisJnt = params.pPoseData->GetJointAbsolute(parent) * params.pPoseData->GetJointRelative(i); CRY_ASSERT(params.pPoseData->GetJointRelative(i).IsValid()); CRY_ASSERT(thisJnt.IsValid()); } break; case TransformationPinJoint::Inherit: break; } } 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; }
//------------------------------------------------------------------------ IStatObj* CVehiclePartAnimated::GetGeometryForState(CVehiclePartAnimatedJoint* pPart, EVehiclePartState state) { string name; pPart->GetGeometryName(state, name); IStatObj* pStatObj = 0; if (state > eVGS_Default) { if (pPart->m_pDestroyedGeometry) { pStatObj = pPart->m_pDestroyedGeometry; } else { IDefaultSkeleton* pIDefaultSkeleton = m_pCharInstanceDestroyed ? &m_pCharInstanceDestroyed->GetIDefaultSkeleton() : 0; if (pIDefaultSkeleton) { int jointId = pIDefaultSkeleton->GetJointIDByName(name.c_str()); ISkeletonPose* pSkeletonPose = m_pCharInstanceDestroyed->GetISkeletonPose(); if (jointId != -1) pStatObj = pSkeletonPose->GetStatObjOnJoint(jointId); } } } else { TStringStatObjMap::const_iterator it = m_intactStatObjs.find(name.c_str()); if (it != m_intactStatObjs.end()) pStatObj = it->second; } return pStatObj; }
Vec3 CVehicleSeatActionOrientateBoneToView::GetCurrentLookPosition() const { ISkeletonPose* pSkeleton = GetSkeleton(); CRY_ASSERT_MESSAGE(pSkeleton, "CVehicleSeatActionOrientateBoneToView::GetCurrentLookPosition - Couldn't get ISkeletonPose from vehicle entity"); QuatT lookQuat = pSkeleton->GetAbsJointByID(m_LookBoneId); return m_pVehicle->GetEntity()->GetWorldPos() + lookQuat.t; }
void CLookAim_Helper::UpdateLook(CPlayer* pPlayer, ICharacterInstance* pCharacter, bool bEnabled, f32 FOV, const Vec3& targetGlobal,const f32 *customBlends /*= NULL*/) { if (!m_initialized) { Init(pPlayer, pCharacter); } bool useLookAtComplex; bool useLookAtSimple; if (m_canUseLookAtComplex) { // for now just use the old 'complex' look at method until we sort out how to properly blend old and new look at useLookAtComplex = true; useLookAtSimple = false; } else { useLookAtComplex = true; // for backwards compatibility reasons we still update the old look-at even when m_canUseLookAtComplex is false useLookAtSimple = m_canUseLookAtSimple; } // --------------------------- // Complex (old style) Look-At // --------------------------- ISkeletonPose * pSkeletonPose = pCharacter->GetISkeletonPose(); pSkeletonPose->SetLookIK(useLookAtComplex && bEnabled, FOV, targetGlobal, customBlends); // --------------------------- // Simple Head-Only Look-At // --------------------------- if (m_canUseLookAtSimple) { float frameTime = gEnv->pTimer->GetFrameTime(); // Fade In/Out the Weight m_lookAtWeight = bEnabled ? CLAMP(m_lookAtWeight + (frameTime * m_lookAtFadeInSpeed), 0.0f, 1.0f) : CLAMP(m_lookAtWeight - (frameTime * m_lookAtFadeOutSpeed), 0.0f, 1.0f); // Blend To The Target if (targetGlobal.IsValid()) { m_lookAtTargetGlobal = targetGlobal; } SmoothCD(m_lookAtInterpolatedTargetGlobal, m_lookAtTargetRate, frameTime, m_lookAtTargetGlobal, m_lookAtTargetSmoothTime); // Push the LookAtSimple PoseModifier if (useLookAtSimple && (m_lookAtWeight > 0.0f)) { m_lookAtSimple->SetTargetGlobal(m_lookAtInterpolatedTargetGlobal); m_lookAtSimple->SetWeight(m_lookAtWeight); pCharacter->GetISkeletonAnim()->PushLayer(cryinterface_cast<IAnimationPoseModifier>(m_lookAtSimple)); } } }
//------------------------------------------------------------------------ const Matrix33 &CItem::GetSlotHelperRotation(int slot, const char *helper, bool worldSpace, bool relative) { static Matrix33 rotation; rotation.SetIdentity(); IEntity* pEntity = GetEntity(); if(!pEntity) return rotation; SEntitySlotInfo info; if (pEntity->GetSlotInfo(slot, info)) { if (info.pStatObj) { IStatObj *pStatObj = info.pStatObj; rotation = Matrix33(pStatObj->GetHelperTM(helper)); rotation.OrthonormalizeFast(); rotation = Matrix33(GetEntity()->GetSlotLocalTM(slot, false))*rotation; } else if (info.pCharacter) { ICharacterInstance *pCharacter = info.pCharacter; if(!pCharacter) return rotation; IAttachment* pAttachment = pCharacter->GetIAttachmentManager()->GetInterfaceByName(helper); if(pAttachment) { rotation = Matrix33(worldSpace ? pAttachment->GetAttWorldAbsolute().q : pAttachment->GetAttModelRelative().q); return rotation; } else { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose(); int16 id = pICharacterModelSkeleton->GetJointIDByName(helper); if (id > -1) { rotation = relative ? Matrix33(pSkeletonPose->GetRelJointByID(id).q) : Matrix33(pSkeletonPose->GetAbsJointByID(id).q); } } if (!relative) { rotation = Matrix33(pEntity->GetSlotLocalTM(slot, false)) * rotation; } } } if (worldSpace) { rotation = Matrix33(pEntity->GetWorldTM()) * rotation; } return rotation; }
void CFlowConvoyNode::DiscoverConvoyCoaches(IEntity *pEntity) { m_coaches.resize(0); while (pEntity) { SConvoyCoach tc; ICharacterInstance *pCharacterInstance = pEntity->GetCharacter(0); ISkeletonPose *pSkeletonPose = pCharacterInstance ? pCharacterInstance->GetISkeletonPose() : NULL; ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacterInstance ? pCharacterInstance->GetICharacterModel()->GetICharacterModelSkeleton() : NULL; IPhysicalEntity* pPhysics = pEntity->GetPhysics(); if(!pPhysics) { // don't need physics here, but need it later, so don't use entity if it's not physicalized GameWarning("Convoy entity [%s] is not physicalized", pEntity->GetName()); break; } AABB bbox; pEntity->GetLocalBounds(bbox); //tc.m_coachOffset = (bbox.max.y - bbox.min.y) * .5f; tc.m_coachOffset = 10.0f; tc.m_frontWheelBase = pICharacterModelSkeleton ? pICharacterModelSkeleton->GetJointIDByName("wheel_base1") : -1; tc.m_backWheelBase = pICharacterModelSkeleton ? pICharacterModelSkeleton->GetJointIDByName("wheel_base2") : -1; if (tc.m_frontWheelBase >=0 && tc.m_backWheelBase >= 0) { QuatT qt1 = pSkeletonPose->GetRelJointByID(tc.m_frontWheelBase); QuatT qt2 = pSkeletonPose->GetRelJointByID(tc.m_backWheelBase); tc.m_wheelDistance = qt1.t.GetDistance(qt2.t) * .5f; } else { // Fallback for entities that don't have wheel_base joints if ( m_bXAxisFwd ) tc.m_wheelDistance = (bbox.max.x - bbox.min.x) * .5f; else tc.m_wheelDistance = (bbox.max.y - bbox.min.y) * .5f; } tc.m_pEntity = pEntity; // pEntity->SetConvoyEntity(); //for (int i = 0; i < pEntity->GetChildCount(); i++) // pEntity->GetChild(i)->SetConvoyEntity(); //tc.m_pEntitySoundsProxy = (IEntitySoundProxy*) tc.m_pEntity->CreateProxy(ENTITY_PROXY_SOUND); //assert(tc.m_pEntitySoundsProxy); m_coaches.push_back(tc); IEntityLink *pEntityLink = pEntity->GetEntityLinks(); pEntity = pEntityLink ? gEnv->pEntitySystem->GetEntity(pEntityLink->entityId) : NULL; } }
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 CProceduralContextAim::InitialisePoseBlenderAim() { CRY_ASSERT( m_entity ); const int slot = 0; ICharacterInstance* pCharacterInstance = m_entity->GetCharacter( slot ); if ( pCharacterInstance == NULL ) { return; } ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose(); if ( pSkeletonPose == NULL ) { return; } m_pPoseBlenderAim = pSkeletonPose->GetIPoseBlenderAim(); if ( m_pPoseBlenderAim ) { m_defaultPolarCoordinatesSmoothTimeSeconds = 0.1f; float polarCoordinatesMaxYawDegreesPerSecond = 360.f; float polarCoordinatesMaxPitchDegreesPerSecond = 360.f; float fadeInSeconds = 0.25f; float fadeOutSeconds = 0.25f; float fadeOutMinDistance = 0.f; IScriptTable* pScriptTable = m_entity->GetScriptTable(); if ( pScriptTable ) { SmartScriptTable pProceduralContextAimTable; pScriptTable->GetValue( "ProceduralContextAim", pProceduralContextAimTable ); if ( pProceduralContextAimTable ) { pProceduralContextAimTable->GetValue( "polarCoordinatesSmoothTimeSeconds", m_defaultPolarCoordinatesSmoothTimeSeconds ); pProceduralContextAimTable->GetValue( "polarCoordinatesMaxYawDegreesPerSecond", polarCoordinatesMaxYawDegreesPerSecond ); pProceduralContextAimTable->GetValue( "polarCoordinatesMaxPitchDegreesPerSecond", polarCoordinatesMaxPitchDegreesPerSecond ); pProceduralContextAimTable->GetValue( "fadeInSeconds", fadeInSeconds ); pProceduralContextAimTable->GetValue( "fadeOutSeconds", fadeOutSeconds ); pProceduralContextAimTable->GetValue( "fadeOutMinDistance", fadeOutMinDistance ); } } m_defaultPolarCoordinatesMaxSmoothRateRadiansPerSecond = Vec2( DEG2RAD( polarCoordinatesMaxYawDegreesPerSecond ), DEG2RAD( polarCoordinatesMaxPitchDegreesPerSecond ) ); m_pPoseBlenderAim->SetPolarCoordinatesSmoothTimeSeconds( m_defaultPolarCoordinatesSmoothTimeSeconds ); m_pPoseBlenderAim->SetPolarCoordinatesMaxRadiansPerSecond( m_defaultPolarCoordinatesMaxSmoothRateRadiansPerSecond ); m_pPoseBlenderAim->SetFadeInSpeed( fadeInSeconds ); m_pPoseBlenderAim->SetFadeOutSpeed( fadeOutSeconds ); m_pPoseBlenderAim->SetFadeOutMinDistance( fadeOutMinDistance ); m_pPoseBlenderAim->SetState( false ); } }
//------------------------------------------------------------------------ Vec3 CItem::GetSlotHelperPos(int slot, const char *helper, bool worldSpace, bool relative) const { Vec3 position(0,0,0); SEntitySlotInfo info; if (GetEntity()->GetSlotInfo(slot, info)) { if (info.pStatObj) { IStatObj *pStatsObj = info.pStatObj; position = pStatsObj->GetHelperPos(helper); position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } else if (info.pCharacter) { ICharacterInstance *pCharacter = info.pCharacter; IAttachment* pAttachment = pCharacter->GetIAttachmentManager()->GetInterfaceByName(helper); if (pAttachment) { position = worldSpace ? pAttachment->GetAttWorldAbsolute().t : pAttachment->GetAttModelRelative().t; return position; } else { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose(); int16 id = pICharacterModelSkeleton->GetJointIDByName(helper); if (id > -1) { position = relative ? pSkeletonPose->GetRelJointByID(id).t : pSkeletonPose->GetAbsJointByID(id).t; } } if (!relative) { position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position); } } } if (worldSpace) { position = GetWorldTM().TransformPoint(position); } return position; }
bool CVehiclePartSuspensionPart::ChangeState(EVehiclePartState state, int flags) { if (!inherited::ChangeState(state, flags)) return false; // Remove the statobj from the cga joint (again) if (m_animatedRoot && m_jointId>=0) { ICharacterInstance* pCharInstance = m_animatedRoot->GetEntity()->GetCharacter(m_animatedRoot->GetSlot()); if (pCharInstance) { ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose(); pSkeletonPose->SetStatObjOnJoint(m_jointId, NULL); } } return true; }
QuatT CScriptbind_Entity::GetJointRelative(IEntity *pEntity, mono::string jointName, int characterSlot) { if(ICharacterInstance *pCharacter = pEntity->GetCharacter(characterSlot)) { const IDefaultSkeleton *pDefaultSkeleton = &pCharacter->GetIDefaultSkeleton(); ISkeletonPose *pSkeletonPose = pCharacter->GetISkeletonPose(); if (pSkeletonPose != nullptr) { int16 id = pDefaultSkeleton->GetJointIDByName(ToCryString(jointName)); if (id > -1) return pSkeletonPose->GetRelJointByID(id); } } return QuatT(); }
void EntityEffects::SpawnParticleWithEntity( const IEntity* pTargetEntity, const int targetSlot, IParticleEffect* pParticleEffect, const char* helperName, const EntityEffects::SEffectSpawnParams& spawnParams ) { SEffectSpawnParams newSpawnParams = spawnParams; if (pTargetEntity) { SEntitySlotInfo slotInfo; if (pTargetEntity->GetSlotInfo(targetSlot, slotInfo)) { if (slotInfo.pStatObj) { //Get helper position from static object const Vec3 localHelperPosition = slotInfo.pStatObj->GetHelperPos(helperName); newSpawnParams.position = pTargetEntity->GetSlotWorldTM(targetSlot).TransformPoint(localHelperPosition); } else if (slotInfo.pCharacter) { //Get helper position from character IAttachmentManager *pAttachmentManager = slotInfo.pCharacter->GetIAttachmentManager(); if (IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(helperName)) { newSpawnParams.position = pAttachment->GetAttWorldAbsolute().t; } else { ICharacterModelSkeleton* pICharacterModelSkeleton = slotInfo.pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = slotInfo.pCharacter->GetISkeletonPose(); Vec3 localJointPosition = ZERO; const int16 jointId = pICharacterModelSkeleton->GetJointIDByName(helperName); if (jointId >= 0) { localJointPosition = pSkeletonPose->GetAbsJointByID(jointId).t; } newSpawnParams.position = pTargetEntity->GetSlotWorldTM(targetSlot).TransformPoint(localJointPosition); } } } } SpawnParticleFX(pParticleEffect, newSpawnParams); }
void CAnimActionAIAimPose::InitialiseAimPoseBlender() { IScope& rootScope = GetRootScope(); ICharacterInstance* pCharacterInstance = rootScope.GetCharInst(); CRY_ASSERT( pCharacterInstance ); if ( ! pCharacterInstance ) { return; } ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose(); CRY_ASSERT( pSkeletonPose ); IAnimationPoseBlenderDir* pPoseBlenderAim = pSkeletonPose->GetIPoseBlenderAim(); CRY_ASSERT( pPoseBlenderAim ); if ( ! pPoseBlenderAim ) { return; } const uint32 aimPoseAnimationLayer = rootScope.GetBaseLayer(); pPoseBlenderAim->SetLayer( aimPoseAnimationLayer ); }
//-------------------------------------------------------------------------------------------------- // Name: SpawnParticlesOnSkeleton // Desc: Spawn particles on Skeleton //-------------------------------------------------------------------------------------------------- void CGameEffect::SpawnParticlesOnSkeleton(IEntity* pEntity, IParticleEmitter* pParticleEmitter, uint32 numParticles,float maxHeightScale) const { if((pEntity) && (numParticles>0) && (pParticleEmitter) && (maxHeightScale>0.0f)) { ICharacterInstance* pCharacter = pEntity->GetCharacter(0); if(pCharacter) { IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton(); ISkeletonPose* pPose = pCharacter->GetISkeletonPose(); if(pPose) { Vec3 animPos; Quat animRot; IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()); if(pActor) // First try to get animation data { QuatT animLoc = pActor->GetAnimatedCharacter()->GetAnimLocation(); animPos = animLoc.t; animRot = animLoc.q; } else // If no actor, then use entity data { animPos = pEntity->GetWorldPos(); animRot = pEntity->GetWorldRotation(); } animRot.Invert(); AABB bbox; pEntity->GetLocalBounds(bbox); float bbHeight = bbox.max.z - bbox.min.z; // Avoid division by 0 if(bbHeight == 0) { bbHeight = 0.0001f; } const uint32 numJoints = rIDefaultSkeleton.GetJointCount(); for (uint32 i = 0; i < numParticles; ++i) { int id = cry_random(0U, numJoints - 1); int parentId = rIDefaultSkeleton.GetJointParentIDByID(id); if(parentId>0) { QuatT boneQuat = pPose->GetAbsJointByID(id); QuatT parentBoneQuat= pPose->GetAbsJointByID(parentId); float lerpScale = cry_random(0.0f, 1.0f); QuatTS loc(IDENTITY); loc.t = LERP(boneQuat.t,parentBoneQuat.t,lerpScale); float heightScale = ((loc.t.z - bbox.min.z) / bbHeight); if(heightScale < maxHeightScale) { loc.t = loc.t * animRot; loc.t = loc.t + animPos; pParticleEmitter->EmitParticle(NULL, NULL, &loc); } } } } } } }//-------------------------------------------------------------------------------------------------
const Vec3& CTacticalManager::GetTacticalIconWorldPos(const EntityId tacticalEntityId, IEntity* pTacticalEntity, bool& inOutIsHeadBone) { CRY_ASSERT(tacticalEntityId != 0); CRY_ASSERT(pTacticalEntity != NULL); if (pTacticalEntity == NULL) { return m_tempVec3.Set(0.0f,0.0f,0.0f); } // Try to get pos from headbone if don't have an override pos TTacticalEntityToOverrideEntities::const_iterator iter = m_tacEntityToOverrideEntities.find(tacticalEntityId); if (iter == m_tacEntityToOverrideEntities.end()) { static IEntityClass* s_pTurretEntityClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Turret"); IEntityClass* pEntityClass = pTacticalEntity->GetClass(); if (pEntityClass != NULL && pEntityClass == s_pTurretEntityClass) { ICharacterInstance* pCharacterInstance = pTacticalEntity->GetCharacter(0); if (pCharacterInstance != NULL) { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacterInstance->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose(); CRY_ASSERT(pSkeletonPose != NULL); const int16 jointId = pICharacterModelSkeleton->GetJointIDByName("arcjoint"); if (0 <= jointId) { QuatT boneLocation = pSkeletonPose->GetAbsJointByID(jointId); m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t); return m_tempVec3; } } } CUICVars* pCVars = g_pGame->GetUI()->GetCVars(); if (pCVars->hud_InterestPointsAtActorsHeads == 1) { CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(tacticalEntityId)); // Only want units to go from headbone, since vehicles have headbone as well if(pActor) { if(pActor->HasBoneID(BONE_HEAD)) { QuatT boneLocation = pActor->GetBoneTransform(BONE_HEAD); m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t) + Vec3(0.0f, 0.0f, 0.25f); inOutIsHeadBone = true; return m_tempVec3; } else if(pActor->HasBoneID(BONE_SPINE)) { QuatT boneLocation = pActor->GetBoneTransform(BONE_SPINE); m_tempVec3 = pTacticalEntity->GetWorldTM().TransformPoint(boneLocation.t); return m_tempVec3; } } } return GetTacticalIconCenterBBoxWorldPos(pTacticalEntity); } else // Override entity exists so it determines position { IEntity* pOverrideEntity = gEnv->pEntitySystem->GetEntity(iter->second); if (pOverrideEntity) { m_tempVec3 = pOverrideEntity->GetWorldPos(); return m_tempVec3; } else { GameWarning("CTacticalManager::GetTacticalIconWorldPos: ID exists in mapping but failed to find entity, defaulting to center bounding box position"); return GetTacticalIconCenterBBoxWorldPos(pTacticalEntity); } } }
bool CStickyProjectile::StickToEntity( const SStickParams& stickParams, IEntity* pTargetEntity ) { IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity(); ICharacterInstance* pCharInstance = pTargetEntity->GetCharacter(0); if( pCharInstance) { IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()); if (!pActor || (stickParams.m_bStickToFriendlies || !pActor->IsFriendlyEntity(stickParams.m_ownerId)) && (gEnv->bMultiplayer || !pActor->IsDead())) { m_stuckJoint = GetJointIdFromPartId(*pTargetEntity, stickParams.m_targetPartId); m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; ICharacterModelSkeleton* pICharacterModelSkeleton = pCharInstance->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeleton = pCharInstance->GetISkeletonPose(); const char* boneName = pICharacterModelSkeleton->GetJointNameByID(m_stuckJoint); const QuatT jointWorld = QuatT(pTargetEntity->GetWorldTM()) * pSkeleton->GetAbsJointByID(m_stuckJoint); QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); pProjectileEntity->SetWorldTM(Matrix34(loc)); // Get the local pos and rot. loc = jointWorld.GetInverted() * loc; m_stuckPos = loc.t; m_stuckRot = loc.q; // Attach. if(AttachToCharacter( stickParams.m_pProjectile, *pTargetEntity, *pCharInstance, boneName)) { m_flags |= eSF_IsStuck; m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0; SetParentId(pTargetEntity->GetId()); m_childId = pProjectileEntity->GetId(); return true; } } } else { m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); AttachTo(stickParams.m_pProjectile, pTargetEntity); pProjectileEntity->SetWorldTM(Matrix34(loc)); // Set as Stuck. SetParentId(pTargetEntity->GetId()); m_childId = pProjectileEntity->GetId(); m_flags |= eSF_IsStuck; //Store position and rotation relative to parent entity m_stuckPos = pProjectileEntity->GetPos(); m_stuckRot = pProjectileEntity->GetRotation(); return true; } return false; }
//------------------------------------------------------------------------ void CDebugGun::Update( SEntityUpdateContext& ctx, int update) { if (!IsSelected()) return; static float drawColor[4] = {1,1,1,1}; static const int dx = 5; static const int dy = 15; static const float font = 1.2f; static const float fontLarge = 1.4f; IRenderer* pRenderer = gEnv->pRenderer; IRenderAuxGeom* pAuxGeom = pRenderer->GetIRenderAuxGeom(); pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags); pRenderer->Draw2dLabel(pRenderer->GetWidth()/5.f, pRenderer->GetHeight()-35, fontLarge, drawColor, false, "Firemode: %s (%.1f)", m_fireModes[m_fireMode].first.c_str(), m_fireModes[m_fireMode].second); ray_hit rayhit; unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; if (m_fireModes[m_fireMode].first == "pierceability") { flags = (unsigned int)m_fireModes[m_fireMode].second & rwi_pierceability_mask; } // use cam, no need for firing pos/dir CCamera& cam = GetISystem()->GetViewCamera(); if (gEnv->pPhysicalWorld->RayWorldIntersection(cam.GetPosition()+cam.GetViewdir(), cam.GetViewdir()*HIT_RANGE, ent_all, flags, &rayhit, 1)) { IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager(); IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem(); int x = (int)(pRenderer->GetWidth() *0.5f) + dx; int y = (int)(pRenderer->GetHeight()*0.5f) + dx - dy; // draw normal ColorB colNormal(200,0,0,128); Vec3 end = rayhit.pt + 0.75f*rayhit.n; pAuxGeom->DrawLine(rayhit.pt, colNormal, end, colNormal); pAuxGeom->DrawCone(end, rayhit.n, 0.1f, 0.2f, colNormal); IEntity * pEntity = (IEntity*)rayhit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY); if(pEntity) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)fontLarge, drawColor, false, pEntity->GetName()); } // material const char* matName = pMatMan->GetSurfaceType(rayhit.surface_idx)->GetName(); if (matName[0]) pRenderer->Draw2dLabel((float)x, (y+=dy), (float)font, drawColor, false, "%s (%i)", matName, rayhit.surface_idx); pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.1f m", rayhit.dist); if (pEntity) { IScriptTable* pScriptTable = pEntity->GetScriptTable(); // physics if (IPhysicalEntity* pPhysEnt = pEntity->GetPhysics()) { pe_status_dynamics status; if (pPhysEnt->GetStatus(&status)) { if (status.mass > 0.f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.1f kg", status.mass); pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "pe_type: %i", pPhysEnt->GetType()); // PartId - Part name ICharacterInstance* pCharacter = pEntity->GetCharacter(0); if (pCharacter) { CryFixedStringT<64> hit_part("unknown part"); const int FIRST_ATTACHMENT_PARTID = 1000; if (rayhit.partid >= FIRST_ATTACHMENT_PARTID) { IAttachmentManager* pAttachmentManager = pCharacter->GetIAttachmentManager(); IAttachment* pAttachment = pAttachmentManager->GetInterfaceByIndex(rayhit.partid - FIRST_ATTACHMENT_PARTID); if (pAttachment) { hit_part = pAttachment->GetName(); } } else { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeletonPose = pCharacter->GetISkeletonPose(); const char* szJointName = pICharacterModelSkeleton->GetJointNameByID(pSkeletonPose->getBonePhysParentOrSelfIndex(rayhit.partid)); if (szJointName && *szJointName) hit_part = szJointName; } pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "partId: %i (%s)", rayhit.partid, hit_part.c_str()); } if (status.submergedFraction > 0.f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.2f submerged", status.submergedFraction); if (status.v.len2() > 0.0001f) pRenderer->Draw2dLabel((float)x, (float)(y+=dy), (float)font, drawColor, false, "%.2f m/s", status.v.len()); } } // class-specific stuff if (IActor* pActor = pActorSystem->GetActor(pEntity->GetId())) { pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%8.2f health", pActor->GetHealth()); } else if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(pEntity->GetId())) { const SVehicleStatus& status = pVehicle->GetStatus(); pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%.0f%% health", 100.f*status.health); pRenderer->Draw2dLabel((float)x, y+=dy, (float)font, drawColor, false, "%i passengers", status.passengerCount); if (pVehicle->GetMovement() && pVehicle->GetMovement()->IsPowered()) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy),(float) font, drawColor, false, "Running"); } } else { if (pScriptTable) { HSCRIPTFUNCTION func = 0; if (pScriptTable->GetValue("GetHealth", func) && func) { float health = 0.f; if (Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, health)) { pRenderer->Draw2dLabel((float)x, (float)(y+=dy),(float) font, drawColor, false, "%.0f health", health); } } gEnv->pScriptSystem->ReleaseFunc(func); } } } } }
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; } } } }
//------------------------------------------------------------------------ void CVehiclePartTread::Update(const float frameTime) { FUNCTION_PROFILER( GetISystem(), PROFILE_ACTION ); if (!m_pCharInstance) return; if (m_bForceSetU) { m_bForceSetU = false; m_currentU = m_wantedU + 1.0f; UpdateU(); } ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); pSkeletonPose->SetForceSkeletonUpdate(0); if (VehicleCVars().v_staticTreadDeform == 0 && m_pVehicle->GetStatus().speed < 0.001f) { return; } if (frameTime > 0.f && (m_damageRatio >= 1.f || !m_pVehicle->GetGameObject()->IsProbablyVisible() || m_pVehicle->IsProbablyDistant())) { return; } // we need a tread update in next frame pSkeletonPose->SetForceSkeletonUpdate(1); m_pVehicle->NeedsUpdate(); // animate the UV texture according to the wheels speed if (m_uvSpeedMultiplier != 0.0f && frameTime > 0.0f) { IPhysicalEntity* pPhysics = GetEntity()->GetPhysics(); pe_status_wheel wheelStatus; wheelStatus.iWheel = m_lastWheelIndex; if (pPhysics && pPhysics->GetStatus(&wheelStatus) != 0) { m_wantedU += m_uvSpeedMultiplier * (wheelStatus.w * wheelStatus.r * frameTime); m_wantedU -= std::floor(m_wantedU); UpdateU(); } } // deform the tread to follow the wheels QuatT absRoot = pSkeletonPose->GetAbsJointByID(0); for (TWheelInfoVector::const_iterator ite=m_wheels.begin(), end=m_wheels.end(); ite != end; ++ite) { const SWheelInfo& wheelInfo = *ite; const Matrix34& slotTM = GetEntity()->GetSlotLocalTM(wheelInfo.slot, true); VALIDATE_MAT(slotTM); if (m_operatorQueue) { m_operatorQueue->PushPosition(wheelInfo.jointId, IAnimationOperatorQueue::eOp_Override, slotTM.GetTranslation()); } #if ENABLE_VEHICLE_DEBUG if (VehicleCVars().v_debugdraw == 4) { Vec3 local = GetEntity()->GetWorldTM().GetInverted() * slotTM.GetTranslation(); gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(GetEntity()->GetWorldTM() * (local+Vec3((float)sgn(local.x)*0.5f,0.f,0.f)),0.1f,ColorB(0,0,255,255)); } #endif } ISkeletonAnim* pSkeletonAnim = m_pCharInstance->GetISkeletonAnim(); pSkeletonAnim->PushPoseModifier(VEH_ANIM_POSE_MODIFIER_LAYER, m_operatorQueue, "VehiclePartAnimatedJoint"); }
//------------------------------------------------------------------------ void CReplayActor::ProcessEvent(SEntityEvent &event) { switch (event.event) { case ENTITY_EVENT_PREPHYSICSUPDATE: { const int currentFrameId = gEnv->pRenderer->GetFrameID(); if(currentFrameId==m_lastFrameUpdated) return; m_lastFrameUpdated = currentFrameId; if (m_pActionController) { float frameTime = gEnv->pTimer->GetFrameTime(); m_pActionController->Update(frameTime); } ICharacterInstance* pShadowCharacter = GetShadowCharacter(); if (pShadowCharacter) { QuatTS pose = (QuatTS)GetEntity()->GetWorldTM(); SAnimationProcessParams params; params.locationAnimation = pose; params.bOnRender = 1; params.zoomAdjustedDistanceFromCamera = (GetISystem()->GetViewCamera().GetPosition()-pose.t).GetLength(); pShadowCharacter->StartAnimationProcessing(params); //--- Ensure that we disable the automatic update if we're doing it explicitly pShadowCharacter->SetFlags( pShadowCharacter->GetFlags()&(~CS_FLAG_UPDATE) ); } ICharacterInstance *pCharacter = GetEntity()->GetCharacter(0); ISkeletonPose *pSkelPose = pCharacter ? pCharacter->GetISkeletonPose() : NULL; if(pSkelPose) { ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacter->GetICharacterModel()->GetICharacterModelSkeleton(); // GetJointIDByName() returns -1 if it fails; m_headBoneID is initialised to -2 // since -1 is failure and 0+ are valid bone indices. if (m_headBoneID == -2) { // TODO: Should move this to an initialisation function m_headBoneID = pICharacterModelSkeleton->GetJointIDByName("Bip01 Head"); m_cameraBoneID = pICharacterModelSkeleton->GetJointIDByName("Bip01 Camera"); } if (m_headBoneID > -1) { m_headPos = pSkelPose->GetAbsJointByID(m_headBoneID); } if (m_cameraBoneID > -1) { m_cameraPos = pSkelPose->GetAbsJointByID(m_cameraBoneID); } } } break; case ENTITY_EVENT_DONE: case ENTITY_EVENT_RETURNING_TO_POOL: { SAFE_RELEASE(m_pActionController); SAFE_DELETE(m_pAnimContext); m_itemList.OnActionControllerDeleted(); } break; } }
//------------------------------------------------------------------------ void CVehiclePartAnimated::SetDrivingProxy(bool bDrive) { IVehicleMovement* pMovement = m_pVehicle->GetMovement(); if (!(pMovement && pMovement->UseDrivingProxy())) return; if (0 == m_hullMatId[bDrive]) // 0 means, nothin to do return; if (!m_pCharInstance) return; ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); if (!pSkeletonPose) return; IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); IPhysicalEntity* pPhysics = m_pVehicle->GetEntity()->GetPhysics(); if (!pPhysics) return; int id = rIDefaultSkeleton.GetJointIDByName("hull_proxy"); if (id < 0) { m_hullMatId[0] = m_hullMatId[1] = 0; return; } int partid = pSkeletonPose->GetPhysIdOnJoint(id); if (partid == -1) return; pe_params_part params; params.partid = partid; params.ipart = -1; if (!pPhysics->GetParams(¶ms) || !params.nMats) return; phys_geometry* pGeom = params.pPhysGeom; if (pGeom && pGeom->surface_idx < pGeom->nMats) { ISurfaceTypeManager* pSurfaceMan = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager(); // initialize once if (m_hullMatId[0] < 0) { int idDriving = 0; int idOrig = pGeom->pMatMapping[pGeom->surface_idx]; const char* matOrig = pSurfaceMan->GetSurfaceType(idOrig)->GetName(); if (strstr(matOrig, "mat_metal")) idDriving = pSurfaceMan->GetSurfaceTypeByName("mat_metal_nofric")->GetId(); else { string mat(matOrig); mat.append("_nofric"); idDriving = pSurfaceMan->GetSurfaceTypeByName(mat.c_str(), NULL, false)->GetId(); } //if (pDebug->GetIVal()) //CryLog("%s looking up driving surface replacement for %s (id %i) -> got id %i", m_pVehicle->GetEntity()->GetName(), matOrig, idOrig, idDriving); if (idDriving > 0) { // store old and new id m_hullMatId[0] = idOrig; m_hullMatId[1] = idDriving; /*if (pDebug->GetIVal()) { const char* matDriving = pSurfaceMan->GetSurfaceType(idDriving)->GetName(); CryLog("%s storing hull matId for swapping: %i (%s) -> %i (%s)", m_pVehicle->GetEntity()->GetName(), m_hullMatId[0], matOrig, m_hullMatId[1], matDriving); }*/ } else m_hullMatId[0] = m_hullMatId[1] = 0; } // only swap if materials available if (m_hullMatId[bDrive] > 0) { #if ENABLE_VEHICLE_DEBUG if (VehicleCVars().v_debugdraw == eVDB_Parts) CryLog("%s swapping hull proxy from %i (%s) to matId %i (%s)", m_pVehicle->GetEntity()->GetName(), m_hullMatId[bDrive ^ 1], pSurfaceMan->GetSurfaceType(m_hullMatId[bDrive ^ 1])->GetName(), m_hullMatId[bDrive], pSurfaceMan->GetSurfaceType(m_hullMatId[bDrive])->GetName()); #endif for (int n = 0; n < pGeom->nMats; ++n) { pGeom->pMatMapping[n] = m_hullMatId[bDrive]; } } } }
//------------------------------------------------------------------------ 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); }
//------------------------------------------------------------------------ bool CVehiclePartAnimated::ChangeState(EVehiclePartState state, int flags) { if ((state == eVGS_Default) && m_initialiseOnChangeState) { // Initialise! // Having to do this because of the way the glass code // swaps a cstatobj. The way the vehicle code stores its // statobj in m_intactStatObjs is going to need reviewing if (m_pCharInstance) { ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); ISkeletonPose* pSkeletonPoseDestroyed = m_pCharInstanceDestroyed ? m_pCharInstanceDestroyed->GetISkeletonPose() : NULL; IDefaultSkeleton* pICharacterModelSkeletonDestroyed = m_pCharInstanceDestroyed ? &m_pCharInstanceDestroyed->GetIDefaultSkeleton() : NULL; if (pSkeletonPose) { const bool bDestroyedSkelExists = pSkeletonPoseDestroyed && pICharacterModelSkeletonDestroyed; for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); i++) { if (IStatObj* pStatObjIntact = pSkeletonPose->GetStatObjOnJoint(i)) { const char* jointName = rIDefaultSkeleton.GetJointNameByID(i); if (m_intactStatObjs.find(CONST_TEMP_STRING(jointName)) == m_intactStatObjs.end()) { m_intactStatObjs.insert(TStringStatObjMap::value_type(jointName, pStatObjIntact)); } // tell the streaming engine to stream destroyed version together with non destroyed if (bDestroyedSkelExists && i < pICharacterModelSkeletonDestroyed->GetJointCount()) { if (IStatObj* pStatObjIntactDestroyed = pSkeletonPoseDestroyed->GetStatObjOnJoint(i)) { pStatObjIntact->SetStreamingDependencyFilePath(pStatObjIntactDestroyed->GetFilePath()); } } } } } } m_initialiseOnChangeState = false; } bool change = CVehiclePartBase::ChangeState(state, flags); if (state == eVGS_Default && !change) { // need to restore state if one of the children is in higher state EVehiclePartState maxState = GetMaxState(); if (maxState > m_state) change = true; } if (!change) { return false; } if (state == eVGS_Destroyed) { if (m_ignoreDestroyedState) return false; if (m_pCharInstance && m_pCharInstanceDestroyed) { ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose(); IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); if (pSkeletonPose) { IMaterial* pDestroyedMaterial = m_pVehicle->GetDestroyedMaterial(); for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); i++) { if (IStatObj* pStatObjIntact = pSkeletonPose->GetStatObjOnJoint(i)) { const char* jointName = rIDefaultSkeleton.GetJointNameByID(i); IStatObj* pStatObj = GetDestroyedGeometry(jointName); // sets new StatObj to joint, if null, removes it. // object whose name includes "proxy" are not removed. if (pStatObj || !strstr(jointName, "proxy")) { SetCGASlot(i, pStatObj); if (pStatObj && !pDestroyedMaterial) { if (IMaterial* pMaterial = pStatObj->GetMaterial()) SetMaterial(pMaterial); } #if ENABLE_VEHICLE_DEBUG if (IsDebugParts()) { CryLog("swapping StatObj on joint %u (%s) -> %s", i, jointName, pStatObj ? pStatObj->GetGeoName() : "<NULL>"); } #endif } } } FlagSkeleton(pSkeletonPose, rIDefaultSkeleton); for (TStringVehiclePartMap::iterator ite = m_jointParts.begin(); ite != m_jointParts.end(); ++ite) { IVehiclePart* pPart = ite->second; pPart->ChangeState(state, flags | eVPSF_Physicalize); } CryCharAnimationParams animParams; animParams.m_nFlags |= CA_LOOP_ANIMATION; // pSkeleton->SetRedirectToLayer0(1); // pSkeleton->StartAnimation("Default",0, 0,0, animParams); // [MR: commented out on Ivos request] if (pDestroyedMaterial) { SetMaterial(pDestroyedMaterial); } } } } else if (state == eVGS_Default) { if (m_pCharInstance && m_pCharInstanceDestroyed) { // reset material (in case we replaced it with the destroyed material) IMaterial* pMaterial = m_pVehicle->GetPaintMaterial(); if (!pMaterial) { // no paint, so revert to the material already set on the character pMaterial = m_pCharInstance->GetIMaterial(); } if (pMaterial) { SetMaterial(pMaterial); } IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton(); { for (TStringStatObjMap::iterator ite = m_intactStatObjs.begin(); ite != m_intactStatObjs.end(); ++ite) { const string &jointName = ite->first; IStatObj* pStatObj = ite->second; int16 jointId = rIDefaultSkeleton.GetJointIDByName(jointName.c_str()); if (jointId > -1) { // if compound StatObj (from deformation), use first SubObj for restoring if (pStatObj != NULL) { if (!pStatObj->GetRenderMesh() && pStatObj->GetSubObjectCount() > 0) { pStatObj = pStatObj->GetSubObject(0)->pStatObj; } SetCGASlot(jointId, pStatObj); #if ENABLE_VEHICLE_DEBUG if (IsDebugParts()) CryLog("restoring StatObj on joint %i (%s) -> %s", jointId, jointName.c_str(), pStatObj ? pStatObj->GetGeoName() : "<NULL>"); #endif } TStringVehiclePartMap::iterator it = m_jointParts.find(jointName); if (it != m_jointParts.end()) { it->second->ChangeState(state, flags & ~eVPSF_Physicalize | eVPSF_Force); } } } flags |= eVPSF_Physicalize; } } } m_state = state; // physicalize after all parts have been restored if (flags & eVPSF_Physicalize && GetEntity()->GetPhysics()) { Physicalize(); for (TStringVehiclePartMap::iterator it = m_jointParts.begin(); it != m_jointParts.end(); ++it) { it->second->Physicalize(); } } return true; }
bool CVehiclePartSuspensionPart::Init(IVehicle *pVehicle, const CVehicleParams &table, IVehiclePart *pParent, CVehicle::SPartInitInfo &initInfo, int partType) { if (!inherited::Init(pVehicle, table, pParent, initInfo, partType)) return false; m_animatedRoot = CAST_VEHICLEOBJECT(CVehiclePartAnimated, GetParent(true)); m_jointId = -1; m_ikFlags = 0; if (m_animatedRoot) { if(CVehicleParams subPartTable = table.findChild("SubPart")) { // We need to remove this part from the animated root, otherwise we have two parts // NB: for now we are not doing anything with the physics - infact its preferable // if we dont have physics on suspension arms! const char* geoName = subPartTable.getAttr("geometryname"); ICharacterInstance* pCharInstance = m_animatedRoot->GetEntity()->GetCharacter(m_animatedRoot->GetSlot()); if (pCharInstance) { IDefaultSkeleton& rIDefaultSkeleton = pCharInstance->GetIDefaultSkeleton(); ISkeletonPose* pSkeletonPose = pCharInstance->GetISkeletonPose(); m_jointId = rIDefaultSkeleton.GetJointIDByName(geoName); pSkeletonPose->SetStatObjOnJoint(m_jointId, NULL); } } } else { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CVehiclePartSuspensionPart: needs to have an AnimatedPart as a parent!"); return false; } CVehicleParams ikTable = table.findChild("IK"); if (!ikTable) return false; const char* targetPartName = ikTable.getAttr("target"); m_targetPart = static_cast<CVehiclePartBase*>(pVehicle->GetPart(targetPartName)); if (m_targetPart==NULL) { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CVehiclePartSuspensionPart: couldn't find target part: '%s'", targetPartName); return false; } // Set up the target m_targetOffset.zero(); const char* targetHelper = ikTable.getAttr("targetHelper"); if (targetHelper && targetHelper[0]) { if (IVehicleHelper* pHelper = m_pVehicle->GetHelper(targetHelper)) { // NB: this is in vehicle space, and needs translating in PostInit() m_targetOffset = pHelper->GetLocalTM().GetTranslation(); m_ikFlags |= k_flagTargetHelper; } } Vec3 offset(0); ikTable.getAttr("offset", offset); m_targetOffset += offset; m_mode = k_modeStretch; const char* mode = ikTable.getAttr("mode"); if (strcmp(mode,"rotate")==0) m_mode = k_modeRotate; if (strcmp(mode,"stretch")==0) m_mode = k_modeStretch; if (strcmp(mode,"snap")==0) m_mode = k_modeSnapToEF; bool bIgnoreTargetRotation=0; ikTable.getAttr("ignoreTargetRotation", bIgnoreTargetRotation); if (bIgnoreTargetRotation) m_ikFlags |= k_flagIgnoreTargetRotation; return true; }