示例#1
0
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;
	}
}
示例#2
0
//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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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 );
}
示例#6
0
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;
	}
}
示例#7
0
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;
}
示例#8
0
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);
	}
}
示例#9
0
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 );
}