Exemplo n.º 1
0
/*
** All the three given vectors span only a 2D space, and this finds
** the normal to that plane.  Simply sums up all the pair-wise
** cross-products to get a good estimate.  Trick is getting the cross
** products to line up before summing.
*/
void
nullspace1(double ret[3],
           const double r0[3], const double r1[3], const double r2[3]) {
  double crs[3];

  /* ret = r0 x r1 */
  VEC_CROSS(ret, r0, r1);
  /* crs = r1 x r2 */
  VEC_CROSS(crs, r1, r2);
  /* ret += crs or ret -= crs; whichever makes ret longer */
  if (VEC_DOT(ret, crs) > 0) {
    VEC_ADD(ret, crs);
  } else {
    VEC_SUB(ret, crs);
  }
  /* crs = r0 x r2 */
  VEC_CROSS(crs, r0, r2);
  /* ret += crs or ret -= crs; whichever makes ret longer */
  if (VEC_DOT(ret, crs) > 0) {
    VEC_ADD(ret, crs);
  } else {
    VEC_SUB(ret, crs);
  }

  return;
}
Exemplo n.º 2
0
BOOL hit_geo_sphere (GEO *Generic, RAY *Ray, HIT *Hit, PAIR *Bound, void *Info)
{
  GEO_SPHERE  *Geo;
  VECTOR      Point;
  REAL        a, b, Distance, Delta;

  Geo = (GEO_SPHERE *) Generic;

  VEC_SUB (Point, Ray->Point, Geo->Point);
  a = - VEC_DOT (Point, Ray->Vector);
  b = VEC_DOT (Point, Point);
  Delta = a * a - b + Geo->Radius * Geo->Radius;
  if (Delta < 0.0)
    return (FALSE);

  Delta = sqrt (Delta);
  Distance = a - Delta;   /* - Epsilon;*/
  if (Distance < Bound->u || Distance > Bound->v)
    return (FALSE);

  if (Hit) {
    Ray->Distance = Distance;
    VEC_LIN (Point, Ray->Point, Distance, Ray->Vector);
    VEC_SUB (Hit->Normal, Point, Geo->Point);
    if (VEC_DOT (Ray->Vector, Hit->Normal) > 0.0)
      VEC_NEG (Hit->Normal);
    VEC_UNIT (Hit->Normal, Distance);
    VEC_LIN (Hit->Point, Point, Epsilon, Hit->Normal);
    xyz2uv_geo_sphere (Geo, Hit);
  }

  return (TRUE);
}
Exemplo n.º 3
0
/*****************************************
 * Read nappe characterization in a file *
 *****************************************/
GEO *
file_geo_nappe (BYTE Type, FILE *File)
{
  GEO_NAPPE  *Geo;
  PNT        *Pnt, *PntA, *PntB, *PntC, *PntD;
  FCT        *Fct;
  VECTOR     U, V;
  REAL       Real;
  INDEX      Index;

  INIT_MEM (Geo, 1, GEO_NAPPE);
  Geo->Type = Type;
  GET_INDEX (Geo->NbrPnt);
  INIT_MEM (Geo->TabPnt, Geo->NbrPnt, PNT);
  GET_INDEX (Geo->NbrFct);
  INIT_MEM (Geo->TabFct, Geo->NbrFct, FCT);
  Geo->Min.x = Geo->Min.y = Geo->Min.z =  INFINITY;
  Geo->Max.x = Geo->Max.y = Geo->Max.z = -INFINITY;

  for (Index = 0, Pnt = Geo->TabPnt; Index < Geo->NbrPnt; Index++, Pnt++) {
    GET_VECTOR (Pnt->Point);
    VEC_MIN (Geo->Min, Pnt->Point);
    VEC_MAX (Geo->Max, Pnt->Point);
  }

  for (Index = 0, Fct = Geo->TabFct; Index < Geo->NbrFct; Index++, Fct++) {
    if (fscanf (File, " ( %d %d %d %d )", &Fct->i, &Fct->j, &Fct->k, &Fct->l) < 4)
      return (FALSE);
    Fct->NumFct = Index;
    PntA = Geo->TabPnt + Fct->i; 
    PntB = Geo->TabPnt + Fct->j;
    PntC = Geo->TabPnt + Fct->k;
    PntD = Geo->TabPnt + Fct->l;
    VEC_SUB (U, PntC->Point, PntA->Point);
    VEC_SUB (V, PntD->Point, PntB->Point);
    VEC_CROSS (Fct->Normal, U, V);
    VEC_UNIT (Fct->Normal, Real);
    VEC_INC (PntA->Normal, Fct->Normal);
    VEC_INC (PntB->Normal, Fct->Normal);
    VEC_INC (PntC->Normal, Fct->Normal);
    VEC_INC (PntD->Normal, Fct->Normal);
  }

  for (Index = 0, Pnt = Geo->TabPnt; Index < Geo->NbrPnt; Index++, Pnt++)
    VEC_UNIT (Pnt->Normal, Real);

  return ((GEO *) Geo);
}
Exemplo n.º 4
0
/*************************************************
 * Transform uv-coordinates into xyz-coordinates *
 *************************************************/
static void uv2xyz_geo_nappe (GEO *Generic, REAL U, REAL V, VECTOR *Point,
			      VECTOR * Normal, VECTOR *Tangent)
{
    GEO_NAPPE   *Geo;
    INDEX       Num;
    PNT         *A, *B, *C, *D;
    REAL        Real;

    Geo = (GEO_NAPPE *) Generic;

    
    Num = (INDEX) (U * Geo->NbrFct);
    if (Num == Geo->NbrFct)
        Num -= 1;

    A = &(Geo->TabPnt[(Geo->TabFct[Num]).i]);
    B = &(Geo->TabPnt[(Geo->TabFct[Num]).j]);
    C = &(Geo->TabPnt[(Geo->TabFct[Num]).k]);
    D = &(Geo->TabPnt[(Geo->TabFct[Num]).l]);

    VEC_UV (*Point, U, V, A->Point, B->Point, C->Point, D->Point);

    if (Normal != NULL)
    {
        VEC_UV (*Normal, U, V, A->Normal, B->Normal, C->Normal, D->Normal);
        /* or *Normal = (Geo->TabFct[Num]).Normal without any interpolation */
        VEC_UNIT (*Normal, Real);
    }

    if (Tangent != NULL)
    {
        VEC_SUB (*Tangent, (*C).Point, (*A).Point);
        VEC_UNIT (*Tangent, Real);
    }
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
BOOL IsPolyInsideSurface(CTempSurface *pSurface, CPrePoly *pPoly)
{
	DWORD i, j;
	CEditPoly *pEditPoly;
	CPrePlane edgePlane;
	PVector vTemp, testPt;
	
	pEditPoly = pSurface->m_pPoly;
	for(i=0; i < pEditPoly->NumVerts(); i++)
	{
		VEC_SUB(vTemp, pEditPoly->NextPt(i), pEditPoly->Pt(i));
		VEC_CROSS(edgePlane.m_Normal, vTemp, pEditPoly->Normal());
		edgePlane.m_Normal.Norm();
		edgePlane.m_Dist = VEC_DOT(edgePlane.m_Normal, pEditPoly->Pt(i));

		for(j=0; j < pPoly->NumVerts(); j++)
		{
			testPt = pPoly->Pt(j);

			if(DIST_TO_PLANE(testPt, edgePlane) < -0.1f)
			{
				return FALSE;
			}
		}
	}

	return TRUE;
}
Exemplo n.º 7
0
/*************************************************
 * Transform uv-coordinates into xyz-coordinates *
 *************************************************/
static void uv2xyz_geo_sphere (GEO *Generic, REAL U, REAL V, VECTOR *Point,
			       VECTOR * Normal, VECTOR *Tangent)
{
    GEO_SPHERE   *Geo;
    REAL         CosPnt, SinPnt;
    REAL         r, Real;

    Geo = (GEO_SPHERE *) Generic;

    CosPnt = cos(2.0*PI*U);
    SinPnt = sin(2.0*PI*U);
    r = 2.0 * Geo->Radius * sqrt(V*(1.0-V));
    Point->x = Geo->Point.x + r * CosPnt;
    Point->y = Geo->Point.y + r * SinPnt;
    Point->z = Geo->Point.z + Geo->Radius * (2.0*V-1);

    if (Normal != NULL)
    {
        VEC_SUB (*Normal, *Point, Geo->Point);
	VEC_UNIT (*Normal, Real);
    }

    if (Tangent != NULL)
    {
        VEC_MAKE (*Tangent, -SinPnt, CosPnt, 0.0);
    }
}
Exemplo n.º 8
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);
*/
}
Exemplo n.º 9
0
/*
** assign Epsilon
*/
void
assign_epsilon (void)
{
    VECTOR Vector;

    VEC_SUB (Vector, MainBnd->Max, MainBnd->Min);
    Epsilon = MINMIN (Vector.x, Vector.y, Vector.z) * EPSILON/3.0;
    /*Epsilon = EPSILON;*/
}
Exemplo n.º 10
0
/*
** All vectors are in the same 1D space, we have to find two
** mutually vectors perpendicular to that span
*/
void
nullspace2(double reta[3], double retb[3],
           const double r0[3], const double r1[3], const double r2[3]) {
  double sqr[3], sum[3];
  int idx;

  VEC_COPY(sum, r0);
  if (VEC_DOT(sum, r1) > 0) {
    VEC_ADD(sum, r1);
  } else {
    VEC_SUB(sum, r1);
  }
  if (VEC_DOT(sum, r2) > 0) {
    VEC_ADD(sum, r2);
  } else {
    VEC_SUB(sum, r2);
  }
  /* find largest component, to get most stable expression for a
     perpendicular vector */
  sqr[0] = sum[0]*sum[0];
  sqr[1] = sum[1]*sum[1];
  sqr[2] = sum[2]*sum[2];
  idx = 0;
  if (sqr[0] < sqr[1])
    idx = 1;
  if (sqr[idx] < sqr[2])
    idx = 2;
  /* reta will be perpendicular to sum */
  if (0 == idx) {
    VEC_SET(reta, sum[1] - sum[2], -sum[0], sum[0]);
  } else if (1 == idx) {
    VEC_SET(reta, -sum[1], sum[0] - sum[2], sum[1]);
  } else {
    VEC_SET(reta, -sum[2], sum[2], sum[0] - sum[1]);
  }
  /* and now retb will be perpendicular to both reta and sum */
  VEC_CROSS(retb, reta, sum);
  return;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
DBOOL CameraObj::Update()
{
	if (!g_pServerDE) return DFALSE;

   	g_pServerDE->SetNextUpdate(m_hObject, 0.01f);

// Need to check if Camera has Moved...

// If so, we need to change the Line...
// and Send new camera position
//
// Might have to send a pan up, pan down, pan direction, because of client/server slow down.
// That way all the updates are done on the client.

//    if (g_pServerDE->GetVarValueFloat(g_pServerDE->GetGameConVar("DebugCutScene")) == 1.0f)
//    {
//        DisplayRay();
//    }

    // If we are linked then check to make sure the Link has not moved...
    if (m_hLinkObject)
    {
        DVector vPos, vMyPos;
	    VEC_INIT(vPos);
	    VEC_INIT(vMyPos);
        
        // From this Point
    	g_pServerDE->GetObjectPos(m_hObject, &vMyPos);
        
        // To this Point
    	g_pServerDE->GetObjectPos(m_hLinkObject, &vPos);

		DVector vF, vU;

		VEC_SUB(vF, vPos, vMyPos);
		VEC_SET(vU, 0, 1, 0);

    	DRotation rMyNewRot;
    	
		g_pServerDE->AlignRotation(&rMyNewRot, &vF, &vU);

		g_pServerDE->SetObjectRotation(m_hObject, &rMyNewRot);
	}

	// Deactivate if the active time has expired.
	if (m_fActiveTime > 0 && g_pServerDE->GetTime() > m_fDeactivateTime)
		SetActive(DFALSE);

	return DTRUE;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
0
GEO *
file_geo_sphere (BYTE Type, FILE *File)
{
  GEO_SPHERE  *Geo;
  VECTOR      Vector;

  INIT_MEM (Geo, 1, GEO_SPHERE);
  Geo->Type = Type;
  GET_VECTOR (Geo->Point);
  GET_REAL (Geo->Radius);
  Vector.x = Vector.y = Vector.z = Geo->Radius;
  VEC_SUB (Geo->Min, Geo->Point, Vector);
  VEC_ADD (Geo->Max, Geo->Point, Vector);

  return ((GEO *) Geo);
}
Exemplo n.º 16
0
DBOOL CLaserBeamFX::UpdateBeam()
{
	if(!m_pClientDE)	return DFALSE;

	DVector		vDist, vUp;
	DRotation	rRot;

	VEC_SET(vUp, 0.0f, 1.0f, 0.0f);
	VEC_SUB(vDist, m_vDest, m_vSource);

	m_pClientDE->AlignRotation(&rRot, &vDist, &vUp);
	m_pClientDE->SetObjectPos(m_hObject, &m_vSource);
	m_pClientDE->SetObjectRotation(m_hObject, &rRot);

	VEC_SET(m_vScale, m_fMinScale, m_fMinScale, VEC_MAG(vDist));
	return	DTRUE;
}
Exemplo n.º 17
0
BOOL point_geo_sphere (GEO *Generic, HIT *Hit, RAY *NewRay)
{
  VECTOR     Point;

  if (NewRay == NULL)
  {
    uv2xyz_geo_sphere (Generic, Hit->u, Hit->v, &(Hit->Point),
		       &(Hit->Normal), NULL);
  }
  else
  {
    uv2xyz_geo_sphere (Generic, Hit->u, Hit->v, &Point, NULL, NULL);
    NewRay->Point = Hit->Point;
    VEC_SUB (NewRay->Vector, Point, NewRay->Point);
    VEC_UNIT (NewRay->Vector, NewRay->Distance);
  }

  return (TRUE);
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
DBOOL Equal(DVector & v1, DVector & v2)
{
	DVector v;
	VEC_SUB(v, v1, v2);
	return DBOOL(VEC_MAG(v) < 1.0f);
}
Exemplo n.º 21
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);
	}
}
Exemplo n.º 22
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;
}
Exemplo n.º 23
0
DBOOL CFlashlightFX::Update()
{
	if (!m_pClientDE || m_bWantRemove || !m_hServerObject || !m_hObject) return DFALSE;

	DDWORD dwUsrFlags;
	m_pClientDE->GetObjectUserFlags(m_hServerObject, &dwUsrFlags);

	// Hidden
	if (!(dwUsrFlags & USRFLG_VISIBLE))
	{
		m_pClientDE->SetObjectFlags(m_hObject, 0);
	}
	else
	{
		DRotation rRot;
		DVector vPos, vF, vR, vU;
		m_pClientDE->GetObjectRotation(m_hServerObject, &rRot);
		m_pClientDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
		m_pClientDE->GetObjectPos(m_hServerObject, &vPos);

		// Cast a line to see where to put the light..
		ClientIntersectQuery iQuery;
		ClientIntersectInfo  iInfo;
	
		VEC_COPY(iQuery.m_From, vPos);
		VEC_COPY(iQuery.m_Direction, vF);
		iQuery.m_Flags = INTERSECT_OBJECTS;

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

		if (m_pClientDE->CastRay(&iQuery, &iInfo))
		{		
			// Place the light
			m_pClientDE->SetObjectPos(m_hObject, &iInfo.m_Point);
			// Calculate the distance
			VEC_SUB(vPos, vPos, iInfo.m_Point);
			fDistance = VEC_MAG(vPos); 
			if (fDistance < 10.0f) fDistance = 10.0f;

			// The farther away, the brighter and bigger the light
			DFLOAT fRadius = fDistance * 0.40f;
			m_pClientDE->SetLightRadius(m_hObject, fRadius);

			// Determine the minimum intensity based on the current light level
			// (so we don't end up casting a dark light instead).
			DFLOAT fMinIntensity = 100.0f;
			DVector vColor;
			if (m_pClientDE->Common()->GetPointShade(&vPos, &vColor))
			{
				if (vColor.x > fMinIntensity) fMinIntensity = vColor.x;
				if (vColor.y > fMinIntensity) fMinIntensity = vColor.y;
				if (vColor.z > fMinIntensity) fMinIntensity = vColor.z;
			}
			fMinIntensity = DCLAMP((fMinIntensity + 32), 0, 255);
			fMinIntensity /= 255.0f;

			DFLOAT fIntensity = (1000.0f - (fDistance/2.0f)) / 1000.0f;
			if (fIntensity < fMinIntensity) fIntensity = fMinIntensity;

			m_pClientDE->SetLightColor(m_hObject, fIntensity, fIntensity, fIntensity);

			m_pClientDE->SetObjectFlags(m_hObject, FLAG_VISIBLE);
		}
		else
		{
			m_pClientDE->SetObjectFlags(m_hObject, 0);
		}
	}

	return DTRUE;
}
Exemplo n.º 24
0
static DDWORD DemoSky_EngineMessageFn(LPBASECLASS pObject, DDWORD messageID, void *pData, float lData)
{
	DemoSkyWorldModel *pModel;
	SkyDef def;
	DVector pos, temp;
	ObjectCreateStruct *pStruct;
	HOBJECT hObject;

	pModel = (DemoSkyWorldModel*)pObject;
	switch(messageID)
	{
		case MID_PRECREATE:
		{
			pStruct = (ObjectCreateStruct*)pData;

			pStruct->m_ObjectType = OT_WORLDMODEL;

			if( lData == 1.0f )
			{
				g_pServerDE->GetPropVector("SkyDims", &pModel->SkyDims);
				g_pServerDE->GetPropString("Name", pStruct->m_Filename, MAX_CS_FILENAME_LEN);
				g_pServerDE->GetPropReal("InnerPercentX", &pModel->InnerPercentX);
				g_pServerDE->GetPropReal("InnerPercentY", &pModel->InnerPercentY);
				g_pServerDE->GetPropReal("InnerPercentZ", &pModel->InnerPercentZ);
				g_pServerDE->GetPropLongInt("Index", &pModel->Index);
			}
			else
			{
				VEC_INIT( pModel->SkyDims );
				pModel->InnerPercentX = 0.1f;
				pModel->InnerPercentY = 0.1f;
				pModel->InnerPercentZ = 0.1f;
				pModel->Index = 0;
			}
			break;
		}

		case MID_INITIALUPDATE:
		{
			// Set the sky box?
			if(pModel->SkyDims.x != 0.0f && pModel->SkyDims.y != 0.0f && pModel->SkyDims.z != 0.0f)
			{
				g_pServerDE->GetObjectPos(pModel->BaseClass.m_hObject, &pos);
				VEC_SUB(def.m_Min, pos, pModel->SkyDims);
				VEC_ADD(def.m_Max, pos, pModel->SkyDims);

				temp.x = pModel->SkyDims.x * pModel->InnerPercentX;
				temp.y = pModel->SkyDims.y * pModel->InnerPercentY;
				temp.z = pModel->SkyDims.z * pModel->InnerPercentZ;

				VEC_SUB(def.m_ViewMin, pos, temp);
				VEC_ADD(def.m_ViewMax, pos, temp);

				g_pServerDE->SetSkyDef(&def);
			}

			hObject = pModel->BaseClass.m_hObject;
			g_pServerDE->SetObjectFlags(hObject, g_pServerDE->GetObjectFlags(hObject) | (FLAG_SKYOBJECT|FLAG_FORCEOPTIMIZEOBJECT));
			g_pServerDE->AddObjectToSky(pModel->BaseClass.m_hObject, pModel->Index);
			break;
		}
	}

	return bc_EngineMessageFn(pObject, messageID, pData, lData);
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
0
LTBOOL CBulletTrailFX::Update()
{
    if (!m_hObject || !m_pClientDE) return LTFALSE;

    LTFLOAT fTime = m_pClientDE->GetTime();

	if (m_bFirstUpdate)
	{
		// See if we can figure out what color bubbles to make, based on the
		// container we start in...

		HLOCALOBJ objList[1];
        uint32 dwNum = m_pClientDE->GetPointContainers(&m_vStartPos, objList, 1);

		if (dwNum > 0 && objList[0])
		{
            uint32 dwUserFlags;
			m_pClientDE->GetObjectUserFlags(objList[0], &dwUserFlags);

			if (dwUserFlags & USRFLG_VISIBLE)
			{
                uint16 dwCode;
				if (m_pClientDE->GetContainerCode(objList[0], &dwCode))
				{
					GetLiquidColorRange((ContainerCode)dwCode, &m_vColor1, &m_vColor2);
				}
			}
		}


		// Move the particle system to the correct position...

		m_pClientDE->SetObjectPos(m_hObject, &m_vStartPos);

        m_bFirstUpdate = LTFALSE;
		m_fStartTime   = fTime;
		m_fLastTime	   = fTime;

		VEC_INIT(m_vLastPos);

		// Find the end position...

		ClientIntersectQuery iQuery;
		ClientIntersectInfo  iInfo;

        LTVector vTemp, vEndPoint;

		VEC_MULSCALAR(vTemp, m_vDir, MAX_TRAIL_LENGTH);
		VEC_ADD(vEndPoint, m_vStartPos, vTemp);

		VEC_COPY(iQuery.m_From, m_vStartPos);
		VEC_COPY(iQuery.m_To, vEndPoint);

		if (m_pClientDE->IntersectSegment(&iQuery, &iInfo))
		{
			VEC_SUB(vEndPoint, iInfo.m_Point, m_vStartPos);
			m_fDistance = VEC_MAG(vEndPoint);
		}

        if (m_fDistance <= 0.0f || m_fFadeTime <= 0.0f) return LTFALSE;

		// Calculate the trail velocity...

		m_fTrailVel = m_fDistance / m_fFadeTime;

		VEC_MULSCALAR(m_vDir, m_vDir, m_fTrailVel);
	}



	// Check to see if we should just wait for last bubble to go away...

	if (fTime > m_fStartTime + m_fFadeTime)
	{
		if (fTime > m_fLastTime + m_fLifeTime)
		{
            return LTFALSE;
		}

        LTFLOAT fScale = (m_fLifeTime - (fTime - m_fLastTime)) / m_fLifeTime;

		// m_pClientDE->SetParticleSystemColorScale(m_hObject, fScale);
        LTFLOAT r, g, b, a;
		m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
		m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale);

        return LTTRUE;
	}


	// Create the necessary particles...


    LTFLOAT fTimeOffset = g_pGameClientShell->GetFrameTime();



	// Calculate distance traveled this frame...

    LTFLOAT fDist = m_fTrailVel * fTimeOffset;
	if (fDist > m_fDistance) fDist = m_fDistance;

	m_fDistTraveled += fDist;
	if (m_fDistTraveled > m_fDistance)
	{
		fDist = m_fDistance - (m_fDistTraveled - fDist);
        if (fDist <= 0.0f) return LTTRUE;
	}


	// Calculate number of particles to create...

    LTFLOAT fNumParticles = fDist * m_fNumParticles / m_fDistance;


	// Calculate starting bubble position...

    LTVector vCurPos, vPos, vDelta, vTemp, vDriftVel, vColor;

	VEC_MULSCALAR(vTemp, m_vDir, fTimeOffset);
	VEC_ADD(vCurPos, m_vLastPos, vTemp);


	// What is the range of colors?

    LTFLOAT fRange = m_vColor2.x - m_vColor1.x;


	// Fill the distance between the last projectile position, and it's
	// current position with bubbles...

	VEC_SUB(vTemp, vCurPos, m_vLastPos);
	VEC_MULSCALAR(vDelta, vTemp, 1.0f/fNumParticles);

	VEC_COPY(vPos, m_vLastPos);

    LTFLOAT fLifeTime = 100.0f;

    LTFLOAT fOffset = 0.0f;
    LTVector vDriftOffset;
	VEC_SET(vDriftOffset, 0.0f, 0.0f, 0.0f);

	int nNumParticles = GetNumParticles((int)fNumParticles);

	for (int i=0; i < nNumParticles; i++)
	{
		// Build the individual bubbless...

		for (int j=0; j < 1; j++)
		{
			VEC_COPY(vTemp, vPos);

			VEC_SET(vDriftVel, 0.0f, GetRandom(5.0f, 6.0f), 0.0f);

			vTemp.x += GetRandom(-fOffset, fOffset);
			vTemp.y += GetRandom(-fOffset, fOffset);
			vTemp.z += GetRandom(-fOffset, fOffset);

			GetRandomColorInRange(vColor);

			m_pClientDE->AddParticle(m_hObject, &vTemp, &vDriftVel, &vColor, fLifeTime);
		}

		VEC_ADD(vPos, vPos, vDelta);
	}

	VEC_COPY(m_vLastPos, vCurPos);
	m_fLastTime = fTime;

    return LTTRUE;
}
Exemplo n.º 27
0
static DDWORD SkyPointer_EngineMessageFn(LPBASECLASS pObject, DDWORD messageID, void *pData, float lData)
{
	SkyPointer *pModel;
	SkyDef def;
	DVector pos, temp;
	ObjectCreateStruct *pStruct;
	ObjectList *pList;
	HOBJECT hObject;

	pModel = (SkyPointer*)pObject;
	switch(messageID)
	{
		case MID_PRECREATE:
		{
			pStruct = (ObjectCreateStruct*)pData;

			pStruct->m_ObjectType = OT_NORMAL;
			pModel->m_hObject = 0;

			if( lData == 1.0f )
			{
				g_pServerDE->GetPropVector("SkyDims", &pModel->SkyDims);
				g_pServerDE->GetPropString("Name", pStruct->m_Filename, MAX_CS_FILENAME_LEN);
				g_pServerDE->GetPropString("SkyObjectName", pModel->m_ObjectName, sizeof(pModel->m_ObjectName)-1);
				g_pServerDE->GetPropReal("InnerPercentX", &pModel->InnerPercentX);
				g_pServerDE->GetPropReal("InnerPercentY", &pModel->InnerPercentY);
				g_pServerDE->GetPropReal("InnerPercentZ", &pModel->InnerPercentZ);
				g_pServerDE->GetPropLongInt("Index", &pModel->Index);
			}
			else
			{
				pModel->m_ObjectName[0] = 0;
				VEC_INIT( pModel->SkyDims );
				pModel->InnerPercentX = 0.1f;
				pModel->InnerPercentY = 0.1f;
				pModel->InnerPercentZ = 0.1f;
				pModel->Index = 0;
			}
			break;
		}

		case MID_INITIALUPDATE:
		{
			// Set the sky box?
			if(pModel->SkyDims.x != 0.0f && pModel->SkyDims.y != 0.0f && pModel->SkyDims.z != 0.0f)
			{
				g_pServerDE->GetObjectPos(pModel->BaseClass.m_hObject, &pos);
				VEC_SUB(def.m_Min, pos, pModel->SkyDims);
				VEC_ADD(def.m_Max, pos, pModel->SkyDims);

				temp.x = pModel->SkyDims.x * pModel->InnerPercentX;
				temp.y = pModel->SkyDims.y * pModel->InnerPercentY;
				temp.z = pModel->SkyDims.z * pModel->InnerPercentZ;

				VEC_SUB(def.m_ViewMin, pos, temp);
				VEC_ADD(def.m_ViewMax, pos, temp);

				g_pServerDE->SetSkyDef(&def);
			}

			g_pServerDE->SetNextUpdate(pModel->BaseClass.m_hObject, 0.001f);
			break;
		}

		case MID_UPDATE:
		{
			// Add the first object to the sky.
			pList = g_pServerDE->FindNamedObjects(pModel->m_ObjectName);
			if(pList && pList->m_pFirstLink)
			{
				hObject = pList->m_pFirstLink->m_hObject;
				g_pServerDE->AddObjectToSky(hObject, pModel->Index);
				g_pServerDE->SetObjectFlags(hObject, g_pServerDE->GetObjectFlags(hObject) | (FLAG_SKYOBJECT|FLAG_FORCEOPTIMIZEOBJECT));
				g_pServerDE->RelinquishList(pList);
			}
			
			g_pServerDE->RemoveObject(pModel->BaseClass.m_hObject);
			break;
		}
	}

	return bc_EngineMessageFn(pObject, messageID, pData, lData);
}
Exemplo n.º 28
0
void CParticleExplosionFX::AddParticles(MovingObject* pObject)
{
    if (!m_hObject || !m_pClientDE || !pObject || pObject->m_PhysicsFlags & MO_RESTING) return;

    LTFLOAT fTime = m_pClientDE->GetTime();

    LTVector vCurPos, vLastPos, vPos, vDelta, vTemp, vDriftVel, vColor;

    VEC_COPY(vCurPos, pObject->m_Pos);
    VEC_COPY(vLastPos, pObject->m_LastPos);

    // Calculate Particle puff positions...

    // Current position is relative to the particle system's postion (i.e.,
    // each puff of Particle is some distance away from the particle system's
    // position)...

    VEC_SUB(vCurPos, vCurPos, m_vPos);
    VEC_SUB(vLastPos, vLastPos, m_vPos);


    // How long has it been since the last Particle puff?

    LTFLOAT fTimeOffset = fTime - m_fLastTime;


    // Fill the distance between the last projectile position, and it's
    // current position with Particle puffs...

    VEC_SUB(vTemp, vCurPos, vLastPos);
    VEC_MULSCALAR(vDelta, vTemp, 1.0f/LTFLOAT(m_nNumSteps));

    VEC_COPY(vPos, vLastPos);

    LTFLOAT fCurLifeTime    = 10.0f;
    LTFLOAT fLifeTimeOffset = fTimeOffset / LTFLOAT(m_nNumSteps);

    LTFLOAT fOffset = 0.5f;

    if (m_bSmall)
    {
        fOffset /= 2.0f;
    }

    for (int i=0; i < m_nNumSteps; i++)
    {
        // Build the individual Particle puffs...

        for (int j=0; j < m_nNumPerPuff; j++)
        {
            VEC_COPY(vTemp, vPos);

            VEC_SET(vDriftVel, GetRandom(m_vMinDriftOffset.x, m_vMaxDriftOffset.x),
                    GetRandom(m_vMinDriftOffset.y, m_vMaxDriftOffset.y),
                    GetRandom(m_vMinDriftOffset.z, m_vMaxDriftOffset.z));

            if (!m_bIgnoreWind)
            {
                vDriftVel.x += g_vWorldWindVel.x;
                vDriftVel.y += g_vWorldWindVel.y;
                vDriftVel.z += g_vWorldWindVel.z;
            }

            vTemp.x += GetRandom(-fOffset, fOffset);
            vTemp.y += GetRandom(-fOffset, fOffset);
            vTemp.z += GetRandom(-fOffset, fOffset);

            GetRandomColorInRange(vColor);

            m_pClientDE->AddParticle(m_hObject, &vTemp, &vDriftVel, &vColor, fCurLifeTime);
        }

        VEC_ADD(vPos, vPos, vDelta);
        fCurLifeTime += fLifeTimeOffset;
    }
}
Exemplo n.º 29
0
/********************************************************
 * Search for an intersection between a nappe and a ray *
 *******************************************************/
BOOL hit_geo_nappe (GEO *Generic, RAY *Ray, HIT *Hit, PAIR *Bound, void *Info)
{
	GEO_NAPPE	*Geo;
	FCT		*Fct;
	PNT	        *Pnt, *PntA, *PntB;
	VECTOR		Normal;
	VECTOR		Point;
	REAL		a, b, c, u, v, uA, vA, uB, vB, Distance, Real;

  Geo = (GEO_NAPPE *) Generic;

  Fct = (FCT *) Info;
  Distance = VEC_DOT (Ray->Vector, Fct->Normal);
  if (ABS(Distance) < EPSILON)
    return (FALSE);
  Pnt = Geo->TabPnt + Fct->i;
  VEC_SUB (Point, Pnt->Point, Ray->Point);
  Distance = VEC_DOT (Point, Fct->Normal) / Distance ; /*-Epsilon est vire*/
  if (Distance < Bound->u || Distance > Bound->v)
    return (FALSE);
  VEC_LIN (Point, Ray->Point, Distance, Ray->Vector);

  if ((ABS(Fct->Normal.z) > ABS(Fct->Normal.x)) && (ABS(Fct->Normal.z) > ABS(Fct->Normal.y))) {
    u = Point.x - Pnt->Point.x; v = Point.y - Pnt->Point.y;
    PntA = Geo->TabPnt + Fct->j; PntB = Geo->TabPnt + Fct->k;
    uA = PntA->Point.x - Pnt->Point.x; vA = PntA->Point.y - Pnt->Point.y;
    uB = PntB->Point.x - Pnt->Point.x; vB = PntB->Point.y - Pnt->Point.y;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA-u*vA) / a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }

    if (Fct->l == Fct->i) 
      return (FALSE);
    
    PntA = Geo->TabPnt + Fct->l;
    uA = PntA->Point.x - Pnt->Point.x; vA = PntA->Point.y - Pnt->Point.y;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    return (FALSE);
  }

  else if (ABS(Fct->Normal.y) > ABS(Fct->Normal.x)) {
    u = Point.z - Pnt->Point.z; v = Point.x - Pnt->Point.x;
    PntA = Geo->TabPnt + Fct->j; PntB = Geo->TabPnt + Fct->k;
    uA = PntA->Point.z - Pnt->Point.z; vA = PntA->Point.x - Pnt->Point.x;
    uB = PntB->Point.z - Pnt->Point.z; vB = PntB->Point.x - Pnt->Point.x;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    
    if (Fct->l == Fct->i) return (FALSE);

    PntA = Geo->TabPnt + Fct->l;
    uA = PntA->Point.z - Pnt->Point.z; vA = PntA->Point.x - Pnt->Point.x;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    return (FALSE);
  }

  else if (ABS(Fct->Normal.x) > EPSILON) {
    u = Point.y - Pnt->Point.y; v = Point.z - Pnt->Point.z;
    PntA = Geo->TabPnt + Fct->j; PntB = Geo->TabPnt + Fct->k;
    uA = PntA->Point.y - Pnt->Point.y; vA = PntA->Point.z - Pnt->Point.z;
    uB = PntB->Point.y - Pnt->Point.y; vB = PntB->Point.z - Pnt->Point.z;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    
    if (Fct->l == Fct->i) return (FALSE);

    PntA = Geo->TabPnt + Fct->l;
    uA = PntA->Point.y - Pnt->Point.y; vA = PntA->Point.z - Pnt->Point.z;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    return (FALSE);
  }
  return (FALSE);
}
Exemplo n.º 30
0
LTBOOL CParticleTrailSegmentFX::Update()
{
    if (!m_hObject || !m_pClientDE) return LTFALSE;

    if (!CBaseParticleSystemFX::Update()) return LTFALSE;

	CGameSettings* pSettings = g_pInterfaceMgr->GetSettings();
    if (!pSettings) return LTFALSE;

    uint8 nDetailLevel = pSettings->SpecialFXSetting();


    LTFLOAT fTime = m_pClientDE->GetTime();

	if (m_bFirstUpdate)
	{
        if (!m_hServerObject) return LTFALSE;

        m_bFirstUpdate = LTFALSE;
		m_fStartTime   = fTime;
		m_fLastTime	   = fTime;

		// Where is the server (moving) object...

        LTVector vPos, vTemp;
		m_pClientDE->GetObjectPos(m_hServerObject, &vPos);

		// Current position is relative to the particle system's postion (i.e.,
		// each puff of Particle is some distance away from the particle system's
		/// position)...

		m_pClientDE->GetObjectPos(m_hObject, &vTemp);
		VEC_SUB(vPos, vPos, vTemp);

		VEC_COPY(m_vLastPos, vPos);
	}


	// Check to see if we should just wait for last Particle puff to go away...

	if (m_bWantRemove || (fTime > m_fStartTime + m_fFadeTime))
	{
		if (fTime > m_fLastTime + m_fLifeTime)
		{
            return LTFALSE;
		}

        LTFLOAT fScale = (m_fLifeTime - (fTime - m_fLastTime)) / m_fLifeTime;

        LTFLOAT r, g, b, a;
		m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
		m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale);

        return LTTRUE;
	}


	// See if it is time to create a new Particle puff...

	if ((fTime > m_fLastTime + m_fOffsetTime) && m_hServerObject)
	{
        LTVector vCurPos, vPos, vDelta, vTemp, vDriftVel, vColor;

		// Calculate Particle puff position...

		// Where is the server (moving) object...

		m_pClientDE->GetObjectPos(m_hServerObject, &vCurPos);


		// Current position is relative to the particle system's postion (i.e.,
		// each puff of Particle is some distance away from the particle system's
		/// position)...

		m_pClientDE->GetObjectPos(m_hObject, &vTemp);
		VEC_SUB(vCurPos, vCurPos, vTemp);


		// How long has it been since the last Particle puff?

        LTFLOAT fTimeOffset = fTime - m_fLastTime;


		// What is the range of colors?

        LTFLOAT fRange = m_vColor2.x - m_vColor1.x;


		// Fill the distance between the last projectile position, and it's
		// current position with Particle puffs...

		int nNumSteps = (m_fLastTime > 0) ? (((m_nType & PT_BLOOD) || (m_nType & PT_GIBSMOKE)) ? 20 : 5): 1;

		if (nDetailLevel != RS_HIGH)
		{
			nNumSteps /= 2;
		}

		VEC_SUB(vTemp, vCurPos, m_vLastPos);
		VEC_MULSCALAR(vDelta, vTemp, 1.0f/float(nNumSteps));

		VEC_COPY(vPos, m_vLastPos);

        LTFLOAT fCurLifeTime = 10.0f;
		if (nDetailLevel == RS_HIGH)
		{
			fCurLifeTime /= 2;
		}

        LTFLOAT fLifeTimeOffset = fTimeOffset / float(nNumSteps);

        LTFLOAT fOffset = 0.5f;

		int nNumPerPuff = GetNumParticles(m_nNumPerPuff);

		for (int i=0; i < nNumSteps; i++)
		{
			// Build the individual Particle puffs...

			for (int j=0; j < nNumPerPuff; j++)
			{
				VEC_COPY(vTemp, vPos);

				if (m_bIgnoreWind)
				{
					VEC_SET(vDriftVel, GetRandom(-m_vDriftOffset.x*2.0f, -m_vDriftOffset.x),
									   GetRandom(5.0f, 6.0f),
									   GetRandom(-m_vDriftOffset.z, m_vDriftOffset.z));
				}
				else
				{
					VEC_SET(vDriftVel, g_vWorldWindVel.x + GetRandom(-m_vDriftOffset.x*2.0f, -m_vDriftOffset.x),
									   g_vWorldWindVel.y + GetRandom(5.0f, 6.0f),
									   g_vWorldWindVel.z + GetRandom(-m_vDriftOffset.z, m_vDriftOffset.z));
				}

				vTemp.x += GetRandom(-fOffset, fOffset);
				vTemp.y += GetRandom(-fOffset, fOffset);
				vTemp.z += GetRandom(-fOffset, fOffset);

				GetRandomColorInRange(vColor);

				m_pClientDE->AddParticle(m_hObject, &vTemp, &vDriftVel, &vColor, fCurLifeTime);
			}

			VEC_ADD(vPos, vPos, vDelta);
			fCurLifeTime += fLifeTimeOffset;
		}

		m_fLastTime = fTime;

		VEC_COPY(m_vLastPos, vCurPos);
	}

    return LTTRUE;
}