Exemple #1
0
void CBaseGrabHandler::UpdatePosVelRot(float frameTime)
{
	IEntity *pGrab = gEnv->pEntitySystem->GetEntity(m_grabStats.grabId);
	
	if ( !pGrab) return;

	IEntity *pEnt = m_pActor->GetEntity();

	// NOTE Dez 14, 2006: <pvl> fade away the initial difference between
	// orientations of grabber and grabbed entities, so that they're
	// the same finally.
	m_grabStats.additionalRotation = Quat::CreateSlerp( m_grabStats.additionalRotation, IDENTITY, frameTime * 3.3f );
	pGrab->SetRotation(pEnt->GetRotation() * m_grabStats.additionalRotation,ENTITY_XFORM_USER);

	AABB bbox;
	pGrab->GetLocalBounds(bbox);
	Vec3 grabCenter(pGrab->GetWorldTM() * ((bbox.max + bbox.min) * 0.5f));

	Vec3 grabWPos(GetGrabWPos());
	Vec3 setGrabVel(0,0,0);

	// TODO Dez 14, 2006: <pvl> if you finally delete this make sure that
	// BasicActor:DropObject() (in BasicActor.lua) doesn't support its
	// 'throwDelay' parameter anymore.
























	// NOTE Dez 14, 2006: <pvl> grabCenter is where the grabbed object's
	// AABB's center is, grabWPos is where it should be.  Use physics
	// to set the grabbed object's speed towards grabWPos.
	if (pEnt->GetPhysics() && pGrab->GetPhysics())
	{
		pe_status_dynamics dyn;
		pEnt->GetPhysics()->GetStatus(&dyn);

		pe_action_set_velocity asv;
		if (setGrabVel.len2()>0.01f)
			asv.v = dyn.v + setGrabVel;
		else
			asv.v = dyn.v + (grabWPos - grabCenter)*m_grabStats.followSpeed;
		asv.w.Set(0,0,0);
		
		pGrab->GetPhysics()->Action(&asv);
	}

}
Exemple #2
0
void CAnimatedGrabHandler::UpdatePosVelRot(float frameTime)
{
	IEntity *pGrab = gEnv->pEntitySystem->GetEntity(m_grabStats.grabId);

	if(!pGrab) return;

	IEntity *pEnt = m_pActor->GetEntity();

	if(m_grabStats.grabDelay<0.001f)
	{
		Vec3 grabWPos(GetGrabBoneWorldTM().t);

		// NOTE Aug 3, 2007: <pvl> the second part of this test means don't enable
		// the correction if animation/ik wasn't used for grabbing in the first place
		if(m_grabStats.readIkInaccuracyCorrection && m_grabStats.grabAnimGraphSignal[0])
		{
			// NOTE Aug 2, 2007: <pvl> executed the first time this function is called
			// for a particular grabbing action
			m_grabStats.ikInaccuracyCorrection = grabWPos - (pGrab->GetWorldTM().GetTranslation() + m_grabStats.entityGrabSpot);
			m_grabStats.readIkInaccuracyCorrection = false;

			// FIXME Sep 13, 2007: <pvl> only putting it here because it's called just
			// once, at the instant when the object is grabbed - rename readIkInaccuracyCorrection
			// to make this clearer, or put this somewhere else
			DisableGrabbedAnimatedCharacter(true);
		}
		else
		{
			// NOTE Aug 2, 2007: <pvl> phase it out gradually
			m_grabStats.ikInaccuracyCorrection *= 0.9f;

			if(m_grabStats.ikInaccuracyCorrection.len2() < 0.01f)
				m_grabStats.ikInaccuracyCorrection = Vec3(0.0f, 0.0f, 0.0f);
		}

		// NOTE Sep 13, 2007: <pvl> this should prevent us from calling SetWPos()
		// later so that the IK "release" phase can take over
		m_grabStats.IKActive = false;

		Matrix34 tm(pGrab->GetWorldTM());
		tm.SetTranslation(grabWPos - (m_grabStats.ikInaccuracyCorrection + pGrab->GetRotation() * m_grabStats.entityGrabSpot));
		pGrab->SetWorldTM(tm,ENTITY_XFORM_USER);
	}

	//update IK
	for(int i=0; i<m_grabStats.limbNum; ++i)
	{
		SIKLimb *pLimb = m_pActor->GetIKLimb(m_grabStats.limbId[i]);

		// NOTE Dez 14, 2006: <pvl> this class is always supposed to have
		// m_grabStats.usingAnimation == true
		if(m_grabStats.usingAnimation && m_grabStats.releaseIKTime>0.001f && m_grabStats.IKActive)
		{
			// NOTE Dez 15, 2006: <pvl> use IK to constantly offset the
			// animation so that the difference between where the animation
			// expects the object to be and where the object really is is taken
			// into account.
			Vec3 animPos = pEnt->GetSlotWorldTM(0) * pLimb->lAnimPos;
			Vec3 assumedGrabPos = pEnt->GetSlotWorldTM(0) * m_grabStats.grabbedObjOfs;
			Vec3 actualGrabPos = pGrab->GetWorldPos() + m_grabStats.entityGrabSpot;
			Vec3 adjustment = actualGrabPos - assumedGrabPos;
			pLimb->SetWPos(pEnt,animPos + adjustment,ZERO,0.5f,2.0f,1000);
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(pGrab->GetWorldPos() + m_grabStats.entityGrabSpot, 0.5f, ColorB(0,255,0,100));
		}

		//if there are multiple limbs, only the first one sets the rotation of the object.
		if(m_grabStats.useIKRotation && i == 0 && m_grabStats.grabDelay<0.001f)
		{
			// NOTE Aug 8, 2007: <pvl> the idea here is to store current world
			// rotations of both the object being grabbed and the end bone of
			// a grabbing limb.  Then track how the end bone rotates with respect
			// to the stored original rotation and rotate the grabbed object
			// the same way.  That way, the grabbed object rotates the same as
			// the limb and appears to be "stabbed" by it.
			QuatT endBoneWorldRot = GetGrabBoneWorldTM();
			endBoneWorldRot.q.Normalize();	// may not be necessary - just to be safe

			if(! m_grabStats.origRotationsValid)
			{
				m_grabStats.origRotation = pGrab->GetRotation();
				m_grabStats.origRotation.Normalize();			// may not be necessary - just to be safe
				m_grabStats.origEndBoneWorldRot = endBoneWorldRot;
				m_grabStats.origRotationsValid = true;
			}

			Quat grabQuat((endBoneWorldRot*m_grabStats.origEndBoneWorldRot.GetInverted()).q * m_grabStats.origRotation);
			grabQuat.Normalize();

			// NOTE Dez 14, 2006: <pvl> this code sets up and look vectors for the grabbed
			// entity in case it's an Actor (the player, mostly) so that the player always
			// looks roughly at the grabber.  The grabber is supposed to be the Hunter here
			// so this code is somewhat Hunter-specific.
			// UPDATE Aug 7, 2007: <pvl> do the above for the player only
			// UPDATE Sep 13, 2007: <pvl> don't do it for anybody ATM, it doesn't seem useful
// 			CActor *pGrabbedActor = (CActor *)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_grabStats.grabId);
// 			if (false && pGrabbedActor && pGrabbedActor->IsClient() && pGrabbedActor->GetActorStats())
// 			{
// 				Vec3 upVec(Quat(endBoneWorldRot.q * m_grabStats.additionalRotation).GetColumn2());
// 				upVec.z = fabs_tpl(upVec.z) * 2.0f;
// 				upVec.NormalizeSafe(Vec3(0,0,1));
//
// 				SActorStats *pAS = pGrabbedActor->GetActorStats();
// 				if (pAS)
// 				{
// 					pAS->forceUpVector = upVec;
// 					pAS->forceLookVector = (pEnt->GetSlotWorldTM(0) * m_pActor->GetLocalEyePos()) - pGrabbedActor->GetEntity()->GetWorldPos();
// 					float lookLen(pAS->forceLookVector.len());
// 					pAS->forceLookVector *= (1.0f/lookLen)*0.33f;
// 					//pAS->forceLookVector = -Quat(boneRot * m_grabStats.additionalRotation).GetColumn1();//boneRot.GetColumn2();
// 				}
// 			}
// 			else
// 			{
			pGrab->SetRotation(grabQuat,ENTITY_XFORM_USER);
// 			}
		}
	}

	if(m_grabStats.grabDelay<0.001f)
	{
		// NOTE Sep 16, 2007: <pvl> now that grabbed entity rotation coming from
		// a grabbing bone (if any) is computed, bone-space offset can be applied
		Matrix34 tm(pGrab->GetWorldTM());
		tm.AddTranslation(GetGrabBoneWorldTM().q * m_grabStats.boneGrabOffset);
		pGrab->SetWorldTM(tm,ENTITY_XFORM_USER);

		/*
		{
			// debug draw for the grab bone
			QuatT grabBoneWorldTM = GetGrabBoneWorldTM();
			Vec3 start = grabBoneWorldTM.t;
			Vec3 end = start + grabBoneWorldTM.q * Vec3 (1,0,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (255,0,0), end, ColorB (0,0,255), 6.0f);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere (start, 0.5f, ColorB (255,128,0));
		}
		*/
		/*
		{
			// draw complete coord systems for both the end bone and the grabbed thing
			QuatT grabBoneWorldTM = GetGrabBoneWorldTM();
			Vec3 start = grabBoneWorldTM.t;
			Vec3 end = start + grabBoneWorldTM.q * Vec3 (1,0,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (128,0,0), end, ColorB (128,0,0), 6.0f);
			end = start + grabBoneWorldTM.q * Vec3 (0,1,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (0,128,0), end, ColorB (0,128,0), 6.0f);
			end = start + grabBoneWorldTM.q * Vec3 (0,0,1) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (0,0,128), end, ColorB (0,0,128), 6.0f);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere (start, 0.2f, ColorB (255,255,255));

			start = pGrab->GetWorldTM().GetTranslation();
			end = start + pGrab->GetRotation() * Vec3 (1,0,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (128,0,0), end, ColorB (128,0,0), 6.0f);
			end = start + pGrab->GetRotation() * Vec3 (0,1,0) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (0,128,0), end, ColorB (0,128,0), 6.0f);
			end = start + pGrab->GetRotation() * Vec3 (0,0,1) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (0,0,128), end, ColorB (0,0,128), 6.0f);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere (start, 0.2f, ColorB (64,64,64));
		}
		*/
	}

	/*
		{
			// debug draw for the grabbed object
			Vec3 start = pGrab->GetWorldTM().GetTranslation();
			Vec3 end = start + pGrab->GetRotation() * Vec3 (0,0,1) * 3;
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine (start, ColorB (255,0,0), end, ColorB (0,0,255), 6.0f);
			gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere (start, 0.2f, ColorB (255,128,0));
		}
	*/
}