void CNodeController::UpdateRotationTimed(NCSTRUCT* pNodeControl) { LTRotation rRot(0.0f, 0.0f, 0.0f, 1.0f); LTransform transform; LTMatrix matRotate; // g_pLTClient->CPrint("Rotating %s around <%f,%f,%f> by %f radians", g_pModelButeMgr->GetSkeletonNodeName(GetCFX()->GetModelSkeleton(), pNodeControl->eModelNode), // pNodeControl->vRotationAxis.x, pNodeControl->vRotationAxis.y, pNodeControl->vRotationAxis.z, // pNodeControl->fnRotationFunction(pNodeControl->fRotationDistance, pNodeControl->fRotationTimer, pNodeControl->fRotationDuration)); // Rotate the node around that axis Mat_SetupRot(&matRotate, &pNodeControl->vRotationAxis, pNodeControl->fnRotationFunction(pNodeControl->fRotationDistance, pNodeControl->fRotationTimer, pNodeControl->fRotationDuration)); // Apply the rotation to the node m_aNodes[pNodeControl->eModelNode].matTransform = matRotate * m_aNodes[pNodeControl->eModelNode].matTransform; // Update our timing info LTFLOAT fRotationTime = g_pGameClientShell->GetFrameTime(); pNodeControl->fRotationTimer += fRotationTime; if ( pNodeControl->fRotationTimer >= pNodeControl->fRotationDuration ) { // We're done pNodeControl->bValid = LTFALSE; } }
//given a vector, this will return a rotation that uses the vector as the forward direction with a //random twist static LTRotation ConvertDirectionToOrientation(const LTVector& vUnitDir) { //create a random rotation around the plane that we hit LTRotation rRot(vUnitDir, LTVector(0.0f, 1.0f, 0.0f)); rRot.Rotate(vUnitDir, GetRandom(0.0f, MATH_TWOPI)); return rRot; }
LTRotation SecurityCamera::GetScanRotation() { LTRotation rRot(0.0f, m_fYaw, 0.0f); // Fix from port...use the object's rotation, not just the yaw... g_pLTServer->GetObjectRotation(m_hObject, &rRot); return rRot; }
LTRotation AI_Helicopter::GetAttachmentRotation(HOBJECT hObject) { LTRotation rRot(0,0,0,1); HATTACHMENT hAttachment; if ( LT_OK == g_pLTServer->FindAttachment(m_hObject, hObject, &hAttachment) ) { LTransform transform; g_pLTServer->Common()->GetAttachmentTransform(hAttachment, transform, LTTRUE); g_pTransLT->GetRot(transform, rRot); } return rRot; }
void GameBase::HandleSetRotationMsg( HOBJECT hSender, const CParsedMsg &crParsedMsg ) { // Make sure we have all the arguments. if( crParsedMsg.GetArgCount( ) < 4 ) return; // Get the euler angles. Convert to radians. LTVector vEulerAngle; vEulerAngle.y = (( float )atof( crParsedMsg.GetArg( 1 )) * MATH_PI / 180.0f ); vEulerAngle.x = (( float )atof( crParsedMsg.GetArg( 2 )) * MATH_PI / 180.0f ); vEulerAngle.z = (( float )atof( crParsedMsg.GetArg( 3 )) * MATH_PI / 180.0f ); LTRotation rRot( vEulerAngle.x, vEulerAngle.y, vEulerAngle.z ); g_pLTServer->SetObjectRotation( m_hObject, rRot ); }
void CHUDRadar::Update() { // No need to update if we aren't going to render... if( !m_bDraw || (m_mapRadarObjects.size() == 0 && m_Players.size() == 0) ) return; //see if we have changed ratios and need to recalculate the name positions if( (m_fNameXRatio != g_pInterfaceResMgr->GetXRatio()) || (m_fNameYRatio != g_pInterfaceResMgr->GetYRatio())) { UpdateNamePositions(); m_fNameXRatio = g_pInterfaceResMgr->GetXRatio(); m_fNameYRatio = g_pInterfaceResMgr->GetYRatio(); } LTVector vLocalPos, vObjPos, vDir; g_pLTClient->GetObjectPos( g_pLTClient->GetClientObject(), &vLocalPos ); float fYaw = g_pPlayerMgr->GetYaw() - MATH_PI; if (g_pPlayerMgr->IsCameraAttachedToHead()) { fYaw = m_fLastRotation; } else { m_fLastRotation = fYaw; } LTRotation rRot( 0.0f, fYaw, 0.0f ); LTMatrix mMat; rRot.ConvertToMatrix( mMat ); mMat = ~mMat; RADAROBJECT *pRadarObj = LTNULL; HOBJECT hObj = LTNULL; RadarObjectList::iterator iter; for( iter = m_mapRadarObjects.begin(); iter != m_mapRadarObjects.end(); ++iter ) { hObj = iter->first; pRadarObj = iter->second; pRadarObj->m_bDraw = false; g_pLTClient->GetObjectPos( hObj, &vObjPos ); float fDist = vLocalPos.Dist( vObjPos ); // Focus on all objects within maxshowdist. All objects father than maxshowdist // are pushed to within 1/e^2 of the edge. // This will scale fDist between 0 and 1. fDist = 1.0f - 1.0f / ( float )( exp( 2.0f * fDist / m_nMaxShowDist )); // This will scale fDist within the hud element size. fDist = ( fDist * (float)m_nBaseSize / 2.0f); vDir = vLocalPos - vObjPos; MatVMul_InPlace_3x3( &mMat, &vDir ); vDir.y = 0.0f; if( vDir.LengthSquared() > 0.01f ) { vDir.Normalize(); } else { vDir.Init(); } vDir *= fDist; float fx = (float)(m_BasePos.x + vDir.x) * g_pInterfaceResMgr->GetXRatio(); float fy = (float)(m_BasePos.y - vDir.z) * g_pInterfaceResMgr->GetXRatio(); float fw = (float)(m_nObjectSize) * g_pInterfaceResMgr->GetXRatio(); g_pDrawPrim->SetXYWH( &pRadarObj->m_Poly, fx, fy, fw, fw ); pRadarObj->m_bDraw = true; } }
void CProjectileFX::Detonate(CollisionInfo* pInfo) { if (!m_pClientDE || m_bDetonated) return; m_bDetonated = LTTRUE; SurfaceType eType = ST_UNKNOWN; LTVector vPos; g_pLTClient->GetObjectPos(m_hServerObject, &vPos); // Determine the normal of the surface we are impacting on... LTVector vNormal; VEC_SET(vNormal, 0.0f, 1.0f, 0.0f); if (pInfo) { if (pInfo->m_hObject) { eType = GetSurfaceType(pInfo->m_hObject); } else if (pInfo->m_hPoly != INVALID_HPOLY) { eType = GetSurfaceType(pInfo->m_hPoly); VEC_COPY(vNormal, pInfo->m_Plane.m_Normal); LTRotation rRot(vNormal, LTVector(0.0f, 1.0f, 0.0f)); m_pClientDE->SetObjectRotation(m_hServerObject, &rRot); // Calculate where we really hit the plane... LTVector vVel, vP0, vP1; g_pPhysicsLT->GetVelocity(m_hServerObject, &vVel); VEC_COPY(vP1, vPos); VEC_MULSCALAR(vVel, vVel, g_pGameClientShell->GetFrameTime()); VEC_SUB(vP0, vP1, vVel); LTFLOAT fDot1 = VEC_DOT(pInfo->m_Plane.m_Normal, vP0) - pInfo->m_Plane.m_Dist; LTFLOAT fDot2 = VEC_DOT(pInfo->m_Plane.m_Normal, vP1) - pInfo->m_Plane.m_Dist; if (fDot1 < 0.0f && fDot2 < 0.0f || fDot1 > 0.0f && fDot2 > 0.0f) { VEC_COPY(vPos, vP1); } else { LTFLOAT fPercent = -fDot1 / (fDot2 - fDot1); VEC_LERP(vPos, vP0, vP1, fPercent); } } } else { // Since pInfo was null, this means the projectile's lifetime was up, // so we just blow-up in the air. eType = ST_AIR; } HOBJECT hObj = !!pInfo ? pInfo->m_hObject : LTNULL; ::AddLocalImpactFX(hObj, m_vFirePos, vPos, vNormal, eType, m_vPath, m_nWeaponId, m_nAmmoId, 0); m_bWantRemove = LTTRUE; }
void Prop::Update() { if (m_bFirstUpdate && m_bMoveToFloor) { // Make sure object starts on floor... m_bFirstUpdate = LTFALSE; MoveObjectToFloor(m_hObject); SetNextUpdate(UPDATE_NEXT_FRAME); } else if( m_pDisturb && (m_eState == kState_PropTouching) ) { HandleTouch(LTNULL); } else if( m_pDisturb && (m_eState == kState_PropHit) ) { HandleHit(LTNULL); } else if( m_bRotating ) { if( m_fPitchVel != 0 || m_fYawVel != 0 || m_fRollVel != 0 ) { float fDeltaTime = g_pLTServer->GetFrameTime(); m_fPitch += m_fPitchVel * fDeltaTime; m_fYaw += m_fYawVel * fDeltaTime; m_fRoll += m_fRollVel * fDeltaTime; LTRotation rRot( m_fPitch, m_fYaw, m_fRoll ); g_pLTServer->SetObjectRotation( m_hObject, &rRot ); SetNextUpdate(UPDATE_NEXT_FRAME); } } else if ( m_bFading ) { UpdateFade(); } else if ( m_bCanDeactivate ) { // At this point the model only needs to get updates if we're playing // a non-looping animation so we can deactivate the object when the animation // is done playing. However, if the model is playing a looping animation // we'll stop updating but leave the object active (so it will continue to // animate and get key strings)... // See if we're animating... HMODELANIM hAnim = g_pLTServer->GetModelAnimation(m_hObject); if (hAnim != INVALID_ANI) { if (g_pLTServer->GetModelLooping(m_hObject)) { // We're playing a looping animation that is long enough, don't deactivate, // just stop updating the object (since the state can only be changed // externally)...NOTE: Short animations are default anis that you can't // see so we'll deactivate in those cases... uint32 nLength = 0; g_pModelLT->GetAnimLength(m_hObject, hAnim, nLength); if (nLength > 200) { SetNextUpdate(UPDATE_NEVER, eControlUpdateOnly); } else { SetNextUpdate(UPDATE_NEVER); } } else // Playing a non-looping animation... { bool bAniDone = !!(MS_PLAYDONE & g_pLTServer->GetModelPlaybackState(m_hObject)); if (bAniDone) { // Cool we can stop updating SetNextUpdate(UPDATE_NEVER); } else { // Keep updating until the animation is done... SetNextUpdate(UPDATE_NEXT_FRAME); } } } else // Not animating so no reason to update... { SetNextUpdate(UPDATE_NEVER); } } else { // Just keep updating SetNextUpdate(UPDATE_NEXT_FRAME); } }
void Prop::HandleAttachmentTouch( HOBJECT hToucher ) { if( !hToucher || !m_bAttachmentShotOff ) return; // Don't touch the owner... if( hToucher == m_hAttachmentOwner ) return; // Or any non-solid objects... uint32 dwToucherFlags; g_pCommonLT->GetObjectFlags( hToucher, OFT_Flags, dwToucherFlags ); if( !(dwToucherFlags & FLAG_SOLID) ) return; CollisionInfo info; g_pLTServer->GetLastCollision( &info ); LTVector vVel; g_pPhysicsLT->GetVelocity( m_hObject, &vVel ); // Calculate where we really hit the world... if( IsMainWorld( hToucher )) { LTVector vPos, vCurVel, vP0, vP1; g_pLTServer->GetObjectPos( m_hObject, &vPos ); vP1 = vPos; vCurVel = vVel * g_pLTServer->GetFrameTime(); vP0 = vP1 - vCurVel; vP1 += vCurVel; LTFLOAT fDot1 = VEC_DOT( info.m_Plane.m_Normal, vP0 ) - info.m_Plane.m_Dist; LTFLOAT fDot2 = VEC_DOT( info.m_Plane.m_Normal, vP1 ) - info.m_Plane.m_Dist; if( fDot1 < 0.0f && fDot2 < 0.0f || fDot1 > 0.0f && fDot2 > 0.0f ) { vPos = vP1; } else { LTFLOAT fPercent = -fDot1 / (fDot2 - fDot1); VEC_LERP( vPos, vP0, vP1, fPercent); } // Set our new "real" pos... g_pLTServer->SetObjectPos( m_hObject, &vPos ); } // If we're on the ground (or an object), stop movement... CollisionInfo standingInfo; g_pLTServer->GetStandingOn( m_hObject, &standingInfo ); CollisionInfo* pInfo = standingInfo.m_hObject ? &standingInfo : &info; if( pInfo->m_hObject ) { // Don't stop on walls... if( pInfo->m_Plane.m_Normal.y > 0.75f ) { vVel.Init(); // Turn off gravity, solid, and touch notify.... uint32 dwFlags = FLAG_POINTCOLLIDE | FLAG_NOSLIDING | FLAG_TOUCH_NOTIFY | FLAG_GRAVITY; g_pCommonLT->SetObjectFlags( m_hObject, OFT_Flags, 0, dwFlags ); // Rotate to rest... if( m_bRotating ) { LTRotation rRot( 0.0f, m_fYaw, 0.0f ); g_pLTServer->SetObjectRotation( m_hObject, &rRot ); m_bRotating = false; StartFade( s_vtAttachmentFadeDuration.GetFloat(), s_vtAttachmentFadeDelay.GetFloat() ); } } } // Remove the stoping velocity... vVel = -info.m_vStopVel; g_pPhysicsLT->SetVelocity( m_hObject, &vVel ); }