예제 #1
0
DBOOL UpdateMovingObject(PhysicsState *pUserState, MovingObject *pObject, DVector *pNewPos)
{
	if (!pObject || !pNewPos) return DFALSE;

	PhysicsState* pState = pUserState ? pUserState : GetCurPhysicsState(pObject);
	if (!pState) return DFALSE;

	DVector vTemp, velocityDelta, posDelta;

	if(pObject->m_PhysicsFlags & MO_RESTING)
		return DFALSE;
	
	// Prevent tiny movements.
	if(VEC_MAGSQR(pObject->m_Acceleration) < 0.01f)
	{
		VEC_INIT(pObject->m_Acceleration);
	}

	if(VEC_MAGSQR(pObject->m_Velocity) < 0.01f)
	{
		VEC_INIT(pObject->m_Velocity);
	}

	// velocityDelta = ( acceleration + accelDelta * 0.5 ) * dt;
	VEC_INIT(vTemp);
	if (!(pObject->m_PhysicsFlags & MO_NOGRAVITY))
	{
		DFLOAT fScale = 0.5f;
		if (pObject->m_PhysicsFlags & MO_HALFGRAVITY)
		{
			fScale = 0.20f;
		}
		VEC_MULSCALAR(vTemp, pState->m_GravityAccel, fScale);
	}
	VEC_ADD(vTemp, vTemp, pObject->m_Acceleration);
	VEC_MULSCALAR(velocityDelta, vTemp, pState->m_TimeStep);

	// Apply the velocity to the position (p = p + vt + 0.5a(t^2)).
	VEC_MULSCALAR(posDelta, pObject->m_Acceleration, pState->m_TimeStepIntegral);
	VEC_ADDSCALED(posDelta, posDelta, pObject->m_Velocity, pState->m_TimeStep);

	// Add the final velocity to the new velocity.
	VEC_ADD(pObject->m_Velocity, pObject->m_Velocity, velocityDelta);

	if(!pNewPos)
		pNewPos = &pObject->m_Pos;

	VEC_ADD(*pNewPos, pObject->m_Pos, posDelta);
	
	// Zero out the acceleration.
	VEC_INIT(pObject->m_Acceleration);

	return DTRUE;
}
void WorldModelDebris::Start(LTVector *pvRotationPeriods, LTVector* pvVel)
{
	if (!pvRotationPeriods || !pvVel) return;

    LTFLOAT fMag = VEC_MAGSQR(*pvRotationPeriods);
	if (fMag > 0.001f)
	{
        m_bRotate = LTTRUE;

		if (pvRotationPeriods->x < -0.001 || 0.001f < pvRotationPeriods->x)
		{
			m_fXRotVel = MATH_CIRCLE / pvRotationPeriods->x;
		}
		if (pvRotationPeriods->y < -0.001 || 0.001f < pvRotationPeriods->y)
		{
			m_fXRotVel = MATH_CIRCLE / pvRotationPeriods->y;
		}
		if (pvRotationPeriods->z < -0.001 || 0.001f < pvRotationPeriods->z)
		{
			m_fXRotVel = MATH_CIRCLE / pvRotationPeriods->z;
		}
	}

    uint32 dwFlags = FLAG_VISIBLE | FLAG_GRAVITY | FLAG_RAYHIT;
    g_pLTServer->SetObjectFlags(m_hObject, dwFlags);
    g_pLTServer->SetNextUpdate(m_hObject, 0.01f);
    g_pLTServer->SetVelocity(m_hObject, pvVel);
    g_pLTServer->SetBlockingPriority(m_hObject, 100);
    g_pLTServer->SetForceIgnoreLimit(m_hObject, 0.0f);
    g_pLTServer->SetFrictionCoefficient(m_hObject, GetRandom(10.0f, 20.0f));

    m_fLastTime = g_pLTServer->GetTime();
}
예제 #3
0
파일: Scanner.cpp 프로젝트: Arc0re/lithtech
LTBOOL CScanner::CanSeeObject(ObjectFilterFn ofn, HOBJECT hObject)
{
	_ASSERT(hObject);
    if (!hObject) return LTFALSE;

	if (g_pGameServerShell->GetGameType() == COOPERATIVE_ASSAULT && m_nPlayerTeamFilter && IsPlayer(hObject))
	{
		CPlayerObj* pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject(hObject);
		if (pPlayer->GetTeamID() != m_nPlayerTeamFilter)
			return LTFALSE;
	}


    LTVector vPos;
    g_pLTServer->GetObjectPos(hObject, &vPos);

    LTVector vDir;
	vDir = vPos - GetScanPosition();

	if (VEC_MAGSQR(vDir) >= m_fVisualRange)
	{
        return LTFALSE;
	}

	vDir.Norm();

    LTRotation rRot = GetScanRotation();

    LTVector vUp, vRight, vForward;
    g_pLTServer->GetRotationVectors(&rRot, &vUp, &vRight, &vForward);

    LTFLOAT fDp = vDir.Dot(vForward);

	if (fDp < m_fFOV)
	{
        return LTFALSE;
	}

	// See if we can see the position in question

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	VEC_COPY(IQuery.m_From, GetScanPosition());
	VEC_COPY(IQuery.m_To, vPos);
	IQuery.m_Flags	  = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	IQuery.m_FilterFn = ofn;

    if (g_pLTServer->IntersectSegment(&IQuery, &IInfo))
	{
		if (IInfo.m_hObject == hObject)
		{
            return LTTRUE;
		}
	}

    return LTFALSE;
}
예제 #4
0
DBOOL BounceMovingObject(PhysicsState *pUserState, MovingObject *pObject, 
						 DVector *pNewPos, ClientIntersectInfo* pInfo, SurfaceType *eType)
{

	if (!pObject || !pNewPos || !pInfo) return DFALSE;

	PhysicsState* pState = pUserState ? pUserState : GetCurPhysicsState(pObject);
	if (!pState) return DFALSE;

	ClientIntersectQuery query;
	float dot;

	// Only do an intersection test if the line is long enough (sometimes the 
	// intersection test will fail on really short lines).
	memset(&query, 0, sizeof(query));
	VEC_COPY(query.m_From, pObject->m_Pos);
	VEC_COPY(query.m_To, *pNewPos);

	if (eType)
		query.m_Flags = INTERSECT_HPOLY;

	if (pState->m_pClientDE->IntersectSegment(&query, pInfo))
	{
		// get the surface type
		if (eType)
			*eType = GetSurfaceType(pInfo->m_hObject, pInfo->m_hPoly);

		// Reflect the velocity.
		dot = VEC_DOT(pObject->m_Velocity, pInfo->m_Plane.m_Normal);
		dot *= -2.0f;

		VEC_ADDSCALED(pObject->m_Velocity, pObject->m_Velocity, pInfo->m_Plane.m_Normal, dot);

		// If the plane hit is in the opposite direction of travel, then move back a little...
		if( dot > 0.0f )
		{
			// Move the dest point a little in front of the plane.
			VEC_ADDSCALED(*pNewPos, pInfo->m_Point, pInfo->m_Plane.m_Normal, 0.3f);
		}
	
		// Dampen it.
		VEC_MULSCALAR(pObject->m_Velocity, pObject->m_Velocity, pState->m_VelocityDampen);
		
		// (250 is the max squared magnitude).
		if(pInfo->m_Plane.m_Normal.y > 0.6f && (VEC_MAGSQR(pObject->m_Velocity) < (250.0f)))
		{
			pObject->m_PhysicsFlags |= MO_RESTING;
		}

		return DTRUE;
	}

	return DFALSE;
}
예제 #5
0
파일: Scanner.cpp 프로젝트: Arc0re/lithtech
LTBOOL CScanner::CanSeePos(ObjectFilterFn ofn, const LTVector& vPos)
{
    LTVector vDir;
	vDir = vPos - GetScanPosition();

	if (VEC_MAGSQR(vDir) >= m_fVisualRange)
	{
        return LTFALSE;
	}

	vDir.Norm();

    LTRotation rRot = GetScanRotation();

    LTVector vUp, vRight, vForward;
    g_pLTServer->GetRotationVectors(&rRot, &vUp, &vRight, &vForward);

    LTFLOAT fDp = vDir.Dot(vForward);

	if (fDp < m_fFOV)
	{
        return LTFALSE;
	}

	// See if we can see the position in question

	IntersectQuery IQuery;
	IntersectInfo IInfo;

	VEC_COPY(IQuery.m_From, GetScanPosition());
	VEC_COPY(IQuery.m_To, vPos);
	IQuery.m_Flags	  = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	IQuery.m_FilterFn = ofn;

    if (!g_pLTServer->IntersectSegment(&IQuery, &IInfo))
	{
        return LTTRUE;
	}

    return LTFALSE;
}
예제 #6
0
void CDestructable::ApplyDamagePhysics(DFLOAT fDamage, DVector *pvDir)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE || !m_hObject || !pvDir) return;

	// Don't apply damage physics if the object is a trapped character (Andy 2/22/99)
	if(IsBaseCharacter(m_hObject))
	{
		CBaseCharacter *pObj = (CBaseCharacter*)pServerDE->HandleToObject(m_hObject);
		if(pObj->IsTrapped()) return;
	}

	if (VEC_MAGSQR(*pvDir) < 0.01) return;

	DVector vTemp, vVel;

	pServerDE->GetVelocity(m_hObject, &vVel);

	VEC_COPY(vTemp, *pvDir);
	VEC_NORM(vTemp);

	if (m_fMass <= 0) m_fMass = 1;
	
	DFLOAT fMultiplier = (fDamage * PA_DAMAGE_VEL_MUTLIPLIER) / m_fMass;

	VEC_MULSCALAR(vTemp, vTemp, fMultiplier);
	VEC_ADD(vVel, vTemp, vVel);

	// Accumulate damage velocity for player objects to send to the client..
	if (IsPlayer(m_hObject))
	{
		VEC_ADD(m_vAddVelocity, m_vAddVelocity, vTemp);
		m_bAddVelocity = DTRUE;
	}

	pServerDE->SetVelocity(m_hObject, &vVel);
}
예제 #7
0
void SoccerBall::OnInitialUpdate(void* pData, DFLOAT fData)
{
	DVector vDims;
	DDWORD dwFlags;

	g_pServerDE->SetForceIgnoreLimit( m_hObject, 0.0f );
//	g_pServerDE->SetFrictionCoefficient( m_hObject, 10.0f );

	g_pServerDE->GetModelAnimUserDims( m_hObject, &vDims, 0 );
	if( VEC_MAGSQR( vDims ) < 1.0f )
		VEC_SET( vDims, 1.0f, 1.0f, 1.0f );
	g_pServerDE->SetObjectDims( m_hObject, &vDims );
	m_fRadius = ( vDims.x + vDims.y + vDims.z ) / 3.0f;

	g_pServerDE->SetNextUpdate( m_hObject, 0.001f );

//	CreateLight( );

	// Mark this object as savable
	dwFlags = g_pServerDE->GetObjectUserFlags( m_hObject );
	dwFlags |= USERFLG_NIGHTGOGGLESGLOW;
	g_pServerDE->SetObjectUserFlags( m_hObject, dwFlags );

}
예제 #8
0
void CNodeController::HandleNodeControlRecoilMessage(HMESSAGEREAD hMessage)
{
	if ( m_cRecoils >= MAX_RECOILS )
		return;

	m_fRecoilTimers[m_cRecoils++] = 0.50f;


	ModelNode eModelNode;
    eModelNode = (ModelNode)g_pLTClient->ReadFromMessageByte(hMessage);

    LTVector vRecoilDir;
    g_pLTClient->ReadFromMessageCompVector(hMessage, &vRecoilDir);

	// Get the magnitude of the recoil vector

    LTFLOAT fRecoilMag = VEC_MAGSQR(vRecoilDir);

	// Get the unit impact/recoil vector

	vRecoilDir /= (float)sqrt(fRecoilMag);

	// Cap it if necessary

	if ( fRecoilMag > 100.0f )
	{
		fRecoilMag = 100.0f;
	}

	// Get the position of the impact

	NSTRUCT* pNode = &m_aNodes[eModelNode];
    ILTModel* pModelLT = g_pLTClient->GetModelLT();
	LTransform transform;
    pModelLT->GetNodeTransform(GetCFX()->GetServerObj(), pNode->hModelNode, transform, LTTRUE);

	// Decompose the transform into the position and rotation

    LTVector vPos;
    ILTTransform* pTransformLT = g_pLTClient->GetTransformLT();
	pTransformLT->GetPos(transform, vPos);

    LTVector vRecoilPos = vPos;

	// Add angular rotations up the recoil parent chain

	ModelNode eModelNodeCurrent = g_pModelButeMgr->GetSkeletonNodeRecoilParent(GetCFX()->GetModelSkeleton(), eModelNode);

	while ( eModelNodeCurrent != eModelNodeInvalid )
	{
		// Get the rotation of the node

		NSTRUCT* pNode = &m_aNodes[eModelNodeCurrent];

		LTransform transform;
        ILTModel* pModelLT = g_pLTClient->GetModelLT();

		// Get the transform of the node we're controlling

        pModelLT->GetNodeTransform(GetCFX()->GetServerObj(), pNode->hModelNode, transform, LTTRUE);

        ILTTransform* pTransformLT = g_pLTClient->GetTransformLT();

		// Decompose the transform into the position and rotation

        LTVector vPos;
        LTRotation rRot;
		pTransformLT->Get(transform, vPos, rRot);

		// Get the rotation vectors of the transform

        LTVector vRight, vUp, vForward;
        g_pLTClient->GetRotationVectors(&rRot, &vUp, &vRight, &vForward);

		// Cross the right vector with the impact vector to get swing

        LTVector vRotationAxis = vRight.Cross(vRecoilDir);
		vRotationAxis.Norm();

		// Add the timed rotation control for the swing

		// !!! HACK
		// !!! Do not add swing if this is a leg node

		if ( !strstr(g_pModelButeMgr->GetSkeletonNodeName(GetCFX()->GetModelSkeleton(), eModelNodeCurrent), "leg") )
		AddNodeControlRotationTimed(eModelNodeCurrent, vRotationAxis, MATH_PI/1000.0f*fRecoilMag, 0.50f);

		// Use the right vector to get twist, but make sure the sign is correct based on location
		// of impact and whether we're getting shot at from behind/front etc

		vRotationAxis = vRight;
		vRotationAxis.Norm();

		// Get the twist

        LTVector vSideDir = vRecoilPos-vPos;
		vSideDir.Norm();

        LTFLOAT fSign = vUp.Dot(vRecoilDir);
		fSign *= vForward.Dot(vSideDir);

		if ( fSign > 0.0f )
		{
			vRotationAxis = -vRotationAxis;
		}

		// Add the timed rotation control for the twist

	//	AddNodeControlRotationTimed(eModelNodeCurrent, vRotationAxis, MATH_PI/1000.0f*fRecoilMag, 0.50f);

		// Decrease the magnitude

		fRecoilMag /= 2.0f;

		eModelNodeCurrent = g_pModelButeMgr->GetSkeletonNodeRecoilParent(GetCFX()->GetModelSkeleton(), eModelNodeCurrent);
	}
}
예제 #9
0
void SoccerBall::OnTouchNotify( HOBJECT hObj, float fForce )
{
	CollisionInfo colInfo;
	DVector vVel, vOtherVel, vEffectiveVel, vPos, vNewVel;
	DVector vNormal;
	float fEffectiveVelMag, fMultiplier, fVelMag;
	DRotation rRot;
	DVector vUp, vRight;
	DBOOL bIsPlayer;
	
	g_pServerDE->GetVelocity( m_hObject, &vVel );
	g_pServerDE->GetVelocity( hObj, &vOtherVel );

	g_pServerDE->GetObjectPos( m_hObject, &vPos );

	if( hObj == g_pServerDE->GetWorldObject( ))
	{
		VEC_SUB( vEffectiveVel, vOtherVel, vVel );
		fEffectiveVelMag = VEC_MAG( vEffectiveVel );
	
		g_pServerDE->GetLastCollision( &colInfo );

		// Compute new velocity reflected off of the surface.
		if( VEC_MAGSQR( colInfo.m_Plane.m_Normal ) > 0.0f )
		{
			VEC_COPY( vNormal, colInfo.m_Plane.m_Normal );
			if( fEffectiveVelMag > MAXBALLVEL )
				fMultiplier = MAXBOUNCEFACTOR;
			else
				fMultiplier = MINBOUNCEFACTOR + ( MAXBOUNCEFACTOR - MINBOUNCEFACTOR ) * fEffectiveVelMag / MAXBALLVEL;
			VEC_MULSCALAR( vNormal, vNormal, fEffectiveVelMag * fMultiplier );
			VEC_ADD( vNewVel, vVel, vNormal );
			if( fabs( vNewVel.y + vVel.y ) < 100.0f )
				vNewVel.y = vVel.y;
			g_pServerDE->SetVelocity( m_hObject, &vNewVel );
		}

		if( fabs( fForce ) > MINFORCESOUND )
			m_bBounced = DTRUE;
	}
	else
	{
		// Ignore non-solid objects
		if( !( g_pServerDE->GetObjectFlags( hObj ) & FLAG_SOLID ))
			return;

		bIsPlayer = IsPlayer( hObj );
		if( bIsPlayer )
		{
			if( m_hLastPlayer && hObj != m_hLastPlayer )
			{
				g_pServerDE->BreakInterObjectLink( m_hObject, m_hLastPlayer );
			}

			m_hLastPlayer = hObj;
			g_pServerDE->CreateInterObjectLink( m_hObject, m_hLastPlayer );

			m_fRespawnTime = g_pServerDE->GetTime( ) + BALLRESPAWNTIME;
		}

		VEC_ADD( vVel, vVel, vOtherVel );
		if( m_bOnGround && vVel.y < 0.0f )
			vVel.y = 0.0f;
		if( bIsPlayer )
			vVel.y += g_pServerDE->Random( 150.0f, 300.0f );
		fVelMag = VEC_MAG( vVel );
		g_pServerDE->AlignRotation( &rRot, &vVel, DNULL );
		g_pServerDE->EulerRotateX( &rRot, g_pServerDE->Random( -0.1f, 0.1f ));
		g_pServerDE->EulerRotateY( &rRot, g_pServerDE->Random( -0.1f, 0.1f ));
		g_pServerDE->EulerRotateZ( &rRot, g_pServerDE->Random( -0.1f, 0.1f ));
		g_pServerDE->GetRotationVectors( &rRot, &vUp, &vRight, &vVel );
		VEC_MULSCALAR( vVel, vVel, fVelMag );
		g_pServerDE->SetVelocity( m_hObject, &vVel );

		if( fabs( fForce ) > MINFORCESOUND || bIsPlayer )
			m_bBounced = DTRUE;
	}
}