protected override void Initialize() { // Dont initialize stuff on edit mode if (Application.isPlaying) { float time = Time.realtimeSinceStartup; itemPrefabs = Resources.LoadAll <Item>(RESOURCES_ITEM_PATH); itemDataArray = new ItemData[itemPrefabs.Length]; BuildTagDictionary(); // First pass: item data for (int i = 0; i < itemPrefabs.Length; i++) { Item item = itemPrefabs[i]; if (item == null) { Debug.LogError("Item factory references null item!", this); } if (itemsById.ContainsKey(item.itemId)) { Debug.LogError("Duplicate item id! " + item.itemId, item); } AddItemToTagParents(item.itemTag, i); itemsById[item.itemId] = item; itemIndexById[item.itemId] = i; ItemData itemData = new ItemData(); itemData.itemIndex = i; itemData.itemId = item.itemId; itemData.itemTag = item.itemTag; itemData.anchorPlane = item.anchorPlane; itemData.itemBounds = item.CalculateBoundsLocalSpace(0); // Important to calculate only the base level itemDataArray[i] = itemData; } // Second pass: item reference data for (int i = 0; i < itemDataArray.Length; i++) { int lOffset = 0; ItemData itemData = itemDataArray[i]; Item item = itemPrefabs[i]; ItemLayout[] layouts = item.GetItemLayouts(); itemData.layoutOffsets = new int[layouts.Length]; itemData.layoutMetadata = new ItemLayoutController[layouts.Length]; List <ItemReferenceData> references = new List <ItemReferenceData>(); for (int layout = 0; layout < layouts.Length; layout++) { ItemReference[] itemReferences = layouts[layout].GetItemReferences(); itemData.layoutOffsets[layout] = lOffset; ItemLayoutMetadata metadata = layouts[layout].GetComponent <ItemLayoutMetadata>(); if (metadata) { itemData.layoutMetadata[layout] = metadata.GetController(); } else // Just set a simple controller with simple data { itemData.layoutMetadata[layout] = new ItemLayoutController(); } itemData.layoutMetadata[layout].Initialize(layouts[layout].weight); for (int r = 0; r < itemReferences.Length; r++) { ItemReference itemReference = itemReferences[r]; ItemReferenceData itemReferenceData = new ItemReferenceData(); ItemReferenceMetadata itemRefMetadata = itemReference.GetComponent <ItemReferenceMetadata>(); if (itemRefMetadata) { itemReferenceData.metadata = itemRefMetadata.GetController(); } else // Just set a simple controller with simple data { itemReferenceData.metadata = new ItemReferenceController(); } itemReferenceData.metadata.Initialize(itemReference.probability); if (itemIndexById.ContainsKey(itemReference.itemId)) { itemReferenceData.itemIndex = itemIndexById[itemReference.itemId]; } else { itemReferenceData.itemIndex = -1; } // Ignore item root transform, because prefabs may be modified itemReferenceData.transform = item.transform.worldToLocalMatrix * itemReference.transform.localToWorldMatrix; itemReferenceData.maxChildDepth = itemReference.maxChildDepth; itemReferenceData.probability = itemReference.probability; itemReferenceData.procedural = itemReference.procedural; itemReferenceData.instanceCount = itemReference.instanceCount; itemReferenceData.uniformScale = itemReference.uniformScale; itemReferenceData.anchorPlane = itemReference.anchorPlane; itemReferenceData.randomOrientation = itemReference.randomSnappedOrientation; itemReferenceData.randomPositionAmplitude = itemReference.randomPositionAmplitude; itemReferenceData.randomRotationAmplitude = itemReference.randomRotationAmplitude; itemReferenceData.randomScaleAmplitude = itemReference.randomScaleAmplitude; // Procedural volume is ALWAYS LOCAL TO REFERENCE itemReferenceData.availableProceduralVolume = itemReference.availableProceduralVolume; references.Add(itemReferenceData); } lOffset += itemReferences.Length; } itemData.references = references.ToArray(); // Save back data itemDataArray[i] = itemData; } // Calculate bounds, save them temporarily and then assign Bounds[] tempItemBounds = new Bounds[itemDataArray.Length]; for (int i = 0; i < itemDataArray.Length; i++) { tempItemBounds[i] = CalculateItemBounds(ref itemDataArray[i]); } for (int i = 0; i < itemDataArray.Length; i++) { Bounds b = tempItemBounds[i]; itemDataArray[i].itemBounds = b; itemDataArray[i].itemVolume = b.size.x * b.size.y * b.size.z; } for (int i = 0; i < itemDataArray.Length; i++) { ItemData item = itemDataArray[i]; if (item.references != null) { // Basically, for each reference, precalculate every item that can fit inside it :) for (int r = 0; r < item.references.Length; r++) { item.references[r].availableItemIndicesByTag = CalculateAvailableItemsInProceduralVolume(item.itemTag, item.references[r].availableProceduralVolume, item.references[r].anchorPlane).ToArray(); } } } //initMillis = (Time.realtimeSinceStartup - time) * 1000f; } }