void CPedModelInfo::CreateHitColModelSkinned(RpClump* clump) { RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(clump); CColModel* hitColModel = new CColModel; RwMatrixTag* frameInverseMat = CGame::GetWorkingMatrix1(); RwMatrixTag* transformMatrix = CGame::GetWorkingMatrix2(); hitColModel->AllocateData(12, 0, 0, 0, 0, 0); RwMatrixInvert(frameInverseMat, &RpClumpGetFrame(clump)->modelling); for (size_t i = 0; i < ELEMS_COUNT(m_pColNodeInfos); i++) { CColSphere colSphere; colSphere.Set(m_pColNodeInfos[i].sphere.GetRadius(), m_pColNodeInfos[i].sphere.GetCenter()); CCollisionData* colData = hitColModel->GetColData(); *transformMatrix = *frameInverseMat; RwInt32 matIndex = RpHAnimIDGetIndex(hier, m_pColNodeInfos[i].animId) << 6; RwMatrix* mat = (RwMatrix*)(RpHAnimHierarchyGetMatrixArray(hier) + matIndex); RwMatrixTransform((RwMatrix *)transformMatrix, mat, rwCOMBINEPRECONCAT); RwV3dTransformPoints(&colSphere.center, &colSphere.center, 1, (RwMatrix *)transformMatrix); colSphere.SetSurfaceTypeA(EColSurface::PED); colSphere.SetSurfaceTypeB(m_pColNodeInfos[i].surfaceTypeB); colData->SetSphere(i, colSphere); } CBoundingBox boundingBox; CVector maxbb(0.5f, 0.5f, 1.2f); CVector minbb(-0.5f,-0.5f,-1.2f); CBox box; box.Set(minbb, maxbb); boundingBox.SetBoundingSphere(CSphere(0, 0, 0, 1.5f)); hitColModel->SetBoundingBox(boundingBox); hitColModel->SetColNum(0); m_hitColModel = hitColModel; }
// // Handle the changing state of collision between one entity and any colshape // void CColManager::DoHitDetectionForEntity ( const CVector& vecNowPosition, CElement* pEntity ) { std::map < CColShape*, int > shortList; // Get all entities within the sphere CElementResult queryResult; GetSpatialDatabase()->SphereQuery ( queryResult, CSphere ( vecNowPosition, 0.0f ) ); // Extract colshapes for ( CElementResult ::const_iterator it = queryResult.begin () ; it != queryResult.end (); ++it ) if ( (*it)->GetType () == CElement::COLSHAPE ) shortList[ (CColShape*)*it ] = 1; // Add existing collisions, so they can be disconnected if required for ( list < CColShape* > ::const_iterator it = pEntity->CollisionsBegin () ; it != pEntity->CollisionsEnd (); ++it ) shortList[ *it ] = 1; // Test each colshape against the entity for ( std::map < CColShape*, int > ::const_iterator it = shortList.begin () ; it != shortList.end (); ++it ) { CColShape* pShape = it->first; // Enabled and not being deleted? if ( !pShape->IsBeingDeleted () && pShape->IsEnabled () ) { // Collided? bool bHit = pShape->DoHitDetection ( vecNowPosition ); HandleHitDetectionResult ( bHit, pShape, pEntity ); } } }
/////////////////////////////////////////////////////////////// // // CClientModelCacheManagerImpl::DoPulseVehicleModels // // Pulse caching system for vehicle models // /////////////////////////////////////////////////////////////// void CClientModelCacheManagerImpl::DoPulseVehicleModels(void) { // Scale up query radius to compensate for the camera speed and possible vehicle speeds float fVehicleQueryRadius = VEHICLE_STREAM_IN_DISTANCE + STREAMER_STREAM_OUT_EXTRA_DISTANCE + m_fSmoothCameraSpeed * 2 + VEHICLE_MAX_VELOCITY * 2; // Get all entities within range CClientEntityResult result; GetClientSpatialDatabase()->SphereQuery(result, CSphere(m_vecCameraPos, fVehicleQueryRadius)); std::vector<CClientVehicle*> vehicleList; // For each entity found for (CClientEntityResult::const_iterator iter = result.begin(); iter != result.end(); ++iter) { switch ((*iter)->GetType()) { case CCLIENTVEHICLE: vehicleList.push_back((CClientVehicle*)*iter); break; } } // Compile a list of vehicle models which should be cached std::map<ushort, float> newNeedCacheList; ProcessVehicleList(newNeedCacheList, vehicleList, Square(VEHICLE_STREAM_IN_DISTANCE + STREAMER_STREAM_OUT_EXTRA_DISTANCE + m_fSmoothCameraSpeed * 2)); // Apply desired caching m_pCoreModelCacheManager->UpdateVehicleModelCaching(newNeedCacheList); }
bool CClientObjectManager::ObjectsAroundPointLoaded ( const CVector& vecPosition, float fRadius, unsigned short usDimension, SString* pstrStatus ) { // Get list of objects that may be intersecting the sphere CClientEntityResult result; GetClientSpatialDatabase()->SphereQuery ( result, CSphere ( vecPosition, fRadius ) ); bool bResult = true; // Extract relevant types for ( CClientEntityResult::const_iterator it = result.begin () ; it != result.end (); ++it ) { CClientEntity* pEntity = *it; if ( pEntity->GetType () == CCLIENTOBJECT ) { CClientObject* pObject = static_cast < CClientObject* > ( pEntity ); if ( !pObject->GetGameObject () || !pObject->GetModelInfo ()->IsLoaded () || !pObject->IsStreamedIn () ) { if ( pObject->GetDimension () == usDimension ) { // Final distance check float fDistSquared = pObject->GetDistanceToBoundingBoxSquared ( vecPosition ); if ( fDistSquared < fRadius * fRadius ) bResult = false; if ( pstrStatus ) { // Debugging information *pstrStatus += SString ( "ID:%05d Dist:%4.1f GetGameObject:%d IsLoaded:%d IsStreamedIn:%d\n" ,pObject->GetModel () ,sqrtf ( fDistSquared ) ,pObject->GetGameObject () ? 1 : 0 ,pObject->GetModelInfo ()->IsLoaded () ? 1 : 0 ,pObject->IsStreamedIn () ? 1 : 0 ); } else if ( !bResult ) break; } } } } return bResult; }
//////////////////////////////////////////////////////////// // // CClientSound::GetWorldBoundingSphere // // For spatial database // //////////////////////////////////////////////////////////// CSphere CClientSound::GetWorldBoundingSphere ( void ) { return CSphere ( m_vecPosition, m_fMaxDistance ); }
CSphere CElement::GetWorldBoundingSphere ( void ) { // Default to a point around the entity's position return CSphere ( GetPosition (), 0.f ); }
CSphere CClientColSphere::GetWorldBoundingSphere ( void ) { return CSphere ( m_vecPosition, m_fRadius ); }
// Put this player in other players nearlist if this player can observe them in some way void CPlayer::UpdateOthersNearList ( void ) { m_UpdateNearListTimer.Reset (); // Get the two positions to check const CVector& vecPlayerPosition = GetPosition (); CVector vecCameraPosition; GetCamera ()->GetPosition ( vecCameraPosition ); m_vecUpdateNearLastPosition = vecPlayerPosition; // Fill resultNearBoth with rough list of nearby players CElementResult resultNearBoth; { // Calculate distance from player to his camera. (Note as spatial database is 2D, we can use the 2D distance here) const float fCameraDistance = DistanceBetweenPoints2D ( vecCameraPosition, vecPlayerPosition ); if ( fCameraDistance < 40.f ) { // // If player near his camera (which is the usual case), we can do optimized things // // Do one query with a slightly bigger sphere const CVector vecAvgPos = ( vecCameraPosition + vecPlayerPosition ) * 0.5f; GetSpatialDatabase()->SphereQuery ( resultNearBoth, CSphere ( vecAvgPos, DISTANCE_FOR_NEAR_VIEWER + fCameraDistance * 0.5f ) ); } else { // // Bit more complicated if camera is not near player // // Perform queries on spatial database CElementResult resultNearCamera; GetSpatialDatabase()->SphereQuery ( resultNearCamera, CSphere ( vecCameraPosition, DISTANCE_FOR_NEAR_VIEWER ) ); CElementResult resultNearPlayer; GetSpatialDatabase()->SphereQuery ( resultNearPlayer, CSphere ( vecPlayerPosition, DISTANCE_FOR_NEAR_VIEWER ) ); std::set < CPlayer* > mergedList; // Merge for ( CElementResult::const_iterator it = resultNearCamera.begin () ; it != resultNearCamera.end (); ++it ) if ( (*it)->GetType () == CElement::PLAYER ) mergedList.insert ( (CPlayer*)*it ); for ( CElementResult::const_iterator it = resultNearPlayer.begin () ; it != resultNearPlayer.end (); ++it ) if ( (*it)->GetType () == CElement::PLAYER ) mergedList.insert ( (CPlayer*)*it ); // Copy to resultNearBoth for ( std::set < CPlayer* > ::iterator it = mergedList.begin (); it != mergedList.end (); ++it ) resultNearBoth.push_back ( *it ); } } // Accurately check distance to other players, and put this player in their near list for ( CElementResult::const_iterator it = resultNearBoth.begin () ; it != resultNearBoth.end (); ++it ) { if ( (*it)->GetType () == CElement::PLAYER ) { CPlayer* pOtherPlayer = (CPlayer*)*it; if ( pOtherPlayer != this ) { const CVector& vecOtherPlayerPos = pOtherPlayer->GetPosition (); // Check distance is accurate if ( ( vecPlayerPosition - vecOtherPlayerPos ).LengthSquared () < DISTANCE_FOR_NEAR_VIEWER * DISTANCE_FOR_NEAR_VIEWER || ( vecCameraPosition - vecOtherPlayerPos ).LengthSquared () < DISTANCE_FOR_NEAR_VIEWER * DISTANCE_FOR_NEAR_VIEWER ) { // Check dimension matches if ( m_usDimension == pOtherPlayer->GetDimension () ) { pOtherPlayer->RefreshNearPlayer ( this ); // Lightsync needs it the other way round if ( g_pBandwidthSettings->bLightSyncEnabled ) this->RefreshNearPlayer ( pOtherPlayer ); } } } } } }
CSphere CMarker::GetWorldBoundingSphere ( void ) { return CSphere ( GetPosition (), GetSize () ); }
#include "StdInc.h" ColNodeInfo CPedModelInfo::m_pColNodeInfos[12] = { {0, 5, 9, CSphere(0.05, 0.0, 0.0, 0.15)}, {0, 3, 3, CSphere(0.2, 0.0, 0.0, 0.2)}, {0, 3, 3, CSphere(0.0, 0.0, 0.0, 0.2)}, {0, 2, 4, CSphere(-0.1, 0.0, 0.0, 0.2)}, {0, 0x20, 5,CSphere(0.06, 0.0, 0.0, 0.14)}, {0, 0x16, 6,CSphere(0.06, 0.0, 0.0, 0.14)}, {0, 0x21, 5,CSphere(0.05, 0.0, 0.0, 0.14)}, {0, 0x17, 6,CSphere(0.05, 0.0, 0.0, 0.14)}, {0, 0x2A, 7,CSphere(-0.1, 0.0, 0.0, 0.18)}, {0, 0x34, 8,CSphere(-0.1, 0.0, 0.0, 0.18)}, {0, 0x2B, 7,CSphere(-0.18, 0.0, 0.0, 0.16)}, {0, 0x35, 8,CSphere(-0.18, 0.0, 0.0, 0.16)} }; RwObjectNameIdAssocation CPedModelInfo::m_pPedIds[13] = { {"Smid", 1, 0}, {"Shead", 2, 0}, {"Supperarml", 3, 0}, {"Supperarmr", 4, 0}, {"SLhand", 5, 0}, {"SRhand", 6, 0}, {"Supperlegl", 7, 0}, {"Supperlegr", 8, 0}, {"Sfootl", 9, 0}, {"Sfootr", 10, 0}, {"Slowerlegl", 11, 0},