diff --git a/Engine/source/scene/zones/sceneZoneSpaceManager.cpp b/Engine/source/scene/zones/sceneZoneSpaceManager.cpp index 97f8c1e44..84f733d03 100644 --- a/Engine/source/scene/zones/sceneZoneSpaceManager.cpp +++ b/Engine/source/scene/zones/sceneZoneSpaceManager.cpp @@ -714,9 +714,10 @@ void SceneZoneSpaceManager::_zoneRemove( SceneObject* obj, bool freeList ) PROFILE_SCOPE( SceneZoneSpaceManager_zoneRemove ); // Remove the object from the zone lists. - + U32 numZones = 0; U32* zones = NULL; + bool zonesDirty = obj->mZoneRefDirty; zones = mObjectZoneLists.getValues(obj->mZoneListHandle, numZones); for (U32 i=0; i_onZoneRemoveObject(obj); + SceneZoneSpace* space = getZoneOwner(zones[i]); + + if (space == NULL) + { + AssertFatal(zonesDirty, "Object still has reference to removed zone"); + continue; + } + + space->_onZoneRemoveObject(obj); + + // Remove the object from the zones object list + Vector* objectList = getZoneObjects(zones[i]); + if (objectList) + { + Vector::iterator itr = T3D::find(objectList->begin(), objectList->end(), obj); + if (itr != objectList->end()) + { + objectList->erase(itr); + } + } } // Clear the object's zoning state. @@ -779,6 +799,12 @@ void SceneZoneSpaceManager::_setObjectZoneList( SceneObject* object, U32 numZone mObjectZoneLists.reallocList(object->mZoneListHandle, numZones, zoneList); } + // Make sure each zone has the object in its list + for (U32 i = 0; i < numZones; i++) + { + mZoneLists[zoneList[i]]->mObjects.push_back(object); + } + object->mNumCurrZones = numZones; } @@ -801,17 +827,16 @@ void SceneZoneSpaceManager::_clearZoneList( U32 zoneId ) object->mNumCurrZones --; - // If this is the only zone the object was in, mark - // its zoning state as dirty so it will get assigned - // to the outdoor zone on the next update. - - if( object->mNumCurrZones == 0 ) - object->mZoneRefDirty = true; + // Keep things simple here and flag the objects zone list for re-calculation + object->mZoneRefDirty = true; // Let the zone know we have removed the object. zoneSpace->_onZoneRemoveObject( object ); } + + // Reset all objects for zone + list->mObjects.clear(); } //----------------------------------------------------------------------------- diff --git a/Engine/source/scene/zones/sceneZoneSpaceManager.h b/Engine/source/scene/zones/sceneZoneSpaceManager.h index 2d39ee635..860d24a51 100644 --- a/Engine/source/scene/zones/sceneZoneSpaceManager.h +++ b/Engine/source/scene/zones/sceneZoneSpaceManager.h @@ -94,7 +94,7 @@ class SceneZoneSpaceManager ZoneObjectList(SceneObject* manager) : mManager(manager) { ; } inline SceneObject* getManager() const { return mManager; } - inline Vector getObjects() const { return mObjects; } + inline Vector& getObjects() { return mObjects; } }; protected: @@ -260,6 +260,13 @@ class SceneZoneSpaceManager return ( SceneZoneSpace* )(list ? list->getManager() : NULL); } + Vector* getZoneObjects(const U32 zoneId) const + { + AssertFatal(isValidZoneId(zoneId), "SceneManager::getZoneOwner - Invalid zone ID!"); + ZoneObjectList* list = mZoneLists[zoneId]; + return (list ? &list->getObjects() : NULL); + } + /// Return the total number of zones in the scene. U32 getNumZones() const { return mNumTotalAllocatedZones; }