コード例 #1
0
        public virtual SpatialConstraintRuleDomain GetDomain(SpatialConstraintProcessorContext context)
        {
            var domain = new SpatialConstraintRuleDomain();
            var nodes  = context.constraintAsset.Graph.Nodes;

            domain.referenceNode = nodes.Where(node => node is SCReferenceNode).FirstOrDefault() as SCReferenceNode;
            return(domain);
        }
コード例 #2
0
        public bool ProcessSpatialConstraint(SpatialConstraintProcessorContext context, out Matrix4x4 outOffset, out PropSocket[] outMarkersToRemove)
        {
            outOffset = Matrix4x4.identity;
            var domain = GetDomain(context);

            if (context.constraintAsset != null && context.constraintAsset.Graph != null)
            {
                Matrix4x4[] rotationFrames;
                if (context.constraintAsset.rotateToFit)
                {
                    rotationFrames = new Matrix4x4[]
                    {
                        Matrix4x4.identity,
                        Matrix4x4.Rotate(Quaternion.Euler(0, 90, 0)),
                        Matrix4x4.Rotate(Quaternion.Euler(0, 180, 0)),
                        Matrix4x4.Rotate(Quaternion.Euler(0, 270, 0)),
                    };
                }
                else
                {
                    rotationFrames = new Matrix4x4[]
                    {
                        Matrix4x4.identity
                    };
                }

                foreach (var rotationFrame in rotationFrames)
                {
                    if (ProcessSpatialConstraintFrame(context, domain, rotationFrame, out outMarkersToRemove))
                    {
                        if (context.constraintAsset.applyFitRotation)
                        {
                            outOffset = rotationFrame;
                        }
                        return(true);
                    }
                }
            }

            outMarkersToRemove = new PropSocket[0];
            return(false);
        }
コード例 #3
0
        bool ProcessSpatialConstraintFrame(SpatialConstraintProcessorContext context, SpatialConstraintRuleDomain domain, Matrix4x4 rotationFrame, out PropSocket[] outMarkersToRemove)
        {
            var nodes = context.constraintAsset.Graph.Nodes.Where(node => node is SCRuleNode);

            outMarkersToRemove = new PropSocket[0];

            if (nodes.Count() == 0)
            {
                // No rules specified.  Return true by default
                return(true);
            }

            var nodeWorldPositions = new Dictionary <SCRuleNode, Vector3>();

            foreach (var node in nodes)
            {
                var ruleNode = node as SCRuleNode;

                var nodePosition = SpatialConstraintProcessorUtils.GetRuleNodeWorldPosition(ruleNode, domain.referenceNode,
                                                                                            context.marker, domain.gridSize, ref rotationFrame);
                nodeWorldPositions.Add(ruleNode, nodePosition);

                var constraints = ruleNode.constraints.Where(c => c != null);
                if (constraints.Count() == 0)
                {
                    continue;
                }

                bool allRulesPassed       = true;
                bool atleastOneRulePassed = false;

                foreach (var constraint in constraints)
                {
                    var ruleContext = new ConstraintRuleContext();
                    ruleContext.processorContext      = context;
                    ruleContext.domain                = domain;
                    ruleContext.ruleNode              = ruleNode;
                    ruleContext.rotationFrame         = rotationFrame;
                    ruleContext.ruleNodeWorldPosition = nodePosition;


                    bool success = constraint.Process(ruleContext);
                    if (constraint.inverseRule)
                    {
                        success = !success;
                    }

                    allRulesPassed       &= success;
                    atleastOneRulePassed |= success;
                }

                if (ruleNode.constraintEvaluationMode == SCRuleNodeEvaluationMode.AllRulesMustPass && !allRulesPassed)
                {
                    return(false);
                }
                else if (ruleNode.constraintEvaluationMode == SCRuleNodeEvaluationMode.AtleastOneRuleShouldPass && !atleastOneRulePassed)
                {
                    return(false);
                }
            }

            // The spatial constraint setup has passed
            // Process removal rules
            var markersToRemove = new List <PropSocket>();

            foreach (var node in nodes)
            {
                var ruleNode = node as SCRuleNode;
                if (ruleNode.exclusionRuleMarkersToRemove.Length == 0)
                {
                    continue;
                }

                var   radius         = ruleNode.exclusionRuleSearchRadius;
                float searchRadiusSq = radius * radius;
                var   nodePosition3D = nodeWorldPositions[ruleNode];
                var   searchPosition = SpatialConstraintProcessorUtils.GetPosition2D(nodePosition3D);
                foreach (var markerToRemove in ruleNode.exclusionRuleMarkersToRemove)
                {
                    var markerSearchSpace = context.levelMarkers.GetMarkersInSearchArea(searchPosition, radius);
                    foreach (var candidateMarker in markerSearchSpace)
                    {
                        var candidateMarkerName = candidateMarker.SocketType;
                        if (ruleNode.exclusionRuleMarkersToRemove.Contains(candidateMarkerName))
                        {
                            var   candidateMarkerPosition = SpatialConstraintProcessorUtils.GetPosition2D(Matrix.GetTranslation(ref candidateMarker.Transform));
                            float distanceSq = (searchPosition - candidateMarkerPosition).sqrMagnitude;
                            if (distanceSq < searchRadiusSq)
                            {
                                markersToRemove.Add(candidateMarker);
                            }
                        }
                    }
                }
            }
            outMarkersToRemove = markersToRemove.ToArray();

            return(true);
        }