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); } }
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)); } */ }