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); }
//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; }
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; }
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(); } } }
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); } }
//----------------------------------------------------------------------------- // 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; }
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; }
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); } }