Beispiel #1
0
static void handle_T0(FmmvHandle *FMMV, Box *box, int T0[][9], _FLOAT_ *X, _FLOAT_ *X1, _FLOAT_ *X2)
{
	int i;
	_FLOAT_ *D_X2X = FMMV->D_X2X;
	int s_exp = FMMV->s_exp;
	int s_exp2 = FMMV->s_exp/2;
	
	for (i=0; i<8; i++) {
	        if (isSource(box->child[T0[i][0]])) {
		    if (T0[i][2]) { /* conjugate */
       	        	 VEC_MUL_CJ(s_exp2, D_X2X + s_exp*T0[i][1], X1 + s_exp*T0[i][0], X + s_exp*T0[i][3]);
		    }	 
		    else {
       	        	 VEC_MUL_C(s_exp2, D_X2X + s_exp*T0[i][1], X1 + s_exp*T0[i][0], X + s_exp*T0[i][3]);
		    }	 
                    VEC_ADD(s_exp, X + s_exp*T0[i][3], X + s_exp*T0[i][4], X + s_exp*T0[i][4]);
		    if (T0[i][6]) { /* conjugate */
       	        	 VEC_MUL_CJ(s_exp2, D_X2X + s_exp*T0[i][5], X2 + s_exp*T0[i][0], X + s_exp*T0[i][7]);
		    }	 
		    else {
       	        	 VEC_MUL_C(s_exp2, D_X2X + s_exp*T0[i][5], X2 + s_exp*T0[i][0], X + s_exp*T0[i][7]);
		    }	 
                    VEC_ADD(s_exp, X + s_exp*T0[i][7], X + s_exp*T0[i][8], X + s_exp*T0[i][8]);
		}
        }
        VEC_ADD(s_exp, X + s_exp*XU_D, X + s_exp*XU_all, X + s_exp*XU_all);
        VEC_ADD(s_exp, X + s_exp*XD_D, X + s_exp*XD_all, X + s_exp*XD_all);
}
Beispiel #2
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;
}
Beispiel #3
0
DBOOL CShellCasingFX::CreateObject(CClientDE *pClientDE)
{
	if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE;

	char* pModelName = DNULL;
	char* pSkinName = DNULL;
	if (!GetFileNames(&pModelName, &pSkinName))
		return DFALSE;

	if (!pModelName || !pSkinName) return DFALSE;

	// Setup the shell...

	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

	createStruct.m_ObjectType = OT_MODEL;
	createStruct.m_Flags = 0;
	_mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)pModelName);
	_mbscpy((unsigned char*)createStruct.m_SkinName, (const unsigned char*)pSkinName);
	VEC_COPY(createStruct.m_Pos, m_vStartPos);
	ROT_COPY(createStruct.m_Rotation, m_rRot);

	m_hObject = pClientDE->CreateObject(&createStruct);
	if (!m_hObject) return DFALSE;


	m_pClientDE->SetObjectScale(m_hObject, &m_vScale);

	DVector vU, vR, vF;
	pClientDE->GetRotationVectors(&m_rRot, &vU, &vR, &vF);

	DVector vVel;

	if(m_bLeftHanded)
		VEC_NEGATE(vR, vR);

	DFLOAT fUpVel = GetRandom(60.0f, 90.0f);
	VEC_MULSCALAR(vU, vU, fUpVel);
	DFLOAT fRightVel = GetRandom(50.0f, 70.0f);
	VEC_MULSCALAR(vR, vR, fRightVel);
	DFLOAT fForwardVel = GetRandom(10.0f, 25.0f);
	VEC_MULSCALAR(vF, vF, fForwardVel);

	VEC_ADD(vVel, vU, vR);
	VEC_ADD(vVel, vVel, vF);

	InitMovingObject(&m_movingObj, &m_vStartPos, &vVel);;
	m_movingObj.m_PhysicsFlags |= MO_HALFGRAVITY;

	m_fExpireTime = 20.0f + m_pClientDE->GetTime();

	// Set the pitch velocity
	m_fPitchVel = GetRandom(-MATH_CIRCLE * 2, MATH_CIRCLE * 2);
	m_fYawVel = GetRandom(-MATH_CIRCLE * 2, MATH_CIRCLE * 2);
	m_fPitch	= m_fYaw = 0.0f;

	return DTRUE;
}
Beispiel #4
0
DBOOL UpdateMovingObject(PhysicsState *pUserState, MovingObject *pObject, DVector *pNewPos)
{
	if (!pObject || !pNewPos) return DFALSE;

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

	DVector vTemp, velocityDelta, posDelta;

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

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

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

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

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

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

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

	return DTRUE;
}
Beispiel #5
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;
}
DBOOL CBaseParticleSystemFX::Update()
{
	if(!m_hObject || !m_pClientDE) return DFALSE;


	// See if we should rotate this bad-boy...

	if (m_vRotVel.x != 0.0f || m_vRotVel.y != 0.0f || m_vRotVel.z != 0.0f)
	{
		DFLOAT fDelta = m_pClientDE->GetFrameTime();

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

		DVector vTemp;
		VEC_MULSCALAR(vTemp, m_vRotVel, fDelta);
		VEC_ADD(m_vRotAmount, m_vRotAmount, vTemp);

		if (m_vRotVel.x != 0.0f) m_pClientDE->EulerRotateX(&rRot, m_vRotAmount.x);
		if (m_vRotVel.y != 0.0f) m_pClientDE->EulerRotateY(&rRot, m_vRotAmount.y);
		if (m_vRotVel.z != 0.0f) m_pClientDE->EulerRotateZ(&rRot, m_vRotAmount.z);

		m_pClientDE->SetObjectRotation(m_hObject, &rRot);
	}


	return DTRUE;
}
bool test_vector()
{
    Vector init;
    bool test_result = true; // true == passed
    
    init.v[0] = 0.0f;
    
    VEC_INIT(init);
    
    CHECK(init.v[0] == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.v[1] == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.v[2] == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.v[3] == 0.0f, "test_vector: INIT failed\n");

    CHECK(init.vec.x == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.vec.y == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.vec.z == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.vec.w == 0.0f, "test_vector: INIT failed\n");
    
    CHECK(init.col.r == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.col.g == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.col.b == 0.0f, "test_vector: INIT failed\n");
    CHECK(init.col.a == 0.0f, "test_vector: INIT failed\n");
    
    init.v[0] = 1.0f;
    init.v[1] = 2.0f;
    init.v[2] = 3.0f;
    init.v[3] = 4.0f;
    
    CHECK(init.vec.x == 1.0f, "test_vector: union test failed\n");
    CHECK(init.vec.y == 2.0f, "test_vector: union test failed\n");
    CHECK(init.vec.z == 3.0f, "test_vector: union test failed\n");
    CHECK(init.vec.w == 4.0f, "test_vector: union test failed\n");
    
    CHECK(init.col.r == 1.0f, "test_vector: union test failed\n");
    CHECK(init.col.g == 2.0f, "test_vector: union test failed\n");
    CHECK(init.col.b == 3.0f, "test_vector: union test failed\n");
    CHECK(init.col.a == 4.0f, "test_vector: union test failed\n");
    
    VEC_ASSIGN(init, 5.0f, 6.0f, 7.0f, 8.0f);
    
    CHECK(init.v[0] == 5.0f, "test_vector: VEC_ASSIGN failed\n");
    CHECK(init.v[1] == 6.0f, "test_vector: VEC_ASSIGN failed\n");
    CHECK(init.v[2] == 7.0f, "test_vector: VEC_ASSIGN failed\n");
    CHECK(init.v[3] == 8.0f, "test_vector: VEC_ASSIGN failed\n");
    
    Vector second;
    VEC_ASSIGN(second, 9.0f, 10.0f, 11.0f, 12.0f);
    
    Vector result;
    VEC_ADD(result, init, second);
    
    CHECK(result.v[0] == 14.0f, "test_vector: VEC_ADD failed\n");
    CHECK(result.v[1] == 16.0f, "test_vector: VEC_ADD failed\n");
    CHECK(result.v[2] == 18.0f, "test_vector: VEC_ADD failed\n");
    CHECK(result.v[3] == 20.0f, "test_vector: VEC_ADD failed\n");
    
    return test_result;
}
Beispiel #8
0
DVector	CPlayerCamera::FindFirstPersonCameraPosition(DVector vPos, DVector vF)
{
	DVector vTemp;
	VEC_MULSCALAR(vTemp, vF, m_TargetFirstPersonOffset.x);
	VEC_ADD(vPos, vPos, vTemp);
	vPos.y += m_TargetFirstPersonOffset.y;

	return vPos;
}
Beispiel #9
0
void BugAI::MC_Run()
{
   if (m_bAnimating == DFALSE || m_nCurMetacmd != MC_RUN)
    {
		DBOOL bRet = DFALSE;

    	m_fTimeStart = m_pServerDE->GetTime();

		Move(m_MoveObj.GetForwardVector(),m_fRunSpeed);
        
        m_bAnimating = DTRUE; 
		m_nCurMetacmd = MC_RUN;
    }
    else
    {   
		//Check for obstruction; otherwise continue on
		if(CheckObstructed(m_MoveObj.GetForwardVector(), m_fRunSpeed))
		{
			IntersectQuery IQuery;
			IntersectInfo ii;
	
			IQuery.m_Flags	  = INTERSECT_OBJECTS;
			IQuery.m_FilterFn = DNULL;

			DVector vTemp;
			VEC_MULSCALAR(vTemp,m_MoveObj.GetForwardVector(),m_fRunSpeed);
			VEC_COPY(IQuery.m_From,m_MoveObj.GetPos());
			VEC_ADD(IQuery.m_To,IQuery.m_From,vTemp);

			if(m_pServerDE->IntersectSegment(&IQuery, &ii))
			{
				//climb the object
				DRotation rRot;
				m_pServerDE->AlignRotation(&rRot,&m_MoveObj.GetUpVector(),&ii.m_Plane.m_Normal);

				m_pServerDE->SetObjectRotation(m_hObject,&rRot);

				m_bAnimating = DFALSE; 
				Metacmd++;

				return;
			}
		}

		Move(m_MoveObj.GetForwardVector(),m_fRunSpeed);
    
		//Are we done running?
		if(m_pServerDE->GetModelPlaybackState(m_hObject) & MS_PLAYDONE)
        {
            m_bAnimating = DFALSE; 
            Metacmd++;
        }
    }
	
    return;
}
Beispiel #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;
}
Beispiel #11
0
void CHandWeaponModel::Drop()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	m_bDropped = DTRUE;

	DVector vF, vR, vU;
	DRotation rRot;

	// Set some minimum dims, and make sure x and z are the same.
	DVector vDims;
	pServerDE->GetModelAnimUserDims(m_hObject, &vDims, pServerDE->GetModelAnimation(m_hObject));
	if (vDims.x < 10.0f)
		vDims.x = 10.0f;
	if (vDims.x > vDims.z)
		vDims.z = vDims.x;
	else 
		vDims.x = vDims.z;

//	g_pServerDE->BPrint("Setting PU dims %f,%f,%f", VEC_EXPAND(vDims));
	if (pServerDE->SetObjectDims2(m_hObject, &vDims) == DE_ERROR)

	// Get vectors to set a velocity	
	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

	// Set some forward and upward velocity
	VEC_ADD(vF, vF, vU);
	VEC_MULSCALAR(vF, vF, 150.0f);

	pServerDE->SetVelocity(m_hObject, &vF);

	// Make it visible
	DDWORD dwFlags = pServerDE->GetObjectFlags(m_hObject);
	pServerDE->SetObjectFlags(m_hObject, dwFlags | FLAG_NOSLIDING | FLAG_VISIBLE | FLAG_GRAVITY | FLAG_REMOVEIFOUTSIDE);

	// Show the model on the client now
/*	if(m_dwClientID)
	{
		HMESSAGEWRITE hMsg = pServerDE->StartSpecialEffectMessage(this);
		pServerDE->WriteToMessageByte(hMsg, SFX_WEAPONHANDMODEL_ID);
		pServerDE->WriteToMessageDWord(hMsg, m_dwClientID);
		pServerDE->WriteToMessageByte(hMsg, (m_bLeftHand << 1) | DTRUE);
		pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED);
	}
*/
	// Set next update for 1 second to spawn a powerup
	pServerDE->SetNextUpdate( m_hObject, 1.0f);
}
Beispiel #12
0
static size_t
ve_anchors_add(br_x509_certificate *xcs, size_t num, anchor_list *anchors)
{
	br_x509_trust_anchor ta;
	size_t u;

	for (u = 0; u < num; u++) {
		if (certificate_to_trust_anchor_inner(&ta, &xcs[u]) < 0) {
			break;
		}
		VEC_ADD(*anchors, ta);
	}
	return (u);
}
Beispiel #13
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);
	}
}
Beispiel #14
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);
}
Beispiel #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);
}
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;
}
bool test_list()
{
    bool test_result = true; // true == passed
    
    DEFINE_LIST(int, int_list);
    DEFINE_LIST(Vector, vec_list);
    
    int_list test_int;
    vec_list test_vec;
    
    CREATE_LIST(test_int, int, 5);
    CREATE_LIST(test_vec, Vector, 5);
    
    ADD_LIST(test_int, 5);
    
    CHECK(test_int.l[0] == 5, "test_int vector ADD_LIST failed");
    CHECK(test_int.cur_size = 1, "test_int vector ADD_LIST failed");

    ADD_LIST(test_int, 6);
    ADD_LIST(test_int, 7);
    ADD_LIST(test_int, 8);
    ADD_LIST(test_int, 9);
    ADD_LIST(test_int, 10);
    ADD_LIST(test_int, 11);

    CHECK(test_int.l[0] == 5, "test_int vector ADD_LIST failed");
    CHECK(test_int.l[1] == 6, "test_int vector ADD_LIST failed");
    CHECK(test_int.l[2] == 7, "test_int vector ADD_LIST failed");
    CHECK(test_int.l[3] == 8, "test_int vector ADD_LIST failed");
    CHECK(test_int.l[4] == 9, "test_int vector ADD_LIST failed");
    CHECK(test_int.l[5] == 10, "test_int vector ADD_LIST failed");
    CHECK(test_int.l[6] == 11, "test_int vector ADD_LIST failed");
    CHECK(test_int.cur_size == 7, "test_int vector ADD_LIST failed");
    CHECK(test_int.max_size == 10, "test_int vector ADD_LIST failed");

    FREE_LIST(test_int);
    
    Vector val;
    val.v[0] = val.v[1] = val.v[2] = val.v[3] = 10.0f;
    ADD_LIST(test_vec, val);
    
    CHECK(test_vec.l[0].v[0] == 10.0f, "test_vec vector ADD_LIST failed");
    CHECK(test_vec.l[0].v[1] == 10.0f, "test_vec vector ADD_LIST failed");
    CHECK(test_vec.l[0].v[2] == 10.0f, "test_vec vector ADD_LIST failed");
    CHECK(test_vec.l[0].v[3] == 10.0f, "test_vec vector ADD_LIST failed");
    
    Vector inc;
    VEC_ASSIGN(inc, 1.0f, 1.0f, 1.0f, 1.0f);
    
    VEC_ADD(val, val, inc);
    ADD_LIST(test_vec, val);
    VEC_ADD(val, val, inc);
    ADD_LIST(test_vec, val);
    VEC_ADD(val, val, inc);
    ADD_LIST(test_vec, val);
    VEC_ADD(val, val, inc);
    ADD_LIST(test_vec, val);
    VEC_ADD(val, val, inc);
    ADD_LIST(test_vec, val);
    VEC_ADD(val, val, inc);
    ADD_LIST(test_vec, val);
    
    CHECK(test_vec.l[6].v[0] == 16.0f, "test_vec vector ADD_LIST failed");
    CHECK(test_vec.l[6].v[1] == 16.0f, "test_vec vector ADD_LIST failed");
    CHECK(test_vec.l[6].v[2] == 16.0f, "test_vec vector ADD_LIST failed");
    CHECK(test_vec.l[6].v[3] == 16.0f, "test_vec vector ADD_LIST failed");
    CHECK(test_int.cur_size == 7, "test_int vector ADD_LIST failed");
    CHECK(test_int.max_size == 10, "test_int vector ADD_LIST failed");
    
    return test_result;
}
Beispiel #18
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);
}
Beispiel #19
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;
}
Beispiel #20
0
DBOOL CSmokePuffFX::Update()
{
	if(!m_hObject || !m_pClientDE) return DFALSE;

	DFLOAT fTime = m_pClientDE->GetTime();

	if (m_fStartTime < 0)
	{
		m_fStartTime = m_fLastTime = fTime;
	}


	// Make sure we update our position relative to the server object (if the
	// server object is valid)...

	if (m_hServerObject)
	{
		DVector vServPos;
		m_pClientDE->GetObjectPos(m_hServerObject, &vServPos);
		m_pClientDE->SetObjectPos(m_hObject, &vServPos);
	}


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

	DFLOAT fTimeDelta = fTime - m_fStartTime;

	if (fTimeDelta > m_fLifeTime)
	{
		return DFALSE;
	}

	if (m_fDriftDeceleration)
	{
		DFLOAT fDecel = 1 - m_pClientDE->GetFrameTime() * m_fDriftDeceleration;
		VEC_MULSCALAR(m_vMinDriftVel, m_vMinDriftVel, fDecel);
		VEC_MULSCALAR(m_vMaxDriftVel, m_vMaxDriftVel, fDecel);
	}


	DFLOAT fScale = ((m_fLifeTime - fTimeDelta) / m_fLifeTime) * m_fMaxAlpha;

	// Adjust the alpha
	DFLOAT r, g, b, a;
	m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a);
	m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale);



	// See if it is time to add some more smoke...

	if (fTime > m_fLastTime + m_fParticleCreateDelta && (fTimeDelta < m_fCreateLifetime) )
	{
		DVector vDriftVel, vColor, vPos;

		// What is the range of colors?

		DFLOAT fRange = m_vColor2.x - m_vColor1.x;


		// Build the individual smoke puffs...

		for (DDWORD j=0; j < m_nNumParticles; j++)
		{
			DFLOAT fX, fY, fAngle, fRadius;
			fAngle = GetRandom(-MATH_PI, MATH_PI);
			fRadius = GetRandom(0.0f, m_fVolumeRadius);
			fX = fRadius * (DFLOAT)cos(fAngle);
			fY = fRadius * (DFLOAT)sin(fAngle);
			VEC_SET(vPos,  fX, -2.0f, fY);

			VEC_SET(vDriftVel,	
					GetRandom(m_vMinDriftVel.x, m_vMaxDriftVel.x), 
					GetRandom(m_vMinDriftVel.y, m_vMaxDriftVel.y), 
					GetRandom(m_vMinDriftVel.z, m_vMaxDriftVel.z));

			if (!m_bIgnoreWind)
			{
				VEC_ADD(vDriftVel, vDriftVel, g_vWorldWindVel);
			}

			DFLOAT fOffset  = GetRandom(m_vColor1.x, m_vColor2.x);
			DFLOAT fPercent = 1.0f;

			if (fRange > 0.01)
			{
				fPercent = fOffset / fRange;
			}

			vColor.x = m_vColor1.x + fOffset;

			fOffset = fPercent * (m_vColor2.y - m_vColor1.y);
			vColor.y = m_vColor1.y + fOffset;

			fOffset = fPercent * (m_vColor2.z - m_vColor1.z);
			vColor.z = m_vColor1.z + fOffset;

			DFLOAT fLifeTime = GetRandom(m_fMinParticleLife, m_fMaxParticleLife);

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

		m_fLastTime = fTime;
	}

	return DTRUE;
}
Beispiel #21
0
LTBOOL CSmokeFX::Update()
{
    if (!m_hObject || !m_pClientDE ) return LTFALSE;

	if( g_pGameClientShell->IsServerPaused() )
	{
		g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_PAUSED, FLAG_PAUSED);
		return LTTRUE;
	}
	
	//make sure we aren't paused
	g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, 0, FLAG_PAUSED);

    LTFLOAT fFrameTime = m_pClientDE->GetFrameTime();

	m_fElapsedTime += fFrameTime;
	m_fElapsedEmissionTime += fFrameTime;

	// Hide/show the particle system if necessary...

	if (m_hServerObject)
	{
        uint32 dwUserFlags;
		g_pCommonLT->GetObjectFlags(m_hServerObject, OFT_User, dwUserFlags);

		if (!(dwUserFlags & USRFLG_VISIBLE))
		{
			uint32 dwFlags;
			g_pCommonLT->GetObjectFlags(m_hObject, OFT_Flags, dwFlags);

			// Once last puff as disappeared, hide the system (no new puffs
			// will be added...)

			if (dwFlags & FLAG_VISIBLE)
			{
				if (m_fElapsedEmissionTime > m_fMaxParticleLife)
				{
					g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, 0, FLAG_VISIBLE);
				}
			}
			else
			{
				m_fElapsedEmissionTime = 0.0f;
			}

            return LTTRUE;
		}
		else
		{
			g_pCommonLT->SetObjectFlags(m_hObject, OFT_Flags, FLAG_VISIBLE, FLAG_VISIBLE);
		}
	}



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

	if (m_fElapsedTime > m_fLifeTime)
	{
		if (m_fElapsedEmissionTime > m_fMaxParticleLife)
		{
            return LTFALSE;
		}

        return LTTRUE;
	}


	// See if it is time to add some more smoke...

	if (m_fElapsedEmissionTime >= m_fParticleCreateDelta)
	{
        LTVector vDriftVel, vColor, vPos;

		// What is the range of colors?

        LTFLOAT fRange = m_vColor2.x - m_vColor1.x;


		// Determine how many particles to add...

		int nNumParticles = GetNumParticles(m_nNumParticles);

		// Build the individual smoke puffs...

		for (int j=0; j < nNumParticles; j++)
		{
			VEC_SET(vPos,  GetRandom(-m_fVolumeRadius, m_fVolumeRadius),
					-2.0f, GetRandom(-m_fVolumeRadius, m_fVolumeRadius));

			VEC_SET(vDriftVel,
					GetRandom(m_vMinDriftVel.x, m_vMaxDriftVel.x),
					GetRandom(m_vMinDriftVel.y, m_vMaxDriftVel.y),
					GetRandom(m_vMinDriftVel.z, m_vMaxDriftVel.z));

			if (!m_bIgnoreWind)
			{
				VEC_ADD(vDriftVel, vDriftVel, g_vWorldWindVel);
			}

			GetRandomColorInRange(vColor);

            LTFLOAT fLifeTime = GetRandom(m_fMinParticleLife, m_fMaxParticleLife);

			vDriftVel -= (m_vVel * 0.1f);

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

		m_fElapsedEmissionTime = 0.0f;
	}


	return CBaseParticleSystemFX::Update();
}
Beispiel #22
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);
}
Beispiel #23
0
DBOOL CMarkSFX::CreateObject(CClientDE *pClientDE)
{
	if (!CSpecialFX::CreateObject(pClientDE)) return DFALSE;

	CSFXMgr* psfxMgr = g_pBloodClientShell->GetSFXMgr();
	if (!psfxMgr) return DFALSE;


	// Before we create a new buillet hole see if there is already another
	// bullet hole close by that we could use instead...

	CSpecialFXList* pList = psfxMgr->GetBulletHoleFXList();
	if (!pList) return DFALSE;

	int nNumBulletHoles = pList->GetSize();

	HOBJECT hMoveObj		 = DNULL;
	HOBJECT hObj			 = DNULL;
	DFLOAT	fClosestMarkDist = REGION_DIAMETER;
	DBYTE	nNumInRegion	 = 0;
	DVector vPos;

	for (int i=0; i < nNumBulletHoles; i++)
	{
		if ((*pList)[i])
		{
			hObj = (*pList)[i]->GetObject();
			if (hObj)
			{
				pClientDE->GetObjectPos(hObj, &vPos);
				
				DFLOAT fDist = VEC_DISTSQR(vPos, m_Pos);
				if (fDist < REGION_DIAMETER)
				{
					if (fDist < fClosestMarkDist)
					{
						fClosestMarkDist = fDist;
						hMoveObj = hObj;
					}

					if (++nNumInRegion > MAX_MARKS_IN_REGION)
					{
						// Just move this bullet-hole to the correct pos, and
						// remove thyself...

						pClientDE->SetObjectPos(hMoveObj, &m_Pos);
						return DFALSE;
					}
				}
			}
		}
	}


	// Setup the mark...
	ObjectCreateStruct createStruct;
	INIT_OBJECTCREATESTRUCT(createStruct);

	createStruct.m_ObjectType = OT_SPRITE;
	_mbscpy((unsigned char*)createStruct.m_Filename, (const unsigned char*)m_pClientDE->GetStringData( m_hstrSprite ));
	createStruct.m_Flags	  = FLAG_VISIBLE | FLAG_ROTATEABLESPRITE;
	VEC_COPY(createStruct.m_Pos, m_Pos);
	ROT_COPY( createStruct.m_Rotation, m_Rotation );

	m_hObject = pClientDE->CreateObject(&createStruct);

	m_pClientDE->SetObjectScale(m_hObject, &m_vScale);


	// See what it hit
	DVector vU, vR;
	pClientDE->GetRotationVectors(&m_Rotation, &vU, &vR, &m_vForward);

	ClientIntersectQuery iq;
	ClientIntersectInfo  ii;

	iq.m_Flags = INTERSECT_OBJECTS | INTERSECT_HPOLY;

	VEC_COPY(iq.m_From, vPos);			// Get start point at the last known position.
	VEC_MULSCALAR(iq.m_To, m_vForward, -1.0f);
	VEC_ADD(iq.m_To, iq.m_To, iq.m_From);	// Get destination point slightly past where we should be

	// Hit something!  try to clip against it. (since this is only being used for bullet marks,
	if (pClientDE->IntersectSegment(&iq, &ii))
	{
		HPOLY hPoly = ii.m_hPoly;
		pClientDE->ClipSprite(m_hObject, hPoly);
	}
	m_pClientDE->SetObjectColor(m_hObject, 0.1f, 0.1f, 0.1f, 1.0f);
	
	return DTRUE;
}
LTBOOL CBaseParticleSystemFX::Update()
{
    if (!CSpecialFX::Update() || !m_hObject || !m_pClientDE) return LTFALSE;


	// See if we should rotate this bad-boy...

	if (m_vRotVel.x != 0.0f || m_vRotVel.y != 0.0f || m_vRotVel.z != 0.0f)
	{
        LTFLOAT fDelta = g_pGameClientShell->GetFrameTime();

        LTRotation rRot;
		m_pClientDE->GetObjectRotation(m_hObject, &rRot);

        LTVector vTemp;
		VEC_MULSCALAR(vTemp, m_vRotVel, fDelta);
		VEC_ADD(m_vRotAmount, m_vRotAmount, vTemp);

		if (m_vRotVel.x != 0.0f) m_pClientDE->EulerRotateX(&rRot, m_vRotAmount.x);
		if (m_vRotVel.y != 0.0f) m_pClientDE->EulerRotateY(&rRot, m_vRotAmount.y);
		if (m_vRotVel.z != 0.0f) m_pClientDE->EulerRotateZ(&rRot, m_vRotAmount.z);

		m_pClientDE->SetObjectRotation(m_hObject, &rRot);
	}


	// Update each particles scale / alpha if necessary...

    LTParticle *pCur, *pTail;

	if (m_basecs.bAdjustParticleScale || m_basecs.bAdjustParticleAlpha)
	{
		if (m_pClientDE->GetParticles(m_hObject, &pCur, &pTail))
		{
            LTFLOAT fLifetime = 0.0f, fTotalLifetime = 0.0f;
            LTFLOAT fAlphaRange = m_basecs.fEndParticleAlpha - m_basecs.fStartParticleAlpha;
            LTFLOAT fScaleRange = m_basecs.fEndParticleScale - m_basecs.fStartParticleScale;
            LTVector vColorRange = m_vColor2 - m_vColor1;

			while (pCur && pCur != pTail)
			{
				m_pClientDE->GetParticleLifetime(m_hObject, pCur, fLifetime);
				m_pClientDE->GetParticleTotalLifetime(m_hObject, pCur, fTotalLifetime);

				if (fLifetime > 0.0f && fTotalLifetime > 0.0f)
				{
                    LTFLOAT fLifePercent = 1.0f - (fLifetime / fTotalLifetime);

					// Adjust scale...

					if (m_basecs.bAdjustParticleScale)
					{
						pCur->m_Size = m_fRadius * (m_basecs.fStartParticleScale + (fScaleRange * fLifePercent));
					}

					// Adjust alpha...

					if (m_basecs.bAdjustParticleAlpha)
					{
						pCur->m_Alpha = m_basecs.fStartParticleAlpha + (fAlphaRange * fLifePercent);
					}
				}

				pCur = pCur->m_pNext;
			}
		}
	}


	// Make sure we update our position relative to the server object
	// (if the server object is valid and the client isn't controling
	// the particle system pos)...

	if (m_hServerObject && !m_basecs.bClientControlsPos)
	{
        LTVector vNewPos;
		m_pClientDE->GetObjectPos(m_hServerObject, &vNewPos);
		vNewPos += m_vPosOffset;

		m_pClientDE->SetObjectPos(m_hObject, &vNewPos);
	}

    return LTTRUE;
}
void CFolderWeaponControls::CreateModelSFX()
{
	// no model = no SFX
	if (!strlen(m_szModel)) return;

	HOBJECT hCamera = g_pGameClientShell->GetInterfaceCamera();
	if (!hCamera) return;


	BSCREATESTRUCT bcs;

    LTVector vPos, vU, vR, vF, vTemp, vScale(1.0f,1.0f,1.0f);
    LTRotation rRot;

    g_pLTClient->GetObjectPos(hCamera, &vPos);
    g_pLTClient->GetObjectRotation(hCamera, &rRot);
    g_pLTClient->GetRotationVectors(&rRot, &vU, &vR, &vF);

    g_pLTClient->RotateAroundAxis(&rRot, &vU, MATH_HALFPI);
    g_pLTClient->RotateAroundAxis(&rRot, &vR, -0.3f);

	VEC_MULSCALAR(vScale, vScale, m_fScale);

    LTVector vModPos = g_pLayoutMgr->GetFolderCustomVector((eFolderID)m_nFolderID,"ModelPos");
	VEC_ADD(vModPos,vModPos,m_vOffset);

	VEC_MULSCALAR(vTemp, vF, vModPos.z);
	VEC_MULSCALAR(vTemp, vTemp, g_pInterfaceResMgr->GetXRatio());
	VEC_ADD(vPos, vPos, vTemp);

	VEC_MULSCALAR(vTemp, vR, vModPos.x);
	VEC_ADD(vPos, vPos, vTemp);

	VEC_MULSCALAR(vTemp, vU, vModPos.y);
	VEC_ADD(vPos, vPos, vTemp);


	VEC_COPY(bcs.vPos, vPos);
    bcs.rRot = rRot;
	VEC_COPY(bcs.vInitialScale, vScale);
	VEC_COPY(bcs.vFinalScale, vScale);
	VEC_SET(bcs.vInitialColor, 1.0f, 1.0f, 1.0f);
	VEC_SET(bcs.vFinalColor, 1.0f, 1.0f, 1.0f);
    bcs.bUseUserColors = LTTRUE;

	bcs.pFilename = m_szModel;
	bcs.pSkin = m_szSkin;
	bcs.dwFlags = FLAG_VISIBLE | FLAG_FOGDISABLE | FLAG_NOLIGHT;
	bcs.nType = OT_MODEL;
	bcs.fInitialAlpha = 1.0f;
	bcs.fFinalAlpha = 1.0f;
	bcs.fLifeTime = 1000000.0f;

	if (m_ModelSFX.Init(&bcs))
	{
        m_ModelSFX.CreateObject(g_pLTClient);
		g_pInterfaceMgr->AddInterfaceSFX(&m_ModelSFX, IFX_NORMAL);
		m_fSFXRot = g_pLayoutMgr->GetFolderCustomFloat((eFolderID)m_nFolderID,"ModelRotSpeed");
	}

}
Beispiel #26
0
DDWORD BugAI::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
	switch(messageID)
	{
		case MID_PRECREATE:
		{
			// Need to call base class to have the object name read in before
			// we call PostPropRead()

			DDWORD dwRet = AI_Mgr::EngineMessageFn(messageID, pData, fData);

			if (fData == 1.0)
				AI_Mgr::ReadProp((ObjectCreateStruct*)pData);  // inside BaseCharacter

			PostPropRead((ObjectCreateStruct*)pData);

			return dwRet;
		}
		break;
        
		case MID_INITIALUPDATE:
		{
			InitialUpdate((DVector *)pData);
			break;
		}

		case MID_UPDATE:
		{
			CServerDE* pServerDE = GetServerDE();
			if (!pServerDE) return 0;

			//gotta keep the bug stuck to whatever surface it is on
			DRotation rRot;
			DVector vU,vR,vF,vVel,vPos;

			pServerDE->GetObjectPos(m_hObject,&vPos);
			pServerDE->GetObjectRotation(m_hObject,&rRot);
			pServerDE->GetRotationVectors(&rRot,&vU,&vR,&vF);
			VEC_MULSCALAR(vVel,vU,-15.0f);

			Move(vVel, MATH_EPSILON);

			//check if there is something below, if not rotate
			IntersectQuery IQuery;
			IntersectInfo ii;
	
			IQuery.m_Flags	  = INTERSECT_OBJECTS;
			IQuery.m_FilterFn = DNULL;

			DVector vTemp;
			VEC_MULSCALAR(vTemp,vU,-2.0f);
			VEC_COPY(IQuery.m_From,vPos);
			VEC_ADD(IQuery.m_To,IQuery.m_From,vTemp);

			if(pServerDE->IntersectSegment(&IQuery, &ii))
			{
				DRotation rRot;
				DVector vDown;

				VEC_MULSCALAR(vDown,vU,-1.0f);
				pServerDE->AlignRotation(&rRot,&vDown,&vF);

				pServerDE->SetObjectRotation(m_hObject,&rRot);
			}
		}
		break;

		default : break;
	}


	return AI_Mgr::EngineMessageFn(messageID, pData, fData);
}
Beispiel #27
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;
    }
}
Beispiel #28
0
LTBOOL CParticleExplosionFX::CreateObject(ILTClient *pClientDE)
{
    LTBOOL bRet = CBaseParticleSystemFX::CreateObject(pClientDE);
    if (!bRet) return bRet;

    // Initialize the emmitters velocity ranges based on our rotation...

    LTVector vVelMin, vVelMax, vTemp, vU, vR, vF;
    VEC_SET(vVelMin, 1.0f, 1.0f, 1.0f);
    VEC_SET(vVelMax, 1.0f, 1.0f, 1.0f);

    m_pClientDE->Common()->GetRotationVectors(m_rSurfaceRot, vU, vR, vF);

    if (vF.y <= -0.95f || vF.y >= 0.95f)
    {
        vF.y = vF.y > 0.0f ? 1.0f : -1.0f;
        VEC_SET(vR, 1.0f, 0.0f, 0.0f);
        VEC_SET(vU, 0.0f, 0.0f, 1.0f);
    }
    else if (vF.x <= -0.95f || vF.x >= 0.95f)
    {
        vF.x = vF.x > 0.0f ? 1.0f : -1.0f;
        VEC_SET(vR, 0.0f, 1.0f, 0.0f);
        VEC_SET(vU, 0.0f, 0.0f, 1.0f);
    }
    else if (vF.z <= -0.95f || vF.z >= 0.95f)
    {
        vF.z = vF.z > 0.0f ? 1.0f : -1.0f;
        VEC_SET(vR, 1.0f, 0.0f, 0.0f);
        VEC_SET(vU, 0.0f, 1.0f, 0.0f);
    }

    VEC_MULSCALAR(vVelMin, vF, m_vMinVel.y);
    VEC_MULSCALAR(vVelMax, vF, m_vMaxVel.y);

    VEC_MULSCALAR(vTemp, vR, m_vMinVel.x);
    VEC_ADD(vVelMin, vVelMin, vTemp);

    VEC_MULSCALAR(vTemp, vR, m_vMaxVel.x);
    VEC_ADD(vVelMax, vVelMax, vTemp);

    VEC_MULSCALAR(vTemp, vU, m_vMinVel.z);
    VEC_ADD(vVelMin, vVelMin, vTemp);

    VEC_MULSCALAR(vTemp, vU, m_vMaxVel.z);
    VEC_ADD(vVelMax, vVelMax, vTemp);


    // Initialize our emmitters...

    LTVector vStartVel;
    for (int i=0; i < m_nNumEmmitters; i++)
    {
        if (m_bCreateDebris)
        {
            m_hDebris[i] = CreateDebris();
        }

        m_ActiveEmmitters[i] = LTTRUE;
        m_BounceCount[i] = 2;

        VEC_SET(vStartVel, GetRandom(vVelMin.x, vVelMax.x),
                GetRandom(vVelMin.y, vVelMax.y),
                GetRandom(vVelMin.z, vVelMax.z));

        InitMovingObject(&(m_Emmitters[i]), &m_vPos, &vStartVel);
        m_Emmitters[i].m_PhysicsFlags |= m_nEmmitterFlags;
    }

    return bRet;
}
Beispiel #29
0
void M2M(FmmvHandle *FMMV, Box *box)
{
        int p = FMMV->pM;
	int len0 = (p+1)*(p+1);
	int len = (p+1)*(p+2);
        int *P_RT = FMMV->P_MRT;
	int *P_riri2rrii = FMMV->P_Mriri2rrii;

	_FLOAT_ x1[(FMM_P_MAX+1)*(FMM_P_MAX+2)];
	_FLOAT_ x2[(FMM_P_MAX+1)*(FMM_P_MAX+2)];
	_FLOAT_ xx[(FMM_P_MAX+1)*(FMM_P_MAX+2)];

	if (!isSource(box)) return;
	
	if (isSource(box->child[SWD])&&box->child[SWD]->M) {
		Rz_pi4(p, box->child[SWD]->M, x2);
		perm(len0, P_riri2rrii, x2, x1);
		Ry(p, FMMV->Ry_pi_minus_theta, x1, x2);
		perm(len0, P_RT, x2, x1);
		Tz_M2M(FMMV, x1);
		perm_inv(len0, P_RT, x1, xx);
		if (isSource(box->child[NEU])&&box->child[NEU]->M) {
			Rz_pi4(p, box->child[NEU]->M, x2);
			perm(len0, P_riri2rrii, x2, x1);
			Ry(p, FMMV->Ry_minus_theta, x1, x2);
			perm(len0, P_RT, x2, x1);
			Tz_M2M(FMMV, x1);
			perm_inv(len0, P_RT, x1, x2);
			Ry_pi(p, x2);
			VEC_ADD(len, x2, xx, xx);
		}
		Ry(p, FMMV->Ry_minus_pi_minus_theta, xx, x1);
		perm_inv(len0, P_riri2rrii, x1, x2);
		Rz_minus_pi4(p, x2, x1);
		box->M = VEC_ADD2(FMMV, len, x1, box->M);
	}
	else if (isSource(box->child[NEU])&&box->child[NEU]->M) {
		Rz_pi4(p, box->child[NEU]->M, x2);
		perm(len0, P_riri2rrii, x2, x1);
		Ry(p, FMMV->Ry_minus_theta,x1, x2);
		perm(len0, P_RT, x2, x1);
		Tz_M2M(FMMV, x1);
		perm_inv(len0, P_RT, x1, x2);
		Ry(p, FMMV->Ry_theta, x2, x1);
		perm_inv(len0, P_riri2rrii, x1, x2);
		Rz_minus_pi4(p, x2, x1);
		box->M = VEC_ADD2(FMMV, len, x1, box->M);
	}
	if (isSource(box->child[NWD])&&box->child[NWD]->M) {
		Rz_minus_pi4(p, box->child[NWD]->M, x2);
		perm(len0, P_riri2rrii, x2, x1);
		Ry(p, FMMV->Ry_pi_minus_theta, x1, x2);
		perm(len0, P_RT, x2, x1);
		Tz_M2M(FMMV, x1);
		perm_inv(len0, P_RT, x1, xx);
		if (isSource(box->child[SEU])&&box->child[SEU]->M) {
			Rz_minus_pi4(p, box->child[SEU]->M, x2);
			perm(len0, P_riri2rrii, x2, x1);
			Ry(p, FMMV->Ry_minus_theta, x1, x2);
			perm(len0, P_RT, x2, x1);
			Tz_M2M(FMMV, x1);
			perm_inv(len0, P_RT, x1, x2);
			Ry_pi(p, x2);
			VEC_ADD(len, x2, xx, xx);
		}
		Ry(p, FMMV->Ry_minus_pi_minus_theta, xx, x1);
		perm_inv(len0, P_riri2rrii, x1, x2);
		Rz_pi4(p, x2, x1);
		box->M = VEC_ADD2(FMMV, len, x1, box->M);
	}
	else if (isSource(box->child[SEU])&&box->child[SEU]->M) {
		Rz_minus_pi4(p, box->child[SEU]->M, x2);
		perm(len0, P_riri2rrii, x2, x1);
		Ry(p, FMMV->Ry_minus_theta, x1, x2);
		perm(len0, P_RT, x2, x1);
		Tz_M2M(FMMV, x1);
		perm_inv(len0, P_RT, x1, x2);
		Ry(p, FMMV->Ry_theta, x2, x1);
		perm_inv(len0, P_riri2rrii, x1, x2);
		Rz_pi4(p, x2, x1);
		box->M = VEC_ADD2(FMMV, len, x1, box->M);
	}
	if (isSource(box->child[SED])&&box->child[SED]->M) {
		Rz_3pi4(p, box->child[SED]->M, x2);
		perm(len0, P_riri2rrii, x2, x1);
		Ry(p, FMMV->Ry_pi_minus_theta, x1, x2);
		perm(len0, P_RT, x2, x1);
		Tz_M2M(FMMV, x1);
		perm_inv(len0, P_RT, x1, xx);
		if (isSource(box->child[NWU])&&box->child[NWU]->M) {
			Rz_3pi4(p, box->child[NWU]->M, x2);
			perm(len0, P_riri2rrii, x2, x1);
			Ry(p, FMMV->Ry_minus_theta, x1, x2);
			perm(len0, P_RT, x2, x1);
			Tz_M2M(FMMV, x1);
			perm_inv(len0, P_RT, x1, x2);
			Ry_pi(p, x2);
			VEC_ADD(len, x2, xx, xx);
		}
		Ry(p, FMMV->Ry_minus_pi_minus_theta, xx, x1);
		perm_inv(len0, P_riri2rrii, x1, x2);
		Rz_minus_3pi4(p, x2, x1);
		box->M = VEC_ADD2(FMMV, len, x1, box->M);
	}
	else if (isSource(box->child[NWU])&&box->child[NWU]->M) {
		Rz_3pi4(p, box->child[NWU]->M, x2);
		perm(len0, P_riri2rrii, x2, x1);
		Ry(p, FMMV->Ry_minus_theta, x1, x2);
		perm(len0, P_RT, x2, x1);
		Tz_M2M(FMMV, x1);
		perm_inv(len0, P_RT, x1, x2);
		Ry(p, FMMV->Ry_theta, x2, x1);
		perm_inv(len0, P_riri2rrii, x1, x2);
		Rz_minus_3pi4(p, x2, x1);
		box->M = VEC_ADD2(FMMV, len, x1, box->M);
	}
	if (isSource(box->child[NED])&&box->child[NED]->M) {
		Rz_minus_3pi4(p, box->child[NED]->M, x2);
		perm(len0, P_riri2rrii, x2, x1);
		Ry(p, FMMV->Ry_pi_minus_theta, x1, x2);
		perm(len0, P_RT, x2, x1);
		Tz_M2M(FMMV, x1);
		perm_inv(len0, P_RT, x1, xx);
		if (isSource(box->child[SWU])&&box->child[SWU]->M) {
			Rz_minus_3pi4(p, box->child[SWU]->M, x2);
			perm(len0, P_riri2rrii, x2, x1);
			Ry(p, FMMV->Ry_minus_theta, x1, x2);
			perm(len0, P_RT, x2, x1);
			Tz_M2M(FMMV, x1);
			perm_inv(len0, P_RT, x1, x2);
			Ry_pi(p, x2);
			VEC_ADD(len, x2, xx, xx);
		}
		Ry(p, FMMV->Ry_minus_pi_minus_theta, xx, x1);
		perm_inv(len0, P_riri2rrii, x1, x2);
		Rz_3pi4(p, x2, x1);
		box->M = VEC_ADD2(FMMV, len, x1, box->M);
	}
	else if (isSource(box->child[SWU])&&box->child[SWU]->M) {
		Rz_minus_3pi4(p, box->child[SWU]->M, x2);
		perm(len0, P_riri2rrii, x2, x1);
		Ry(p, FMMV->Ry_minus_theta, x1, x2);
		perm(len0, P_RT, x2, x1);
		Tz_M2M(FMMV, x1);
		perm_inv(len0, P_RT, x1, x2);
		Ry(p, FMMV->Ry_theta, x2, x1);
		perm_inv(len0, P_riri2rrii, x1, x2);
		Rz_3pi4(p, x2, x1);
		box->M = VEC_ADD2(FMMV, len, x1, box->M);
	}
}
Beispiel #30
0
LTBOOL CSmokeFX::Update()
{
	if(!m_hObject || !m_pClientDE) return LTFALSE;

	LTFLOAT fTime = m_pClientDE->GetTime();

	if (m_fStartTime < 0)
	{
		m_fStartTime = m_fLastTime = fTime;
	}


	// Make sure we update our position relative to the server object (if the
	// server object is valid)...

	if (m_hServerObject)
	{
		LTVector vServPos;
		m_pClientDE->GetObjectPos(m_hServerObject, &vServPos);
		m_pClientDE->SetObjectPos(m_hObject, &vServPos);
	}


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

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


	// See if it is time to add some more smoke...

	if (fTime > m_fLastTime + m_fParticleCreateDelta)
	{
		LTVector vDriftVel, vColor, vPos;

		// What is the range of colors?

		LTFLOAT fRange = m_vColor2.x - m_vColor1.x;


		// Build the individual smoke puffs...

		for (uint32 j=0; j < m_nNumParticles; j++)
		{
			VEC_SET(vPos,  GetRandom(-m_fVolumeRadius, m_fVolumeRadius),
					-2.0f, GetRandom(-m_fVolumeRadius, m_fVolumeRadius));

			VEC_SET(vDriftVel,	
					GetRandom(m_vMinDriftVel.x, m_vMaxDriftVel.x), 
					GetRandom(m_vMinDriftVel.y, m_vMaxDriftVel.y), 
					GetRandom(m_vMinDriftVel.z, m_vMaxDriftVel.z));

			if (!m_bIgnoreWind)
			{
				VEC_ADD(vDriftVel, vDriftVel, g_vWorldWindVel);
			}

			GetRandomColorInRange(vColor);

			LTFLOAT fLifeTime = GetRandom(m_fMinParticleLife, m_fMaxParticleLife);

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

		m_fLastTime = fTime;
	}

	return LTTRUE;
}