Ejemplo n.º 1
0
    // Token: 0x060006E2 RID: 1762 RVA: 0x00042C9C File Offset: 0x0004109C
    public List <Vector3> Apply(List <Vector3> vs)
    {
        if (vs == null || vs.Count < 3)
        {
            return(vs);
        }
        if (this.radi.Length < vs.Count)
        {
            this.radi = new float[vs.Count];
            this.a1   = new float[vs.Count];
            this.a2   = new float[vs.Count];
            this.dir  = new bool[vs.Count];
        }
        for (int i = 0; i < vs.Count; i++)
        {
            this.radi[i] = this.radius;
        }
        this.radi[0]            = 0f;
        this.radi[vs.Count - 1] = 0f;
        int num = 0;

        for (int j = 0; j < vs.Count - 1; j++)
        {
            num++;
            if (num > 2 * vs.Count)
            {
                Debug.LogWarning("Could not resolve radiuses, the path is too complex. Try reducing the base radius");
                break;
            }
            RadiusModifier.TangentType tangentType;
            if (j == 0)
            {
                tangentType = this.CalculateTangentTypeSimple(vs[j], vs[j + 1], vs[j + 2]);
            }
            else if (j == vs.Count - 2)
            {
                tangentType = this.CalculateTangentTypeSimple(vs[j - 1], vs[j], vs[j + 1]);
            }
            else
            {
                tangentType = this.CalculateTangentType(vs[j - 1], vs[j], vs[j + 1], vs[j + 2]);
            }
            float num4;
            float num5;
            if ((tangentType & RadiusModifier.TangentType.Inner) != (RadiusModifier.TangentType) 0)
            {
                float num2;
                float num3;
                if (!this.CalculateCircleInner(vs[j], vs[j + 1], this.radi[j], this.radi[j + 1], out num2, out num3))
                {
                    float magnitude = (vs[j + 1] - vs[j]).magnitude;
                    this.radi[j]      = magnitude * (this.radi[j] / (this.radi[j] + this.radi[j + 1]));
                    this.radi[j + 1]  = magnitude - this.radi[j];
                    this.radi[j]     *= 0.99f;
                    this.radi[j + 1] *= 0.99f;
                    j -= 2;
                }
                else if (tangentType == RadiusModifier.TangentType.InnerRightLeft)
                {
                    this.a2[j]     = num3 - num2;
                    this.a1[j + 1] = num3 - num2 + 3.14159274f;
                    this.dir[j]    = true;
                }
                else
                {
                    this.a2[j]     = num3 + num2;
                    this.a1[j + 1] = num3 + num2 + 3.14159274f;
                    this.dir[j]    = false;
                }
            }
            else if (!this.CalculateCircleOuter(vs[j], vs[j + 1], this.radi[j], this.radi[j + 1], out num4, out num5))
            {
                if (j == vs.Count - 2)
                {
                    this.radi[j]  = (vs[j + 1] - vs[j]).magnitude;
                    this.radi[j] *= 0.99f;
                    j--;
                }
                else
                {
                    if (this.radi[j] > this.radi[j + 1])
                    {
                        this.radi[j + 1] = this.radi[j] - (vs[j + 1] - vs[j]).magnitude;
                    }
                    else
                    {
                        this.radi[j + 1] = this.radi[j] + (vs[j + 1] - vs[j]).magnitude;
                    }
                    this.radi[j + 1] *= 0.99f;
                }
                j--;
            }
            else if (tangentType == RadiusModifier.TangentType.OuterRight)
            {
                this.a2[j]     = num5 - num4;
                this.a1[j + 1] = num5 - num4;
                this.dir[j]    = true;
            }
            else
            {
                this.a2[j]     = num5 + num4;
                this.a1[j + 1] = num5 + num4;
                this.dir[j]    = false;
            }
        }
        List <Vector3> list = ListPool <Vector3> .Claim();

        list.Add(vs[0]);
        if (this.detail < 1f)
        {
            this.detail = 1f;
        }
        float num6 = 6.28318548f / this.detail;

        for (int k = 1; k < vs.Count - 1; k++)
        {
            float num7 = this.a1[k];
            float num8 = this.a2[k];
            float d    = this.radi[k];
            if (this.dir[k])
            {
                if (num8 < num7)
                {
                    num8 += 6.28318548f;
                }
                for (float num9 = num7; num9 < num8; num9 += num6)
                {
                    list.Add(new Vector3((float)Math.Cos((double)num9), 0f, (float)Math.Sin((double)num9)) * d + vs[k]);
                }
            }
            else
            {
                if (num7 < num8)
                {
                    num7 += 6.28318548f;
                }
                for (float num10 = num7; num10 > num8; num10 -= num6)
                {
                    list.Add(new Vector3((float)Math.Cos((double)num10), 0f, (float)Math.Sin((double)num10)) * d + vs[k]);
                }
            }
        }
        list.Add(vs[vs.Count - 1]);
        return(list);
    }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns randomly selected points on the specified nodes with each point being separated by clearanceRadius from each other.
        /// Selecting points ON the nodes only works for TriangleMeshNode (used by Recast Graph and Navmesh Graph) and GridNode (used by GridGraph).
        /// For other node types, only the positions of the nodes will be used.
        ///
        /// clearanceRadius will be reduced if no valid points can be found.
        ///
        /// Note: This method assumes that the nodes in the list have the same type for some special cases.
        /// More specifically if the first node is not a TriangleMeshNode or a GridNode, it will use a fast path
        /// which assumes that all nodes in the list have the same surface area (which usually is a surface area of zero and the
        /// nodes are all PointNodes).
        /// </summary>
        public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0)
        {
            if (nodes == null)
            {
                throw new System.ArgumentNullException("nodes");
            }
            if (nodes.Count == 0)
            {
                throw new System.ArgumentException("no nodes passed");
            }

            List <Vector3> pts = ListPool <Vector3> .Claim(count);

            // Square
            clearanceRadius *= clearanceRadius;

            if (clearanceRadius > 0 || nodes[0] is TriangleMeshNode
#if !ASTAR_NO_GRID_GRAPH
                || nodes[0] is GridNode
#endif
                )
            {
                // Accumulated area of all nodes
                List <float> accs = ListPool <float> .Claim(nodes.Count);

                // Total area of all nodes so far
                float tot = 0;

                for (int i = 0; i < nodes.Count; i++)
                {
                    var surfaceArea = nodes[i].SurfaceArea();
                    // Ensures that even if the nodes have a surface area of 0, a random one will still be picked
                    // instead of e.g always picking the first or the last one.
                    surfaceArea += 0.001f;
                    tot         += surfaceArea;
                    accs.Add(tot);
                }

                for (int i = 0; i < count; i++)
                {
                    //Pick point
                    int  testCount = 0;
                    int  testLimit = 10;
                    bool worked    = false;

                    while (!worked)
                    {
                        worked = true;

                        // If no valid points could be found, progressively lower the clearance radius until such a point is found
                        if (testCount >= testLimit)
                        {
                            // Note that clearanceRadius is a squared radius
                            clearanceRadius *= 0.9f * 0.9f;
                            testLimit       += 10;
                            if (testLimit > 100)
                            {
                                clearanceRadius = 0;
                            }
                        }

                        // Pick a random node among the ones in the list weighted by their area
                        float tg = Random.value * tot;
                        int   v  = accs.BinarySearch(tg);
                        if (v < 0)
                        {
                            v = ~v;
                        }

                        if (v >= nodes.Count)
                        {
                            // Cover edge cases
                            worked = false;
                            continue;
                        }

                        var node = nodes[v];
                        var p    = node.RandomPointOnSurface();

                        // Test if it is some distance away from the other points
                        if (clearanceRadius > 0)
                        {
                            for (int j = 0; j < pts.Count; j++)
                            {
                                if ((pts[j] - p).sqrMagnitude < clearanceRadius)
                                {
                                    worked = false;
                                    break;
                                }
                            }
                        }

                        if (worked)
                        {
                            pts.Add(p);
                            break;
                        }
                        testCount++;
                    }
                }

                ListPool <float> .Release(ref accs);
            }
            else
            {
                // Fast path, assumes all nodes have the same area (usually zero)
                for (int i = 0; i < count; i++)
                {
                    pts.Add((Vector3)nodes[Random.Range(0, nodes.Count)].RandomPointOnSurface());
                }
            }

            return(pts);
        }
Ejemplo n.º 3
0
        public void ValidateGraph()
        {
            var propertyNodes = GetNodes <PropertyNode>().Where(n => !m_Properties.Any(p => p.guid == n.propertyGuid)).ToArray();

            foreach (var pNode in propertyNodes)
            {
                ReplacePropertyNodeWithConcreteNodeNoValidate(pNode);
            }

            messageManager?.ClearAllFromProvider(this);
            //First validate edges, remove any
            //orphans. This can happen if a user
            //manually modifies serialized data
            //of if they delete a node in the inspector
            //debug view.
            foreach (var edge in edges.ToArray())
            {
                var outputNode = GetNodeFromGuid(edge.outputSlot.nodeGuid);
                var inputNode  = GetNodeFromGuid(edge.inputSlot.nodeGuid);

                MaterialSlot outputSlot = null;
                MaterialSlot inputSlot  = null;
                if (outputNode != null && inputNode != null)
                {
                    outputSlot = outputNode.FindOutputSlot <MaterialSlot>(edge.outputSlot.slotId);
                    inputSlot  = inputNode.FindInputSlot <MaterialSlot>(edge.inputSlot.slotId);
                }

                if (outputNode == null ||
                    inputNode == null ||
                    outputSlot == null ||
                    inputSlot == null ||
                    !outputSlot.IsCompatibleWith(inputSlot))
                {
                    //orphaned edge
                    RemoveEdgeNoValidate(edge);
                }
            }

            var temporaryMarks = IndexSetPool.Get();
            var permanentMarks = IndexSetPool.Get();
            var slots          = ListPool <MaterialSlot> .Get();

            // Make sure we process a node's children before the node itself.
            var stack = StackPool <AbstractMaterialNode> .Get();

            foreach (var node in GetNodes <AbstractMaterialNode>())
            {
                stack.Push(node);
            }
            while (stack.Count > 0)
            {
                var node = stack.Pop();
                if (permanentMarks.Contains(node.tempId.index))
                {
                    continue;
                }

                if (temporaryMarks.Contains(node.tempId.index))
                {
                    node.ValidateNode();
                    permanentMarks.Add(node.tempId.index);
                }
                else
                {
                    temporaryMarks.Add(node.tempId.index);
                    stack.Push(node);
                    node.GetInputSlots(slots);
                    foreach (var inputSlot in slots)
                    {
                        var nodeEdges = GetEdges(inputSlot.slotReference);
                        foreach (var edge in nodeEdges)
                        {
                            var fromSocketRef = edge.outputSlot;
                            var childNode     = GetNodeFromGuid(fromSocketRef.nodeGuid);
                            if (childNode != null)
                            {
                                stack.Push(childNode);
                            }
                        }
                    }
                    slots.Clear();
                }
            }

            StackPool <AbstractMaterialNode> .Release(stack);

            ListPool <MaterialSlot> .Release(slots);

            IndexSetPool.Release(temporaryMarks);
            IndexSetPool.Release(permanentMarks);

            foreach (var edge in m_AddedEdges.ToList())
            {
                if (!ContainsNodeGuid(edge.outputSlot.nodeGuid) || !ContainsNodeGuid(edge.inputSlot.nodeGuid))
                {
                    Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}\n{2}", edge.outputSlot.nodeGuid, edge.inputSlot.nodeGuid, Environment.StackTrace);
                    m_AddedEdges.Remove(edge);
                }
            }
        }
Ejemplo n.º 4
0
    IEnumerator TravelPath()
    {
        Vector3 a, b, c = pathToTravel[0].Position;

        yield return(LookAt(pathToTravel[1].Position));

        if (!currentTravelLocation)
        {
            currentTravelLocation = pathToTravel[0];
        }
        Grid.DecreaseVisibility(currentTravelLocation, VisionRange);
        int currentColumn = currentTravelLocation.ColumnIndex;

        float t = Time.deltaTime * travelSpeed;

        for (int i = 1; i < pathToTravel.Count; i++)
        {
            currentTravelLocation = pathToTravel[i];
            a = c;
            b = pathToTravel[i - 1].Position;

            int nextColumn = currentTravelLocation.ColumnIndex;
            if (currentColumn != nextColumn)
            {
                if (nextColumn < currentColumn - 1)
                {
                    a.x -= HexMetrics.innerDiameter * HexMetrics.wrapSize;
                    b.x -= HexMetrics.innerDiameter * HexMetrics.wrapSize;
                }
                else if (nextColumn > currentColumn + 1)
                {
                    a.x += HexMetrics.innerDiameter * HexMetrics.wrapSize;
                    b.x += HexMetrics.innerDiameter * HexMetrics.wrapSize;
                }
                Grid.MakeChildOfColumn(transform, nextColumn);
                currentColumn = nextColumn;
            }

            c = (b + currentTravelLocation.Position) * 0.5f;
            Grid.IncreaseVisibility(pathToTravel[i], VisionRange);

            for (; t < 1f; t += Time.deltaTime * travelSpeed)
            {
                transform.localPosition = Bezier.GetPoint(a, b, c, t);
                Vector3 d = Bezier.GetDerivative(a, b, c, t);
                d.y = 0f;
                transform.localRotation = Quaternion.LookRotation(d);
                yield return(null);
            }
            Grid.DecreaseVisibility(pathToTravel[i], VisionRange);
            t -= 1f;
        }
        currentTravelLocation = null;

        a = c;
        b = location.Position;
        c = b;
        Grid.IncreaseVisibility(location, VisionRange);
        for (; t < 1f; t += Time.deltaTime * travelSpeed)
        {
            transform.localPosition = Bezier.GetPoint(a, b, c, t);
            Vector3 d = Bezier.GetDerivative(a, b, c, t);
            d.y = 0f;
            transform.localRotation = Quaternion.LookRotation(d);
            yield return(null);
        }

        transform.localPosition = location.Position;
        orientation             = transform.localRotation.eulerAngles.y;
        ListPool <HexCell> .Add(pathToTravel);

        pathToTravel = null;
    }
        static string GetShaderPassFromTemplate(bool isColorPass, string template, SpriteLitMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions)
        {
            // ----------------------------------------------------- //
            //                         SETUP                         //
            // ----------------------------------------------------- //

            // -------------------------------------
            // String builders

            var shaderProperties       = new PropertyCollector();
            var shaderPropertyUniforms = new ShaderStringBuilder(1);
            var functionBuilder        = new ShaderStringBuilder(1);
            var functionRegistry       = new FunctionRegistry(functionBuilder);

            var defines = new ShaderStringBuilder(1);
            var graph   = new ShaderStringBuilder(0);

            var vertexDescriptionInputStruct = new ShaderStringBuilder(1);
            var vertexDescriptionStruct      = new ShaderStringBuilder(1);
            var vertexDescriptionFunction    = new ShaderStringBuilder(1);

            var surfaceDescriptionInputStruct = new ShaderStringBuilder(1);
            var surfaceDescriptionStruct      = new ShaderStringBuilder(1);
            var surfaceDescriptionFunction    = new ShaderStringBuilder(1);

            var vertexInputStruct  = new ShaderStringBuilder(1);
            var vertexOutputStruct = new ShaderStringBuilder(2);

            var vertexShader = new ShaderStringBuilder(2);
            var vertexShaderDescriptionInputs = new ShaderStringBuilder(2);
            var vertexShaderOutputs           = new ShaderStringBuilder(2);

            var pixelShader = new ShaderStringBuilder(2);
            var pixelShaderSurfaceInputs = new ShaderStringBuilder(2);

            // -------------------------------------
            // Get Slot and Node lists per stage
            var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot <MaterialSlot>).ToList();
            var vertexNodes = ListPool <AbstractMaterialNode> .Get();

            NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);

            var pixelSlots = pass.PixelShaderSlots.Select(masterNode.FindSlot <MaterialSlot>).ToList();
            var pixelNodes = ListPool <AbstractMaterialNode> .Get();

            NodeUtils.DepthFirstCollectNodesFromNode(pixelNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.PixelShaderSlots);

            // -------------------------------------
            // Get Requirements
            var vertexRequirements  = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false);
            var pixelRequirements   = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment);
            var surfaceRequirements = ShaderGraphRequirements.FromNodes(pixelNodes, ShaderStageCapability.Fragment, false);

            var modelRequiements = ShaderGraphRequirements.none;

            modelRequiements.requiresVertexColor = true;

            if (isColorPass)
            {
                modelRequiements.requiresMeshUVs = new List <UVChannel>()
                {
                    UVChannel.UV0
                };
            }

            // ----------------------------------------------------- //
            //                START SHADER GENERATION                //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Calculate material options

            var blendingBuilder = new ShaderStringBuilder(1);
            var cullingBuilder  = new ShaderStringBuilder(1);
            var zTestBuilder    = new ShaderStringBuilder(1);
            var zWriteBuilder   = new ShaderStringBuilder(1);

            materialOptions.GetBlend(blendingBuilder);
            materialOptions.GetCull(cullingBuilder);
            materialOptions.GetDepthTest(zTestBuilder);
            materialOptions.GetDepthWrite(zWriteBuilder);


            // ----------------------------------------------------- //
            //                START VERTEX DESCRIPTION               //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Generate Input structure for Vertex Description function
            // TODO - Vertex Description Input requirements are needed to exclude intermediate translation spaces

            vertexDescriptionInputStruct.AppendLine("struct VertexDescriptionInputs");
            using (vertexDescriptionInputStruct.BlockSemicolonScope())
            {
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresNormal, InterpolatorType.Normal, vertexDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresTangent, InterpolatorType.Tangent, vertexDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresBitangent, InterpolatorType.BiTangent, vertexDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresViewDir, InterpolatorType.ViewDirection, vertexDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresPosition, InterpolatorType.Position, vertexDescriptionInputStruct);

                if (vertexRequirements.requiresVertexColor)
                {
                    vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor);
                }

                if (vertexRequirements.requiresScreenPosition)
                {
                    vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
                }

                foreach (var channel in vertexRequirements.requiresMeshUVs.Distinct())
                {
                    vertexDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
                }
            }

            // -------------------------------------
            // Generate Output structure for Vertex Description function

            GraphUtil.GenerateVertexDescriptionStruct(vertexDescriptionStruct, vertexSlots);

            // -------------------------------------
            // Generate Vertex Description function

            GraphUtil.GenerateVertexDescriptionFunction(
                masterNode.owner as GraphData,
                vertexDescriptionFunction,
                functionRegistry,
                shaderProperties,
                mode,
                vertexNodes,
                vertexSlots);

            // ----------------------------------------------------- //
            //               START SURFACE DESCRIPTION               //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Generate Input structure for Surface Description function
            // Surface Description Input requirements are needed to exclude intermediate translation spaces

            surfaceDescriptionInputStruct.AppendLine("struct SurfaceDescriptionInputs");
            using (surfaceDescriptionInputStruct.BlockSemicolonScope())
            {
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresNormal, InterpolatorType.Normal, surfaceDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresTangent, InterpolatorType.Tangent, surfaceDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresBitangent, InterpolatorType.BiTangent, surfaceDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresViewDir, InterpolatorType.ViewDirection, surfaceDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresPosition, InterpolatorType.Position, surfaceDescriptionInputStruct);

                if (surfaceRequirements.requiresVertexColor)
                {
                    surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor);
                }

                if (surfaceRequirements.requiresScreenPosition)
                {
                    surfaceDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
                }

                if (surfaceRequirements.requiresFaceSign)
                {
                    surfaceDescriptionInputStruct.AppendLine("float {0};", ShaderGeneratorNames.FaceSign);
                }

                foreach (var channel in surfaceRequirements.requiresMeshUVs.Distinct())
                {
                    surfaceDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
                }
            }

            // -------------------------------------
            // Generate Output structure for Surface Description function

            GraphUtil.GenerateSurfaceDescriptionStruct(surfaceDescriptionStruct, pixelSlots);

            // -------------------------------------
            // Generate Surface Description function

            GraphUtil.GenerateSurfaceDescriptionFunction(
                pixelNodes,
                masterNode,
                masterNode.owner as GraphData,
                surfaceDescriptionFunction,
                functionRegistry,
                shaderProperties,
                pixelRequirements,
                mode,
                "PopulateSurfaceData",
                "SurfaceDescription",
                null,
                pixelSlots);

            // ----------------------------------------------------- //
            //           GENERATE VERTEX > PIXEL PIPELINE            //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Property uniforms

            shaderProperties.GetPropertiesDeclaration(shaderPropertyUniforms, mode, masterNode.owner.concretePrecision);

            // -------------------------------------
            // Generate Input structure for Vertex shader

            GraphUtil.GenerateApplicationVertexInputs(vertexRequirements.Union(pixelRequirements.Union(modelRequiements)), vertexInputStruct);

            // -------------------------------------
            // Generate standard transformations
            // This method ensures all required transform data is available in vertex and pixel stages

            ShaderGenerator.GenerateStandardTransforms(
                3,
                10,
                vertexOutputStruct,
                vertexShader,
                vertexShaderDescriptionInputs,
                vertexShaderOutputs,
                pixelShader,
                pixelShaderSurfaceInputs,
                pixelRequirements,
                surfaceRequirements,
                modelRequiements,
                vertexRequirements,
                CoordinateSpace.World);


            // ----------------------------------------------------- //
            //                      FINALIZE                         //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Combine Graph sections

            graph.AppendLines(shaderPropertyUniforms.ToString());

            graph.AppendLine(vertexDescriptionInputStruct.ToString());
            graph.AppendLine(surfaceDescriptionInputStruct.ToString());

            graph.AppendLine(functionBuilder.ToString());

            graph.AppendLine(vertexDescriptionStruct.ToString());
            graph.AppendLine(vertexDescriptionFunction.ToString());

            graph.AppendLine(surfaceDescriptionStruct.ToString());
            graph.AppendLine(surfaceDescriptionFunction.ToString());

            graph.AppendLine(vertexInputStruct.ToString());

            // -------------------------------------
            // Generate final subshader

            var resultPass = template.Replace("${Tags}", string.Empty);

            resultPass = resultPass.Replace("${Blending}", blendingBuilder.ToString());
            resultPass = resultPass.Replace("${Culling}", cullingBuilder.ToString());
            resultPass = resultPass.Replace("${ZTest}", zTestBuilder.ToString());
            resultPass = resultPass.Replace("${ZWrite}", zWriteBuilder.ToString());
            resultPass = resultPass.Replace("${Defines}", defines.ToString());

            resultPass = resultPass.Replace("${Graph}", graph.ToString());
            resultPass = resultPass.Replace("${VertexOutputStruct}", vertexOutputStruct.ToString());

            resultPass = resultPass.Replace("${VertexShader}", vertexShader.ToString());
            resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexShaderDescriptionInputs.ToString());
            resultPass = resultPass.Replace("${VertexShaderOutputs}", vertexShaderOutputs.ToString());

            resultPass = resultPass.Replace("${PixelShader}", pixelShader.ToString());
            resultPass = resultPass.Replace("${PixelShaderSurfaceInputs}", pixelShaderSurfaceInputs.ToString());

            return(resultPass);
        }
Ejemplo n.º 6
0
        private void Awake()
        {
            this.openMessageList = ListPool <ResultMessageElement> .Get();

            this.closeMessageList = ListPool <ResultMessageElement> .Get();
        }
Ejemplo n.º 7
0
        public void BuildFunnelCorridor(List <GraphNode> nodes, int start, int end)
        {
            this.exactStart = (nodes[start] as MeshNode).ClosestPointOnNode(this.exactStart);
            this.exactEnd   = (nodes[end] as MeshNode).ClosestPointOnNode(this.exactEnd);
            this.left.Clear();
            this.right.Clear();
            this.left.Add(this.exactStart);
            this.right.Add(this.exactStart);
            this.nodes.Clear();
            IRaycastableGraph raycastableGraph = this.graph as IRaycastableGraph;

            if (raycastableGraph != null && this.funnelSimplificationMode != RichFunnel.FunnelSimplification.None)
            {
                List <GraphNode> list = ListPool <GraphNode> .Claim(end - start);

                RichFunnel.FunnelSimplification funnelSimplification = this.funnelSimplificationMode;
                if (funnelSimplification != RichFunnel.FunnelSimplification.Iterative)
                {
                    if (funnelSimplification != RichFunnel.FunnelSimplification.RecursiveBinary)
                    {
                        if (funnelSimplification == RichFunnel.FunnelSimplification.RecursiveTrinary)
                        {
                            RichFunnel.SimplifyPath3(raycastableGraph, nodes, start, end, list, this.exactStart, this.exactEnd, 0);
                        }
                    }
                    else
                    {
                        RichFunnel.SimplifyPath2(raycastableGraph, nodes, start, end, list, this.exactStart, this.exactEnd);
                    }
                }
                else
                {
                    this.SimplifyPath(raycastableGraph, nodes, start, end, list, this.exactStart, this.exactEnd);
                }
                if (this.nodes.Capacity < list.Count)
                {
                    this.nodes.Capacity = list.Count;
                }
                for (int i = 0; i < list.Count; i++)
                {
                    TriangleMeshNode triangleMeshNode = list[i] as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        this.nodes.Add(triangleMeshNode);
                    }
                }
                ListPool <GraphNode> .Release(list);
            }
            else
            {
                if (this.nodes.Capacity < end - start)
                {
                    this.nodes.Capacity = end - start;
                }
                for (int j = start; j <= end; j++)
                {
                    TriangleMeshNode triangleMeshNode2 = nodes[j] as TriangleMeshNode;
                    if (triangleMeshNode2 != null)
                    {
                        this.nodes.Add(triangleMeshNode2);
                    }
                }
            }
            for (int k = 0; k < this.nodes.Count - 1; k++)
            {
                this.nodes[k].GetPortal(this.nodes[k + 1], this.left, this.right, false);
            }
            this.left.Add(this.exactEnd);
            this.right.Add(this.exactEnd);
        }
Ejemplo n.º 8
0
        public void AutoComplete()
        {
            var cmd = this.screen.GetInputText();

            var first = cmd;

            string[] subModuleArgs;
            var      args = ConsoleManager.GetCmdArgs(ref cmd, out first, out subModuleArgs, System.StringSplitOptions.None);

            var variants       = new List <string>();
            var variantsConcat = new List <string>();

            //Debug.Log(args.Length);

            if (args.Length == 1)
            {
                // module auto-complete

                var search = args[0].ToLower();

                foreach (var module in this.loadedModules)
                {
                    var found = false;

                    var names = module.GetNames();
                    foreach (var name in names)
                    {
                        if (name == search)
                        {
                            variants.Add(name);
                            variantsConcat.Add(name);
                            found = true;
                            break;
                        }
                    }

                    if (found == false)
                    {
                        foreach (var name in names)
                        {
                            if (name.StartsWith(search) == true)
                            {
                                variants.Add(name);
                                variantsConcat.Add(name);
                                break;
                            }
                        }
                    }
                }
            }
            else if (args.Length == 2)
            {
                // method auto-complete
                var moduleName = args[0].Trim().ToLower();
                if (this.modules.ContainsKey(moduleName) == true)
                {
                    var output = ListPool <string> .Get();

                    var outputConcat = ListPool <string> .Get();

                    var module = this.modules[moduleName];
                    module.HasAutoComplete(cmd, subModuleArgs, output, outputConcat);
                    variants.AddRange(output);
                    variantsConcat.AddRange(outputConcat);

                    ListPool <string> .Release(output);

                    ListPool <string> .Release(outputConcat);
                }
            }
            else if (args.Length > 2)
            {
                // method parameters auto-complete
                var moduleName = args[0].Trim().ToLower();
                if (this.modules.ContainsKey(moduleName) == true)
                {
                    var output = ListPool <string> .Get();

                    var outputConcat = ListPool <string> .Get();

                    var module = this.modules[moduleName];
                    module.GetParamAutoComplete(cmd, subModuleArgs, args.Length, output, outputConcat);
                    variants.AddRange(output);
                    //variantsConcat.AddRange(outputConcat);

                    ListPool <string> .Release(output);

                    ListPool <string> .Release(outputConcat);
                }
            }

            if (variantsConcat.Count == 1)
            {
                var c = variantsConcat[0];
                // concat (args - 1) and output with `c`
                var str = string.Format("{0} {1}", string.Join(" ", args, 0, args.Length - 1), c).Trim() + " ";
                this.screen.SetInputText(str);
                this.screen.MoveCaretToEnd();

                this.autoComplete = false;
            }
            else if (variantsConcat.Count > 1)
            {
                this.screen.AddLine("<color=#c2c>Variants:</color>");
                foreach (var v in variants)
                {
                    this.AddLine(string.Format("\t{0}", v), reusable: false);
                }

                this.autoComplete = true;
            }
            else
            {
                this.autoComplete = true;
            }

            //Debug.Log("Complete: " + this.screen.GetInputText());
        }
Ejemplo n.º 9
0
        public string[] ShowHelp_INTERNAL(SubModuleBase module, string methodNameStart, bool distinct = false, bool commandsOnly = false)
        {
            //var moduleName = module.GetType().Name;
            var help = ListPool <string> .Get();

            var helpMethods = ListPool <string> .Get();

            var methods = ListPool <MethodInfo> .Get();

            ConsoleManager.GetModuleMethods(module, methods);
            foreach (var method in methods)
            {
                var methodName = method.Name.ToLower();
                if (string.IsNullOrEmpty(methodNameStart) == true || methodName.StartsWith(methodNameStart) == true)
                {
                    if (distinct == true)
                    {
                        if (helpMethods.Contains(methodName) == true)
                        {
                            continue;
                        }

                        helpMethods.Add(methodName);
                    }

                    var pstr = string.Empty;
                    var pars = method.GetParameters();
                    foreach (var par in pars)
                    {
                        if (par.ParameterType == typeof(bool))
                        {
                            pstr += string.Format("[b:{0}]", par.Name);
                        }
                        else if (par.ParameterType == typeof(int))
                        {
                            pstr += string.Format("[i:{0}]", par.Name);
                        }
                        else if (par.ParameterType == typeof(long))
                        {
                            pstr += string.Format("[l:{0}]", par.Name);
                        }
                        else if (par.ParameterType == typeof(float))
                        {
                            pstr += string.Format("[f:{0}]", par.Name);
                        }
                        else if (par.ParameterType.IsEnum == true)
                        {
                            pstr += string.Format("[e:{0}]", par.Name);
                        }
                        else if (par.ParameterType == typeof(string))
                        {
                            pstr += string.Format("[s:{0}]", par.Name);
                        }
                        else
                        {
                            pstr += string.Format("[{0}:{1}]", par.ParameterType, par.Name);
                        }
                    }

                    HelpAttribute comment  = null;
                    var           comments = method.GetCustomAttributes(typeof(HelpAttribute), false);
                    if (comments.Length > 0)
                    {
                        comment = (HelpAttribute)comments[0];
                    }

                    if (commandsOnly == true)
                    {
                        help.Add(methodName);
                    }
                    else
                    {
                        help.Add(methodName +
                                 (string.IsNullOrEmpty(pstr) == true ? string.Empty : string.Format("\t{0}", pstr)) +
                                 (comment == null || string.IsNullOrEmpty(comment.comment) == true ? string.Empty : (string.Format("\t<color=grey>// {0}</color>", comment.comment))));
                    }
                }
            }

            var result = help.ToArray();

            ListPool <string> .Release(help);

            ListPool <string> .Release(helpMethods);

            ListPool <MethodInfo> .Release(methods);

            return(result);
        }
Ejemplo n.º 10
0
        public void Release()
        {
            ListPool <string> .Release(ref path);

            ReleaseGenerics();
        }
Ejemplo n.º 11
0
    List <HexCell> GetVisibleCells(HexCell fromCell, int range)
    {
        List <HexCell> visibleCells = ListPool <HexCell> .Get();

        searchFrontierPhase += 2;
        if (searchFrontier == null)
        {
            searchFrontier = new HexCellPriorityQueue();
        }
        else
        {
            searchFrontier.Clear();
        }

        range += fromCell.ViewElevation;
        fromCell.SearchPhase = searchFrontierPhase;
        fromCell.Distance    = 0;
        searchFrontier.Enqueue(fromCell);
        HexCoordinates fromCoordinates = fromCell.coordinates;

        while (searchFrontier.Count > 0)
        {
            HexCell current = searchFrontier.Dequeue();
            current.SearchPhase += 1;
            visibleCells.Add(current);

            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = current.GetNeighbor(d);
                if (
                    neighbor == null ||
                    neighbor.SearchPhase > searchFrontierPhase ||
                    !neighbor.Explorable
                    )
                {
                    continue;
                }

                int distance = current.Distance + 1;
                if (distance + neighbor.ViewElevation > range ||
                    distance > fromCoordinates.DistanceTo(neighbor.coordinates)
                    )
                {
                    continue;
                }

                if (neighbor.SearchPhase < searchFrontierPhase)
                {
                    neighbor.SearchPhase     = searchFrontierPhase;
                    neighbor.Distance        = distance;
                    neighbor.SearchHeuristic = 0;
                    searchFrontier.Enqueue(neighbor);
                }
                else if (distance < neighbor.Distance)
                {
                    int oldPriority = neighbor.SearchPriority;
                    neighbor.Distance = distance;
                    searchFrontier.Change(neighbor, oldPriority);
                }
            }
        }
        return(visibleCells);
    }
Ejemplo n.º 12
0
        public void CanGetPermutationMapPerNode()
        {
            var previewNode = m_Graph.GetNodes <PreviewNode>().FirstOrDefault();

            Assert.IsNotNull(previewNode, "Preview Node not in graph.");

            var descendentNodes = new List <AbstractMaterialNode>();

            NodeUtils.DepthFirstCollectNodesFromNode(descendentNodes, previewNode, NodeUtils.IncludeSelf.Include);
            List <int>[] keywordPermutationsPerNode = new List <int> [descendentNodes.Count];
            Assert.IsNotEmpty(descendentNodes, "No Nodes in graph.");

            for (int i = 0; i < m_Collector.permutations.Count; i++)
            {
                var localNodes = ListPool <AbstractMaterialNode> .Get();

                NodeUtils.DepthFirstCollectNodesFromNode(localNodes, previewNode, NodeUtils.IncludeSelf.Include, keywordPermutation: m_Collector.permutations[i]);

                foreach (AbstractMaterialNode node in localNodes)
                {
                    int nodeIndex = descendentNodes.IndexOf(node);

                    if (keywordPermutationsPerNode[nodeIndex] == null)
                    {
                        keywordPermutationsPerNode[nodeIndex] = new List <int>();
                    }
                    keywordPermutationsPerNode[nodeIndex].Add(i);
                }
            }

            ShaderKeyword booleanAKeyword = m_Collector.keywords.Where(x => x.displayName == "Boolean A").FirstOrDefault();
            ShaderKeyword booleanBKeyword = m_Collector.keywords.Where(x => x.displayName == "Boolean B").FirstOrDefault();
            ShaderKeyword enumAKeyword    = m_Collector.keywords.Where(x => x.displayName == "Enum A").FirstOrDefault();
            ShaderKeyword enumBKeyword    = m_Collector.keywords.Where(x => x.displayName == "Enum B").FirstOrDefault();

            if (booleanAKeyword == null || booleanBKeyword == null || enumAKeyword == null || enumBKeyword == null)
            {
                Assert.Fail("One or more Keywords not in graph.");
            }

            var         keywordNodes = m_Graph.GetNodes <KeywordNode>().ToList();
            KeywordNode booleanANode = keywordNodes.Where(x => x.keyword == booleanAKeyword).FirstOrDefault();
            KeywordNode booleanBNode = keywordNodes.Where(x => x.keyword == booleanBKeyword).FirstOrDefault();
            KeywordNode enumANode    = keywordNodes.Where(x => x.keyword == enumAKeyword).FirstOrDefault();
            KeywordNode enumBNode    = keywordNodes.Where(x => x.keyword == enumBKeyword).FirstOrDefault();

            if (booleanANode == null || booleanBNode == null || enumANode == null || enumBNode == null)
            {
                Assert.Fail("One or more Keywords Nodes not in graph.");
            }

            int        booleanAIndex        = descendentNodes.IndexOf(booleanANode);
            List <int> booleanAPermutations = keywordPermutationsPerNode[booleanAIndex];

            Assert.AreEqual(24, booleanAPermutations.Count, "Boolean A had incorrect permutations.");

            int        booleanBIndex        = descendentNodes.IndexOf(booleanBNode);
            List <int> booleanBPermutations = keywordPermutationsPerNode[booleanBIndex];

            Assert.AreEqual(48, booleanBPermutations.Count, "Boolean B had incorrect permutations.");

            int        enumAIndex        = descendentNodes.IndexOf(enumANode);
            List <int> enumAPermutations = keywordPermutationsPerNode[enumAIndex];

            Assert.AreEqual(12, enumAPermutations.Count, "Enum A had incorrect permutations.");

            int        enumBIndex        = descendentNodes.IndexOf(enumBNode);
            List <int> enumBPermutations = keywordPermutationsPerNode[enumBIndex];

            Assert.AreEqual(24, enumBPermutations.Count, "Enum B had incorrect permutations.");
        }
Ejemplo n.º 13
0
    protected override TreeViewItem BuildRoot()
    {
        Stack <ElementTreeItem> stack = StackPool <ElementTreeItem> .Get();

        // todo -- maybe pool tree items

        TreeViewItem root = new TreeViewItem(-9999, -1);

        foreach (UIView uiView in views)
        {
            if (uiView.RootElement == null)
            {
                continue;
            }
            if (uiView.RootElement.isDisabled && !showDisabled)
            {
                continue;
            }

            ElementTreeItem firstChild = new ElementTreeItem(uiView.RootElement);
            firstChild.displayName = uiView.RootElement.ToString();
            stack.Push(firstChild);

            while (stack.Count > 0)
            {
                ElementTreeItem current = stack.Pop();
                if (current.element.isDisabled && !showDisabled)
                {
                    continue;
                }

                UIElement element = current.element;

                List <UIElement> ownChildren = element.GetChildren();

                if (ownChildren.Count == 0)
                {
                    ListPool <UIElement> .Release(ref ownChildren);

                    continue;
                }

                for (int i = 0; i < ownChildren.Count; i++)
                {
                    ElementTreeItem childItem = new ElementTreeItem(ownChildren[i]);
                    if (childItem.element.isDisabled && !showDisabled)
                    {
                        continue;
                    }
                    childItem.displayName = ownChildren[i].ToString();
                    current.AddChild(childItem);
                    stack.Push(childItem);
                }
            }

            root.AddChild(firstChild);
        }

        root.displayName = "ROOT";
        SetupDepthsFromParentsAndChildren(root);
        needsReload = false;
        if (root.children == null)
        {
            root.children = new List <TreeViewItem>();
        }
        return(root);
    }
Ejemplo n.º 14
0
    protected override void RowGUI(RowGUIArgs args)
    {
        ElementTreeItem item      = (ElementTreeItem)args.item;
        GUIStyleState   textStyle = s_ElementNameStyle.normal;

        bool isTemplateRoot = (item.element.flags & UIElementFlags.TemplateRoot) != 0;

        Color mainColor = isTemplateRoot
            ? UIForiaEditorTheme.mainColorTemplateRoot
            : UIForiaEditorTheme.mainColorRegularChild;

        if (item.element.style.LayoutBehavior == LayoutBehavior.TranscludeChildren)
        {
            mainColor = UIForiaEditorTheme.mainColorChildrenElement;
        }

        textStyle.textColor = AdjustColor(mainColor, item.element);

        float indent   = GetContentIndent(args.item);
        float rowWidth = args.rowRect.width;

        args.rowRect.x     += indent;
        args.rowRect.width -= indent;
        s_Content.text      = item.element.GetDisplayName();

        if (showLayoutStats)
        {
            s_Content.text += $"w: {item.element.layoutBox.cacheHit}, {item.element.layoutBox.cacheMiss}";
        }

        if (item.element.isEnabled && item.element.renderBox != null)
        {
            if (item.element.renderBox.overflowX != Overflow.Visible || item.element.renderBox.overflowY != Overflow.Visible)
            {
                s_Content.text += " [Clipper]";
            }
        }

        if ((item.element.flags & UIElementFlags.DebugLayout) != 0)
        {
            s_Content.text = "{Debug Layout} " + s_Content.text;
        }

        Vector2 v = s_ElementNameStyle.CalcSize(s_Content);
        Rect    r = new Rect(args.rowRect);

        GUI.Label(args.rowRect, s_Content, s_ElementNameStyle);
        r.x     += v.x + 5f;
        r.width -= v.x + 5f;

        List <string> names = ListPool <string> .Get();

        item.element.style.GetStyleNameList(names);
        string styleName = string.Empty;

        for (int i = 0; i < names.Count; i++)
        {
            styleName += names[i] + " ";
        }

        ListPool <string> .Release(ref names);

        if (styleName.Length > 0)
        {
            styleName = '[' + styleName.TrimEnd() + "] ";
        }

        s_Content.text = styleName; // + "(children: " + box.children.Count + ", id: " + item.element.id + ")";

        if (showChildrenAndId)
        {
            s_Content.text += "(id: " + item.element?.id + ")";
        }

        textStyle.textColor = AdjustColor(UIForiaEditorTheme.elementStyleNormal, item.element);

        GUI.Label(r, s_Content, s_ElementNameStyle);

        v        = s_ElementNameStyle.CalcSize(s_Content);
        r.x     += v.x + 5f;
        r.width -= v.x + 5f;

        r = DrawAdditionalInfo(item.element, r);

        if (!isTemplateRoot)
        {
            return;
        }

        ViewState viewState;

        m_ViewState.TryGetValue(item.element.id, out viewState);

        r.x            = rowWidth - 16;
        r.width        = 16;
        s_Content.text = viewState.showTemplateContents ? "+" : "-";
        GUI.Label(r, s_Content);

        if (Event.current.type == EventType.MouseDown)
        {
            if (r.Contains(Event.current.mousePosition))
            {
                viewState.showTemplateContents = !viewState.showTemplateContents;
                m_ViewState[item.element.id]   = viewState;
                needsReload = true;
            }
        }
    }
Ejemplo n.º 15
0
        static string GetExtraPassesFromTemplate(string template, UnlitMasterNode masterNode, Pass pass, GenerationMode mode, SurfaceMaterialOptions materialOptions)
        {
            // ----------------------------------------------------- //
            //                         SETUP                         //
            // ----------------------------------------------------- //

            // -------------------------------------
            // String builders

            var dummyBuilder     = new ShaderStringBuilder(0);
            var shaderProperties = new PropertyCollector();
            var functionBuilder  = new ShaderStringBuilder(1);
            var functionRegistry = new FunctionRegistry(functionBuilder);

            var defines = new ShaderStringBuilder(2);
            var graph   = new ShaderStringBuilder(0);

            var vertexDescriptionInputStruct = new ShaderStringBuilder(1);
            var vertexDescriptionStruct      = new ShaderStringBuilder(1);
            var vertexDescriptionFunction    = new ShaderStringBuilder(1);

            var vertexInputStruct = new ShaderStringBuilder(1);

            var vertexShader            = new ShaderStringBuilder(2);
            var vertexDescriptionInputs = new ShaderStringBuilder(2);

            // -------------------------------------
            // Get Slot and Node lists per stage

            var vertexSlots = pass.VertexShaderSlots.Select(masterNode.FindSlot <MaterialSlot>).ToList();
            var vertexNodes = ListPool <AbstractMaterialNode> .Get();

            NodeUtils.DepthFirstCollectNodesFromNode(vertexNodes, masterNode, NodeUtils.IncludeSelf.Include, pass.VertexShaderSlots);

            // -------------------------------------
            // Get requirements

            var vertexRequirements = ShaderGraphRequirements.FromNodes(vertexNodes, ShaderStageCapability.Vertex, false);

            var modelRequiements = ShaderGraphRequirements.none;

            modelRequiements.requiresNormal   |= m_VertexCoordinateSpace;
            modelRequiements.requiresPosition |= m_VertexCoordinateSpace;
            modelRequiements.requiresMeshUVs.Add(UVChannel.UV1);

            // ----------------------------------------------------- //
            //                START SHADER GENERATION                //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Calculate material options

            var cullingBuilder = new ShaderStringBuilder(1);

            materialOptions.GetCull(cullingBuilder);

            // -------------------------------------
            // Generate defines

            if (masterNode.IsSlotConnected(PBRMasterNode.AlphaThresholdSlotId))
            {
                defines.AppendLine("#define _AlphaClip 1");
            }

            // ----------------------------------------------------- //
            //                START VERTEX DESCRIPTION               //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Generate Input structure for Vertex Description function
            // TODO - Vertex Description Input requirements are needed to exclude intermediate translation spaces

            vertexDescriptionInputStruct.AppendLine("struct VertexDescriptionInputs");
            using (vertexDescriptionInputStruct.BlockSemicolonScope())
            {
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresNormal, InterpolatorType.Normal, vertexDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresTangent, InterpolatorType.Tangent, vertexDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresBitangent, InterpolatorType.BiTangent, vertexDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresViewDir, InterpolatorType.ViewDirection, vertexDescriptionInputStruct);
                ShaderGenerator.GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresPosition, InterpolatorType.Position, vertexDescriptionInputStruct);

                if (vertexRequirements.requiresVertexColor)
                {
                    vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.VertexColor);
                }

                if (vertexRequirements.requiresScreenPosition)
                {
                    vertexDescriptionInputStruct.AppendLine("float4 {0};", ShaderGeneratorNames.ScreenPosition);
                }

                foreach (var channel in vertexRequirements.requiresMeshUVs.Distinct())
                {
                    vertexDescriptionInputStruct.AppendLine("half4 {0};", channel.GetUVName());
                }
            }

            // -------------------------------------
            // Generate Output structure for Vertex Description function

            GraphUtil.GenerateVertexDescriptionStruct(vertexDescriptionStruct, vertexSlots);

            // -------------------------------------
            // Generate Vertex Description function

            GraphUtil.GenerateVertexDescriptionFunction(
                masterNode.owner as AbstractMaterialGraph,
                vertexDescriptionFunction,
                functionRegistry,
                shaderProperties,
                mode,
                vertexNodes,
                vertexSlots);

            // ----------------------------------------------------- //
            //           GENERATE VERTEX > PIXEL PIPELINE            //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Generate Input structure for Vertex shader

            GraphUtil.GenerateApplicationVertexInputs(vertexRequirements.Union(modelRequiements), vertexInputStruct);

            // -------------------------------------
            // Generate standard transformations
            // This method ensures all required transform data is available in vertex and pixel stages

            ShaderGenerator.GenerateStandardTransforms(
                3,
                10,
                dummyBuilder,
                vertexShader,
                vertexDescriptionInputs,
                dummyBuilder,
                dummyBuilder,
                dummyBuilder,
                ShaderGraphRequirements.none,
                ShaderGraphRequirements.none,
                modelRequiements,
                vertexRequirements,
                CoordinateSpace.World);

            // ----------------------------------------------------- //
            //                      FINALIZE                         //
            // ----------------------------------------------------- //

            // -------------------------------------
            // Combine Graph sections

            graph.AppendLine(shaderProperties.GetPropertiesDeclaration(1));

            graph.AppendLine(vertexDescriptionInputStruct.ToString());

            graph.AppendLine(functionBuilder.ToString());

            graph.AppendLine(vertexDescriptionStruct.ToString());
            graph.AppendLine(vertexDescriptionFunction.ToString());

            graph.AppendLine(vertexInputStruct.ToString());

            // -------------------------------------
            // Generate final subshader

            var resultPass = template.Replace("${Culling}", cullingBuilder.ToString());

            resultPass = resultPass.Replace("${Defines}", defines.ToString());
            resultPass = resultPass.Replace("${Graph}", graph.ToString());
            resultPass = resultPass.Replace("${VertexShader}", vertexShader.ToString());
            resultPass = resultPass.Replace("${VertexShaderDescriptionInputs}", vertexDescriptionInputs.ToString());

            return(resultPass);
        }
Ejemplo n.º 16
0
        private bool Call(string cmd, SubModuleBase module, string[] args)
        {
            var first = string.Empty;

            if (args.Length > 0)
            {
                first = args[0];
            }

            if (module.HasCommandRewrite(args) == true)
            {
                var result = module.OnCommandRewrite(args);
                if (string.IsNullOrEmpty(result) == false)
                {
                    this.screen.AddLine(string.Format("<color=red>{0}</color>", result));
                    return(false);
                }
                else
                {
                    return(true);
                }
            }

            var i       = 0;
            var methods = ListPool <MethodInfo> .Get();

            ConsoleManager.GetModuleMethods(module, methods);
            foreach (var method in methods)
            {
                if (method.Name.ToLower() == first.ToLower().Trim() && method.GetParameters().Length == args.Length - 1)
                {
                    var pars = new List <object>();

                    i = 1;
                    foreach (var par in method.GetParameters())
                    {
                        if (par.ParameterType == typeof(bool))
                        {
                            pars.Add((object)bool.Parse(args[i]));
                        }
                        else if (par.ParameterType == typeof(int))
                        {
                            pars.Add((object)int.Parse(args[i]));
                        }
                        else if (par.ParameterType == typeof(long))
                        {
                            pars.Add((object)long.Parse(args[i]));
                        }
                        else if (par.ParameterType == typeof(float))
                        {
                            pars.Add((object)float.Parse(args[i]));
                        }
                        else if (par.ParameterType.IsEnum == true)
                        {
                            var names = System.Enum.GetNames(par.ParameterType);
                            for (int j = 0; j < names.Length; ++j)
                            {
                                names[j] = names[j].ToLower();
                            }
                            var index = System.Array.IndexOf(names, args[i]);

                            pars.Add(System.Enum.GetValues(par.ParameterType).GetValue(index));
                        }
                        else
                        {
                            pars.Add((object)args[i]);
                        }

                        ++i;
                    }

                    var result = (string)method.Invoke(module, pars.ToArray());
                    if (string.IsNullOrEmpty(result) == false)
                    {
                        this.screen.AddLine(string.Format("<color=red>{0}</color>", result));
                    }
                    else
                    {
                        return(true);
                    }

                    return(false);
                }
            }

            ListPool <MethodInfo> .Release(methods);

            this.AddCommandNotFound(cmd);

            return(false);
        }
Ejemplo n.º 17
0
        private static bool LoadDLLs(string path)
        {
            try
            {
                if (Testing.dll_loading == Testing.DLLLoading.Fail || Testing.dll_loading == Testing.DLLLoading.UseModLoaderDLLExclusively)
                {
                    return(false);
                }

                var directoryInfo = new DirectoryInfo(path);

                if (!directoryInfo.Exists)
                {
                    return(false);
                }

                var assemblies = new List <Assembly>();
                var files      = directoryInfo.GetFiles();

                foreach (FileInfo file in files)
                {
                    if (file.Name.ToLower().EndsWith(".dll"))
                    {
                        logger.Info("Loading Mod DLL: {file_name}", file.Name);
                        Assembly assembly = Assembly.LoadFrom(file.FullName);
                        if (assembly != null)
                        {
                            assemblies.Add(assembly);
                        }
                    }
                }

                if (assemblies.Count == 0)
                {
                    return(false);
                }

                ListPool <MethodInfo, Manager> .PooledList pre_patch_methods = ListPool <MethodInfo, Manager> .Allocate();

                ListPool <MethodInfo, Manager> .PooledList post_patch_methods = ListPool <MethodInfo, Manager> .Allocate();

                ListPool <MethodInfo, Manager> .PooledList on_load_method_without_paremeters = ListPool <MethodInfo, Manager> .Allocate();

                ListPool <MethodInfo, Manager> .PooledList on_load_method_with_string_parameter = ListPool <MethodInfo, Manager> .Allocate();

                var no_parameters    = new Type[0];
                var string_parameter = new Type[1] {
                    typeof(string)
                };
                var harmony_instance_parameter = new Type[1] {
                    typeof(HarmonyInstance)
                };

                MethodInfo methodInfo = null;
                foreach (Assembly assembly in assemblies)
                {
                    var types = assembly.GetTypes();
                    foreach (Type type in types)
                    {
                        if (type != null)
                        {
                            methodInfo = type.GetMethod("OnLoad", no_parameters);
                            if (methodInfo != null)
                            {
                                on_load_method_without_paremeters.Add(methodInfo);
                            }
                            methodInfo = type.GetMethod("OnLoad", string_parameter);
                            if (methodInfo != null)
                            {
                                on_load_method_with_string_parameter.Add(methodInfo);
                            }
                            methodInfo = type.GetMethod("PrePatch", harmony_instance_parameter);
                            if (methodInfo != null)
                            {
                                pre_patch_methods.Add(methodInfo);
                            }
                            methodInfo = type.GetMethod("PostPatch", harmony_instance_parameter);
                            if (methodInfo != null)
                            {
                                post_patch_methods.Add(methodInfo);
                            }
                        }
                    }
                }

                var harmonyInstance = HarmonyInstance.Create($"OxygenNotIncluded_v{0}.{1}");
                if (harmonyInstance != null)
                {
                    var parameters = new object[1] {
                        harmonyInstance
                    };
                    foreach (MethodInfo pre_patch in pre_patch_methods)
                    {
                        logger.Debug("Running PrePatch in {module} from {assembly}", pre_patch.DeclaringType.FullName, pre_patch.Module.Name);
                        var watch = Stopwatch.StartNew();
                        try
                        {
                            pre_patch.Invoke(null, parameters);
                        }
                        finally
                        {
                            watch.Stop();
                        }
                        logger.Debug("{module} PrePatch took {time}ms to complete", pre_patch.DeclaringType.FullName, watch.ElapsedMilliseconds);
                    }
                    foreach (Assembly assembly in assemblies)
                    {
                        logger.Debug("Patching assembly {assembly}", assembly.GetName());
                        var watch = Stopwatch.StartNew();
                        try
                        {
                            harmonyInstance.PatchAll(assembly);
                        }
                        finally
                        {
                            watch.Stop();
                        }
                        logger.Debug("Patching {module} took {time}ms to complete", assembly.GetName(), watch.ElapsedMilliseconds);
                    }
                    foreach (MethodInfo post_patch in post_patch_methods)
                    {
                        logger.Debug("Running PostPatch in {module} from {assembly}", post_patch.DeclaringType.FullName, post_patch.Module.Name);
                        var watch = Stopwatch.StartNew();
                        try
                        {
                            post_patch.Invoke(null, parameters);
                        }
                        finally
                        {
                            watch.Stop();
                        }
                        logger.Debug("{module} PostPatch took {time}ms to complete", post_patch.DeclaringType.FullName, watch.ElapsedMilliseconds);
                    }
                }
                pre_patch_methods.Recycle();
                post_patch_methods.Recycle();

                foreach (MethodInfo on_load in on_load_method_without_paremeters)
                {
                    logger.Debug("Running OnLoad in {module} from {assembly}", on_load.DeclaringType.FullName, on_load.Module.Name);
                    var watch = Stopwatch.StartNew();
                    try
                    {
                        on_load.Invoke(null, null);
                    }
                    finally
                    {
                        watch.Stop();
                    }
                    logger.Debug("{module} OnLoad took {time}ms to complete", on_load.DeclaringType.FullName, watch.ElapsedMilliseconds);
                }
                on_load_method_without_paremeters.Recycle();

                object[] path_parameter = new object[1] {
                    path
                };
                foreach (MethodInfo on_load in on_load_method_with_string_parameter)
                {
                    logger.Debug("Running OnLoad(path) in {module} from {assembly}", on_load.DeclaringType.FullName, on_load.Module.Name);
                    var watch = Stopwatch.StartNew();
                    try
                    {
                        on_load.Invoke(null, path_parameter);
                    }
                    finally
                    {
                        watch.Stop();
                    }
                    logger.Debug("{module} OnLoad(path) took {time}ms to complete", on_load.DeclaringType.FullName, watch.ElapsedMilliseconds);
                }
                on_load_method_with_string_parameter.Recycle();

                return(true);
            }
            catch (Exception e)
            {
                logger.Error(e, "Failed to load mod from {path}", path);
                return(false);
            }
        }
Ejemplo n.º 18
0
        static IEnumerable <List <DenormalizedRecord> > denormalizedRecords(string newClientContent, Binder errorRecordBinder, ILogger log)
        {
            var outgoingList = ListPool <DenormalizedRecord> .Allocate();

            outgoingList.Capacity = 450;
            var sizeOfListItems = 0;

            try
            {
                NSGFlowLogRecords logs = JsonConvert.DeserializeObject <NSGFlowLogRecords>(newClientContent);

                foreach (var record in logs.records)
                {
                    float version = record.properties.Version;

                    foreach (var outerFlow in record.properties.flows)
                    {
                        foreach (var innerFlow in outerFlow.flows)
                        {
                            foreach (var flowTuple in innerFlow.flowTuples)
                            {
                                var tuple = new NSGFlowLogTuple(flowTuple, version);

                                var denormalizedRecord = new DenormalizedRecord(
                                    record.properties.Version,
                                    record.time,
                                    record.category,
                                    record.operationName,
                                    record.resourceId,
                                    outerFlow.rule,
                                    innerFlow.mac,
                                    tuple);

                                var sizeOfDenormalizedRecord = denormalizedRecord.GetSizeOfJSONObject();

                                //for Event hub binding fork  -- start
                                // Event hub basic message size is 256KB and the 'if' statement below ensures that list does not exceed size this size for Eventhub

                                string outputBinding = Util.GetEnvironmentVariable("outputBinding");

                                if (outputBinding == "eventhub")
                                {
                                    if (sizeOfListItems > 120) // this will chunk below 256KB : this is ideal sample message size. Feel free to go maximum till 150 : smaller values will create lot of outbound connections.
                                    {
                                        yield return(outgoingList);

                                        outgoingList.Clear();
                                        sizeOfListItems = 0;
                                    }
                                    outgoingList.Add(denormalizedRecord);
                                    sizeOfListItems += 1;
                                }

                                //for Event hub binding fork  -- end
                                //other output bindings

                                else if (sizeOfListItems + sizeOfDenormalizedRecord > MAXTRANSMISSIONSIZE + 20)
                                {
                                    yield return(outgoingList);

                                    outgoingList.Clear();
                                    sizeOfListItems = 0;
                                }
                                outgoingList.Add(denormalizedRecord);
                                sizeOfListItems += sizeOfDenormalizedRecord;
                            }
                        }
                    }
                }
                if (sizeOfListItems > 0)
                {
                    yield return(outgoingList);
                }
            }
            finally
            {
                ListPool <DenormalizedRecord> .Free(outgoingList);
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Finds all contours of a collection of nodes in a grid graph.
        ///
        /// <code>
        /// var grid = AstarPath.active.data.gridGraph;
        ///
        /// // Find all contours in the graph and draw them using debug lines
        /// GraphUtilities.GetContours(grid, vertices => {
        ///     for (int i = 0; i < vertices.Length; i++) {
        ///         Debug.DrawLine(vertices[i], vertices[(i+1)%vertices.Length], Color.red, 4);
        ///     }
        /// }, 0);
        /// </code>
        ///
        /// In the image below you can see the contour of a graph.
        /// [Open online documentation to see images]
        ///
        /// In the image below you can see the contour of just a part of a grid graph (when the nodes parameter is supplied)
        /// [Open online documentation to see images]
        ///
        /// Contour of a hexagon graph
        /// [Open online documentation to see images]
        ///
        /// See: <see cref="GetContours(NavGraph)"/>
        /// </summary>
        /// <param name="grid">The grid to find the contours of</param>
        /// <param name="callback">The callback will be called once for every contour that is found with the vertices of the contour. The contour always forms a cycle.</param>
        /// <param name="yMergeThreshold">Contours will be simplified if the y coordinates for adjacent vertices differ by no more than this value.</param>
        /// <param name="nodes">Only these nodes will be searched. If this parameter is null then all nodes in the grid graph will be searched.</param>
        public static void GetContours(GridGraph grid, System.Action <Vector3[]> callback, float yMergeThreshold, GridNodeBase[] nodes = null)
        {
            // Set of all allowed nodes or null if all nodes are allowed
            HashSet <GridNodeBase> nodeSet = nodes != null ? new HashSet <GridNodeBase>(nodes) : null;

            // Use all nodes if the nodes parameter is null
            if (grid is LayerGridGraph)
            {
                nodes = nodes ?? (grid as LayerGridGraph).nodes;
            }
            nodes = nodes ?? grid.nodes;
            int[] neighbourXOffsets = grid.neighbourXOffsets;
            int[] neighbourZOffsets = grid.neighbourZOffsets;
            var   neighbourIndices  = grid.neighbours == NumNeighbours.Six ? GridGraph.hexagonNeighbourIndices : new [] { 0, 1, 2, 3 };
            var   offsetMultiplier  = grid.neighbours == NumNeighbours.Six ? 1 / 3f : 0.5f;

            if (nodes != null)
            {
                var trace = ListPool <Vector3> .Claim();

                var seenStates = new HashSet <int>();

                for (int i = 0; i < nodes.Length; i++)
                {
                    var startNode = nodes[i];
                    // The third check is a fast check for if the node has connections in all grid directions, if it has then we can skip processing it (unless the nodes parameter was used in which case we have to handle the edge cases)
                    if (startNode != null && startNode.Walkable && (!startNode.HasConnectionsToAllEightNeighbours || nodeSet != null))
                    {
                        for (int startDir = 0; startDir < neighbourIndices.Length; startDir++)
                        {
                            int startState = (startNode.NodeIndex << 4) | startDir;

                            // Check if there is an obstacle in that direction
                            var startNeighbour = startNode.GetNeighbourAlongDirection(neighbourIndices[startDir]);
                            if ((startNeighbour == null || (nodeSet != null && !nodeSet.Contains(startNeighbour))) && !seenStates.Contains(startState))
                            {
                                // Start tracing a contour here
                                trace.ClearFast();
                                int          dir  = startDir;
                                GridNodeBase node = startNode;

                                while (true)
                                {
                                    int state = (node.NodeIndex << 4) | dir;
                                    if (state == startState && trace.Count > 0)
                                    {
                                        break;
                                    }

                                    seenStates.Add(state);

                                    var neighbour = node.GetNeighbourAlongDirection(neighbourIndices[dir]);
                                    if (neighbour == null || (nodeSet != null && !nodeSet.Contains(neighbour)))
                                    {
                                        // Draw edge
                                        var d0 = neighbourIndices[dir];
                                        dir = (dir + 1) % neighbourIndices.Length;
                                        var d1 = neighbourIndices[dir];

                                        // Position in graph space of the vertex
                                        Vector3 graphSpacePos = new Vector3(node.XCoordinateInGrid + 0.5f, 0, node.ZCoordinateInGrid + 0.5f);
                                        // Offset along diagonal to get the correct XZ coordinates
                                        graphSpacePos.x += (neighbourXOffsets[d0] + neighbourXOffsets[d1]) * offsetMultiplier;
                                        graphSpacePos.z += (neighbourZOffsets[d0] + neighbourZOffsets[d1]) * offsetMultiplier;
                                        graphSpacePos.y  = grid.transform.InverseTransform((Vector3)node.position).y;

                                        if (trace.Count >= 2)
                                        {
                                            var v0  = trace[trace.Count - 2];
                                            var v1  = trace[trace.Count - 1];
                                            var v1d = v1 - v0;
                                            var v2d = graphSpacePos - v0;
                                            // Replace the previous point if it is colinear with the point just before it and just after it (the current point), because that point wouldn't add much information, but it would add CPU overhead
                                            if (((Mathf.Abs(v1d.x) > 0.01f || Mathf.Abs(v2d.x) > 0.01f) && (Mathf.Abs(v1d.z) > 0.01f || Mathf.Abs(v2d.z) > 0.01f)) || (Mathf.Abs(v1d.y) > yMergeThreshold || Mathf.Abs(v2d.y) > yMergeThreshold))
                                            {
                                                trace.Add(graphSpacePos);
                                            }
                                            else
                                            {
                                                trace[trace.Count - 1] = graphSpacePos;
                                            }
                                        }
                                        else
                                        {
                                            trace.Add(graphSpacePos);
                                        }
                                    }
                                    else
                                    {
                                        // Move
                                        node = neighbour;
                                        dir  = (dir + neighbourIndices.Length / 2 + 1) % neighbourIndices.Length;
                                    }
                                }

                                var result = trace.ToArray();
                                grid.transform.Transform(result);
                                callback(result);
                            }
                        }
                    }
                }

                ListPool <Vector3> .Release(ref trace);
            }
        }
        public List <Vector3> CurvedNonuniform(List <Vector3> path)
        {
            if (maxSegmentLength <= 0)
            {
                Debug.LogWarning("Max Segment Length is <= 0 which would cause DivByZero-exception or other nasty errors (avoid this)");
                return(path);
            }

            int pointCounter = 0;

            for (int i = 0; i < path.Count - 1; i++)
            {
                //pointCounter += Mathf.FloorToInt ((path[i]-path[i+1]).magnitude / maxSegmentLength)+1;

                float dist = (path[i] - path[i + 1]).magnitude;
                //In order to avoid floating point errors as much as possible, and in lack of a better solution
                //loop through it EXACTLY as the other code further down will
                for (float t = 0; t <= dist; t += maxSegmentLength)
                {
                    pointCounter++;
                }
            }

            List <Vector3> subdivided = ListPool <Vector3> .Claim(pointCounter);

            //Set first velocity
            Vector3 preEndVel = (path[1] - path[0]).normalized;

            for (int i = 0; i < path.Count - 1; i++)
            {
                //subdivided[counter] = path[i];
                //counter++;

                float dist = (path[i] - path[i + 1]).magnitude;

                Vector3 startVel1 = preEndVel;
                Vector3 endVel1   = i < path.Count - 2 ? ((path[i + 2] - path[i + 1]).normalized - (path[i] - path[i + 1]).normalized).normalized : (path[i + 1] - path[i]).normalized;

                Vector3 startVel = startVel1 * dist * factor;
                Vector3 endVel   = endVel1 * dist * factor;



                Vector3 start = path[i];
                Vector3 end   = path[i + 1];

                //Vector3 p1 = start + startVel;
                //Vector3 p2 = end - endVel;

                float onedivdist = 1F / dist;

                for (float t = 0; t <= dist; t += maxSegmentLength)
                {
                    float t2 = t * onedivdist;

                    subdivided.Add(GetPointOnCubic(start, end, startVel, endVel, t2));
                    //counter++;
                }

                preEndVel = endVel1;
            }

            subdivided[subdivided.Count - 1] = path[path.Count - 1];

            return(subdivided);
        }
        public void GenerateNodeEntries()
        {
            Profiler.BeginSample("SearchWindowProvider.GenerateNodeEntries");
            // First build up temporary data structure containing group & title as an array of strings (the last one is the actual title) and associated node type.
            List <NodeEntry> nodeEntries = new List <NodeEntry>();

            if (target is ContextView contextView)
            {
                // Iterate all BlockFieldDescriptors currently cached on GraphData
                foreach (var field in m_Graph.blockFieldDescriptors)
                {
                    if (field.isHidden)
                    {
                        continue;
                    }

                    // Test stage
                    if (field.shaderStage != contextView.contextData.shaderStage)
                    {
                        continue;
                    }

                    // Create title
                    List <string> title = ListPool <string> .Get();

                    if (!string.IsNullOrEmpty(field.path))
                    {
                        var path = field.path.Split('/').ToList();
                        title.AddRange(path);
                    }
                    title.Add(field.displayName);

                    // Create and initialize BlockNode instance then add entry
                    var node = (BlockNode)Activator.CreateInstance(typeof(BlockNode));
                    node.Init(field);
                    AddEntries(node, title.ToArray(), nodeEntries);
                }

                SortEntries(nodeEntries);
                currentNodeEntries = nodeEntries;
                return;
            }

            foreach (var type in NodeClassCache.knownNodeTypes)
            {
                if ((!type.IsClass || type.IsAbstract) ||
                    type == typeof(PropertyNode) ||
                    type == typeof(KeywordNode) ||
                    type == typeof(SubGraphNode))
                {
                    continue;
                }

                TitleAttribute titleAttribute = NodeClassCache.GetAttributeOnNodeType <TitleAttribute>(type);
                if (titleAttribute != null)
                {
                    var node = (AbstractMaterialNode)Activator.CreateInstance(type);
                    if (ShaderGraphPreferences.allowDeprecatedBehaviors && node.latestVersion > 0)
                    {
                        for (int i = 0; i <= node.latestVersion; ++i)
                        {
                            var depNode = (AbstractMaterialNode)Activator.CreateInstance(type);
                            depNode.ChangeVersion(i);
                            AddEntries(depNode, titleAttribute.title.Append($"V{i}").ToArray(), nodeEntries);
                        }
                    }
                    else
                    {
                        AddEntries(node, titleAttribute.title, nodeEntries);
                    }
                }
            }

            foreach (var guid in AssetDatabase.FindAssets(string.Format("t:{0}", typeof(SubGraphAsset))))
            {
                var asset = AssetDatabase.LoadAssetAtPath <SubGraphAsset>(AssetDatabase.GUIDToAssetPath(guid));
                var node  = new SubGraphNode {
                    asset = asset
                };
                var title = asset.path.Split('/').ToList();

                if (asset.descendents.Contains(m_Graph.assetGuid) || asset.assetGuid == m_Graph.assetGuid)
                {
                    continue;
                }

                if (string.IsNullOrEmpty(asset.path))
                {
                    AddEntries(node, new string[1] {
                        asset.name
                    }, nodeEntries);
                }

                else if (title[0] != k_HiddenFolderName)
                {
                    title.Add(asset.name);
                    AddEntries(node, title.ToArray(), nodeEntries);
                }
            }

            foreach (var property in m_Graph.properties)
            {
                if (property is Serialization.MultiJsonInternal.UnknownShaderPropertyType)
                {
                    continue;
                }

                var node = new PropertyNode();
                node.property = property;
                AddEntries(node, new[] { "Properties", "Property: " + property.displayName }, nodeEntries);
            }
            foreach (var keyword in m_Graph.keywords)
            {
                var node = new KeywordNode();
                node.keyword = keyword;
                AddEntries(node, new[] { "Keywords", "Keyword: " + keyword.displayName }, nodeEntries);
            }

            SortEntries(nodeEntries);
            currentNodeEntries = nodeEntries;
            Profiler.EndSample();
        }
        public List <Vector3> SmoothOffsetSimple(List <Vector3> path)
        {
            if (path.Count <= 2 || iterations <= 0)
            {
                return(path);
            }

            if (iterations > 12)
            {
                Debug.LogWarning("A very high iteration count was passed, won't let this one through");
                return(path);
            }

            int maxLength = (path.Count - 2) * (int)Mathf.Pow(2, iterations) + 2;

            List <Vector3> subdivided = ListPool <Vector3> .Claim(maxLength);

            //new Vector3[(path.Length-2)*(int)Mathf.Pow(2,iterations)+2];
            List <Vector3> subdivided2 = ListPool <Vector3> .Claim(maxLength);

            //new Vector3[(path.Length-2)*(int)Mathf.Pow(2,iterations)+2];

            for (int i = 0; i < maxLength; i++)
            {
                subdivided.Add(Vector3.zero); subdivided2.Add(Vector3.zero);
            }

            for (int i = 0; i < path.Count; i++)
            {
                subdivided[i] = path[i];
            }

            for (int iteration = 0; iteration < iterations; iteration++)
            {
                int currentPathLength = (path.Count - 2) * (int)Mathf.Pow(2, iteration) + 2;

                //Switch the arrays
                List <Vector3> tmp = subdivided;
                subdivided  = subdivided2;
                subdivided2 = tmp;

                float nextMultiplier = 1F;

                for (int i = 0; i < currentPathLength - 1; i++)
                {
                    Vector3 current = subdivided2[i];
                    Vector3 next    = subdivided2[i + 1];

                    Vector3 normal = Vector3.Cross(next - current, Vector3.up);
                    normal = normal.normalized;

                    //This didn't work very well, made the path jaggy

                    /*Vector3 dir = next-current;
                     * dir *= strength*0.5F;
                     * current += dir;
                     * next -= dir;*/

                    bool firstRight  = false;
                    bool secondRight = false;
                    bool setFirst    = false;
                    bool setSecond   = false;
                    if (i != 0 && !Polygon.IsColinear(current, next, subdivided2[i - 1]))
                    {
                        setFirst   = true;
                        firstRight = Polygon.Left(current, next, subdivided2[i - 1]);
                    }
                    if (i < currentPathLength - 1 && !Polygon.IsColinear(current, next, subdivided2[i + 2]))
                    {
                        setSecond   = true;
                        secondRight = Polygon.Left(current, next, subdivided2[i + 2]);
                    }

                    if (setFirst)
                    {
                        subdivided[i * 2] = current + (firstRight ? normal * offset * nextMultiplier : -normal * offset * nextMultiplier);
                    }
                    else
                    {
                        subdivided[i * 2] = current;
                    }

                    //Didn't work very well

                    /*if (setFirst && setSecond) {
                     *      if (firstRight != secondRight) {
                     *              nextMultiplier = 0.5F;
                     *      } else {
                     *              nextMultiplier = 1F;
                     *      }
                     * }*/

                    if (setSecond)
                    {
                        subdivided[i * 2 + 1] = next + (secondRight ? normal * offset * nextMultiplier : -normal * offset * nextMultiplier);
                    }
                    else
                    {
                        subdivided[i * 2 + 1] = next;
                    }
                }

                subdivided[(path.Count - 2) * (int)Mathf.Pow(2, iteration + 1) + 2 - 1] = subdivided2[currentPathLength - 1];
            }


            ListPool <Vector3> .Release(subdivided2);

            return(subdivided);
        }
Ejemplo n.º 23
0
        protected override void CompileList(List <TreeGumpNode> list)
        {
            foreach (var n in Nodes.Keys)
            {
                list.Update(n);
            }

            var nodes = ListPool <TreeGumpNode> .AcquireObject();

            var selected = ListPool <TreeGumpNode> .AcquireObject();

            var parents = ListPool <TreeGumpNode> .AcquireObject();

            nodes.Capacity = list.Count;

            foreach (var n in list)
            {
                foreach (var p in n.GetParents())
                {
                    nodes.Update(p);
                }

                nodes.Update(n);
            }

            if (SelectedNode.HasParent)
            {
                nodes.Update(SelectedNode.Parent);
            }

            selected.AddRange(SelectedNode.GetParents());

            nodes.RemoveAll(
                c =>
            {
                parents.AddRange(c.GetParents());

                var remove = false;

                if (parents.Count > 0)
                {
                    if (parents.Count <= selected.Count && c != SelectedNode && !parents.Contains(SelectedNode) &&
                        !selected.Any(p => p == c || c.Parent == p))
                    {
                        remove = true;
                    }
                    else if (parents.Count > selected.Count && c.Parent != SelectedNode)
                    {
                        remove = true;
                    }
                }

                parents.Clear();

                return(remove);
            });

            list.Clear();
            list.AddRange(nodes);

            ObjectPool.Free(ref nodes);
            ObjectPool.Free(ref selected);
            ObjectPool.Free(ref parents);

            base.CompileList(list);
        }
        public List <Vector3> SmoothSimple(List <Vector3> path)
        {
            if (path.Count < 2)
            {
                return(path);
            }

            if (uniformLength)
            {
                int numSegments = 0;
                maxSegmentLength = maxSegmentLength < 0.005F ? 0.005F : maxSegmentLength;

                for (int i = 0; i < path.Count - 1; i++)
                {
                    float length = Vector3.Distance(path[i], path[i + 1]);

                    numSegments += Mathf.FloorToInt(length / maxSegmentLength);
                }

                List <Vector3> subdivided = ListPool <Vector3> .Claim(numSegments + 1);

                int c = 0;

                float carry = 0;

                for (int i = 0; i < path.Count - 1; i++)
                {
                    float length = Vector3.Distance(path[i], path[i + 1]);

                    int numSegmentsForSegment = Mathf.FloorToInt((length + carry) / maxSegmentLength);

                    float carryOffset = carry / length;
                    //float t = 1F / numSegmentsForSegment;

                    Vector3 dir = path[i + 1] - path[i];

                    for (int q = 0; q < numSegmentsForSegment; q++)
                    {
                        //Debug.Log (q+" "+c+" "+numSegments+" "+length+" "+numSegmentsForSegment);
                        subdivided.Add(dir * (System.Math.Max(0, (float)q / numSegmentsForSegment - carryOffset)) + path[i]);
                        c++;
                    }

                    carry = (length + carry) % maxSegmentLength;
                }

                subdivided.Add(path[path.Count - 1]);

                if (strength != 0)
                {
                    for (int it = 0; it < iterations; it++)
                    {
                        Vector3 prev = subdivided[0];

                        for (int i = 1; i < subdivided.Count - 1; i++)
                        {
                            Vector3 tmp = subdivided[i];

                            subdivided[i] = Vector3.Lerp(tmp, (prev + subdivided[i + 1]) / 2F, strength);

                            prev = tmp;
                        }
                    }
                }

                return(subdivided);
            }
            else
            {
                List <Vector3> subdivided = ListPool <Vector3> .Claim();

                //Polygon.Subdivide (path,subdivisions);
                if (subdivisions < 0)
                {
                    subdivisions = 0;
                }

                int steps = 1 << subdivisions;

                for (int i = 0; i < path.Count - 1; i++)
                {
                    for (int j = 0; j < steps; j++)
                    {
                        subdivided.Add(Vector3.Lerp(path[i], path[i + 1], (float)j / steps));
                    }
                }

                for (int it = 0; it < iterations; it++)
                {
                    Vector3 prev = subdivided[0];

                    for (int i = 1; i < subdivided.Count - 1; i++)
                    {
                        Vector3 tmp = subdivided[i];

                        subdivided[i] = Vector3.Lerp(tmp, (prev + subdivided[i + 1]) / 2F, strength);

                        prev = tmp;
                    }
                }
                return(subdivided);
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Returns all nodes up to a given node-distance from the seed node.
        /// This function performs a BFS (<a href="https://en.wikipedia.org/wiki/Breadth-first_search">breadth-first search</a>) or flood fill of the graph and returns all nodes within a specified node distance which can be reached from
        /// the seed node. In almost all cases when depth is large enough this will be identical to returning all nodes which have the same area as the seed node.
        /// In the editor areas are displayed as different colors of the nodes.
        /// The only case where it will not be so is when there is a one way path from some part of the area to the seed node
        /// but no path from the seed node to that part of the graph.
        ///
        /// The returned list is sorted by node distance from the seed node
        /// i.e distance is measured in the number of nodes the shortest path from seed to that node would pass through.
        /// Note that the distance measurement does not take heuristics, penalties or tag penalties.
        ///
        /// Depending on the number of nodes, this function can take quite some time to calculate
        /// so don't use it too often or it might affect the framerate of your game.
        ///
        /// Returns: A List<GraphNode> containing all nodes reachable up to a specified node distance from the seed node.
        /// For better memory management the returned list should be pooled, see Pathfinding.Util.ListPool
        ///
        /// Warning: This method is not thread safe. Only use it from the Unity thread (i.e normal game code).
        ///
        /// The video below shows the BFS result with varying values of depth. Points are sampled on the nodes using <see cref="GetPointsOnNodes"/>.
        /// [Open online documentation to see videos]
        /// </summary>
        /// <param name="seed">The node to start the search from.</param>
        /// <param name="depth">The maximum node-distance from the seed node.</param>
        /// <param name="tagMask">Optional mask for tags. This is a bitmask.</param>
        /// <param name="filter">Optional filter for which nodes to search. You can combine this with depth = int.MaxValue and tagMask = -1 to make the filter determine everything.
        ///      Only walkable nodes are searched regardless of the filter. If the filter function returns false the node will be treated as unwalkable.</param>
        public static List <GraphNode> BFS(GraphNode seed, int depth, int tagMask = -1, System.Func <GraphNode, bool> filter = null)
        {
                        #if ASTAR_PROFILE
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
                        #endif

            BFSQueue = BFSQueue ?? new Queue <GraphNode>();
            var que = BFSQueue;

            BFSMap = BFSMap ?? new Dictionary <GraphNode, int>();
            var map = BFSMap;

            // Even though we clear at the end of this function, it is good to
            // do it here as well in case the previous invocation of the method
            // threw an exception for some reason
            // and didn't clear the que and map
            que.Clear();
            map.Clear();

            List <GraphNode> result = ListPool <GraphNode> .Claim();

            int currentDist = -1;
            System.Action <GraphNode> callback;
            if (tagMask == -1)
            {
                callback = node => {
                    if (node.Walkable && !map.ContainsKey(node))
                    {
                        if (filter != null && !filter(node))
                        {
                            return;
                        }

                        map.Add(node, currentDist + 1);
                        result.Add(node);
                        que.Enqueue(node);
                    }
                };
            }
            else
            {
                callback = node => {
                    if (node.Walkable && ((tagMask >> (int)node.Tag) & 0x1) != 0 && !map.ContainsKey(node))
                    {
                        if (filter != null && !filter(node))
                        {
                            return;
                        }

                        map.Add(node, currentDist + 1);
                        result.Add(node);
                        que.Enqueue(node);
                    }
                };
            }

            callback(seed);

            while (que.Count > 0)
            {
                GraphNode n = que.Dequeue();
                currentDist = map[n];

                if (currentDist >= depth)
                {
                    break;
                }

                n.GetConnections(callback);
            }

            que.Clear();
            map.Clear();

                        #if ASTAR_PROFILE
            watch.Stop();
            Debug.Log((1000 * watch.Elapsed.TotalSeconds).ToString("0.0 ms"));
                        #endif
            return(result);
        }
Ejemplo n.º 26
0
        /** Should be called on every node which is updated with this GUO before it is updated.
         * \param node The node to save fields for. If null, nothing will be done
         * \see #trackChangedNodes
         */
        public virtual void WillUpdateNode(GraphNode node)
        {
            if (trackChangedNodes && node != null)
            {
                if (changedNodes == null)
                {
                    changedNodes = ListPool <GraphNode> .Claim(); backupData = ListPool <uint> .Claim(); backupPositionData = ListPool <VInt3> .Claim();
                }
                changedNodes.Add(node);
                backupPositionData.Add(node.position);
                backupData.Add(node.Penalty);
                backupData.Add(node.Flags);
#if !ASTAR_NO_GRID_GRAPH
                var gridNode = node as GridNode;
                if (gridNode != null)
                {
                    backupData.Add(gridNode.InternalGridFlags);
                }
#endif
            }
        }
Ejemplo n.º 27
0
        public override void ValidateNode()
        {
            var isInError    = false;
            var errorMessage = k_validationErrorMessage;

            var dynamicInputSlotsToCompare = DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicVectorMaterialSlot> .Get();

            var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .Get();

            // iterate the input slots
            using (var tempSlots = PooledList <MaterialSlot> .Get())
            {
                GetInputSlots(tempSlots);
                foreach (var inputSlot in tempSlots)
                {
                    inputSlot.hasError = false;

                    // if there is a connection
                    var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                    if (!edges.Any())
                    {
                        if (inputSlot is DynamicVectorMaterialSlot)
                        {
                            skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot);
                        }
                        if (inputSlot is DynamicMatrixMaterialSlot)
                        {
                            skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot);
                        }
                        continue;
                    }

                    // get the output details
                    var outputSlotRef = edges[0].outputSlot;
                    var outputNode    = owner.GetNodeFromGuid(outputSlotRef.nodeGuid);
                    if (outputNode == null)
                    {
                        continue;
                    }

                    var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                    if (outputSlot == null)
                    {
                        continue;
                    }

                    if (outputSlot.hasError)
                    {
                        inputSlot.hasError = true;
                        continue;
                    }

                    var outputConcreteType = outputSlot.concreteValueType;
                    // dynamic input... depends on output from other node.
                    // we need to compare ALL dynamic inputs to make sure they
                    // are compatable.
                    if (inputSlot is DynamicVectorMaterialSlot)
                    {
                        dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                    else if (inputSlot is DynamicMatrixMaterialSlot)
                    {
                        dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                }

                // and now dynamic matrices
                var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                }
                foreach (var skippedSlot in skippedDynamicMatrixSlots)
                {
                    skippedSlot.SetConcreteType(dynamicMatrixType);
                }

                // we can now figure out the dynamic slotType
                // from here set all the
                var dynamicType = SlotValueHelper.ConvertMatrixToVectorType(dynamicMatrixType);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicType);
                }

                tempSlots.Clear();
                GetInputSlots(tempSlots);
                var inputError = tempSlots.Any(x => x.hasError);

                // configure the output slots now
                // their slotType will either be the default output slotType
                // or the above dynanic slotType for dynamic nodes
                // or error if there is an input error
                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                foreach (var outputSlot in tempSlots)
                {
                    outputSlot.hasError = false;

                    if (inputError)
                    {
                        outputSlot.hasError = true;
                        continue;
                    }

                    if (outputSlot is DynamicVectorMaterialSlot)
                    {
                        (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType);
                        continue;
                    }
                    else if (outputSlot is DynamicMatrixMaterialSlot)
                    {
                        (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType);
                        continue;
                    }
                }

                isInError |= inputError;
                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                isInError |= tempSlots.Any(x => x.hasError);
            }

            isInError |= CalculateNodeHasError(ref errorMessage);
            isInError |= ValidateConcretePrecision(ref errorMessage);
            hasError   = isInError;

            if (isInError)
            {
                ((GraphData)owner).AddValidationError(tempId, errorMessage);
            }
            else
            {
                ++version;
            }

            ListPool <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);

            ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots);

            DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare);
        }
Ejemplo n.º 28
0
        // Internal validation
        // -------------------------------------------------

        public override void ValidateNode()
        {
            var isInError    = false;
            var errorMessage = k_validationErrorMessage;

            // all children nodes needs to be updated first
            // so do that here
            var slots = ListPool <MaterialSlot> .Get();

            GetInputSlots(slots);
            foreach (var inputSlot in slots)
            {
                inputSlot.hasError = false;

                var edges = owner.GetEdges(inputSlot.slotReference);
                foreach (var edge in edges)
                {
                    var fromSocketRef = edge.outputSlot;
                    var outputNode    = owner.GetNodeFromGuid(fromSocketRef.nodeGuid);
                    if (outputNode == null)
                    {
                        continue;
                    }

                    outputNode.ValidateNode();
                }
            }
            ListPool <MaterialSlot> .Release(slots);

            var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get();

            // iterate the input slots
            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            foreach (var inputSlot in s_TempSlots)
            {
                // if there is a connection
                var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                if (!edges.Any())
                {
                    if (inputSlot is DynamicValueMaterialSlot)
                    {
                        skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot);
                    }
                    continue;
                }

                // get the output details
                var outputSlotRef = edges[0].outputSlot;
                var outputNode    = owner.GetNodeFromGuid(outputSlotRef.nodeGuid);
                if (outputNode == null)
                {
                    continue;
                }

                var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                if (outputSlot == null)
                {
                    continue;
                }

                if (outputSlot.hasError)
                {
                    inputSlot.hasError = true;
                    continue;
                }

                var outputConcreteType = outputSlot.concreteValueType;
                // dynamic input... depends on output from other node.
                // we need to compare ALL dynamic inputs to make sure they
                // are compatable.
                if (inputSlot is DynamicValueMaterialSlot)
                {
                    dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType);
                    continue;
                }

                // if we have a standard connection... just check the types work!
                if (!ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType))
                {
                    inputSlot.hasError = true;
                }
            }

            m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values);

            // Resolve dynamics depending on matrix/vector configuration
            switch (m_MultiplyType)
            {
            // If all matrix resolve as per dynamic matrix
            case MultiplyType.Matrix:
                var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicMatrixType);
                }
                break;

            // If mixed handle differently:
            // Iterate all slots and set their concretes based on their edges
            // Find matrix slot and convert its type to a vector type
            // Reiterate all slots and set non matrix slots to the vector type
            case MultiplyType.Mixed:
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    SetConcreteValueTypeFromEdge(dynamicKvP.Key);
                }
                MaterialSlot          matrixSlot = GetMatrixSlot();
                ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    if (dynamicKvP.Key != matrixSlot)
                    {
                        dynamicKvP.Key.SetConcreteType(vectorType);
                    }
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(vectorType);
                }
                break;

            // If all vector resolve as per dynamic vector
            default:
                var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicVectorType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicVectorType);
                }
                break;
            }

            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            var inputError = s_TempSlots.Any(x => x.hasError);

            // configure the output slots now
            // their slotType will either be the default output slotType
            // or the above dynanic slotType for dynamic nodes
            // or error if there is an input error
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            foreach (var outputSlot in s_TempSlots)
            {
                outputSlot.hasError = false;

                if (inputError)
                {
                    outputSlot.hasError = true;
                    continue;
                }

                if (outputSlot is DynamicValueMaterialSlot)
                {
                    // Apply similar logic to output slot
                    switch (m_MultiplyType)
                    {
                    // As per dynamic matrix
                    case MultiplyType.Matrix:
                        var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType);
                        break;

                    // Mixed configuration
                    // Find matrix slot and convert type to vector
                    // Set output concrete to vector
                    case MultiplyType.Mixed:
                        MaterialSlot          matrixSlot = GetMatrixSlot();
                        ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType);
                        break;

                    // As per dynamic vector
                    default:
                        var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType);
                        break;
                    }
                    continue;
                }
            }

            isInError |= inputError;
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            isInError |= s_TempSlots.Any(x => x.hasError);
            isInError |= CalculateNodeHasError(ref errorMessage);
            hasError   = isInError;

            if (isInError)
            {
                ((AbstractMaterialGraph)owner).AddValidationError(tempId, errorMessage);
            }
            else
            {
                ++version;
            }

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
Ejemplo n.º 29
0
        public void ReplaceWith(IGraph other)
        {
            var otherMg = other as AbstractNodeGraph;

            if (otherMg == null)
            {
                throw new ArgumentException("Can only replace with another AbstractNodeGraph", "other");
            }

            using (var removedPropertiesPooledObject = ListPool <Guid> .GetDisposable())
            {
                var removedPropertyGuids = removedPropertiesPooledObject.value;
                foreach (var property in m_Properties)
                {
                    removedPropertyGuids.Add(property.guid);
                }
                foreach (var propertyGuid in removedPropertyGuids)
                {
                    RemoveShaderPropertyNoValidate(propertyGuid);
                }
            }
            foreach (var otherProperty in otherMg.properties)
            {
                if (!properties.Any(p => p.guid == otherProperty.guid))
                {
                    AddShaderProperty(otherProperty);
                }
            }

            other.ValidateGraph();
            ValidateGraph();

            // Current tactic is to remove all nodes and edges and then re-add them, such that depending systems
            // will re-initialize with new references.
            using (var pooledList = ListPool <IEdge> .GetDisposable())
            {
                var removedNodeEdges = pooledList.value;
                removedNodeEdges.AddRange(m_Edges);
                foreach (var edge in removedNodeEdges)
                {
                    RemoveEdgeNoValidate(edge);
                }
            }

            using (var removedNodesPooledObject = ListPool <Guid> .GetDisposable())
            {
                var removedNodeGuids = removedNodesPooledObject.value;
                removedNodeGuids.AddRange(m_Nodes.Where(n => n != null).Select(n => n.guid));
                foreach (var nodeGuid in removedNodeGuids)
                {
                    RemoveNodeNoValidate(m_NodeDictionary[nodeGuid]);
                }
            }

            ValidateGraph();

            foreach (var node in other.GetNodes())
            {
                AddNodeNoValidate(node);
            }

            foreach (var edge in other.GetEdges())
            {
                ConnectNoValidate(edge.outputSlot, edge.inputSlot);
            }

            ValidateGraph();
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Checks all NavmeshCut instances and updates graphs if needed.
        /// Note: This schedules updates for all necessary tiles to happen as soon as possible.
        /// The pathfinding threads will continue to calculate the paths that they were calculating when this function
        /// was called and then they will be paused and the graph updates will be carried out (this may be several frames into the
        /// future and the graph updates themselves may take several frames to complete).
        /// If you want to force all navmesh cutting to be completed in a single frame call this method
        /// and immediately after call AstarPath.FlushWorkItems.
        ///
        /// <code>
        /// // Schedule pending updates to be done as soon as the pathfinding threads
        /// // are done with what they are currently doing.
        /// AstarPath.active.navmeshUpdates.ForceUpdate();
        /// // Block until the updates have finished
        /// AstarPath.active.FlushGraphUpdates();
        /// </code>
        /// </summary>
        public void ForceUpdate()
        {
            lastUpdateTime = Time.realtimeSinceStartup;

            List <NavmeshClipper> hasBeenUpdated = null;

            var graphs = AstarPath.active.graphs;

            for (int graphIndex = 0; graphIndex < graphs.Length; graphIndex++)
            {
                var navmeshBase = graphs[graphIndex] as NavmeshBase;
                if (navmeshBase == null)
                {
                    continue;
                }

                // Done in Update as well, but users may call ForceUpdate directly
                navmeshBase.navmeshUpdateData.Refresh();

                var handler = navmeshBase.navmeshUpdateData.handler;

                if (handler == null)
                {
                    continue;
                }

                var forcedReloadRects = navmeshBase.navmeshUpdateData.forcedReloadRects;

                // Get all navmesh cuts in the scene
                var allCuts = handler.cuts.AllItems;

                if (forcedReloadRects.Count == 0)
                {
                    bool any = false;

                    // Check if any navmesh cuts need updating
                    for (var cut = allCuts; cut != null; cut = cut.next)
                    {
                        if (cut.obj.RequiresUpdate())
                        {
                            any = true;
                            break;
                        }
                    }

                    // Nothing needs to be done for now
                    if (!any)
                    {
                        continue;
                    }
                }

                // Start batching tile updates which is good for performance
                // if we are updating a lot of them
                handler.StartBatchLoad();

                for (int i = 0; i < forcedReloadRects.Count; i++)
                {
                    handler.ReloadInBounds(forcedReloadRects[i]);
                }
                forcedReloadRects.ClearFast();

                if (hasBeenUpdated == null)
                {
                    hasBeenUpdated = ListPool <NavmeshClipper> .Claim();
                }

                // Reload all bounds touching the previous bounds and current bounds
                // of navmesh cuts that have moved or changed in some other way
                for (var cut = allCuts; cut != null; cut = cut.next)
                {
                    if (cut.obj.RequiresUpdate())
                    {
                        // Make sure the tile where it was is updated
                        handler.ReloadInBounds(cut.previousBounds);

                        var newGraphSpaceBounds = cut.obj.GetBounds(handler.graph.transform);
                        var newTouchingTiles    = handler.graph.GetTouchingTilesInGraphSpace(newGraphSpaceBounds);
                        handler.cuts.Move(cut.obj, newTouchingTiles);
                        handler.ReloadInBounds(newTouchingTiles);

                        hasBeenUpdated.Add(cut.obj);
                    }
                }

                handler.EndBatchLoad();
            }

            if (hasBeenUpdated != null)
            {
                // Notify navmesh cuts that they have been updated
                // This will cause RequiresUpdate to return false
                // until it is changed again.
                // Note: This is not as efficient as it could be when multiple graphs are used
                // because every navmesh cut will be added to the list once for every graph.
                for (int i = 0; i < hasBeenUpdated.Count; i++)
                {
                    hasBeenUpdated[i].NotifyUpdated();
                }

                ListPool <NavmeshClipper> .Release(ref hasBeenUpdated);
            }
        }