Ejemplo n.º 1
0
        public static GraphInfo GetGraphInfo(this UIGraphData graph, BlobAssetReference <CompiledUISchema> schema, out NativeArray <NodeInfo> configLayout, Allocator allocator)
        {
            var offset = sizeof(ulong) + sizeof(int);

            configLayout = new NativeArray <NodeInfo>(graph.GetNodeCount(), allocator);
            var graphInfo = new GraphInfo();

            for (int currentIndex = 0; currentIndex < graph.GetNodeCount(); currentIndex++)
            {
                //var size = UnsafeUtility.AsRef<int>((((IntPtr)graph.Value.initialConfiguration.GetUnsafePtr()) + offset).ToPointer());
                var size   = *(int *)(graph.value + offset).ToPointer();
                var header = (HeaderConfig *)(graph.value + offset + sizeof(int)).ToPointer();
                //var size = graph.GetNodeLength(currentIndex);
                if (header->IsDedicatedNode)
                {
                    graphInfo.subMeshCount++;
                }
                offset += UnsafeUtility.SizeOf <int>();
                NodeInfo info = new NodeInfo
                {
                    configurationMask = header->configurationMask,
                    nodeOffset        = offset,
                    childrenOffset    = offset + UnsafeUtility.SizeOf <HeaderConfig>(),
                    configOffset      = offset + UnsafeUtility.SizeOf <HeaderConfig>() + (sizeof(int) * header->childCount),
                    length            = size,
                    index             = currentIndex
                };
                var call = header->schemaIndex >= 0 ? schema.Value.elements[header->schemaIndex].renderBoxCounter : default;
                info.renderBoxCount        = call.IsCreated ? call.Invoke(graph.value, (NodeInfo *)UnsafeUtility.AddressOf(ref info)) : 1;
                configLayout[currentIndex] = info;
                graphInfo.renderBoxCount  += info.renderBoxCount;
                offset += size;
            }
            return(graphInfo);
        }
Ejemplo n.º 2
0
        public static IntPtr GetNodeConfigPointer(this UIGraphData self, int index)
        {
            HeaderConfig *header     = (HeaderConfig *)(GetNodePointer(self, index) + sizeof(int)).ToPointer();
            var           childCount = header->childCount;

            return(((IntPtr)header) + UnsafeUtility.SizeOf <HeaderConfig>() + (sizeof(int) * childCount));
        }
Ejemplo n.º 3
0
        public static ulong GetNodeConfigurationMask(this UIGraphData self, int index)
        {
            HeaderConfig result = default;

            GetNodeHeader(self, index, ref result);
            return(result.configurationMask);
        }
Ejemplo n.º 4
0
        public static HeaderConfig GetNodeHeader(this UIGraphData self, int index)
        {
            HeaderConfig result = default;

            GetNodeHeader(self, index, ref result);
            return(result);
        }
Ejemplo n.º 5
0
        public static IntPtr GetConfigBlock(this UIGraphData self, int index, byte config)
        {
            HeaderConfig *header     = (HeaderConfig *)(GetNodePointer(self, index) + sizeof(int)).ToPointer();
            var           childCount = header->childCount;
            var           offset     = UIConfigUtility.GetOffset(header->configurationMask, config);

            return(((IntPtr)header) + UnsafeUtility.SizeOf <HeaderConfig>() + (sizeof(int) * childCount) + offset);
        }
Ejemplo n.º 6
0
        public static IntPtr GetNodePointer(this UIGraphData self, int index)
        {
            var offset = sizeof(ulong) + sizeof(int);

            for (int currentIndex = 0; currentIndex < index; currentIndex++)
            {
                offset += *(int *)(self.value + offset).ToPointer() + sizeof(int);
            }
            return(self.value + offset);
        }
Ejemplo n.º 7
0
        private void Layout(int index, UIGraphData graph, NativeArray <NodeInfo> configLayout, NativeArray <UIPassState> stateLayout, UIContextData *context)
        {
            if (!graph.TryGetConfigBlock(index, UIConfigLayoutTable.DisplayConfig, out IntPtr displayConfig) || (((DisplayConfig *)displayConfig.ToPointer())->display == VisibilityStyle.Visible))
            {
                var nodeInfo     = configLayout[index];
                var headerConfig = (HeaderConfig *)(graph.value + nodeInfo.nodeOffset).ToPointer();
                var configSource = graph.value + nodeInfo.configOffset;
                var state        = (UIPassState *)(((IntPtr)stateLayout.GetUnsafePtr()) + (UnsafeUtility.SizeOf <UIPassState>() * index)).ToPointer();

                IntPtr boxConfig;
                bool   hasBoxConfig = graph.TryGetConfigBlock(index, UIConfigLayoutTable.BoxModelConfig, out boxConfig);
                if (hasBoxConfig)
                {
                    BoxModelConfig *boxConfigPtr = (BoxModelConfig *)boxConfig.ToPointer();
                    state->localBox += boxConfigPtr->margin.Normalize(*context);
                    state->inner     = boxConfigPtr->padding.Normalize(*context);
                }
                FunctionPointer <UILayoutPass> layout = headerConfig->schemaIndex >= 0 ? schema.Value.elements[headerConfig->schemaIndex].layout : default;
                for (int childIndex = 0; childIndex < headerConfig->childCount; childIndex++)
                {
                    if (layout.IsCreated)
                    {
                        layout.Invoke(
                            childIndex,
                            graph.value,
                            (NodeInfo *)UnsafeUtility.AddressOf(ref nodeInfo),
                            (IntPtr)stateLayout.GetUnsafePtr(),
                            context
                            );
                    }
                    Layout(UnsafeUtility.ReadArrayElement <int>((graph.value + nodeInfo.childrenOffset).ToPointer(), childIndex), graph, configLayout, stateLayout, context);
                }
                if (layout.IsCreated)
                {
                    layout.Invoke(
                        -1,
                        graph.value,
                        (NodeInfo *)UnsafeUtility.AddressOf(ref nodeInfo),
                        (IntPtr)stateLayout.GetUnsafePtr(),
                        context
                        );
                }
                if (graph.TryGetConfigBlock(index, UIConfigLayoutTable.SizeConfig, out IntPtr sizeConfig))
                {
                    var sizeConfigPtr = ((SizeConfig *)sizeConfig.ToPointer());
                    state->size = new float2(
                        math.clamp(state->size.x, sizeConfigPtr->minWidth.Normalize(*context), sizeConfigPtr->maxWidth.Normalize(*context)),
                        math.clamp(state->size.y, sizeConfigPtr->minHeight.Normalize(*context), sizeConfigPtr->maxHeight.Normalize(*context)));
                }
                if (hasBoxConfig)
                {
                    state->size += new float2(state->inner.x + state->inner.z, state->inner.y + state->inner.w);
                }
            }
        }
Ejemplo n.º 8
0
        public static int CountRenderBoxes(this UIGraphData graph, NativeArray <NodeInfo> configLayout, NativeArray <UISchema.CompiledElement> schema)
        {
            int count = 0;

            for (int currentIndex = 0; currentIndex < configLayout.Length; currentIndex++)
            {
                var info   = configLayout[currentIndex];
                var header = (HeaderConfig *)(graph.value + info.nodeOffset);
                var call   = header->schemaIndex >= 0 ? schema[header->schemaIndex].renderBoxCounter : default;
                count += call.IsCreated ? call.Invoke(graph.value, (NodeInfo *)UnsafeUtility.AddressOf(ref info)) : 1;
            }
            return(count);
        }
Ejemplo n.º 9
0
        public static bool HasConfigBlock(this UIGraphData self, int index, byte config)
        {
            HeaderConfig *header     = (HeaderConfig *)(GetNodePointer(self, index) + sizeof(int)).ToPointer();
            var           childCount = header->childCount;
            var           offset     = UIConfigUtility.GetOffset(header->configurationMask, config);

            if (offset < 0)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Ejemplo n.º 10
0
        public unsafe void DecomposeHead(UIGraphData graph, int threadIndex)
        {
            var graphInfo         = graph.GetGraphInfo(schema, out NativeArray <NodeInfo> configLayout, Allocator.Temp);
            int currentSubmesh    = 0;
            var dedicatedNodeInfo = new NativeArray <DedicatedNodeInfo>(graphInfo.subMeshCount, Allocator.Temp);

            Decompose(graph, threadIndex, 0, configLayout, ref currentSubmesh, dedicatedNodeInfo, graphInfo.subMeshCount + 1);
            nodes.BeginForEachIndex(threadIndex);
            this.submeshCount[threadIndex] = graphInfo.subMeshCount;
            for (int i = 0; i < graphInfo.subMeshCount; i++)
            {
                nodes.Write(dedicatedNodeInfo[i]);
            }
            nodes.EndForEachIndex();
        }
Ejemplo n.º 11
0
        public unsafe void Decompose(UIGraphData graph, int threadIndex, int currentIndex, NativeArray <NodeInfo> nodeInfo, ref int currentSubmesh, NativeArray <DedicatedNodeInfo> nodes, int subMeshCount)
        {
            var ptr    = graph.GetNodePointer(currentIndex) + sizeof(int);
            var header = (HeaderConfig *)ptr;

            if (header->IsDedicatedNode)
            {
                nodes[currentSubmesh] = new DedicatedNodeInfo(threadIndex, currentIndex, nodeInfo[currentIndex], subMeshCount - (++currentSubmesh));
            }
            var children = ptr + UnsafeUtility.SizeOf <HeaderConfig>();

            for (int i = 0; i < header->childCount; i++)
            {
                Decompose(graph, threadIndex, UnsafeUtility.ReadArrayElement <int>(children.ToPointer(), i), nodeInfo, ref currentSubmesh, nodes, subMeshCount);
            }
        }
Ejemplo n.º 12
0
        public static bool TryGetConfigBlock(this UIGraphData self, int index, byte config, out IntPtr result)
        {
            HeaderConfig *header     = (HeaderConfig *)(GetNodePointer(self, index) + sizeof(int)).ToPointer();
            var           childCount = header->childCount;
            var           offset     = UIConfigUtility.GetOffset(header->configurationMask, config);

            if (offset < 0)
            {
                result = IntPtr.Zero;
                return(false);
            }
            else
            {
                result = ((IntPtr)header) + UnsafeUtility.SizeOf <HeaderConfig>() + (sizeof(int) * childCount) + offset;
                return(true);
            }
        }
Ejemplo n.º 13
0
 public void Execute(UIGraphData graph, MeshData meshData, int index)
 {
     if (graph.GetNodeCount() > 0)
     {
         var states  = new NativeArray <UIPassState>(graph.GetNodeCount(), Allocator.Temp);
         var initial = UIPassState.Null;
         UnsafeUtility.MemCpyReplicate(states.GetUnsafePtr(), UnsafeUtility.AddressOf(ref initial), UnsafeUtility.SizeOf <UIPassState>(), states.Length);
         var graphInfo = graph.GetGraphInfo(schema, out NativeArray <NodeInfo> layout, Allocator.Temp);
         InitMeshData(ref meshData, graphInfo);
         NativeArray <UIVertexData> vertices = meshData.GetVertexData <UIVertexData>();
         var contextPtr = (UIContextData *)((IntPtr)contexts.GetUnsafePtr() + (UnsafeUtility.SizeOf <UIContextData>() * index)).ToPointer();
         Layout(0, graph, layout, states, contextPtr);
         Render(vertices, contextPtr, ref meshData, graph, layout, graphInfo, states);
         states.Dispose();
         layout.Dispose();
     }
 }
Ejemplo n.º 14
0
        protected unsafe override void OnUpdate()
        {
            var ecb = entityCommandBufferSystem.CreateCommandBuffer();

            Entities
            .WithoutBurst()
            .WithNone <UIGraphData, UIGraphHandleData>()
            .ForEach((Entity entity, in UIGraph ui) =>
            {
                var handle = Addressables.LoadAssetAsync <TextAsset>(ui.value.ToHex());
                var id     = this.handles.Count;
                ecb.AddComponent(entity, new UIGraphHandleData {
                    id = id
                });
                this.handles.Add(handle);
            })
            .Run();
            Entities
            .WithoutBurst()
            .WithNone <UIGraphData>()
            .ForEach((Entity entity, in UIGraphHandleData handleData, in UIGraph ui) =>
            {
                var handle = this.handles[handleData.id];
                if (handle.IsDone)
                {
                    IntPtr ptr;
                    long allocatedLength;
                    using (var ms = new MemoryStream(handle.Result.bytes)) {
                        allocatedLength = math.ceilpow2(ms.Length);
                        ptr             = (IntPtr)UnsafeUtility.Malloc(allocatedLength, 0, Allocator.Persistent);
                        using (var us = new UnmanagedMemoryStream((byte *)ptr.ToPointer(), 0, ms.Length, FileAccess.Write)) {
                            ms.CopyTo(us);
                        }
                    }
                    //int id = this.graphs.Length;
                    var graph = new UIGraphData {
                        value = ptr, allocatedLength = allocatedLength
                    };
                    //this.graphs.Add(graph);
                    ecb.AddComponent(entity, graph);
                }
            })
Ejemplo n.º 15
0
        public static int GetFirstSelectableIndex(this UIGraphData graph)
        {
            if (!graph.IsCreated)
            {
                return(-1);
            }
            //Index, priority
            ValueTuple <int, int> selectableIndex = (-1, int.MinValue);

            for (int currentIndex = 0; currentIndex < graph.GetNodeCount(); currentIndex++)
            {
                if (graph.TryGetConfigBlock(currentIndex, UIConfigLayoutTable.SelectableConfig, out IntPtr block))
                {
                    SelectableConfig *selectableConfig = (SelectableConfig *)block;
                    if (selectableConfig->onSelect.IsCreated && selectableIndex.Item2.CompareTo(selectableConfig->priority) < 0)
                    {
                        selectableIndex = (currentIndex, selectableConfig->priority);
                    }
                }
            }
            return(selectableIndex.Item1);
        }
Ejemplo n.º 16
0
 public static int GetNodeCount(this UIGraphData self) => self.IsCreated ? *(int *)(self.value + sizeof(ulong)).ToPointer() : 0;
Ejemplo n.º 17
0
        private void Render(NativeArray <UIVertexData> vertices, UIContextData *context, ref MeshData meshData, UIGraphData graph, NativeArray <NodeInfo> layout, GraphInfo graphInfo, NativeArray <UIPassState> stateLayout)
        {
            var    indices      = meshData.GetIndexData <ushort>();
            var    subMeshes    = new NativeArray <SubMeshInfo>(graphInfo.subMeshCount, Allocator.Temp);
            int    submeshIndex = 0;
            int    renderIndex  = 0;
            float4 bounds       = float4.zero;

            RenderMesh(0, -1, 0, vertices, context, indices, graph, graphInfo, layout, stateLayout, subMeshes, true, true, true, ref submeshIndex, ref renderIndex, ref bounds);
            float4 totalBounds = bounds;
            int    submesh0RenderIndexCount = renderIndex;

            for (int i = 0; i < subMeshes.Length; i++)
            {
                SubMeshInfo current            = subMeshes[i];
                var         initialRenderIndex = renderIndex;
                RenderMesh(current.nodeIndex, -1, current.nodeIndex, vertices, context, indices, graph, graphInfo, layout, stateLayout, subMeshes, true, false, false, ref submeshIndex, ref renderIndex, ref bounds);
                totalBounds            = new float4(math.min(totalBounds.x, bounds.x), math.min(totalBounds.y, bounds.y), math.max(totalBounds.z, bounds.z), math.max(totalBounds.w, bounds.w));
                current.meshIndexStart = initialRenderIndex * 6;
                current.meshIndexCount = (renderIndex - initialRenderIndex) * 6;
                current.bounds         = bounds;
                subMeshes[i]           = current;
                for (int j = 0; j < (renderIndex - initialRenderIndex); j++)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        UIVertexData vertex = vertices[(initialRenderIndex + j) * 4 + k];
                        vertex.position.z -= 0.001f * (i + 1);
                        vertices[(initialRenderIndex + j) * 4 + k] = vertex;
                    }
                }
            }
            //Center Mesh
            float3 totalSize = new float3(math.abs(totalBounds.z - totalBounds.x), math.abs(totalBounds.y - totalBounds.w), 0f);
            var    adjust    = new float3(totalSize.x / 2f, totalSize.y / 2f, 0);

            for (int i = 0; i < vertices.Length; i++)
            {
                UIVertexData vertex = vertices[i];
                vertex.position -= adjust;
                vertices[i]      = vertex;
            }
            for (int i = 0; i < subMeshes.Length; i++)
            {
                SubMeshInfo current = subMeshes[i];
                var         size    = new float3(math.abs(current.bounds.z - current.bounds.x), math.abs(current.bounds.y - current.bounds.w), 0.00001f);
                meshData.SetSubMesh(meshData.subMeshCount - (i + 1), new UnityEngine.Rendering.SubMeshDescriptor(current.meshIndexStart, current.meshIndexCount)
                {
                    //bounds = new Bounds(new float3(current.bounds.x + (size.x / 2f), bounds.y + (size.y / 2f), 0f) - adjust, size),
                    bounds      = new Bounds(float3.zero, size),
                    firstVertex = (current.meshIndexStart / 6) * 4,
                    vertexCount = (current.meshIndexCount / 6) * 4
                }
                                    //,MeshUpdateFlags.DontRecalculateBounds | MeshUpdateFlags.DontValidateIndices
                                    );
            }
            meshData.SetSubMesh(0, new UnityEngine.Rendering.SubMeshDescriptor(0, submesh0RenderIndexCount * 6)
            {
                bounds      = new Bounds(float3.zero, new float3(totalSize.x, totalSize.y, 0.00001f)),
                firstVertex = 0,
                vertexCount = submesh0RenderIndexCount * 4
            }
                                //,MeshUpdateFlags.DontRecalculateBounds | MeshUpdateFlags.DontValidateIndices
                                );
            subMeshes.Dispose();
        }
Ejemplo n.º 18
0
 public static ulong GetLength(this UIGraphData self) => self.IsCreated ? *(ulong *)self.value.ToPointer() : 0UL;
Ejemplo n.º 19
0
        private void RenderMesh(
            int startIndex,
            int parentIndex,
            int currentIndex,
            NativeArray <UIVertexData> vertexData,
            UIContextData *context,
            NativeArray <ushort> indices,
            UIGraphData graph,
            GraphInfo graphInfo,
            NativeArray <NodeInfo> nodeInfo,
            NativeArray <UIPassState> stateLayout,
            NativeArray <SubMeshInfo> subMeshes,
            bool renderNow,
            bool updateSubmeshCount,
            bool accumulate,
            ref int subMeshIndex,
            ref int renderIndex,
            ref float4 bounds

            )
        {
            var           info         = nodeInfo[currentIndex];
            HeaderConfig *headerConfig = (HeaderConfig *)(graph.value + info.nodeOffset).ToPointer();
            var           state        = stateLayout[currentIndex];

            if (accumulate)
            {
                state.globalBox += state.localBox;
                if (parentIndex >= 0)
                {
                    state.globalBox += stateLayout[parentIndex].inner;
                }
                stateLayout[currentIndex] = state;
            }
            if (headerConfig->IsDedicatedNode)
            {
                if (updateSubmeshCount)
                {
                    subMeshes[subMeshIndex] = new SubMeshInfo(++subMeshIndex, currentIndex);
                }
                renderNow = currentIndex == startIndex;
            }
            if (renderNow)
            {
                bool display = true;
                bool visible = true;
                if (graph.TryGetConfigBlock(currentIndex, UIConfigLayoutTable.DisplayConfig, out IntPtr displayConfig))
                {
                    var dc = ((DisplayConfig *)displayConfig.ToPointer());
                    display = dc->display == VisibilityStyle.Visible;
                    visible = dc->visible == VisibilityStyle.Visible;
                }
                if (display)
                {
                    FunctionPointer <UIRenderPass> render = headerConfig->schemaIndex >= 0 ? schema.Value.elements[headerConfig->schemaIndex].render : default;
                    if (render.IsCreated)
                    {
                        render.Invoke(
                            graph.value,
                            (NodeInfo *)UnsafeUtility.AddressOf(ref info),
                            (UIPassState *)UnsafeUtility.AddressOf(ref state),
                            (UIVertexData *)(((IntPtr)vertexData.GetUnsafePtr()) + (renderIndex * UnsafeUtility.SizeOf <UIVertexData>() * 4)).ToPointer(),
                            context
                            );
                    }
                    for (int j = 0; j < info.renderBoxCount; j++)
                    {
                        indices[(renderIndex + j) * 6]       = (ushort)((renderIndex + j) * 4);
                        indices[((renderIndex + j) * 6) + 1] = (ushort)(((renderIndex + j) * 4) + 2);
                        indices[((renderIndex + j) * 6) + 2] = (ushort)(((renderIndex + j) * 4) + 1);
                        indices[((renderIndex + j) * 6) + 3] = (ushort)(((renderIndex + j) * 4) + 2);
                        indices[((renderIndex + j) * 6) + 4] = (ushort)(((renderIndex + j) * 4) + 3);
                        indices[((renderIndex + j) * 6) + 5] = (ushort)(((renderIndex + j) * 4) + 1);
                        UpdateBounds(vertexData, (renderIndex + j) * 4, ref bounds);
                    }
                }
                if (!display || !visible)
                {
                    UnsafeUtility.MemClear((((IntPtr)vertexData.GetUnsafePtr()) + (renderIndex * UnsafeUtility.SizeOf <UIVertexData>() * 4)).ToPointer(), UnsafeUtility.SizeOf <UIVertexData>() * info.renderBoxCount * 4);
                    UnsafeUtility.MemClear((((IntPtr)indices.GetUnsafePtr()) + (renderIndex * UnsafeUtility.SizeOf <ushort>() * 6)).ToPointer(), UnsafeUtility.SizeOf <ushort>() * info.renderBoxCount * 6);
                }
                renderIndex += info.renderBoxCount;
            }
            for (int i = 0; i < headerConfig->childCount; i++)
            {
                RenderMesh(startIndex, currentIndex, UnsafeUtility.ReadArrayElement <int>((graph.value + info.childrenOffset).ToPointer(), i), vertexData, context, indices, graph, graphInfo, nodeInfo, stateLayout, subMeshes, renderNow, updateSubmeshCount, accumulate, ref subMeshIndex, ref renderIndex, ref bounds);
            }
        }
Ejemplo n.º 20
0
 public static void GetNodeHeader(this UIGraphData self, int index, ref HeaderConfig result)
 {
     result = UnsafeUtility.AsRef <HeaderConfig>((GetNodePointer(self, index) + sizeof(int)).ToPointer());
 }
Ejemplo n.º 21
0
 public static string GetNodeName(this UIGraphData self, int index)
 {
     if (TryGetConfigBlock(self, index, UIConfigLayoutTable.NameConfig, out IntPtr block, out IntPtr header))
     {
         return(((NameConfig *)block.ToPointer())->name.ToString(header.ToPointer()));
     }
Ejemplo n.º 22
0
 public static bool IsDedicatedNode(this UIGraphData self, int index) => GetNodeHeader(self, index).IsDedicatedNode;
Ejemplo n.º 23
0
 public static int GetNodeLength(this UIGraphData self, int index)
 {
     return(*(int *)GetNodePointer(self, index).ToPointer());
 }