//------------------------------------------------------------------------
const Matrix33 &CItem::GetSlotHelperRotation(int slot, const char *helper, bool worldSpace, bool relative)
{
	// if mounted force the slot to be 1st person
	if(m_stats.mounted)
		slot=eIGS_FirstPerson;

	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;

			int16 id = pCharacter->GetISkeletonPose()->GetJointIDByName(helper);

			//	if (id > -1) rotation = Matrix33(pCharacter->GetISkeleton()->GetAbsJMatrixByID(id));
			if(id > -1)
			{
				if(relative)
					rotation = Matrix33(pCharacter->GetISkeletonPose()->GetRelJointByID(id).q);
				else
					rotation = Matrix33(pCharacter->GetISkeletonPose()->GetAbsJointByID(id).q);
			}

			if(!relative)
				rotation = Matrix33(pEntity->GetSlotLocalTM(slot, false))*rotation;
		}
	}

	if(worldSpace)
		rotation=Matrix33(pEntity->GetWorldTM())*rotation;

	return rotation;
}
void CLivingEntitySample::UpdateAnimationParams( const float frameTime )
{
	IEntity* pEntity = GetEntity();

	const int slot = 0;
	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;
	}

	const Vec2 localVelocity( m_localEntityVelocity.x, m_localEntityVelocity.y );
	const float speed = localVelocity.GetLength();
	const float angle = atan2f( -localVelocity.x, localVelocity.y );

	pSkeletonAnim->SetDesiredMotionParam( eMotionParamID_TravelSpeed, speed, frameTime );
	pSkeletonAnim->SetDesiredMotionParam( eMotionParamID_TravelAngle, angle, frameTime );
}
Exemple #3
0
//------------------------------------------------------------------------
void CItem::UpdateFPCharacter(float frameTime)
{
	if (IsClient())
	{
		ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson);

		if (pCharacter && !m_idleAnimation[eIGS_FirstPerson].empty() && pCharacter->GetISkeletonAnim()->GetNumAnimsInFIFO(0)<1)
			PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true);
	}

	// need to explicitly update characters at this point
	// cause the entity system update occered earlier, with the last position
	for (int i=0; i<eIGS_Last; i++)
	{
		if (GetEntity()->GetSlotFlags(i)&ENTITY_SLOT_RENDER)
		{
			ICharacterInstance *pCharacter = GetEntity()->GetCharacter(i);
			if (pCharacter)
			{
				Matrix34 mloc = GetEntity()->GetSlotLocalTM(i,false);
				Matrix34 m34=GetEntity()->GetWorldTM()*mloc;
				QuatT renderLocation = QuatT(m34);
				pCharacter->GetISkeletonPose()->SetForceSkeletonUpdate(8);
				pCharacter->SkeletonPreProcess(renderLocation, renderLocation, GetISystem()->GetViewCamera(),0x55 );
				pCharacter->SetPostProcessParameter(renderLocation, renderLocation, 0, 1.0f, 0x55 ); 
			}
		}
	}

	IEntityRenderProxy *pProxy=GetRenderProxy();
	if (pProxy)
		pProxy->InvalidateLocalBounds();
}
Exemple #4
0
// If there are first person hands present, then position and orient them relative to the view
void CPlayerView::HandsPostProcess(CPlayer &rPlayer,SViewParams &viewParams)
{
	//for testing sake
	float nearPlaneOverride(g_pGameCVars->cl_nearPlane);
	if (nearPlaneOverride > 0.001f)
		viewParams.nearplane = nearPlaneOverride;

	//FIXME:find a better place?
	// Convention: if Player has a renderable object in slot 2 then it's the first person hands.
	if (rPlayer.GetEntity()->GetSlotFlags(2) & ENTITY_SLOT_RENDER)
	{
		Matrix34 handsMtx(rPlayer.m_viewQuatFinal * Quat::CreateRotationZ(gf_PI));
		handsMtx.SetTranslation(viewParams.position);

		rPlayer.GetEntity()->SetSlotLocalTM(2,rPlayer.GetEntity()->GetWorldTM().GetInverted() * handsMtx);
		ICharacterInstance *pHands = rPlayer.GetEntity()->GetCharacter(2);
		if (pHands)
		{
			QuatT renderLocation = QuatT(handsMtx);
			pHands->GetISkeletonPose()->SetForceSkeletonUpdate(5);
			pHands->SkeletonPreProcess(renderLocation, renderLocation, GetISystem()->GetViewCamera(),0x55);
			pHands->SkeletonPostProcess(renderLocation, renderLocation, 0, 0.0f, 0x55);
		}
	}
}
Exemple #5
0
void CBurnEffectManager::UpdateBurnEffect(CBurnEffectManager::SBurnPoint* pBurnPoint)
{
	if (pBurnPoint->m_effect)
	{
		float effectIntensity = pBurnPoint->m_accumulation;
		SpawnParams params;
		GeomRef geomRef;

		if(pBurnPoint->m_attachedEntityId)
		{
			params.eAttachType = pBurnPoint->m_attachType;
			params.eAttachForm = pBurnPoint->m_attachForm;

			IEntity* pEntity = gEnv->pEntitySystem->GetEntity(pBurnPoint->m_attachedEntityId);
			ICharacterInstance* characterInstance = pEntity ? pEntity->GetCharacter(0) : NULL;

			if(characterInstance)
			{
				geomRef.m_pChar = characterInstance;
				geomRef.m_pPhysEnt = characterInstance->GetISkeletonPose()->GetCharacterPhysics();
			}
			else
			{
				pBurnPoint->m_accumulation = 0.f;
			}
		}

		params.fStrength = effectIntensity;
		pBurnPoint->m_effect->SetSpawnParams(params, geomRef);
	}
}
//------------------------------------------------------------------------
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;
}
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 );
}
bool CProceduralContextTurretAimPose::InitialiseCharacter( const int characterSlot )
{
	if ( m_entity == NULL )
	{
		return false;
	}

	ICharacterInstance* pCharacterInstance = m_entity->GetCharacter( characterSlot );
	if ( pCharacterInstance == NULL )
	{
		return false;
	}

	ISkeletonAnim* pSkeletonAnim = pCharacterInstance->GetISkeletonAnim();
	if ( pSkeletonAnim == NULL )
	{
		return false;
	}

	ISkeletonPose* pSkeletonPose = pCharacterInstance->GetISkeletonPose();
	if ( pSkeletonPose == NULL )
	{
		return false;
	}
	ICharacterModelSkeleton* pICharacterModelSkeleton = pCharacterInstance->GetICharacterModel()->GetICharacterModelSkeleton();

	m_pCharacterInstance = pCharacterInstance;
	m_pSkeletonAnim = pSkeletonAnim;
	m_pSkeletonPose = pSkeletonPose;
	m_pICharacterModelSkeleton = pICharacterModelSkeleton;

	return true;
}
Exemple #9
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;
}
Exemple #10
0
void CBaseGrabHandler::IgnoreCollision(EntityId eID,unsigned int flags,bool ignore)
{
	IEntity *pGrab = gEnv->pEntitySystem->GetEntity(eID);
	IPhysicalEntity *ppGrab = pGrab ? pGrab->GetPhysics() : NULL;

	if(!ppGrab) return;

	if(ignore)
	{
		// NOTE Dez 14, 2006: <pvl> this whole block just fills in
		// a request structure and passes it to physics
		IEntity *pEnt = m_pActor->GetEntity();

		pe_action_add_constraint ac;
		ac.flags = constraint_inactive|constraint_ignore_buddy;
		ac.pBuddy = pEnt->GetPhysics();
		ac.pt[0].Set(0,0,0);

		ICharacterInstance *pCharacter = pEnt->GetCharacter(0);
		IPhysicalEntity *pPhysEnt = pCharacter?pCharacter->GetISkeletonPose()->GetCharacterPhysics(-1):NULL;

		if(pPhysEnt)
		{
			pe_simulation_params sp;
			pPhysEnt->GetParams(&sp);

			if(sp.iSimClass <= 2)
				ac.pBuddy = pPhysEnt;
		}

		ppGrab->Action(&ac);
	}
	else
	{
		// NOTE Dez 14, 2006: <pvl> the same as the other branch - just
		// fill in a request and pass it to the physics engine
		pe_action_update_constraint uc;
		uc.bRemove = 1;

		ppGrab->Action(&uc);
	}

	// NOTE Dez 14, 2006: <pvl> flag manipulation is basically a legacy
	// code - probably not used anymore, scheduled for removal.
	if(flags)
	{
		pe_params_part pp;
		pp.flagsAND = pp.flagsColliderAND = ~flags;
		pp.flagsOR = pp.flagsColliderOR = flags * (ignore?0:1);

		pe_status_nparts status_nparts;

		for(pp.ipart = ppGrab->GetStatus(&status_nparts)-1; pp.ipart>=0; pp.ipart--)
			ppGrab->SetParams(&pp);
	}
}
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;
	}
}
Exemple #12
0
//------------------------------------------------------------------------
const char *CItem::GetCharacterAttachmentBone(int slot, const char *name)
{
    ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot);
    if(IAttachment * pAttachment = GetCharacterAttachment(pCharacter, name))
        {
            return pCharacter->GetISkeletonPose()->GetJointNameByID(pAttachment->GetBoneID());
        }

    return 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;
}
Exemple #14
0
//------------------------------------------------------------------------
void CItem::ForceSkinning(bool always)
{
	for (int slot=0; slot<eIGS_Last; slot++)
	{
		ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot);
		if (pCharacter)
		{
			Matrix34 m34=GetEntity()->GetSlotWorldTM(slot);
			QuatT renderLocation = QuatT(m34);

			Vec3 CharOffset = GetEntity()->GetSlotLocalTM(slot,false).GetTranslation();

			pCharacter->GetISkeletonPose()->SetForceSkeletonUpdate(7);
			pCharacter->SkeletonPreProcess(renderLocation, renderLocation, GetISystem()->GetViewCamera(),0x55 );
			pCharacter->SetPostProcessParameter(renderLocation, renderLocation, 0, 0.0f, 0x55 ); 			
			if (!always)
				pCharacter->GetISkeletonPose()->SetForceSkeletonUpdate(0);
		}
	}
}
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 #16
0
//------------------------------------------------------------------------
void CItem::SetCharacterAttachmentWorldTM(int slot, const char *name, const Matrix34 &tm)
{
    ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot);
    if(IAttachment * pAttachment = GetCharacterAttachment(pCharacter, name))
        {
            Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) *	Matrix34(pCharacter->GetISkeletonPose()->GetAbsJointByID(pAttachment->GetBoneID()) );

            Matrix34 localAttachmentMatrix = (boneWorldMatrix.GetInverted()*tm);
            pAttachment->SetAttRelativeDefault(QuatT(localAttachmentMatrix));
        }
}
Exemple #17
0
QuatT CAnimatedGrabHandler::GetGrabBoneWorldTM() const
{
	IEntity *pEnt = m_pActor->GetEntity();
	SIKLimb *pLimb = m_pActor->GetIKLimb(m_grabStats.limbId[0]);
	ICharacterInstance *pCharacter = pEnt->GetCharacter(pLimb->characterSlot);

	QuatT followBoneLocalRot = pCharacter->GetISkeletonPose()->GetAbsJointByID(m_grabStats.followBoneID);
	QuatT rootBoneWorldRot = m_pActor->GetAnimatedCharacter()->GetAnimLocation();
	QuatT followBoneWorldRot = rootBoneWorldRot * followBoneLocalRot;
	return followBoneWorldRot;
}
//------------------------------------------------------------------------
Vec3 CItem::GetSlotHelperPos(int slot, const char *helper, bool worldSpace, bool relative)
{
	Vec3 position(0,0,0);

	// if mounted force the slot to be 1st person
	if(m_stats.mounted)
		slot=eIGS_FirstPerson;

	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;
			int16 id = pCharacter->GetISkeletonPose()->GetJointIDByName(helper);

			if(id > -1)
			{
				if(relative)
					position = pCharacter->GetISkeletonPose()->GetRelJointByID(id).t;
				else
					position = pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t;
			}

			if(!relative)
				position = GetEntity()->GetSlotLocalTM(slot, false).TransformPoint(position);
		}
	}

	if(worldSpace)
		return GetEntity()->GetWorldTM().TransformPoint(position);

	return position;
}
Exemple #19
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;
}
	void CObstructionCheck::DoCheck( IActor* pOwnerActor, EntityId objectId )
	{
		//Still waiting for last one, skip new one
		if (m_queuedPrimitiveId != 0)
			return;

		IMovementController* pMovementController = pOwnerActor ? pOwnerActor->GetMovementController() : NULL;

		if (pMovementController)
		{
			SMovementState movementState;
			pMovementController->GetMovementState(movementState);

			primitives::cylinder cylPrimitive;
			cylPrimitive.axis = movementState.eyeDirection;
			cylPrimitive.center = movementState.eyePosition - Vec3(0.0f, 0.0f, 0.15f) + (movementState.eyeDirection * 0.4f);
			cylPrimitive.hh = 0.6f;
			cylPrimitive.r = 0.25f;

			IEntity* pObjectEntity = gEnv->pEntitySystem->GetEntity(objectId);
			IPhysicalEntity* pObjectPhysics = pObjectEntity ? pObjectEntity->GetPhysics() : NULL;

			const int collisionEntityTypes = ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid;

			int count = 0;
			IPhysicalEntity* skipList[3];
			if(pOwnerActor)
			{
				skipList[count++] = pOwnerActor->GetEntity()->GetPhysics();
				ICharacterInstance* pCharInstance = pOwnerActor->GetEntity()->GetCharacter(0);
				ISkeletonPose* pSkeletonPose(NULL);
				if(pCharInstance && (pSkeletonPose = pCharInstance->GetISkeletonPose()))
				{
					PREFAST_SUPPRESS_WARNING(6386); // fits in skiplist
					skipList[count++] = pSkeletonPose->GetCharacterPhysics();
				}
			}
			if(pObjectPhysics)
			{
				skipList[count++] = pObjectPhysics;
			}

			m_queuedPrimitiveId = g_pGame->GetIntersectionTester().Queue(IntersectionTestRequest::HighestPriority,
				IntersectionTestRequest(cylPrimitive.type, cylPrimitive, ZERO, collisionEntityTypes, 0, geom_colltype0|geom_colltype_player, &skipList[0], count),
				functor(*this, &PickAndThrow::CObstructionCheck::IntersectionTestComplete));
		}
	}
Exemple #21
0
//------------------------------------------------------------------------
const char *CItem::GetCharacterAttachmentBone(int slot, const char *name)
{
	ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot);
	if (!pCharacter)
		return 0;

	IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager();
	IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(name);

	if (!pAttachment)
	{
		GameWarning("Item '%s' trying to get attachment bone on '%s' which does not exist!", GetEntity()->GetName(), name);
		return 0;
	}

	return pCharacter->GetISkeletonPose()->GetJointNameByID(pAttachment->GetBoneID());
}
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;
}
//------------------------------------------------------------------------
Vec3 CVehicleViewFirstPerson::GetWorldPosGoal()
{
	Vec3 vehiclePos;

	if (m_pHelper)
	{
		vehiclePos = m_pHelper->GetVehicleSpaceTranslation();
	}
	else if(!m_sCharacterBoneName.empty())
	{
		Vec3 bonePos;
		IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_pSeat->GetPassenger());
		ICharacterInstance* pCharacter = pEntity ? pEntity->GetCharacter(0) : NULL;
		if(pCharacter)
		{
			IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton();
			uint32 id = rIDefaultSkeleton.GetJointIDByName(m_sCharacterBoneName);
			uint32 numJoints = rIDefaultSkeleton.GetJointCount();
			if(numJoints > id)
			{
				bonePos = pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t;
			}
		}
		vehiclePos = pEntity ? pEntity->GetWorldTM() * bonePos : Vec3(0,0,0);	
		return vehiclePos;
	}
	else
	{
		IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(m_passengerId);
		CRY_ASSERT(pActor);

		vehiclePos = pActor->GetLocalEyePos() + m_offset;

		IEntity* pActorEntity = pActor->GetEntity();
		
		const Matrix34& slotTM = pActorEntity->GetSlotLocalTM(0, false);
    vehiclePos = pActorEntity->GetLocalTM() * slotTM * vehiclePos;
	}

	return m_pVehicle->GetEntity()->GetWorldTM() * vehiclePos;
}
Exemple #24
0
//------------------------------------------------------------------------
void CItem::SetCharacterAttachmentWorldTM(int slot, const char *name, const Matrix34 &tm)
{
	ICharacterInstance *pCharacter = GetEntity()->GetCharacter(slot);
	if (!pCharacter)
		return;

	IAttachmentManager *pAttachmentManager = pCharacter->GetIAttachmentManager();
	IAttachment *pAttachment = pAttachmentManager->GetInterfaceByName(name);

	if (!pAttachment)
	{
		GameWarning("Item '%s' trying to set world TM on attachment '%s' which does not exist!", GetEntity()->GetName(), name);
		return;
	}

//	Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) *	pCharacter->GetISkeleton()->GetAbsJMatrixByID(pAttachment->GetBoneID());
	Matrix34 boneWorldMatrix = GetEntity()->GetSlotWorldTM(slot) *	Matrix34(pCharacter->GetISkeletonPose()->GetAbsJointByID(pAttachment->GetBoneID()) );

	Matrix34 localAttachmentMatrix = (boneWorldMatrix.GetInverted()*tm);
	pAttachment->SetAttRelativeDefault(QuatT(localAttachmentMatrix));
}
void CKVoltEffect::Enter()
{
	m_timer = m_effectTime;

	SHUDEvent eventTempAddToRadar(eHUDEvent_TemporarilyTrackEntity);
	eventTempAddToRadar.AddData(SHUDEventData((int)m_ownerActor->GetEntityId()));
	eventTempAddToRadar.AddData(SHUDEventData(m_effectTime));
	eventTempAddToRadar.AddData(true);
	eventTempAddToRadar.AddData(false);
	CHUDEventDispatcher::CallEvent(eventTempAddToRadar);
	
	if(m_particleEffect)
	{
		IEntity* entity = m_ownerActor->GetEntity();

		const ParticleParams& particleParams = m_particleEffect->GetParticleParams();

		EGeomType geomType = particleParams.eAttachType;
		EGeomForm geomForm = particleParams.eAttachForm;
		SpawnParams	spawnParams( geomType,geomForm );

		m_particleEmitter = m_particleEffect->Spawn(entity->GetWorldTM());
		if(m_particleEmitter)
		{
			m_particleEmitter->AddRef();

			// Set spawn params so that the emitter spawns particles all over the character's physics mesh
			ICharacterInstance* characterInstance = entity->GetCharacter(0);
			if(characterInstance)
			{
				GeomRef geomRef;
				geomRef.m_pChar = characterInstance;
				geomRef.m_pPhysEnt = characterInstance->GetISkeletonPose()->GetCharacterPhysics();
				m_particleEmitter->SetSpawnParams(spawnParams,geomRef);
			}
		}
	}
	ResetScreenEffect();
}
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 );
}
void CProceduralWeaponAnimationContext::Update(float timePassed)
{
	ICharacterInstance* pCharacter = m_pScope->GetCharInst();
	if (m_instanceCount <= 0 || pCharacter == 0)
		return;

	m_weaponSway.Update(timePassed);
	const QuatT rightOffset = m_weaponSway.GetRightOffset();
	const QuatT leftOffset = m_weaponSway.GetLeftOffset();

	const int PWALayer = GetGameConstCVar(g_pwaLayer);
	pCharacter->GetISkeletonAnim()->PushPoseModifier(PWALayer, cryinterface_cast<IAnimationPoseModifier>(m_pPoseModifier), "ProceduralWeapon");

	m_pPoseModifier->Clear();

	const IAnimationOperatorQueue::EOp set = IAnimationOperatorQueue::eOp_OverrideRelative;
	const IAnimationOperatorQueue::EOp additive = IAnimationOperatorQueue::eOp_Additive;

	ISkeletonPose* pPose = pCharacter->GetISkeletonPose();
	Vec3 relBlendPos = Vec3(1.0f, 0.0f, 0.0f);
	m_pPoseModifier->PushPosition(m_params.m_rightBlendIkIdx, set, relBlendPos);

	Quat view = Quat::CreateRotationVDir(m_aimDirection);
	Quat invView = view.GetInverted();

	QuatT rightHand;
	rightHand.t = view * rightOffset.t;
	rightHand.q = view * (rightOffset.q * invView);
	m_pPoseModifier->PushPosition(m_params.m_weaponTargetIdx, additive, rightHand.t);
	m_pPoseModifier->PushOrientation(m_params.m_weaponTargetIdx, additive, rightHand.q);

	QuatT leftHand;
	leftHand.t = view * leftOffset.t;
	leftHand.q = view * (leftOffset.q * invView);
	m_pPoseModifier->PushPosition(m_params.m_leftHandTargetIdx, additive, leftHand.t);
	m_pPoseModifier->PushOrientation(m_params.m_leftHandTargetIdx, additive, leftHand.q);
}
Exemple #28
0
// NOTE Dez 15, 2006: <pvl> not called ATM. Should be moved to BaseGrabHandler.
Vec3 CAnimatedGrabHandler::GetGrabIKPos(IEntity *pGrab,int limbIdx)
{
	AABB bbox;
	pGrab->GetLocalBounds(bbox);

	Vec3 grabCenter((bbox.max + bbox.min) * 0.5f);

	if (m_grabStats.limbNum<2)
	{
	}
	else
	{
		IEntity *pEnt = m_pActor->GetEntity();
		SIKLimb *pLimb = m_pActor->GetIKLimb(m_grabStats.limbId[limbIdx]);
		ICharacterInstance *pCharacter = pEnt->GetCharacter(pLimb->characterSlot);

		if (pCharacter)
		{
			Vec3 posPool[2]={grabCenter,grabCenter};
			posPool[0].x = bbox.min.x;
			posPool[1].x = bbox.max.x;

			Vec3 limbPosInLocal(pGrab->GetWorldTM().GetInverted()*(pEnt->GetSlotWorldTM(pLimb->characterSlot) * pCharacter->GetISkeletonPose()->GetAbsJointByID(pLimb->rootBoneID).t ));

			float minDist(9999.9f);
			for (int i=0;i<2;++i)
			{
				//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(pGrab->GetWorldTM() * posPool[i], ColorB(0,255,0,100), pGrab->GetWorldTM() * limbPosInLocal, ColorB(0,255,0,100));
				float len2((posPool[i] - limbPosInLocal).len2());
				if (len2<minDist)
				{
					minDist = len2;
					grabCenter = posPool[i];
				}
			}
		}
	}

	return (pGrab->GetWorldTM() * grabCenter);
}
Exemple #29
0
bool CAnimatedGrabHandler::SetGrab(SmartScriptTable &rParams)
{
	// NOTE Aug 16, 2007: <pvl> if there's another grab action under way, this one fails
	// first the cheaper check (should also cover the case when output is not yet set because of longer transition time)
	if (m_grabStats.IKActive == true)
		return false;
	// then the more expensive check
	if (IAnimationGraphState* pAGState = m_pActor->GetAnimationGraphState())
	{
		const char* grabActive = pAGState->QueryOutput("GrabActive");
		if (grabActive != NULL && grabActive[0] != 0)
			return false;
	}
	if (m_grabStats.grabId > 0)
		Reset();

	m_grabStats.useIKRotation = false;
	rParams->GetValue("useIKRotation",m_grabStats.useIKRotation);

	m_grabStats.limbNum = 0;

	SmartScriptTable limbsTable;
	if (rParams->GetValue("limbs",limbsTable))
	{
		IScriptTable::Iterator iter = limbsTable->BeginIteration();
	
		while(limbsTable->MoveNext(iter))
		{
			const char *pLimb;
			iter.value.CopyTo(pLimb);

			int limbIdx = m_pActor->GetIKLimbIndex(pLimb);
			if (limbIdx > -1 && m_grabStats.limbNum<GRAB_MAXLIMBS)
				m_grabStats.limbId[m_grabStats.limbNum++] = limbIdx;
		}

		limbsTable->EndIteration(iter);
	}

	m_grabStats.usingAnimation = false;

	const char * pCarryAnimGraphInput = 0;
	if (rParams->GetValue("carryAnimGraphInput",pCarryAnimGraphInput))
	{
		const int maxNameLen = SGrabStats::s_maxAGInputNameLen;
		strncpy(m_grabStats.carryAnimGraphInput,pCarryAnimGraphInput,maxNameLen);
		m_grabStats.carryAnimGraphInput[maxNameLen-1] = 0;
	}
	
	SmartScriptTable animationTable;
	if (rParams->GetValue("animation",animationTable))
	{
		const char *pAnimGraphSignal = NULL;

		if (animationTable->GetValue("animGraphSignal",pAnimGraphSignal))
		{
			const int maxNameLen = SGrabStats::s_maxAGInputNameLen;
			strncpy(m_grabStats.grabAnimGraphSignal,pAnimGraphSignal,maxNameLen);
			m_grabStats.grabAnimGraphSignal[maxNameLen-1] = 0;
		}

		// TODO Dez 15, 2006: <pvl> if there's no graph signal, consider
		// returning false - won't work without graph signal anyway
		if (pAnimGraphSignal)
		{
			m_grabStats.usingAnimation = true;
			m_grabStats.usingAnimationForDrop = true;
			m_grabStats.usingAnimationForGrab = true;
		}

		if (animationTable->GetValue("forceThrow",m_grabStats.throwDelay))
		{
			//m_grabStats.grabDelay = 0.0f;
			m_grabStats.maxDelay = m_grabStats.throwDelay;
		}

		m_grabStats.grabbedObjOfs.zero();
		animationTable->GetValue("grabbedObjOfs",m_grabStats.grabbedObjOfs);

		m_grabStats.releaseIKTime = 0.0f;
		animationTable->GetValue("releaseIKTime",m_grabStats.releaseIKTime);
	} else {
		if (rParams->GetValue("grabAnim",animationTable))
		{
			m_grabStats.usingAnimationForGrab = true;

			m_grabStats.releaseIKTime = 0.0f;
			animationTable->GetValue("releaseIKTime",m_grabStats.releaseIKTime);

			m_grabStats.grabbedObjOfs.zero();
			animationTable->GetValue("grabbedObjOfs",m_grabStats.grabbedObjOfs);

			const char *pAnimGraphSignal = NULL;
			if (animationTable->GetValue("animGraphSignal",pAnimGraphSignal))
			{
				const int maxNameLen = SGrabStats::s_maxAGInputNameLen;
				strncpy(m_grabStats.grabAnimGraphSignal,pAnimGraphSignal,maxNameLen);
				m_grabStats.grabAnimGraphSignal[maxNameLen-1] = 0;
			}
		}
		if (rParams->GetValue("dropAnim",animationTable))
		{
			m_grabStats.usingAnimationForDrop = true;

			// NOTE Feb 10, 2007: <pvl> this is just to get around the
			// condition in CBaseGrabHandler::SetDrop().  If we don't set
			// throwDelay to something bigger than zero SetDrop() executes
			// StartDrop() immediately.
			// All of this stuff around maxDelay, throwDelay etc. should be
			// rewritten but in a way that doesn't break existing behaviour.
			m_grabStats.throwDelay = 1000.0f;

			const char *pAnimGraphSignal = NULL;
			if (animationTable->GetValue("animGraphSignal",pAnimGraphSignal))
			{
				const int maxNameLen = SGrabStats::s_maxAGInputNameLen;
				strncpy(m_grabStats.dropAnimGraphSignal,pAnimGraphSignal,SGrabStats::s_maxAGInputNameLen);
				m_grabStats.dropAnimGraphSignal[maxNameLen-1] = 0;
			}
		}
		m_grabStats.usingAnimation = m_grabStats.usingAnimationForDrop || m_grabStats.usingAnimationForGrab;
	}

	m_grabStats.followBoneID = -1;

	const char *followBone;
	if (rParams->GetValue("followBone",followBone))
	{
		ICharacterInstance *pCharacter = m_pActor->GetEntity()->GetCharacter(0);
		if (pCharacter)
			m_grabStats.followBoneID = pCharacter->GetISkeletonPose()->GetJointIDByName(followBone);
	}
	// TODO Dez 15, 2006: <pvl> consider returning false if bone ID is -1
	// at this point - it won't work anyway without bone ID
	

	//FIXME:remove this garbage when the grabbing setup is refactored too
	float savedThrowDelay(m_grabStats.throwDelay);
	if ( ! CBaseGrabHandler::SetGrab(rParams))
		return false;

	m_grabStats.additionalRotation.SetIdentity();
	m_grabStats.origRotation.SetIdentity();

	if (m_grabStats.carryAnimGraphInput[0])
	{
		m_pActor->SetAnimationInput("CarryItem",m_grabStats.carryAnimGraphInput);	
	}
	if (m_grabStats.grabAnimGraphSignal[0])
	{
		m_pActor->SetAnimationInput("Signal",m_grabStats.grabAnimGraphSignal);
	}
	if ( ! m_grabStats.usingAnimationForGrab)
	{
		StartGrab();
	}

	m_grabStats.maxDelay = m_grabStats.throwDelay = savedThrowDelay;

	return true;
}
Exemple #30
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);
						}
					}
				}
			}
		}
	}
}//-------------------------------------------------------------------------------------------------