示例#1
0
LTBOOL ScaleSprite::Update()
{
	if (m_bStartOn)
	{
		g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, USRFLG_VISIBLE, USRFLG_VISIBLE);

		g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_VISIBLE, FLAG_VISIBLE);
	}

	SetNextUpdate(UPDATE_NEVER);
 
	// BUG - This isn't quite right.  Sometimes this works (flipping the sprite)
	// other times the sprite shouldn't be flipped...Not sure what the bug is.
	// For some reason the sprites are sometimes backwards...Get the rotation
	// so we can flip it...

    LTRotation rRot;
    LTVector vPos, vDir, vU, vR, vF;
	g_pLTServer->GetObjectPos(m_hObject, &vPos);
	g_pLTServer->GetObjectRotation(m_hObject, &rRot);
	vU = rRot.Up();
	vR = rRot.Right();
	vF = rRot.Forward();

	if (m_bFlushWithWorld)
	{
		// Align the sprite to the surface directly behind the sprite
		// (i.e., opposite the forward vector)...

		VEC_NORM(vF);
		VEC_MULSCALAR(vDir, vF, -1.0f);


		// Determine where on the surface to place the sprite...

		IntersectInfo iInfo;
		IntersectQuery qInfo;

		VEC_COPY(qInfo.m_From, vPos);
		VEC_COPY(qInfo.m_Direction, vDir);
		qInfo.m_Flags	 = IGNORE_NONSOLID | INTERSECT_OBJECTS | INTERSECT_HPOLY;
        qInfo.m_FilterFn = LTNULL;

        if (g_pLTServer->CastRay(&qInfo, &iInfo))
		{
            LTVector vTemp;
			VEC_COPY(vPos, iInfo.m_Point);
			VEC_COPY(vDir, iInfo.m_Plane.m_Normal);

			// Place the sprite just above the surface...

			VEC_MULSCALAR(vTemp, vDir, 1.0f);
			VEC_ADD(vPos, vPos, vTemp);

			g_pLTServer->SetObjectPos(m_hObject, &vPos);
		}
	}

    return LTTRUE;
}
void Body::FacePos(const LTVector& vTargetPos)
{
    if (!g_pLTServer || !m_hObject) return;

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

	LTVector vDir;
	VEC_SUB(vDir, vTargetPos, vPos);

	if ( vDir.MagSqr() == 0.0f )
	{
		// Facing the same position... this would be a divide by zero case
		// when we normalize. So just return.
		return;
	}

	vDir.y = 0.0f; // Don't look up/down
	VEC_NORM(vDir);

    LTRotation rRot;
    LTVector temp(0,1,0);
    g_pMathLT->AlignRotation(rRot, vDir, temp);
    g_pLTServer->SetObjectRotation(m_hObject, &rRot);
}
示例#3
0
void CPlayerCamera::PointAtPosition(DVector pos, DRotation rRot, DVector pointFrom)
{
	if (!m_pClientDE) return;

//	m_pServerDE->GetObjectPos(m_hObject, &vPos);
//	vTargetPos.y = vPos.y; // Don't look up/down.

	DVector vDir;
	VEC_SUB(vDir, pos, pointFrom);
	VEC_NORM(vDir);

	m_pClientDE->AlignRotation(&m_rRotation, &vDir, NULL);

	//m_Angles.Copy(m_Target.m_Angles);
	
	//m_Angles.z = angles.z;
	//m_Angles.x = angles.x;
/*	DVector vAngles;
	VEC_INIT(vAngles);

	m_rRotation = rRot;


	DFLOAT diffX = pos.x - m_vPos.x;
	DFLOAT diffY = pos.z - m_vPos.z;
	vAngles.y = (DFLOAT)atan2(diffX, diffY);

	DVector		target, copy;
	DVector	up, right, forward;

	m_pClientDE->GetRotationVectors(&m_rRotation, &up, &right, &forward);

	VEC_SUB(copy, pos, pointFrom);

	target = Apply(right, up, forward, copy);

	diffX = target.z;
	diffY = target.y;

	//DFLOAT temp = -ATan2(diffY,diffX);
	//if(Abs(temp - m_Angles.x) < .5)

	vAngles.x = (DFLOAT)-atan2(diffY, diffX);

	//PrintVector(pos);
	//GetClientShell().CPrint("X = " + RealStr(m_Angles.x));

	DRotation rOldRot;
	ROT_COPY(rOldRot, m_rRotation);

	m_pClientDE->SetupEuler(&m_rRotation, vAngles.x, vAngles.y, vAngles.z);

	// Make sure rotation is valid...

	m_pClientDE->GetRotationVectors(&m_rRotation, &up, &right, &forward);
	if (up.y < 0) ROT_COPY(m_rRotation, rOldRot);
*/
}
示例#4
0
inline bool d3d_ClipSprite(SpriteInstance *pInstance, HPOLY hPoly, 
	T **ppPoints, uint32 *pnPoints, T *pOut)
{
	LTPlane thePlane;
	float dot, d1, d2;
	SPolyVertex *pPrevPoint, *pCurPoint, *pEndPoint;
	LTVector vecTo;
	T *pVerts;
	uint32 nVerts;
	WorldPoly *pPoly;

	if(g_have_world == false)
		return false;
	
	// Get the correct poly.
	pPoly = world_bsp_client->GetPolyFromHPoly(hPoly);
	if(!pPoly)
		return false;

	// First see if the viewer is on the frontside of the poly.
	dot = pPoly->GetPlane()->DistTo(g_ViewParams.m_Pos);
	if(dot <= 0.01f)
		return false;

	pVerts = *ppPoints;
	nVerts = *pnPoints;
	
	// Clip on each edge plane.	
	pEndPoint = &pPoly->GetVertices()[pPoly->GetNumVertices()];
	pPrevPoint = pEndPoint - 1;
	for(pCurPoint=pPoly->GetVertices(); pCurPoint != pEndPoint; )
	{
		VEC_SUB(vecTo, pCurPoint->m_Vertex->m_Vec, pPrevPoint->m_Vertex->m_Vec);
		VEC_CROSS(thePlane.m_Normal, vecTo, pPoly->GetPlane()->m_Normal);
		VEC_NORM(thePlane.m_Normal);
		thePlane.m_Dist = VEC_DOT(thePlane.m_Normal, pCurPoint->m_Vertex->m_Vec);

		#define CLIPTEST PLANETEST
		#define DOCLIP DOPLANECLIP
		#include "polyclip.h"
		#undef CLIPTEST
		#undef DOCLIP

		pPrevPoint = pCurPoint;
		++pCurPoint;
	}

	*ppPoints = pVerts;
	*pnPoints = nVerts;
	return true;
}
示例#5
0
void CClientExplosionSFX::Setup(DVector *vPos, DVector *vNormal, DFLOAT fOffset)
{
	VEC_COPY(m_vPos, *vPos);
	VEC_COPY(m_vNormal, *vNormal);
	m_fOffset = fOffset;

	if(m_fOffset)
	{
		DVector	temp;
		VEC_NORM(m_vNormal);
		VEC_MULSCALAR(temp, m_vNormal, m_fOffset);
		VEC_ADD(m_vPos, m_vPos, temp);
	}
}
LTBOOL CGibFX::OkToRemoveGib(HLOCALOBJ hGib)
{
    if (!m_pClientDE || !g_pGameClientShell || !hGib) return LTTRUE;


	// The only constraint is that the client isn't currently looking
	// at the model...

	HLOCALOBJ hCamera = g_pGameClientShell->GetCamera();
    if (!hCamera) return LTTRUE;

    LTVector vPos, vCamPos;
	m_pClientDE->GetObjectPos(hGib, &vPos);
	m_pClientDE->GetObjectPos(hCamera, &vCamPos);


	// Determine if the client can see us...

    LTVector vDir;
	VEC_SUB(vDir, vPos, vCamPos);

    LTRotation rRot;
    LTVector vU, vR, vF;
	m_pClientDE->GetObjectRotation(hCamera, &rRot);
	m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

	VEC_NORM(vDir);
	VEC_NORM(vF);
    LTFLOAT fMul = VEC_DOT(vDir, vF);
    if (fMul <= 0.0f) return LTTRUE;


	// Client is looking our way, don't remove it yet...

    return LTFALSE;
}
示例#7
0
DBOOL CMovement::ClearToPoint(DVector vStart, DVector vDestPos, DVector vDims, IntersectInfo* IInfo)
{
	GlobalFilterFnData globalFilterFnData;
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return DFALSE;

	DFLOAT fDim = (DFLOAT)sqrt((vDims.x * vDims.x) + (vDims.z * vDims.z)) + 0.1f;

	IntersectQuery IQuery;

	IQuery.m_Flags	  = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	IQuery.m_FilterFn = GlobalFilterFn;
	globalFilterFnData.m_dwFlags = IGNORE_CHARACTER;
	globalFilterFnData.m_nIgnoreObjects = 1;
	globalFilterFnData.m_hIgnoreObjects = &m_hObject;
	IQuery.m_pUserData = &globalFilterFnData;	

	DVector vDir;
	DRotation rRot;

	VEC_SUB(vDir, vDestPos, vStart);
	VEC_NORM(vDir);

	pServerDE->AlignRotation(&rRot, &vDir, &m_vUp);

	DVector vU,vR,vF;
	pServerDE->GetRotationVectors(&rRot,&vU,&vR,&vF);

	//check the right side
	VEC_ADDSCALED(IQuery.m_From, vStart, vR, fDim);
	VEC_ADDSCALED(IQuery.m_To, vDestPos, vR, fDim);

	if(pServerDE->IntersectSegment(&IQuery, IInfo))
	{
		return DFALSE;
	}

	//check the left side
	VEC_ADDSCALED(IQuery.m_From, vStart, vR, (fDim * -1.0f));
	VEC_ADDSCALED(IQuery.m_To,vDestPos, vR, (fDim * -1.0f));

	if(pServerDE->IntersectSegment(&IQuery, IInfo))
	{
		return DFALSE;
	}

	return DTRUE;
}
示例#8
0
DBOOL UndeadGideon::Fire(DBOOL bAltFire)
{
	DVector vPos, vDir;
	DRotation rRot;

	// Sanity check (GK 9/18/98)
	if (!m_InventoryMgr.GetCurrentWeapon())
		return DFALSE;

	m_pServerDE->GetModelNodeTransform(m_hObject,"head",&vPos,&rRot);
	VEC_SUB(vDir, m_vTargetPos, vPos);
	VEC_NORM(vDir);

	vDir.x = m_MoveObj.GetForwardVector().x;
	vDir.z = m_MoveObj.GetForwardVector().z;

	m_pServerDE->AlignRotation(&rRot, &vDir, DNULL);

	DDWORD m_nFiredWeapon = m_InventoryMgr.FireCurrentWeapon(&vPos, &rRot, bAltFire);

	return DTRUE;
}
示例#9
0
文件: Naga.cpp 项目: Arc0re/lithtech
DBOOL Naga::Fire(DBOOL bAltFire)
{
	DVector vPos, vDir;
	DRotation rRot;

	// Sanity check (GK 9/18/98)
	if (!m_InventoryMgr.GetCurrentWeapon())
		return DFALSE;

	switch(m_InventoryMgr.GetCurrentWeapon()->GetType())
	{
		case WEAP_NAGA_EYEBEAM:
		{
			m_pServerDE->GetModelNodeTransform(m_hObject,"head_gun",&vPos,&rRot);
			VEC_SUB(vDir, m_vTargetPos, vPos);
			break;
		}

		case WEAP_NAGA_SPIKE:
		{
			m_pServerDE->GetModelNodeTransform(m_hObject,"l_gun",&vPos,&rRot);
			VEC_SUB(vDir, m_vTargetPos, vPos);
			break;
		}

		default:
		{	
			m_pServerDE->GetObjectPos(m_hObject,&vPos);
			VEC_SUB(vDir, m_vTargetPos, vPos);
			break;
		}
	}

	VEC_NORM(vDir);
	m_pServerDE->AlignRotation(&rRot, &vDir, DNULL);

	m_InventoryMgr.FireCurrentWeapon(&vPos, &rRot, bAltFire);
	return DTRUE;
}
示例#10
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);
}
示例#11
0
void CPlayerCamera::MoveCameraToPosition(DVector pos, DVector vStartPos, DFLOAT deltaTime)
{
	if (!m_pClientDE || !m_hTarget) return;

	DFLOAT nCurrentTime = m_pClientDE->GetTime();

	// Handle transition
	if (m_eCameraMode == GOINGFIRSTPERSON || m_eCameraMode == GOINGCHASE || m_eCameraMode == DEATH)
	{

		if (nCurrentTime > m_fTransitionStart + m_fTransitionTime)
		{
			switch (m_eCameraMode)
			{
				case GOINGFIRSTPERSON:
					m_eCameraMode = FIRSTPERSON;
					break;
				case GOINGCHASE:
					m_eCameraMode = CHASE;
					break;
			}
		}
		else
		{
			// vStartPos is starting pos, pos is the position we want
			DFLOAT percentage = (nCurrentTime - m_fTransitionStart) / (m_fTransitionTime);

			DVector vMagnitude;
			VEC_SUB (vMagnitude, pos, vStartPos);
			VEC_MULSCALAR (vMagnitude, vMagnitude, percentage);
			VEC_ADD (pos, vStartPos, vMagnitude);
		}
	}

	DVector	dir;
	VEC_SUB(dir, pos, m_vPos);

	DFLOAT multiplier = 1.0f; // 0.5f;
	
	DVector	toMove;
	VEC_MULSCALAR(toMove, dir, multiplier);
	
	DFLOAT moveMag;

	if(m_bSlide)
	{
		moveMag = VEC_MAG(toMove);
		if(moveMag > VEC_MAG(dir))
			moveMag = VEC_MAG(dir);

		if (toMove.x != 0.0f || toMove.y != 0.0f || toMove.z != 0.0f)
		{
			VEC_NORM(toMove);
		}
		VEC_MULSCALAR(toMove, toMove, moveMag);

		VEC_ADD(m_vPos, m_vPos, toMove);
	}
	else
	{
		VEC_COPY(m_vPos, pos);
	}
}
void Body::Init(const BODYINITSTRUCT& bi)
{
	if (!bi.pCharacter || !bi.pCharacter->m_hObject) return;

	// Get the death type etc

	m_eDeathType		= bi.pCharacter->GetDeathType();
	m_eModelId			= bi.pCharacter->GetModelId();
	m_eModelSkeleton    = bi.pCharacter->GetModelSkeleton();
	m_eModelStyle		= bi.pCharacter->GetModelStyle();

	// Get the body lifetime

	m_fLifetime		= bi.fLifetime;

	// Create the SFX

	BODYCREATESTRUCT bcs;
	bcs.eBodyState = bi.eBodyState;
	if (IsPlayer(bi.pCharacter->m_hObject))
	{
		CPlayerObj* pPlayer = (CPlayerObj*) bi.pCharacter;
		bcs.nClientId = (uint8) g_pLTServer->GetClientID(pPlayer->GetClient());
	}

    HMESSAGEWRITE hMessage = g_pLTServer->StartSpecialEffectMessage(this);
    g_pLTServer->WriteToMessageByte(hMessage, SFX_BODY_ID);
    bcs.Write(g_pLTServer, hMessage);
    g_pLTServer->EndMessage(hMessage);


	// Create the death scene

	CreateDeathScene(bi.pCharacter);

	// We'll handle creating the necessary debris...

	m_damage.m_bCreatedDebris = LTTRUE;

	m_damage.SetCanDamage(LTFALSE);//bi.pCharacter->CanDamageBody());
	m_damage.SetApplyDamagePhysics(LTFALSE);//bi.pCharacter->CanDamageBody());
	m_damage.SetMass(g_pModelButeMgr->GetModelMass(m_eModelId));

	// Let us get hit by decay powder

	m_damage.ClearCantDamageTypes(DamageTypeToFlag(DT_GADGET_DECAYPOWDER));

	switch ( g_pModelButeMgr->GetModelType(m_eModelId) )
	{
		case eModelTypeVehicle:
		{
			m_eDeathType = CD_GIB;
		}
		break;
	}

	CDestructible* pDest = bi.pCharacter->GetDestructible();
	if (pDest)
	{
		m_eDamageType = pDest->GetDeathType();
		VEC_COPY(m_vDeathDir, pDest->GetDeathDir());
		VEC_NORM(m_vDeathDir);
		VEC_MULSCALAR(m_vDeathDir, m_vDeathDir, 1.0f + (pDest->GetDeathDamage() / pDest->GetMaxHitPoints()));
	}

	LTFLOAT fHitPts = pDest->GetMaxHitPoints();
	m_damage.Reset(fHitPts, 0.0f);
	m_damage.SetHitPoints(fHitPts);
	m_damage.SetMaxHitPoints(fHitPts);
	m_damage.SetArmorPoints(0.0f);
	m_damage.SetMaxArmorPoints(0.0f);

	// Copy our user flags over, setting our surface type to flesh

    uint32 dwUsrFlags = g_pLTServer->GetObjectUserFlags(m_hObject) | USRFLG_NIGHT_INFRARED;
	dwUsrFlags |= SurfaceToUserFlag(ST_FLESH);
    g_pLTServer->SetObjectUserFlags(m_hObject, dwUsrFlags);

	// Make sure model doesn't slide all over the place...

    g_pLTServer->SetFrictionCoefficient(m_hObject, 500.0f);

	LTVector vDims;
    g_pLTServer->GetObjectDims(bi.pCharacter->m_hObject, &vDims);

	// Set the dims.  If we can't set the dims that big, set them
	// as big as possible...

    if (g_pLTServer->SetObjectDims2(m_hObject, &vDims) == LT_ERROR)
	{
        g_pLTServer->SetObjectDims2(m_hObject, &vDims);
	}


	// Create the box used for weapon impact detection...

	CreateHitBox(bi);


	LTFLOAT r, g, b, a;
    g_pLTServer->GetObjectColor(bi.pCharacter->m_hObject, &r, &g, &b, &a);
    g_pLTServer->SetObjectColor(m_hObject, r, g, b, a);

	LTVector vScale;
    g_pLTServer->GetObjectScale(bi.pCharacter->m_hObject, &vScale);
    g_pLTServer->ScaleObject(m_hObject, &vScale);

	// Copy our animation over

    HMODELANIM hAni = g_pLTServer->GetModelAnimation(bi.pCharacter->m_hObject);
    g_pLTServer->SetModelAnimation(m_hObject, hAni);
    g_pLTServer->SetModelLooping(m_hObject, LTFALSE);

	// Copy the flags from the character to us

	uint32 dwFlags = g_pLTServer->GetObjectFlags(bi.pCharacter->m_hObject);
	m_dwFlags |= FLAG_REMOVEIFOUTSIDE;
    g_pLTServer->SetObjectFlags(m_hObject, dwFlags);

	// Move the attachments aggregate from the char to us...

	if (!m_pAttachments && bi.eBodyState != eBodyStateLaser)
	{
		m_hWeaponItem = bi.pCharacter->TransferWeapon(m_hObject);

		// Make sure we're playing the correct ani...

		if (m_hWeaponItem)
		{
			uint32 dwAni = g_pLTServer->GetAnimIndex(m_hWeaponItem, "Hand");
		 	if (dwAni != INVALID_ANI)
			{
				g_pLTServer->SetModelAnimation(m_hWeaponItem, dwAni);
				g_pLTServer->SetModelLooping(m_hWeaponItem, LTFALSE);
			}
		}
	}

	if (!m_pAttachments)
	{
		m_pAttachments = bi.pCharacter->TransferAttachments();

		if (m_pAttachments)
		{
			AddAggregate(m_pAttachments);
			m_pAttachments->ReInit(m_hObject);
		}
	}

	// Set up the spears

	bi.pCharacter->TransferSpears(this);

	// Set our state

	SetState(bi.eBodyState);
}
示例#13
0
void CDebris::Create(DVector vDir, DFLOAT fDamage)
{
	if (!g_pServerDE) return;

//	HCLASS hClass = g_pServerDE->GetClass( "CClientGibFX" );
//	if( !hClass )
//		return;

	VEC_NEGATE(vDir, vDir);

	DFLOAT fVelFactor = 1.0f;

//	DDWORD nType = m_eType*10;
//	if (nType == SURFTYPE_STONE || nType == SURFTYPE_METAL)
//		fVelFactor = 0.75f;

	DFLOAT fVel = 50.0f + fDamage;

	vDir.y -= 1.0f;
	VEC_NORM(vDir);

	VEC_MULSCALAR(vDir, vDir, fVel);

//	ObjectCreateStruct ocStruct;
//	INIT_OBJECTCREATESTRUCT(ocStruct);

	DVector vPos;
	g_pServerDE->GetObjectPos(m_hObject, &vPos);

	if (m_bExploding)
		AddExplosion(vPos);
	
//	VEC_COPY(ocStruct.m_Pos, vPos);
//	g_pServerDE->GetObjectRotation(m_hObject, &ocStruct.m_Rotation);

	DVector vDims;
	g_pServerDE->GetObjectDims( m_hObject, &vDims );

	DDWORD dwCustom = (m_hstrModel1 || m_hstrTexture1 || m_hstrSound) ? TYPEFLAG_CUSTOM : 0;

//	CClientGibFX* pGib;

	if (m_bStone /* && (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct)) */)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_STONE/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_STONE/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bMetal /* && (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct)) */)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_METAL/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_METAL/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bWood /* && (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct)) */)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_WOOD/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_WOOD/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bTerrain /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct)) */)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_TERRAIN/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_TERRAIN/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bPlastic /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_PLASTIC/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_PLASTIC/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bGlass /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_GLASS/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_GLASS/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bFlesh /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_FLESH/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_FLESH/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bLiquid /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_LIQUID/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_LIQUID/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}

	if (m_bEnergy /*&& (pGib = (CClientGibFX*)g_pServerDE->CreateObject(hClass, &ocStruct))*/)
	{
//		pGib->Setup(&vPos, &vDir, &vDims, SURFTYPE_ENERGY/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
//			m_hstrModel1, m_hstrTexture1, m_hstrSound);
		SetupClientGibFX(&vPos, &vDir, &vDims, SURFTYPE_ENERGY/10 | SIZE_SMALL | dwCustom, m_fScale, m_nAmount,
			m_hstrModel1, m_hstrTexture1, m_hstrSound);
	}
}
示例#14
0
void CNodeController::UpdateHeadFollowPosControl(NCSTRUCT *pNodeControl)
{
    LTVector vPos;
    LTRotation rRot;
	LTransform transform;
    LTVector vU, vR, vF;

	//----------------------------------------------------------------------
	// Get information about the control node...
	// *** NOTE: On the head node... vU faces forward, vR faces down, vF faces right ***

	// Get access to the controls...
    ILTMath *pMathLT = g_pLTClient->GetMathLT();
    ILTModel *pModelLT = g_pLTClient->GetModelLT();
    ILTTransform *pTransformLT = g_pLTClient->GetTransformLT();

	// Get the transform of the node we're controlling
    pModelLT->GetNodeTransform(GetCFX()->GetServerObj(), m_aNodes[pNodeControl->eModelNode].hModelNode, transform, LTTRUE);

	// Decompose the transform into the position and rotation
	pTransformLT->Get(transform, vPos, rRot);
	pMathLT->GetRotationVectors(rRot, vR, vU, vF);

	// Get information about the follow position...
    LTVector vObjPos = pNodeControl->vFollowPos;

	// Turn the follow control off if the expire time has past
	if(pNodeControl->fFollowExpireTime <= 0.0f)
	{
		pNodeControl->fFollowExpireTime = 0.0f;
        pNodeControl->bFollowOn = LTFALSE;
	}
	else
        pNodeControl->fFollowExpireTime -= g_pGameClientShell->GetFrameTime();

	//----------------------------------------------------------------------
	// Setup the rotation matrix to directly follow the destination position

	// Get the direction that we're going to face...
    LTVector vDir = vObjPos - vPos;

	// Setup some temp vectors that are on the x/z plane...
    LTVector vTempU, vTempF, vTempDir;
	vTempU = vU; vTempU.y = 0.0f;
	vTempF = vF; vTempF.y = 0.0f;
	vTempDir = vDir; vTempDir.y = 0.0f;

	VEC_NORM(vTempU);
	VEC_NORM(vTempF);
	VEC_NORM(vTempDir);

	// Get the dot products between the dir vector and the up and forward to determine the rotation angles
    LTFLOAT fDotUDir = VEC_DOT(vTempU, vTempDir);
    LTFLOAT fDotFDir = VEC_DOT(vTempF, vTempDir);
    LTFLOAT fDotRDir = 0.0f;

	// Init the vectors to get a rotation matrix from...
    LTVector vRotAxisR(1.0f, 0.0f, 0.0f);

	// Get the first rotation angle
    LTFLOAT fAngle1 = pNodeControl->bFollowOn ? fDotUDir : 1.0f;
	if(fAngle1 < -0.1f) fAngle1 = -0.1f;		// HACK! Limit the head rotation
	fAngle1 = (1.0f - fAngle1) * MATH_HALFPI;
	if(fDotFDir < 0.0f) fAngle1 *= -1.0f;

	// Do a full rotation around the first axis so we can get an angle for the second axis
    LTFLOAT fTempAngle = pNodeControl->bFollowOn ? ((1.0f - fDotUDir) * MATH_HALFPI) : 0.0f;
	pMathLT->RotateAroundAxis(rRot, vR, (fDotFDir < 0.0f) ? -fTempAngle : fTempAngle);
	pMathLT->GetRotationVectors(rRot, vR, vU, vF);

	VEC_NORM(vDir);
	fDotUDir = VEC_DOT(vU, vDir);
	fDotRDir = VEC_DOT(vR, vDir);

	// Get the second rotation angle
    LTFLOAT fAngle2 = pNodeControl->bFollowOn ? fDotUDir : 1.0f;
	if(fAngle2 < 0.25f) fAngle2 = 0.25f;		// HACK! Limit the head rotation
	fAngle2 = (1.0f - fAngle2) * MATH_HALFPI;
	if(fDotRDir > 0.0f) fAngle2 *= -1.0f;

	// Calculate a max rotation value
    LTFLOAT fRotMax = (pNodeControl->fFollowRate * g_pGameClientShell->GetFrameTime() / 180.0f) * MATH_PI;

	// Interpolate the angles based off the previous angle
	if(fAngle1 > pNodeControl->vFollowAngles.y + fRotMax) fAngle1 = pNodeControl->vFollowAngles.y + fRotMax;
	else if(fAngle1 < pNodeControl->vFollowAngles.y - fRotMax) fAngle1 = pNodeControl->vFollowAngles.y - fRotMax;

	if(fAngle2 > pNodeControl->vFollowAngles.x + fRotMax) fAngle2 = pNodeControl->vFollowAngles.x + fRotMax;
	else if(fAngle2 < pNodeControl->vFollowAngles.x - fRotMax) fAngle2 = pNodeControl->vFollowAngles.x - fRotMax;

	// Create a new rotation and rotate around each controlled axis
    LTRotation rNewRot;
    rNewRot.Init();

	pMathLT->RotateAroundAxis(rNewRot, vRotAxisR, fAngle1);
	pNodeControl->vFollowAngles.y = fAngle1;

	pMathLT->GetRotationVectors(rNewRot, vR, vU, vF);

	pMathLT->RotateAroundAxis(rNewRot, vF, fAngle2);
	pNodeControl->vFollowAngles.x = fAngle2;

	// If we're turned off and back at the start rotation... make the control invalid
	if(!pNodeControl->bFollowOn && pNodeControl->vFollowAngles.x == 0.0f && pNodeControl->vFollowAngles.y == 0.0f)
	{
        pNodeControl->bValid = LTFALSE;
		return;
	}

	// Create a rotation matrix and apply it to the current offset matrix
    LTMatrix m1;
	pMathLT->SetupRotationMatrix(m1, rNewRot);
	m_aNodes[pNodeControl->eModelNode].matTransform = m_aNodes[pNodeControl->eModelNode].matTransform * m1;
}
示例#15
0
文件: teigen.c 项目: BRAINSia/teem
int
evals_evecs(double eval[3], double evec[9],
            const double _M00, const double _M01, const double _M02,
            const double _M11, const double _M12,
            const double _M22) {
  double r0[3], r1[3], r2[3], crs[3], len, dot;

  double mean, norm, rnorm, Q, R, QQQ, D, theta,
    M00, M01, M02, M11, M12, M22;
  double epsilon = 1.0E-12;
  int roots;

  /* copy the given matrix elements */
  M00 = _M00;
  M01 = _M01;
  M02 = _M02;
  M11 = _M11;
  M12 = _M12;
  M22 = _M22;

  /*
  ** subtract out the eigenvalue mean (will add back to evals later);
  ** helps with numerical stability
  */
  mean = (M00 + M11 + M22)/3.0;
  M00 -= mean;
  M11 -= mean;
  M22 -= mean;

  /*
  ** divide out L2 norm of eigenvalues (will multiply back later);
  ** this too seems to help with stability
  */
  norm = sqrt(M00*M00 + 2*M01*M01 + 2*M02*M02 +
              M11*M11 + 2*M12*M12 +
              M22*M22);
  rnorm = norm ? 1.0/norm : 1.0;
  M00 *= rnorm;
  M01 *= rnorm;
  M02 *= rnorm;
  M11 *= rnorm;
  M12 *= rnorm;
  M22 *= rnorm;

  /* this code is a mix of prior Teem code and ideas from Eberly's
     "Eigensystems for 3 x 3 Symmetric Matrices (Revisited)" */
  Q = (M01*M01 + M02*M02 + M12*M12 - M00*M11 - M00*M22 - M11*M22)/3.0;
  QQQ = Q*Q*Q;
  R = (M00*M11*M22 + M02*(2*M01*M12 - M02*M11)
       - M00*M12*M12 - M01*M01*M22)/2.0;
  D = QQQ - R*R;
  if (D > epsilon) {
    /* three distinct roots- this is the most common case */
    double mm, ss, cc;
    theta = atan2(sqrt(D), R)/3.0;
    mm = sqrt(Q);
    ss = sin(theta);
    cc = cos(theta);
    eval[0] = 2*mm*cc;
    eval[1] = mm*(-cc + sqrt(3.0)*ss);
    eval[2] = mm*(-cc - sqrt(3.0)*ss);
    roots = ROOT_THREE;
    /* else D is near enough to zero */
  } else if (R < -epsilon || epsilon < R) {
    double U;
    /* one double root and one single root */
    U = airCbrt(R); /* cube root function */
    if (U > 0) {
      eval[0] = 2*U;
      eval[1] = -U;
      eval[2] = -U;
    } else {
      eval[0] = -U;
      eval[1] = -U;
      eval[2] = 2*U;
    }
    roots = ROOT_SINGLE_DOUBLE;
  } else {
    /* a triple root! */
    eval[0] = eval[1] = eval[2] = 0.0;
    roots = ROOT_TRIPLE;
  }

  /* r0, r1, r2 are the vectors we manipulate to
     find the nullspaces of M - lambda*I */
  VEC_SET(r0, 0.0, M01, M02);
  VEC_SET(r1, M01, 0.0, M12);
  VEC_SET(r2, M02, M12, 0.0);
  if (ROOT_THREE == roots) {
    r0[0] = M00 - eval[0]; r1[1] = M11 - eval[0]; r2[2] = M22 - eval[0];
    nullspace1(evec+0, r0, r1, r2);
    r0[0] = M00 - eval[1]; r1[1] = M11 - eval[1]; r2[2] = M22 - eval[1];
    nullspace1(evec+3, r0, r1, r2);
    r0[0] = M00 - eval[2]; r1[1] = M11 - eval[2]; r2[2] = M22 - eval[2];
    nullspace1(evec+6, r0, r1, r2);
  } else if (ROOT_SINGLE_DOUBLE == roots) {
    if (eval[1] == eval[2]) {
      /* one big (eval[0]) , two small (eval[1,2]) */
      r0[0] = M00 - eval[0]; r1[1] = M11 - eval[0]; r2[2] = M22 - eval[0];
      nullspace1(evec+0, r0, r1, r2);
      r0[0] = M00 - eval[1]; r1[1] = M11 - eval[1]; r2[2] = M22 - eval[1];
      nullspace2(evec+3, evec+6, r0, r1, r2);
    }
    else {
      /* two big (eval[0,1]), one small (eval[2]) */
      r0[0] = M00 - eval[0]; r1[1] = M11 - eval[0]; r2[2] = M22 - eval[0];
      nullspace2(evec+0, evec+3, r0, r1, r2);
      r0[0] = M00 - eval[2]; r1[1] = M11 - eval[2]; r2[2] = M22 - eval[2];
      nullspace1(evec+6, r0, r1, r2);
    }
  } else {
    /* ROOT_TRIPLE == roots; use any basis for eigenvectors */
    VEC_SET(evec+0, 1, 0, 0);
    VEC_SET(evec+3, 0, 1, 0);
    VEC_SET(evec+6, 0, 0, 1);
  }
  /* we always make sure its really orthonormal; keeping fixed the
     eigenvector associated with the largest-magnitude eigenvalue */
  if (ABS(eval[0]) > ABS(eval[2])) {
    /* normalize evec+0 but don't move it */
    VEC_NORM(evec+0, len);
    dot = VEC_DOT(evec+0, evec+3); VEC_SCL_SUB(evec+3, dot, evec+0);
    VEC_NORM(evec+3, len);
    dot = VEC_DOT(evec+0, evec+6); VEC_SCL_SUB(evec+6, dot, evec+0);
    dot = VEC_DOT(evec+3, evec+6); VEC_SCL_SUB(evec+6, dot, evec+3);
    VEC_NORM(evec+6, len);
  } else {
    /* normalize evec+6 but don't move it */
    VEC_NORM(evec+6, len);
    dot = VEC_DOT(evec+6, evec+3); VEC_SCL_SUB(evec+3, dot, evec+6);
    VEC_NORM(evec+3, len);
    dot = VEC_DOT(evec+3, evec+0); VEC_SCL_SUB(evec+0, dot, evec+3);
    dot = VEC_DOT(evec+6, evec+0); VEC_SCL_SUB(evec+0, dot, evec+6);
    VEC_NORM(evec+0, len);
  }

  /* to be nice, make it right-handed */
  VEC_CROSS(crs, evec+0, evec+3);
  if (0 > VEC_DOT(crs, evec+6)) {
    VEC_SCL(evec+6, -1);
  }

  /* multiply back by eigenvalue L2 norm */
  eval[0] /= rnorm;
  eval[1] /= rnorm;
  eval[2] /= rnorm;

  /* add back in the eigenvalue mean */
  eval[0] += mean;
  eval[1] += mean;
  eval[2] += mean;

  return roots;
}
示例#16
0
void CProjectile::AddImpact(DVector vPoint, DVector vNormal, HOBJECT hObj)
{
	// Compute a normal vector
	// Cast a ray to see what we hit
	DVector		tempPos;

	IntersectQuery iq;
	IntersectInfo  ii;
	SurfaceType eType = SURFTYPE_UNKNOWN;
	DBYTE nFX = 0;

	VEC_NORM(m_vDir);
	VEC_MULSCALAR(m_vDir, m_vDir, 2.0f);
	VEC_SUB(iq.m_From, vPoint, m_vDir);
	VEC_MULSCALAR(m_vDir, m_vDir, 10.0f);
	VEC_ADD(iq.m_To, vPoint, m_vDir);
	iq.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;
	iq.m_FilterFn = NULL;
	iq.m_pUserData = NULL;	

	if (hObj && g_pServerDE->IntersectSegment(&iq, &ii))
	{
		VEC_COPY(vNormal, ii.m_Plane.m_Normal);
		eType = GetSurfaceType(ii.m_hObject, ii.m_hPoly);

		VEC_COPY(tempPos, ii.m_Point);
	}
	else	// Fake it
	{
		VEC_NEGATE(vNormal, m_vDir);

		VEC_COPY(tempPos, vPoint);
	}

	if(m_bExplosion) 
	{
		AddExplosion(tempPos, vNormal);
		nFX |= WFX_SCREENSHAKE;
	}

	if(m_bClientFX)
	{
		CServerDE* pServerDE = BaseClass::GetServerDE();
		if (!pServerDE) return;

/*		ObjectCreateStruct theStruct;
		INIT_OBJECTCREATESTRUCT(theStruct);

		VEC_COPY(theStruct.m_Pos, vPoint);

		HCLASS hClass = pServerDE->GetClass("CClientWeaponSFX");

		CClientWeaponSFX *pWeaponFX = DNULL;

		if(hClass)
			pWeaponFX = (CClientWeaponSFX*)pServerDE->CreateObject(hClass, &theStruct);
*/
		DDWORD	nFX = WFX_SCREENSHAKE;
		DDWORD	nExtras = WFX_EXTRA_DAMAGE;
		WeaponFXExtras	ext;
		ext.fDamage = m_fDamage;

//		if(pWeaponFX)
		SendWeaponSFXMessage(&vPoint, &vPoint, &vNormal, &vNormal, nFX, nExtras, &ext);
	}
}
示例#17
0
DBOOL CRainFX::Update()
{
	if (!m_hObject || !m_pClientDE) return DFALSE;

	DFLOAT fTime = m_pClientDE->GetTime();

	if (m_bFirstUpdate)
	{
		m_fLastTime = m_pClientDE->GetTime();

		m_bFirstUpdate = DFALSE;
		return DTRUE;
	}


	// Make sure it is time to update...

	if (fTime < m_fLastTime + m_fNextUpdate)
	{
		return DTRUE;
	}

	//set our new position based on the server object
	if(m_hServerObject)
	{
		DVector vPos,vUp,vRight;
		m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
		m_pClientDE->SetObjectPos(m_hObject,&vPos);

		DRotation rRot;
		m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
		m_pClientDE->SetObjectRotation(m_hObject,&rRot);
		m_pClientDE->GetRotationVectors(&rRot,&vUp,&vRight,&m_vDirection);
	}
	else
		return DFALSE;

	// Total time it's been active...

	m_fTimeLen += fTime - m_fLastTime;
	m_fLastTime = fTime;

	//SCHLEGZ 5/1/98 7:07:33 PM: added time limit to the rain effect itself
	if(m_fTimeLimit && m_fTimeLen > m_fTimeLimit)
	{
		WantRemove();
		return DFALSE;
	}


	// How much time it's accounted for by adding particles...

	DFLOAT fAddedTime = m_nParticlesAdded / m_fAreaDensity;


	// Ok, how many to add this frame....

	int nToAdd = (int) floor( m_fAreaDensity * (m_fTimeLen - fAddedTime) );
	m_nParticlesAdded += nToAdd;

	DVector vel, vOffset;
	DBOOL bAddTrails = DFALSE;

	VEC_COPY(vel, m_vDirection);

	if (vel.x == 0.0f && vel.y == 0.0f && vel.z == 0.0f)
		vel.y = -1.0f;
	VEC_COPY(vOffset, vel);
	VEC_NORM(vOffset);
	bAddTrails = (!m_bGravity || (vel.x == 0 && vel.z == 0 && m_fSpread == 0));

	if (!bAddTrails) nToAdd *= 6;

	for(int i=0; i < nToAdd; i++)
	{
		DVector vPos, vTmp, vTmpVel;

		vPos.x = GetRandom(-m_vDims.x, m_vDims.x);
		vPos.y = GetRandom(-m_vDims.y, m_vDims.y);
		vPos.z = GetRandom(-m_vDims.z, m_vDims.z);
		VEC_MULSCALAR(vTmpVel, vel, GetRandom(0.8f, 1.2f));

		if (m_fSpread)
		{
			DFLOAT fOffset = GetRandom(-m_fSpread, m_fSpread);

			vTmpVel.x += fOffset;

			fOffset = GetRandom(-m_fSpread, m_fSpread);
			vTmpVel.z += fOffset;
		}

		// Add the particles
		if (bAddTrails)
		{
			// Set up colors for particle stream
			DVector vPartColors[6];
			vPartColors[0].x  = GetRandom(m_vColor1.x, m_vColor2.x);
			vPartColors[0].y  = GetRandom(m_vColor1.y, m_vColor2.y);
			vPartColors[0].z  = GetRandom(m_vColor1.z, m_vColor2.z);
			VEC_MULSCALAR(vPartColors[1], vPartColors[0], 0.8f);
			VEC_MULSCALAR(vPartColors[2], vPartColors[0], 0.6f);
			VEC_MULSCALAR(vPartColors[3], vPartColors[0], 0.4f);
			VEC_MULSCALAR(vPartColors[4], vPartColors[0], 0.2f);
			VEC_MULSCALAR(vPartColors[5], vPartColors[0], 0.2f);
			
			m_pClientDE->AddParticle(m_hObject, &vPos, &vTmpVel, &vPartColors[0], m_fLifetime);
			VEC_MULSCALAR(vTmp, vOffset, -3.0f);
			VEC_ADD(vPos, vPos, vTmp);
			m_pClientDE->AddParticle(m_hObject, &vPos, &vTmpVel, &vPartColors[1], m_fLifetime);
			VEC_MULSCALAR(vTmp, vOffset, -4.0f);
			VEC_ADD(vPos, vPos, vTmp);
			m_pClientDE->AddParticle(m_hObject, &vPos, &vTmpVel, &vPartColors[2], m_fLifetime);
			VEC_MULSCALAR(vTmp, vOffset, -5.0f);
			VEC_ADD(vPos, vPos, vTmp);
			m_pClientDE->AddParticle(m_hObject, &vPos, &vTmpVel, &vPartColors[3], m_fLifetime);
			VEC_MULSCALAR(vTmp, vOffset, -6.0f);
			VEC_ADD(vPos, vPos, vTmp);
			m_pClientDE->AddParticle(m_hObject, &vPos, &vTmpVel, &vPartColors[4], m_fLifetime);
			VEC_MULSCALAR(vTmp, vOffset, -7.0f);
			VEC_ADD(vPos, vPos, vTmp);
			m_pClientDE->AddParticle(m_hObject, &vPos, &vTmpVel, &vPartColors[5], m_fLifetime);
		}
		else
		{
			DVector vPartColor;
			vPartColor.x  = GetRandom(m_vColor1.x, m_vColor2.x);
			vPartColor.y  = GetRandom(m_vColor1.y, m_vColor2.y);
			vPartColor.z  = GetRandom(m_vColor1.z, m_vColor2.z);
			m_pClientDE->AddParticle(m_hObject, &vPos, &vTmpVel, &vPartColor, m_fLifetime);
		}
	}

	// Determine when next update should occur...

	if (m_cs.fPulse > 0.001f) 
	{
		m_fNextUpdate = m_cs.fPulse * GetRandom(0.01f, 1.0f);
	}
	else 
	{
		m_fNextUpdate = 0.01f;
	}

	return DTRUE;
}
示例#18
0
DBOOL CCastLineFX::Update()
{
	if(!m_hObject || !m_pClientDE || !m_hServerObject) return DFALSE;

	if (m_bWantRemove)
	{
		return DFALSE;
	}

	DRotation rRot;
	m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
	m_pClientDE->SetObjectRotation(m_hObject, &rRot);
	
	DVector vPos;
	m_pClientDE->GetObjectPos(m_hServerObject, &vPos);
	m_pClientDE->SetObjectPos(m_hObject, &vPos);


	if (m_bFirstUpdate)
	{
		m_bFirstUpdate = DFALSE;

		DELine line;

		// Set first vertex...	

		VEC_SET(line.m_Points[0].m_Pos, 0.0f, 0.0f, 0.0f);
		line.m_Points[0].r = m_vStartColor.x;
		line.m_Points[0].g = m_vStartColor.y;
		line.m_Points[0].b = m_vStartColor.z;
		line.m_Points[0].a = m_fStartAlpha;

		// Set second vertex (cast a ray to find it)...

		DVector vEndPoint, vU, vR, vF;
		m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
		VEC_NORM(vF);

		DFLOAT fDistance = 10000.0f;  // Far, far, away...

		if (!m_hCastTo)
		{
			ClientIntersectQuery iQuery;
			ClientIntersectInfo  iInfo;

			VEC_COPY(iQuery.m_From, vPos);
			VEC_COPY(iQuery.m_Direction, vF);
			iQuery.m_Flags = INTERSECT_OBJECTS | IGNORE_NONSOLID;

			if (m_pClientDE->CastRay(&iQuery, &iInfo))
			{		
				VEC_COPY(vEndPoint, iInfo.m_Point);

				fDistance = VEC_MAG(vEndPoint);
			}
		}
		else
		{
			m_pClientDE->GetObjectPos(m_hCastTo, &vEndPoint);
			VEC_SUB(vEndPoint, vEndPoint, vPos);
			fDistance = VEC_MAG(vEndPoint);
		}

		VEC_SET(vEndPoint, 0.0f, 0.0f, 1.0f);
		VEC_MULSCALAR(vEndPoint, vEndPoint, fDistance);

		VEC_COPY(line.m_Points[1].m_Pos, vEndPoint);
		line.m_Points[1].r = m_vEndColor.x;
		line.m_Points[1].g = m_vEndColor.y;
		line.m_Points[1].b = m_vEndColor.z;
		line.m_Points[1].a = m_fEndAlpha;

		m_pClientDE->AddLine(m_hObject, &line);
	}

	return DTRUE;
}
示例#19
0
void SoccerBall::Update( )
{
	DVector vVel, vAccel, vAccelAdd, vPos, vForward, vCross, vTemp, vTemp2;
	CollisionInfo collInfo;
	float fVelMag, fDistTraveled, fTime, fRotAmount, fExp;
	DRotation rRot;

	g_pServerDE->GetObjectPos( m_hObject, &vPos );
	g_pServerDE->GetVelocity( m_hObject, &vVel );
	fVelMag = VEC_MAG( vVel );
	fTime = g_pServerDE->GetTime( );

	// Remove the ball if it's been sitting around for a while.
	if( fTime > m_fRespawnTime )
	{
		g_pServerDE->RemoveObject( m_hObject );
		return;
	}

	// Update the on ground info
	g_pServerDE->GetStandingOn( m_hObject, &collInfo );
	m_bOnGround = ( collInfo.m_hObject ) ? DTRUE : DFALSE;
	if( m_bOnGround )
	{
		m_fLastTimeOnGround = fTime;
	}

	// Get how far we've traveled.
	VEC_SUB( vForward, vPos, m_vLastPos );
	fDistTraveled = VEC_MAG( vForward );
	VEC_COPY( m_vLastPos, vPos );

	// Rotate the ball
	if( fDistTraveled > 0.0f )
	{
		VEC_MULSCALAR( vForward, vForward, 1.0f / fDistTraveled );

		if( m_bOnGround )
		{
			VEC_COPY( m_vLastNormal, collInfo.m_Plane.m_Normal );
			VEC_CROSS( vCross, vForward, m_vLastNormal );
			fRotAmount = VEC_MAG( vCross ) * fDistTraveled / m_fRadius;
		}
		else
		{
			VEC_CROSS( vCross, vForward, m_vLastNormal );
			fRotAmount = VEC_MAG( vCross ) * fDistTraveled / m_fRadius;
		}

		if( fRotAmount > 0.0f )
		{
			VEC_NORM( vCross );
			g_pServerDE->GetObjectRotation( m_hObject, &rRot );
			g_pServerDE->RotateAroundAxis( &rRot, &vCross, fRotAmount );
			g_pServerDE->SetObjectRotation( m_hObject, &rRot );
		}
	}

	// Adjust the velocity and accel
	if( fVelMag < MINBALLVEL )
	{
		VEC_INIT( vVel );
		g_pServerDE->SetVelocity( m_hObject, &vVel );
	}
	else if( fVelMag > MAXBALLVEL )
	{
		VEC_MULSCALAR( vVel, vVel, MAXBALLVEL / fVelMag );				
		g_pServerDE->SetVelocity( m_hObject, &vVel );
	}
	else
	{
		// new velocity is given by:		v = ( a / k ) + ( v_0 - a / k ) * exp( -k * t )
		g_pServerDE->GetAcceleration( m_hObject, &vAccel );
		fExp = ( float )exp( -BALLDRAG * g_pServerDE->GetFrameTime( ));
		VEC_DIVSCALAR( vTemp, vAccel, BALLDRAG );
		VEC_SUB( vTemp2, vVel, vTemp );
		VEC_MULSCALAR( vTemp2, vTemp2, fExp );
		VEC_ADD( vVel, vTemp2, vTemp );
		g_pServerDE->SetVelocity( m_hObject, &vVel );
	}

	// Make sure we're rolling if we're on a slope.  This counteracts the way the
	// engine stops objects on slopes.
	if( m_bOnGround )
	{
		if( collInfo.m_Plane.m_Normal.y < 0.9f && fabs( vVel.y ) < 50.0f )
		{
			g_pServerDE->GetGlobalForce( &vAccelAdd );
			vAccel.y += vAccelAdd.y * 0.5f;
			g_pServerDE->SetAcceleration( m_hObject, &vAccel );
		}
	}

	// Play a bounce sound if enough time has elapsed
	if( m_bBounced )
	{
		if( fTime > m_fLastBounceTime + TIMEBETWEENBOUNCESOUNDS )
		{
			// Play a bounce sound...
			PlaySoundFromPos( &vPos, "Sounds_ao\\events\\soccerball.wav", 750, SOUNDPRIORITY_MISC_MEDIUM );
		}

		m_bBounced = DFALSE;
	}

	g_pServerDE->SetNextUpdate( m_hObject, 0.001f );
}
示例#20
0
DBOOL CParticleStreamFX::AddParticles()
{
	if(!m_hObject || !m_pClientDE) return DFALSE;

	DVector		minOffset, maxOffset;
	DFLOAT		minVel, maxVel;
	DFLOAT		minLife, maxLife;
	DFLOAT		spread;
	DFLOAT		ratio, time = m_pClientDE->GetTime();
	DDWORD		num;

	if(!m_bState)	return	DTRUE;

	num = m_nNumParticles;
	VEC_SET(minOffset, -m_fPosRadius, -m_fPosRadius, -m_fPosRadius);
	VEC_SET(maxOffset, m_fPosRadius, m_fPosRadius, m_fPosRadius);
	minVel = m_fMinVel;
	maxVel = m_fMaxVel;
	minLife = m_fMinLife;
	maxLife = m_fMaxLife;
	spread = m_fSpread;

	if((m_bState == 1) || (m_bState == 3))
	{
		// Set the ratio to ramp the values with
		if(m_bState == 1)
		{
			ratio = (time - m_fTriggerTime) / m_fRampTime;
			if(ratio >= 1.0f)
				{ ratio = 1.0f; m_bState = 2; }
		}
		else
		{
			ratio = 1.0f - ((time - m_fTriggerTime) / m_fRampTime);
			if(ratio <= 0.0f)
				{ ratio = 0.0f; m_bState = 0; return DTRUE; }
		}

		// Check which elements of the stream we should ramp... and calculate new values
		if(m_bRampFlags & PSTREAM_RAMP_NUM)
			num = (DDWORD)(num * ratio);

		if(m_bRampFlags & PSTREAM_RAMP_OFFSET)
		{
			VEC_MULSCALAR(minOffset, minOffset, ratio);
			VEC_MULSCALAR(maxOffset, maxOffset, ratio);
		}

		if(m_bRampFlags & PSTREAM_RAMP_VEL)
		{
			minVel *= ratio;
			maxVel *= ratio;
			spread *= ratio;
		}

		if(m_bRampFlags & PSTREAM_RAMP_LIFE)
		{
			minLife *= ratio;
			maxLife *= ratio;
		}
	}

	// Add the particles one by one... (instead of AddParticles... cause I wanted the spread)
	for(DDWORD i = 0; i < num; i++)
	{
		DVector		pos, vel, vSpread, color;
		DFLOAT		life = GetRandom(minLife, maxLife);

		VEC_SET(pos, GetRandom(minOffset.x, maxOffset.x), GetRandom(minOffset.y, maxOffset.y), GetRandom(minOffset.z, maxOffset.z));
		VEC_SET(vSpread, GetRandom(-spread, spread), GetRandom(-spread, spread), GetRandom(-spread, spread));
		VEC_MULSCALAR(vel, m_vDir, maxVel);
		VEC_ADD(vel, vel, vSpread);
		VEC_NORM(vel);
		VEC_MULSCALAR(vel, vel, GetRandom(minVel, maxVel));

		GetRandomColorInRange(color);

		m_pClientDE->AddParticle(m_hObject, &pos, &vel, &color, life);
	}

	// Make sure we know when the last batch of particles were added
	m_fLastAddTime = time;
	return DTRUE;
}
示例#21
0
DVector	CPlayerCamera::FindOptimalCameraPosition()
{
	DVector pos;
	VEC_INIT(pos);

	if (!m_pClientDE || !m_hTarget) return pos;

	DVector		up, right, forward, dir;
	DFLOAT		distToOptimal;
	DVector		TargetPlusOffset;
	
	DVector vTargetPos;
	m_pClientDE->GetObjectPos(m_hTarget, &vTargetPos);

	DRotation rRot;
	m_pClientDE->GetObjectRotation(m_hTarget, &rRot);

	if (Equal(vTargetPos, m_vLastTargetPos) && Equal(rRot, m_rLastTargetRot) && m_eCameraMode != DEATH)
	{
		return m_vLastOptPos;
	}
	else
	{
		VEC_COPY(m_vLastTargetPos, vTargetPos);
		ROT_COPY(m_rLastTargetRot, rRot);
	}
		
	DVector vTemp;

	if (m_eCameraMode == DEATH)
	{
		VEC_COPY(vTemp, m_TargetDeathOffset);
	}
	else
	{
		VEC_COPY(vTemp, m_TargetChaseOffset);
	}
	VEC_ADD(vTemp, vTargetPos, vTemp);
	VEC_COPY(TargetPlusOffset, vTemp);

	m_pClientDE->GetRotationVectors(&rRot, &up, &right, &forward);

	//	pos = TargetPlusOffset + right*m_OptX + up*m_OptY + forward*m_OptZ;
	
	DVector vTemp1, vTemp2;
	if (m_eCameraMode == DEATH)
	{
		VEC_MULSCALAR(vTemp, right, m_DeathOptX);
		VEC_MULSCALAR(vTemp2, forward, m_DeathOptZ);
	}
	else
	{
		VEC_MULSCALAR(vTemp, right, m_OptX);
		VEC_MULSCALAR(vTemp2, forward, m_OptZ);
	}
	VEC_MULSCALAR(vTemp1, up, m_OptY);

	ClientIntersectQuery iQuery;
	ClientIntersectInfo  iInfo;

	VEC_ADD(vTemp, vTemp, vTemp1);
	VEC_ADD(vTemp, vTemp, vTemp2);
	VEC_ADD(pos, TargetPlusOffset, vTemp);

	VEC_SUB(vTemp, TargetPlusOffset, pos);
	distToOptimal = VEC_MAG(vTemp);

	VEC_SUB(dir, pos, TargetPlusOffset);
	VEC_NORM(dir);

	VEC_COPY(iQuery.m_From, TargetPlusOffset);
	VEC_COPY(iQuery.m_To, pos);

	if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
	{		
		VEC_SUB(vTemp, iInfo.m_Point, TargetPlusOffset);

		// If there was something in the way, move in front of that thing.
		if (VEC_MAG(vTemp) < distToOptimal)
		{
			VEC_ADD(pos, iInfo.m_Point, iInfo.m_Plane.m_Normal);
		}
	}

#ifdef DOING_EXTRA_CHECKS

	// Make sure we aren't clipping into walls...
	
	DFLOAT fClipDistance	= 100.0f; // 15.0f;
	DBOOL bClipRightIssues	= DTRUE;
	DBOOL bClipUpIssues		= DTRUE;


	// Check for walls to the right...

	VEC_MULSCALAR(vTemp, right, fClipDistance);
	VEC_ADD(vTemp, pos, vTemp);

	VEC_COPY(iQuery.m_From, pos);
	VEC_COPY(iQuery.m_To, vTemp);

	if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
	{
		VEC_SUB(vTemp, iInfo.m_Point, pos);
		DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));

		VEC_MULSCALAR(vTemp, right, -fDist)
		VEC_ADD(pos, pos, vTemp);
	}
	else
	{
		bClipRightIssues = DFALSE;
	}


	// If we didn't adjust for a wall to the right, check walls to the left...

	if (!bClipRightIssues)
	{
		VEC_MULSCALAR(vTemp, right, -fClipDistance);
		VEC_ADD(vTemp, pos, vTemp);

		VEC_COPY(iQuery.m_From, pos);
		VEC_COPY(iQuery.m_To, vTemp);

		if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
		{
			VEC_SUB(vTemp, iInfo.m_Point, pos);
			DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));

			VEC_MULSCALAR(vTemp, right, fDist)
			VEC_ADD(pos, pos, vTemp);
		}
	}
			

	// Check for ceilings...

	VEC_MULSCALAR(vTemp, up, fClipDistance);
	VEC_ADD(vTemp, pos, vTemp);

	VEC_COPY(iQuery.m_From, pos);
	VEC_COPY(iQuery.m_To, vTemp);

	if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
	{
		VEC_SUB(vTemp, iInfo.m_Point, pos);
		DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));

		VEC_MULSCALAR(vTemp, up, -fDist)
		VEC_ADD(pos, pos, vTemp);
	}
	else
	{
		bClipUpIssues = DFALSE;
	}


	// If we didn't hit any ceilings, check for floors...

	if (!bClipUpIssues)
	{
		VEC_MULSCALAR(vTemp, up, -fClipDistance);
		VEC_ADD(vTemp, pos, vTemp);

		VEC_COPY(iQuery.m_From, pos);
		VEC_COPY(iQuery.m_To, vTemp);

		if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
		{
			VEC_SUB(vTemp, iInfo.m_Point, pos);
			DFLOAT fDist = (fClipDistance - VEC_MAG(vTemp));

			VEC_MULSCALAR(vTemp, up, fDist)
			VEC_ADD(pos, pos, vTemp);
		}
	}
#endif  // DOING_EXTRA_CHECKS 

	VEC_COPY(m_vLastOptPos, pos);
	return pos;
}
示例#22
0
void VolumeBrush::UpdatePhysics(ContainerPhysics* pCPStruct)
{
	if (m_bHidden || !pCPStruct || !pCPStruct->m_hObject) return;

    LTFLOAT fUpdateDelta = g_pLTServer->GetFrameTime();


	// Let the character know if they are in liquid...

	if (IsLiquid(m_eContainerCode) && IsCharacter(pCPStruct->m_hObject))
	{
        CCharacter* pCharacter = (CCharacter*)g_pLTServer->HandleToObject(pCPStruct->m_hObject);
		if (pCharacter)
		{
			pCharacter->UpdateInLiquid(this, pCPStruct);
		}
	}


	// Player container physics is done on the client...

	if (!IsPlayer(pCPStruct->m_hObject))
	{
		// Dampen velocity based on the viscosity of the container...

        LTVector vVel, vCurVel;
		vVel = vCurVel = pCPStruct->m_Velocity;

		if (m_fViscosity > 0.0f && VEC_MAG(vCurVel) > 1.0f)
		{
            LTVector vDir;
			VEC_COPY(vDir, vCurVel);
			VEC_NORM(vDir);

            LTFLOAT fAdjust = MAX_CONTAINER_VISCOSITY * m_fViscosity * fUpdateDelta;

			vVel = (vDir * fAdjust);

			if (VEC_MAG(vVel) < VEC_MAG(vCurVel))
			{
				VEC_SUB(vVel, vCurVel, vVel);
			}
			else
			{
				VEC_INIT(vVel);
			}

			vVel += (m_vCurrent * fUpdateDelta);

			pCPStruct->m_Velocity = vVel;
		}


		// Do special liquid handling...

		if (IsLiquid(m_eContainerCode))
		{
			UpdateLiquidPhysics(pCPStruct);
		}
	}


	// Update damage...

	// Make damage relative to update delta...

    LTFLOAT fDamage = 0.0f;
	if (m_fDamage > 0.0f)
	{
		fDamage = m_fDamage * fUpdateDelta;
	}

	// Damage using progressive damage.  This insures that the correct
	// damage effect is shown on the client...

	if (fDamage)
	{
		DamageStruct damage;

		damage.eType	  = m_eDamageType;
		damage.fDamage	  = fDamage;
		damage.hDamager   = m_hObject;

		// Use progressive damage...
		damage.fDuration  = 0.25f;
		damage.hContainer = m_hObject;

		damage.DoDamage(this, pCPStruct->m_hObject);
	}
}