//----------------------------------------------------------------------------- // Purpose: Input handler that converts our target to a physics object. //----------------------------------------------------------------------------- void CPhysConvert::InputConvertTarget( inputdata_t &inputdata ) { bool createAsleep = HasSpawnFlags(SF_CONVERT_ASLEEP); // Fire output m_OnConvert.FireOutput( inputdata.pActivator, this ); CBaseEntity *entlist[512]; CBaseEntity *pSwap = gEntList.FindEntityByName( NULL, m_swapModel, inputdata.pActivator ); CBaseEntity *pEntity = NULL; int count = 0; while ( (pEntity = gEntList.FindEntityByName( pEntity, m_target, inputdata.pActivator )) != NULL ) { entlist[count++] = pEntity; if ( count >= ARRAYSIZE(entlist) ) break; } // if we're swapping to model out, don't loop over more than one object // multiple objects with the same brush model will render, but the dynamic lights // and decals will be shared between the two instances... if ( pSwap && count > 0 ) { count = 1; } for ( int i = 0; i < count; i++ ) { pEntity = entlist[i]; // don't convert something that is already physics based if ( pEntity->GetMoveType() == MOVETYPE_VPHYSICS ) { Msg( "ERROR phys_convert %s ! Already MOVETYPE_VPHYSICS\n", STRING(pEntity->m_iClassname) ); continue; } UnlinkFromParent( pEntity ); if ( pSwap ) { // we can't reuse this physics object, so kill it pEntity->VPhysicsDestroyObject(); pEntity->SetModel( STRING(pSwap->GetModelName()) ); } CBaseEntity *pPhys = CreateSimplePhysicsObject( pEntity, createAsleep ); // created phys object, now move hierarchy over if ( pPhys ) { pPhys->SetName( pEntity->GetEntityName() ); TransferChildren( pEntity, pPhys ); pEntity->AddSolidFlags( FSOLID_NOT_SOLID ); pEntity->m_fEffects |= EF_NODRAW; UTIL_Relink( pEntity ); UTIL_Remove( pEntity ); } } }
void ezWorld::SetParent(ezGameObject* pObject, ezGameObject* pNewParent, ezGameObject::TransformPreservation preserve) { EZ_ASSERT_DEV(pObject != pNewParent, "Object can't be its own parent!"); EZ_ASSERT_DEV(pNewParent == nullptr || pObject->IsDynamic() || pNewParent->IsStatic(), "Can't attach a static object to a dynamic parent!"); CheckForWriteAccess(); if (GetObjectUnchecked(pObject->m_ParentIndex) == pNewParent) return; UnlinkFromParent(pObject); // UnlinkFromParent does not clear these as they are still needed in DeleteObjectNow to allow deletes while iterating. pObject->m_NextSiblingIndex = 0; pObject->m_PrevSiblingIndex = 0; if (pNewParent != nullptr) { // Ensure that the parent's global transform is up-to-date otherwise the object's local transform will be wrong afterwards. pNewParent->UpdateGlobalTransform(); pObject->m_ParentIndex = pNewParent->m_InternalId.m_InstanceIndex; LinkToParent(pObject); } PatchHierarchyData(pObject, preserve); }
//----------------------------------------------------------------------------- // Purpose: Clears the parent of all the children of the given object. //----------------------------------------------------------------------------- void UnlinkAllChildren( CBaseEntity *pParent ) { CBaseEntity *pChild = pParent->FirstMoveChild(); while ( pChild ) { CBaseEntity *pNext = pChild->NextMovePeer(); UnlinkFromParent( pChild ); pChild = pNext; } }
//================================================================== void TokNode::Reparent( TokNode *pNewParent ) { if ( mpParent == pNewParent ) { DASSERT( 0 ); return; } UnlinkFromParent(); mpParent = pNewParent; }
void ezWorld::DeleteObjectNow(const ezGameObjectHandle& object) { CheckForWriteAccess(); ezGameObject* pObject = nullptr; if (!m_Data.m_Objects.TryGetValue(object, pObject)) return; // set object to inactive so components and children know that they shouldn't access the object anymore. pObject->m_Flags.Remove(ezObjectFlags::Active); // delete children for (auto it = pObject->GetChildren(); it.IsValid(); ++it) { DeleteObjectNow(it->GetHandle()); } // delete attached components const ezArrayPtr<ezComponent*> components = pObject->m_Components; for (ezUInt32 c = 0; c < components.GetCount(); ++c) { ezComponent* pComponent = components[c]; pComponent->GetOwningManager()->DeleteComponent(pComponent->GetHandle()); } EZ_ASSERT_DEV(pObject->m_Components.GetCount() == 0, "Components should already be removed"); // fix parent and siblings UnlinkFromParent(pObject); // remove from global key tables SetObjectGlobalKey(pObject, ezHashedString()); // invalidate and remove from id table pObject->m_InternalId.Invalidate(); m_Data.m_DeadObjects.PushBack(pObject); EZ_VERIFY(m_Data.m_Objects.Remove(object), "Implementation error."); }
/*! ****************************************************************************** @Function FreeHandle @Description Free a handle data structure. @Input psBase - Pointer to handle base structure hHandle - Handle to be freed eType - Type of the handle to be freed ppvData - Location for data associated with the freed handle @Output ppvData - Points to data that was associated with the freed handle @Return PVRSRV_OK or PVRSRV_ERROR ******************************************************************************/ static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_VOID **ppvData) { HANDLE_DATA *psHandleData = IMG_NULL; HANDLE_DATA *psReleasedHandleData; PVRSRV_ERROR eError; eError = GetHandleData(psBase, &psHandleData, hHandle, eType); if (eError != PVRSRV_OK) { return eError; } PVR_ASSERT(psHandleData->ui32Refs>0); psHandleData->ui32Refs--; if (psHandleData->ui32Refs > 0) { /* Reference count still positive, only possible for shared handles */ PVR_ASSERT(TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_SHARED)); return PVRSRV_OK; } /* else reference count zero, time to clean up */ if (!TEST_ALLOC_FLAG(psHandleData, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) { HAND_KEY aKey; IMG_HANDLE hRemovedHandle; InitKey(aKey, psBase, psHandleData->pvData, psHandleData->eType, ParentIfPrivate(psHandleData)); hRemovedHandle = (IMG_HANDLE)HASH_Remove_Extended(psBase->psHashTab, aKey); PVR_ASSERT(hRemovedHandle != IMG_NULL); PVR_ASSERT(hRemovedHandle == psHandleData->hHandle); PVR_UNREFERENCED_PARAMETER(hRemovedHandle); } eError = UnlinkFromParent(psBase, psHandleData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst unlinking from parent handle (%s)", PVRSRVGetErrorStringKM(eError))); return eError; } /* Free children */ eError = IterateOverChildren(psBase, psHandleData, FreeHandleWrapper); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%s)", PVRSRVGetErrorStringKM(eError))); return eError; } eError = gpsHandleFuncs->pfnReleaseHandle(psBase->psImplBase, psHandleData->hHandle, (IMG_VOID **)&psReleasedHandleData); if (eError == PVRSRV_OK) { PVR_ASSERT(psReleasedHandleData == psHandleData); } if (ppvData) { *ppvData = psHandleData->pvData; } OSFreeMem(psHandleData); return eError; }
void MdlObject::LinkToParent(MdlObject *p) { if (parent) UnlinkFromParent(); p->childs.push_back(this); parent = p; }