//------------------------------------------------------------------------
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;
}
Exemple #10
0
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));
				}
		}
}
Exemple #11
0
//------------------------------------------------------------------------
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 );
	}
}
Exemple #15
0
//------------------------------------------------------------------------
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;
}
Exemple #17
0
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 );
}
Exemple #20
0
//--------------------------------------------------------------------------------------------------
// 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);
        }
      }
    }    
  }  
}
Exemple #24
0
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;
			}
		}
	}
}
Exemple #25
0
//------------------------------------------------------------------------
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(&params) || !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;
}