Example #1
0
void FGPropagate::CalculateQuatdot(void)
{
  vOmegaLocal.InitMatrix( radInv*vVel(eEast),
                         -radInv*vVel(eNorth),
                         -radInv*vVel(eEast)*VState.vLocation.GetTanLatitude() );

  // Compute quaternion orientation derivative on current body rates
  vQtrndot = VState.vQtrn.GetQDot( VState.vPQR - Tl2b*vOmegaLocal);
}
Example #2
0
//given a particle position, a limit on the velocities, and the acceleration type, this will generate the 
//appropriate velocity
static LTVector GenerateObjectSpaceParticleVel(ePSVelocityType eType, const LTVector& vObjSpacePos, 
											   const LTVector& vMinVelocity, const LTVector& vMaxVelocity)
{
	LTVector vVel(0, 0, 0);

	// Randomize the velocity within our range
	switch(eType)
	{
	case PSV_eRandom:
		{
			vVel.x = GetRandom( vMinVelocity.x, vMaxVelocity.x );
			vVel.y = GetRandom( vMinVelocity.y, vMaxVelocity.y );
			vVel.z = GetRandom( vMinVelocity.z, vMaxVelocity.z );
		}
		break;
	case PSV_eCenter:
		{
			//velocity direction is based upon position from 0, 0, 0
			float fMag = LTMAX(vObjSpacePos.Mag(), 0.01f);
			vVel = vObjSpacePos * (GetRandom(vMinVelocity.x, vMaxVelocity.x) / fMag);
		}
		break;
	default:
		LTERROR( "Unknown particle velocity type");
		break;
	}

	return vVel;
}
Example #3
0
LTVector CDebrisSystemFX::GenerateObjectSpaceDebrisVel(const LTVector& vObjSpacePos, const LTVector& vMinVelocity, const LTVector& vMaxVelocity)
{
	LTVector vVel(0, 0, 0);

	// Randomize the velocity within our range
	switch(GetProps()->m_eVelocityType)
	{
	case eDebrisVelocity_Random:
		{
			vVel.x = GetRandom( vMinVelocity.x, vMaxVelocity.x );
			vVel.y = GetRandom( vMinVelocity.y, vMaxVelocity.y );
			vVel.z = GetRandom( vMinVelocity.z, vMaxVelocity.z );
		}
		break;
	case eDebrisVelocity_Center:
		{
			//velocity direction is based upon position from 0, 0, 0
			vVel = vObjSpacePos * (GetRandom(vMinVelocity.x, vMaxVelocity.x) / vObjSpacePos.Mag());
		}
		break;
	default:
		LTERROR( "Unknown Debris velocity type");
		break;
	}

	return vVel;
}
Example #4
0
void CLipstickProx::HandleImpact(HOBJECT hObj)
{
	CGrenade::HandleImpact(hObj);

	if (!g_vtProxGrenadeArmDelay.IsInitted())
	{
        g_vtProxGrenadeArmDelay.Init(g_pLTServer, "ProxArmDelay", LTNULL, -1.0f);
	}

	if (!g_vtProxGrenadeDetonateDelay.IsInitted())
	{
        g_vtProxGrenadeDetonateDelay.Init(g_pLTServer, "ProxDetonateDelay", LTNULL, -1.0f);
	}

	// See if we should stick to the object we just hit...

	SURFACE* pSurf = g_pSurfaceMgr->GetSurface(m_eLastHitSurface);
	if (pSurf)
	{
		// Does this surface support magnatism?  If so, stick...

		if (pSurf->bMagnetic)
		{
			// Need to set velocity to 0.0f but account for stoping vel
			// being added back in...

			CollisionInfo info;
            g_pLTServer->GetLastCollision(&info);

			LTVector vVel(0, 0, 0);
			vVel -= info.m_vStopVel;
			g_pLTServer->SetVelocity(m_hObject, &vVel);

			m_vSurfaceNormal.Init(0, 1, 0);
			m_vSurfaceNormal = info.m_Plane.m_Normal;


			// Turn off gravity, solid, and touch notify....
			// And turn on go-thru-world so it doesn't reflect from the ending position

            uint32 dwFlags = g_pLTServer->GetObjectFlags(m_hObject);
			dwFlags &= ~(FLAG_GRAVITY | FLAG_TOUCH_NOTIFY | FLAG_SOLID);
			dwFlags |= FLAG_GOTHRUWORLD;
            g_pLTServer->SetObjectFlags(m_hObject, dwFlags);


			// Rotate to rest...

			RotateToRest();
		}
	}
}
Example #5
0
void CRouter::MoveLinearly(D3DXVECTOR3 *vCurPos, D3DXMATRIX *mat, const float fSpeed, float fTime)
{
	D3DXVECTOR3 vVel(mat->_31,0,mat->_33);
	D3DXVec3Normalize(&vVel, &vVel);
	vVel *= fSpeed;
	D3DXVECTOR3 vTrans = vVel*fTime;
	*vCurPos += vTrans;
	//平移调整物体世界坐标方向矩阵
	D3DXMATRIX mTrans;
	D3DXMatrixTranslation(&mTrans, vTrans.x, vTrans.y, vTrans.z);
	D3DXMatrixMultiply(mat, mat, &mTrans);
	if(fabs(m_fAgl2Ajust) > 1e-4)
	{
		AdjustYaw(m_fPerAgl, mat);
	}

}
Example #6
0
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Renders the particle system using pointsprites loaded in a vertex
//       buffer.
//
// Note: D3DLOCK_DISCARD:
//
//       The application overwrites, with a write-only operation, the entire
//       index buffer. This enables Direct3D to return a pointer to a new
//       memory area so that the dynamic memory access (DMA) and rendering
//       from the old area do not stall.
//
//       D3DLOCK_NOOVERWRITE:
//
//       Indicates that no vertices that were referred to in drawing calls
//       since the start of the frame or the last lock without this flag will
//       be modified during the lock. This can enable optimizations when the
//       application is appending data only to the vertex buffer.
//-----------------------------------------------------------------------------
HRESULT CParticleSystem::Render( LPDIRECT3DDEVICE9 pd3dDevice )
{
    HRESULT hr;

    //
    // Set the render states for using point sprites..
    //

    pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );       // Turn on point sprites
    pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  TRUE );       // Allow sprites to be scaled with distance
    pd3dDevice->SetRenderState( D3DRS_POINTSIZE,     FtoDW(m_fSize) ); // Float value that specifies the size to use for point size computation in cases where point size is not specified for each vertex.
    pd3dDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(1.0f) );    // Float value that specifies the minimum size of point primitives. Point primitives are clamped to this size during rendering.
    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_A,  FtoDW(0.0f) );    // Default 1.0
    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_B,  FtoDW(0.0f) );    // Default 0.0
    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_C,  FtoDW(1.0f) );    // Default 0.0

    Particle    *pParticle = m_pActiveList;
    PointVertex *pVertices;
    DWORD        dwNumParticlesToRender = 0;

    // Lock the vertex buffer.  We fill the vertex buffer in small
    // chunks, using D3DLOCK_NOOVERWRITE.  When we are done filling
    // each chunk, we call DrawPrim, and lock the next chunk.  When
    // we run out of space in the vertex buffer, we start over at
    // the beginning, using D3DLOCK_DISCARD.

    // Move the offset forward so we can fill the next chunk of the vertex buffer
    m_dwVBOffset += m_dwFlush;

    // If we're about to overflow the buffer, reset the offset counter back to 0
    if( m_dwVBOffset >= m_dwDiscard )
        m_dwVBOffset = 0;

    if( FAILED( hr = m_pVB->Lock( m_dwVBOffset * sizeof(PointVertex), // Offset to lock
                                  m_dwFlush * sizeof(PointVertex),    // Size to lock
                                  (void**) &pVertices,
                                  m_dwVBOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD)))
    {
        return hr;
    }

    // Render each particle
    while( pParticle )
    {
        D3DXVECTOR3 vPos(pParticle->m_vCurPos);
        D3DXVECTOR3 vVel(pParticle->m_vCurVel);

        pVertices->posit = vPos;
        pVertices->color = m_clrColor;
        pVertices++;

        if( ++dwNumParticlesToRender == m_dwFlush )
        {
            // Done filling this chunk of the vertex buffer.  Lets unlock and
            // draw this portion so we can begin filling the next chunk.

            m_pVB->Unlock();

            pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(PointVertex) );
            pd3dDevice->SetFVF( PointVertex::FVF_Flags );

            if( FAILED(hr = pd3dDevice->DrawPrimitive( D3DPT_POINTLIST,
                            m_dwVBOffset, dwNumParticlesToRender)))
            {
                return hr;
            }

            // Lock the next chunk of the vertex buffer.  If we are at the
            // end of the vertex buffer, DISCARD the vertex buffer and start
            // at the beginning.  Otherwise, specify NOOVERWRITE, so we can
            // continue filling the VB while the previous chunk is drawing.
            m_dwVBOffset += m_dwFlush;

            // If we're about to overflow the buffer, reset the offset counter back to 0
            if( m_dwVBOffset >= m_dwDiscard )
                m_dwVBOffset = 0;

            if( FAILED( hr = m_pVB->Lock(
                                 m_dwVBOffset * sizeof(PointVertex), // Offset to lock
                                 m_dwFlush    * sizeof(PointVertex), // Size to lock
                                 (void**) &pVertices,
                                 m_dwVBOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD)))
            {
                return hr;
            }

            dwNumParticlesToRender = 0;
        }

        pParticle = pParticle->m_pNext;
    }

    // Unlock the vertex buffer
    m_pVB->Unlock();

    // Render any remaining particles
    if( dwNumParticlesToRender )
    {
        pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(PointVertex) );
        pd3dDevice->SetFVF( PointVertex::FVF_Flags );

        if(FAILED(hr = pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwVBOffset,
                       dwNumParticlesToRender )))
            return hr;
    }

    //
    // Reset render states...
    //

    pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );
    pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  FALSE );

    return S_OK;
}
Example #7
0
bool FGAuxiliary::Run()
{
  double A,B,D;

  if (FGModel::Run()) return true; // return true if error returned from base class
  if (FDMExec->Holding()) return false;

  const FGColumnVector3& vPQR = Propagate->GetPQR();
  const FGColumnVector3& vUVW = Propagate->GetUVW();
  const FGColumnVector3& vUVWdot = Propagate->GetUVWdot();
  const FGColumnVector3& vVel = Propagate->GetVel();

  p = Atmosphere->GetPressure();
  rhosl = Atmosphere->GetDensitySL();
  psl = Atmosphere->GetPressureSL();
  sat = Atmosphere->GetTemperature();

// Rotation

  double cTht = Propagate->GetCosEuler(eTht);
  double sTht = Propagate->GetSinEuler(eTht);
  double cPhi = Propagate->GetCosEuler(ePhi);
  double sPhi = Propagate->GetSinEuler(ePhi);

  vEulerRates(eTht) = vPQR(eQ)*cPhi - vPQR(eR)*sPhi;
  if (cTht != 0.0) {
    vEulerRates(ePsi) = (vPQR(eQ)*sPhi + vPQR(eR)*cPhi)/cTht;
    vEulerRates(ePhi) = vPQR(eP) + vEulerRates(ePsi)*sTht;
  }

// 12/16/2005, JSB: For ground handling purposes, at this time, let's ramp
// in the effects of wind from 10 fps to 30 fps when there is weight on the
// landing gear wheels.

  if (GroundReactions->GetWOW() && vUVW(eU) < 10) {
    vAeroPQR = vPQR;
    vAeroUVW = vUVW;
  } else if (GroundReactions->GetWOW() && vUVW(eU) < 30) {
    double factor = (vUVW(eU) - 10.0)/20.0;
    vAeroPQR = vPQR - factor*Atmosphere->GetTurbPQR();
    vAeroUVW = vUVW - factor*Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
  } else {
    FGColumnVector3 wind = Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
    vAeroPQR = vPQR - Atmosphere->GetTurbPQR();
    vAeroUVW = vUVW - wind;
  }

  Vt = vAeroUVW.Magnitude();
  if ( Vt > 0.05) {
    if (vAeroUVW(eW) != 0.0)
      alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
    if (vAeroUVW(eV) != 0.0)
      beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV),
             sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;

    double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
    double signU=1;
    if (vAeroUVW(eU) != 0.0)
      signU = vAeroUVW(eU)/fabs(vAeroUVW(eU));

    if ( (mUW == 0.0) || (Vt == 0.0) ) {
      adot = 0.0;
      bdot = 0.0;
    } else {
      adot = (vAeroUVW(eU)*vUVWdot(eW) - vAeroUVW(eW)*vUVWdot(eU))/mUW;
      bdot = (signU*mUW*vUVWdot(eV) - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU)
              + vAeroUVW(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
    }
  } else {
    alpha = beta = adot = bdot = 0;
  }

  Re = Vt * Aircraft->Getcbar() / Atmosphere->GetKinematicViscosity();

  qbar = 0.5*Atmosphere->GetDensity()*Vt*Vt;
  qbarUW = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
  qbarUV = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV));
  Mach = Vt / Atmosphere->GetSoundSpeed();
  MachU = vMachUVW(eU) = vAeroUVW(eU) / Atmosphere->GetSoundSpeed();
  vMachUVW(eV) = vAeroUVW(eV) / Atmosphere->GetSoundSpeed();
  vMachUVW(eW) = vAeroUVW(eW) / Atmosphere->GetSoundSpeed();

// Position

  Vground = sqrt( vVel(eNorth)*vVel(eNorth) + vVel(eEast)*vVel(eEast) );

  psigt = atan2(vVel(eEast), vVel(eNorth));
  if (psigt < 0.0) psigt += 2*M_PI;
  gamma = atan2(-vVel(eDown), Vground);

  tat = sat*(1 + 0.2*Mach*Mach); // Total Temperature, isentropic flow
  tatc = RankineToCelsius(tat);

  if (MachU < 1) {   // Calculate total pressure assuming isentropic flow
    pt = p*pow((1 + 0.2*MachU*MachU),3.5);
  } else {
    // Use Rayleigh pitot tube formula for normal shock in front of pitot tube
    B = 5.76*MachU*MachU/(5.6*MachU*MachU - 0.8);
    D = (2.8*MachU*MachU-0.4)*0.4167;
    pt = p*pow(B,3.5)*D;
  }

  A = pow(((pt-p)/psl+1),0.28571);
  if (MachU > 0.0) {
    vcas = sqrt(7*psl/rhosl*(A-1));
    veas = sqrt(2*qbar/rhosl);
  } else {
    vcas = veas = 0.0;
  }

  vPilotAccel.InitMatrix();
  if ( Vt > 1.0 ) {
     vAircraftAccel = Aerodynamics->GetForces()
                    + Propulsion->GetForces()
                    + GroundReactions->GetForces()
                    + ExternalReactions->GetForces()
                    + BuoyantForces->GetForces();

     vAircraftAccel /= MassBalance->GetMass();
     // Nz is Acceleration in "g's", along normal axis (-Z body axis)
     Nz = -vAircraftAccel(eZ)/Inertial->gravity();
     vToEyePt = MassBalance->StructuralToBody(Aircraft->GetXYZep());
     vPilotAccel = vAircraftAccel + Propagate->GetPQRdot() * vToEyePt;
     vPilotAccel += vPQR * (vPQR * vToEyePt);
  } else {
     // The line below handles low velocity (and on-ground) cases, basically
     // representing the opposite of the force that the landing gear would
     // exert on the ground (which is just the total weight). This eliminates
     // any jitter that could be introduced by the landing gear. Theoretically,
     // this branch could be eliminated, with a penalty of having a short
     // transient at startup (lasting only a fraction of a second).
     vPilotAccel = Propagate->GetTl2b() * FGColumnVector3( 0.0, 0.0, -Inertial->gravity() );
     Nz = -vPilotAccel(eZ)/Inertial->gravity();
  }

  vPilotAccelN = vPilotAccel/Inertial->gravity();

  // VRP computation
  const FGLocation& vLocation = Propagate->GetLocation();
  FGColumnVector3 vrpStructural = Aircraft->GetXYZvrp();
  FGColumnVector3 vrpBody = MassBalance->StructuralToBody( vrpStructural );
  FGColumnVector3 vrpLocal = Propagate->GetTb2l() * vrpBody;
  vLocationVRP = vLocation.LocalToLocation( vrpLocal );

  // Recompute some derived values now that we know the dependent parameters values ...
  hoverbcg = Propagate->GetDistanceAGL() / Aircraft->GetWingSpan();

  FGColumnVector3 vMac = Propagate->GetTb2l()*MassBalance->StructuralToBody(Aircraft->GetXYZrp());
  hoverbmac = (Propagate->GetDistanceAGL() + vMac(3)) / Aircraft->GetWingSpan();

  // when all model are executed, 
  // please calculate the distance from the initial point

  CalculateRelativePosition();

  return false;
}
Example #8
0
void CLipstickProx::UpdateGrenade()
{
	CGrenade::UpdateGrenade();

	// If we're doing normal (in-air) updates, don't do any more
	// processing...

	if (m_bUpdating || !m_pClassData) return;


	// Make sure we aren't moving anymore...
		
	LTVector vVel(0, 0, 0);
	g_pLTServer->SetVelocity(m_hObject, &vVel);


	// Waiting to go boom...

	if (m_bActivated && m_DetonateTime.Stopped())
	{
        Detonate(LTNULL);
		return;
	}


	// See if it is time to arm yet...

	if (!m_bArmed && m_ArmTime.Stopped())
	{
        m_bArmed = LTTRUE;

		// Play armed sound...

		if (m_pClassData->szArmSound[0])
		{
			int nVolume = IsLiquid(m_eContainerCode) ? 50 : 100;

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

			g_pServerSoundMgr->PlaySoundFromPos(vPos, m_pClassData->szArmSound,
                (LTFLOAT)m_pClassData->nArmSndRadius, SOUNDPRIORITY_MISC_MEDIUM,
				0, nVolume);
		}
	}


	// Is there anything close enough to cause us to go boom?

	if (!m_bActivated && m_bArmed)
	{
		if (!m_pAmmoData) return;

        LTFLOAT fRadius = (LTFLOAT) m_pClassData->nActivateRadius;

		// NEED TO FIGURE OUT A BETTER WAY TO DO THIS!!!

        LTVector vPos;
        g_pLTServer->GetObjectPos(m_hObject, &vPos);
        ObjectList* pList = g_pLTServer->FindObjectsTouchingSphere(&vPos, fRadius);
		if (!pList) return;

		ObjectLink* pLink = pList->m_pFirstLink;
		while (pLink)
		{
			if (g_pGameServerShell->GetGameType() == COOPERATIVE_ASSAULT && IsPlayer(pLink->m_hObject) && IsPlayer(m_hFiredFrom) && g_vtNetFriendlyFire.GetFloat() < 1.0f)
			{
				CPlayerObj* pPlayer1 = (CPlayerObj*) g_pLTServer->HandleToObject(m_hFiredFrom);
				CPlayerObj* pPlayer2 = (CPlayerObj*) g_pLTServer->HandleToObject(pLink->m_hObject);
				if (pPlayer1 != pPlayer2 && pPlayer1->GetTeamID() == pPlayer2->GetTeamID())
				{
					//go to next obj
					pLink = pLink->m_pNext;
					continue;
				}
			}
			if (IsCharacter(pLink->m_hObject))
			{
                m_bActivated = LTTRUE;

                LTFLOAT fDelay = g_vtProxGrenadeDetonateDelay.GetFloat() < 0.0f ?
					m_pClassData->fActivateDelay : g_vtProxGrenadeDetonateDelay.GetFloat();

				m_DetonateTime.Start(fDelay);

				// Play activation sound...

				if (m_pClassData->szActivateSound[0])
				{
					int nVolume = IsLiquid(m_eContainerCode) ? 50 : 100;

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

					g_pServerSoundMgr->PlaySoundFromPos(vPos, m_pClassData->szActivateSound,
                        (LTFLOAT) m_pClassData->nActivateSndRadius,
						SOUNDPRIORITY_MISC_MEDIUM, 0, nVolume);
				}

				break;
			}

			pLink = pLink->m_pNext;
		}
        g_pLTServer->RelinquishList(pList);
	}
}