public Bounds CalculateItemReferenceBounds(ref ItemReferenceData itemReference, int depth = ITEM_TREE_MAX_DEPTH) { if (itemReference.procedural) { return(MathUtils.TransformBounds(ref itemReference.transform, itemReference.availableProceduralVolume)); } if (itemReference.itemIndex >= 0) { Bounds itemBounds = CalculateItemBounds(ref itemDataArray[itemReference.itemIndex], depth); return(MathUtils.TransformBounds(ref itemReference.transform, itemBounds)); } return(MathUtils.TransformBounds(ref itemReference.transform, new Bounds())); }
public void TestFromServer_SharedDataSourceNamesAreKept() { var mockServer = new Mock <IReportingService2010>(); var mockDataSource = new ItemReferenceData { Name = "DataSource1", Reference = "/reference/ds1", ReferenceType = "DataSource" }; mockServer.Setup(p => p.GetItemReferences(It.IsAny <string>(), "DataSource")).Returns(new ItemReferenceData[] { mockDataSource }); var sut = new RdlFileIO(mockServer.Object); var references = sut.GetDataSourceReference("path"); Assert.AreEqual(1, references.Count); Assert.AreEqual("DataSource1", references[0].Name); }
public void TestFromServer_SharedDataSetDataSourceNamesAreRenamed() { var mockServer = new Mock <IReportingService2010>(); var mockDataSource = new ItemReferenceData { Name = "DataSource1", Reference = "/reference/ds1", ReferenceType = "DataSource" }; var mockDataSource2 = new ItemReferenceData { Name = "DataSource2", Reference = "/reference/ds2", ReferenceType = "DataSource" }; var mockDataSet = new ItemReferenceData { Name = "Dataset1", Reference = "/reference/ds2", ReferenceType = "DataSource" }; mockServer.Setup(p => p.GetItemReferences("/report", "DataSource")) .Returns(new ItemReferenceData[] { mockDataSource }); mockServer.Setup(p => p.GetItemReferences("/reference/ds2", "DataSource")) .Returns(new ItemReferenceData[] { mockDataSource2 }); mockServer.Setup(p => p.GetItemReferences(It.IsAny <string>(), "DataSet")) .Returns(new ItemReferenceData[] { mockDataSet }); var sut = new RdlFileIO(mockServer.Object); var references = sut.GetDataSourceReference("/report"); Assert.AreEqual(2, references.Count); Assert.AreEqual("DataSource1", references[0].Name); Assert.IsTrue(references[1].Name.Contains("ds2")); }
private Matrix4x4 GetRandomTransformation(ref ItemReferenceData itemReference, ref ItemData itemData, System.Random rnd) { Matrix4x4 matrix = itemReference.transform; if (itemReference.randomOrientation) { matrix *= GetRandomOrientationMatrix(rnd, itemReference.anchorPlane); } Vector3 randPositionAmplitude = itemReference.randomPositionAmplitude; if (itemReference.procedural) { Vector3 refAnchorPosition = GetAnchorPosition(itemReference.anchorPlane, itemReference.availableProceduralVolume); Vector3 itemAnchorPosition = GetAnchorPosition(itemData.anchorPlane, itemData.itemBounds); matrix *= Matrix4x4.TRS(refAnchorPosition - itemAnchorPosition, Quaternion.identity, Vector3.one); // Add random amplitude based on the possible volume Vector3 anchorDirection = GetAnchorDirection(itemReference.anchorPlane); randPositionAmplitude += Vector3.Scale(itemReference.availableProceduralVolume.size, Vector3.one - MathUtils.Abs(anchorDirection)); Vector3 position = GetRandomPositionOffset(randPositionAmplitude, rnd); Quaternion rotation = Quaternion.Euler(GetRandomRotationOffset(itemReference.randomRotationAmplitude, rnd)); Vector3 scale = GetRandomScaleOffset(itemReference.randomScaleAmplitude, itemReference.uniformScale, rnd); return(matrix * Matrix4x4.TRS(position, rotation, scale)); } else { Vector3 position = GetRandomPositionOffset(randPositionAmplitude, rnd); Quaternion rotation = Quaternion.Euler(GetRandomRotationOffset(itemReference.randomRotationAmplitude, rnd)); Vector3 scale = GetRandomScaleOffset(itemReference.randomScaleAmplitude, itemReference.uniformScale, rnd); return(matrix * Matrix4x4.TRS(position, rotation, scale)); } }
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; } }
private void BuildDynamicItem(Vector3 viewDirection, System.Random rnd, int parentItemIndex, Transform parentTransform, int depth, int maxDepth) { if (depth > maxDepth || parentItemIndex < 0 || parentItemIndex >= itemDataArray.Length) { return; } ItemData parentItemData = itemDataArray[parentItemIndex]; if (parentItemData.layoutOffsets != null && parentItemData.layoutOffsets.Length > 0) { reusableWeightList.Clear(); for (int i = 0; i < parentItemData.layoutMetadata.Length; i++) { reusableWeightList.Add(parentItemData.layoutMetadata[i].GetWeight()); } int selectedLayout = GetWeightedRandomIndex(reusableWeightList, rnd); int layoutOffset = parentItemData.layoutOffsets[selectedLayout]; int layoutSize = parentItemData.references.Length - layoutOffset; // By default, layout size is the remaining segment of the reference array // If there is another layout, infer the layout size from the next offset if (selectedLayout + 1 < parentItemData.layoutOffsets.Length) { layoutSize = parentItemData.layoutOffsets[selectedLayout + 1] - layoutOffset; } for (int i = 0; i < layoutSize; i++) { ItemReferenceData itemReference = parentItemData.references[layoutOffset + i]; // Add as many children as possible int childCount = Mathf.Max(1, itemReference.instanceCount); for (int j = 0; j < childCount; ++j) { int childItemIndex = -1; // First define the item to instantiate if (itemReference.procedural) { if (itemReference.availableItemIndicesByTag.Length > 0) { // Reference is a random item, find it! int randomIndex = rnd.Next(itemReference.availableItemIndicesByTag.Length); // TODO: weighted random by volume childItemIndex = itemReference.availableItemIndicesByTag[randomIndex]; } } else { // Reference is a specific item; just instance it if ((float)rnd.NextDouble() < itemReference.metadata.GetProbability()) { childItemIndex = itemReference.itemIndex; } } // Then just build it if (childItemIndex >= 0) { Matrix4x4 childLocalMatrix = GetRandomTransformation(ref itemReference, ref itemDataArray[childItemIndex], rnd); ItemData childItemData = itemDataArray[childItemIndex]; if (ShouldCullObject(ref childItemData, viewDirection, childLocalMatrix)) { continue; } GameObject itemInstance = GameObject.Instantiate(itemPrefabs[childItemIndex].gameObject); itemInstance.name = itemDataArray[childItemIndex].itemId; itemInstance.transform.parent = parentTransform; itemInstance.transform.localPosition = ExtractTranslationFromMatrix(ref childLocalMatrix); itemInstance.transform.localRotation = ExtractRotationFromMatrix(ref childLocalMatrix); itemInstance.transform.localScale = ExtractScaleFromMatrix(childLocalMatrix); InterestPoint[] interestPoints = itemInstance.GetComponentsInChildren <InterestPoint>(); foreach (InterestPoint p in interestPoints) { p.AssociateItemBounds(itemInstance.transform, itemDataArray[childItemIndex].itemBounds); } CleanDynamicItem(itemInstance); BuildDynamicItem(viewDirection, rnd, childItemIndex, itemInstance.transform, depth + 1, Mathf.Min(maxDepth, depth + itemReference.maxChildDepth)); } } } } }