/** Fastest removal */ public void RemoveFoliageInstance(int typeHash, System.Guid guid, Vector3 position) { FoliageCellDataRuntime cell; if (m_FoliageData.TryGetValue(FoliageCell.MakeHash(position), out cell)) { RemoveFoliageInstanceCell(typeHash, guid, cell); } }
/** * Remove the foliage with the marked GUID. Not supported for grass since * we are not having that data for it. */ public void RemoveInstanceGuid(int typeHash, Vector3 position, System.Guid guid) { FoliageCellData cell; if (m_FoliageData.TryGetValue(FoliageCell.MakeHash(position), out cell) == false) { return; } bool anyRemoved = false; // Look through the cell if (cell.m_TypeHashLocationsEditor.ContainsKey(typeHash)) { var labeled = cell.m_TypeHashLocationsEditor[typeHash]; foreach (var instances in labeled.Values) { for (int i = 0; i < instances.Count; i++) { if (instances[i].m_UniqueId == guid) { instances.RemoveAt(i); anyRemoved = true; // Yea, I know. Don't use goto... However we want to break all the iterations goto finished; } } } // Foreach labeled finished finished :; } // If we removed everything from a cell then clear it from the list completely RemoveEmptyTypeDataCell(cell); if (IsCellEmpty(cell)) { m_FoliageData.Remove(cell.GetHashCode()); } if (anyRemoved) { RecalculateBoundsAfterRemove(); } }
/** Add foliage instance. Only works for trees at runtime. */ public void AddFoliageInstance(int typeHash, FoliageInstance instance) { int keyHash = FoliageCell.MakeHash(instance.m_Position); FoliageCellDataRuntime cell; if (m_FoliageData.ContainsKey(keyHash) == false) { cell = new FoliageCellDataRuntime(); FoliageCell fCell = new FoliageCell(instance.m_Position, false); // Set the standard data cell.m_Bounds = fCell.GetBounds(); cell.m_Position = fCell; // Empty subdivided data cell.m_FoliageDataSubdivided = new FoliageKeyValuePair <int, FoliageCellSubdividedDataRuntime> [0]; // Empty type data cell.m_TypeHashLocationsRuntime = new FoliageKeyValuePair <int, FoliageTuple <FoliageInstance[]> > [0]; // Add the data m_FoliageData.Add(keyHash, cell); } cell = m_FoliageData[keyHash]; // Check if we have all the data int idx = System.Array.FindIndex(cell.m_TypeHashLocationsRuntime, (x) => x.Key == keyHash); if (idx < 0) { System.Array.Resize(ref cell.m_TypeHashLocationsRuntime, cell.m_TypeHashLocationsRuntime.Length + 1); idx = cell.m_TypeHashLocationsRuntime.Length - 1; // Add the type cell.m_TypeHashLocationsRuntime[idx] = new FoliageKeyValuePair <int, FoliageTuple <FoliageInstance[]> >(typeHash, new FoliageTuple <FoliageInstance[]>(new FoliageInstance[0])); } // We have the stuff System.Array.Resize(ref cell.m_TypeHashLocationsRuntime[idx].Value.m_EditTime, cell.m_TypeHashLocationsRuntime[idx].Value.m_EditTime.Length + 1); cell.m_TypeHashLocationsRuntime[idx].Value.m_EditTime[cell.m_TypeHashLocationsRuntime[idx].Value.m_EditTime.Length - 1] = instance; }
/** * Add a new foliage instance to the underlaying data. * * The painter should decide if our data is added to the subdivisions or if it is a tree type and must not be added to the subdivision. */ public void AddInstance(int typeHash, FoliageInstance instance, bool subdivision, string label = FoliageGlobals.LABEL_PAINTED) { int hash = FoliageCell.MakeHash(instance.m_Position); if (m_FoliageData.ContainsKey(hash) == false) { FoliageCellData data = new FoliageCellData(); data.m_Position = new FoliageCell(); data.m_Position.Set(instance.m_Position); data.m_Bounds = data.m_Position.GetBounds(); data.m_BoundsExtended = data.m_Bounds; // Add the foliage cell m_FoliageData.Add(hash, data); } FoliageCellData cellData = m_FoliageData[hash]; if (subdivision == false) { if (cellData.m_TypeHashLocationsEditor.ContainsKey(typeHash) == false) { cellData.m_TypeHashLocationsEditor.Add(typeHash, new Dictionary <string, List <FoliageInstance> >()); } var labeled = cellData.m_TypeHashLocationsEditor[typeHash]; if (labeled.ContainsKey(label) == false) { labeled.Add(label, new List <FoliageInstance>()); } // Add the foliage data labeled[label].Add(instance); // Make the extended bounds larger. Encapsulate anything that might make the bounds larger. Only applied to trees m_FoliageData[hash].m_BoundsExtended.Encapsulate(instance.m_Bounds); } else { var foliageSubdividedData = cellData.m_FoliageDataSubdivided; Vector3 localPosition = GetLocalInCell(instance.m_Position, cellData); int hashSubdivided = FoliageCell.MakeHashSubdivided(localPosition); if (foliageSubdividedData.ContainsKey(hashSubdivided) == false) { FoliageCellSubdividedData data = new FoliageCellSubdividedData(); data.m_Position = new FoliageCell(); data.m_Position.SetSubdivided(localPosition); // Get bounds in world space data.m_Bounds = data.m_Position.GetBoundsSubdivided(); data.m_Bounds.center = GetWorldInCell(data.m_Bounds.center, cellData); foliageSubdividedData.Add(hashSubdivided, data); } FoliageCellSubdividedData cellDataSubdivided = foliageSubdividedData[hashSubdivided]; if (cellDataSubdivided.m_TypeHashLocationsEditor.ContainsKey(typeHash) == false) { cellDataSubdivided.m_TypeHashLocationsEditor.Add(typeHash, new Dictionary <string, List <FoliageInstance> >()); } var labeled = cellDataSubdivided.m_TypeHashLocationsEditor[typeHash]; if (labeled.ContainsKey(label) == false) { labeled.Add(label, new List <FoliageInstance>()); } labeled[label].Add(instance); } }