예제 #1
0
    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()));
    }
예제 #2
0
        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);
        }
예제 #3
0
        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"));
        }
예제 #4
0
    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));
        }
    }
예제 #5
0
    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;
        }
    }
예제 #6
0
    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));
                    }
                }
            }
        }
    }