/// <summary>
        /// Compiles an enumeration of DomNode properties (as objects) that matched the conditions of the search predicates</summary>
        /// <param name="predicate">Specifies the test conditions for a query</param>
        /// <returns>The enumeration of DomNode properties (e.g., DomNodeQueryMatch) satisfying the query</returns>
        public IEnumerable <object> Query(IQueryPredicate predicate)
        {
            m_results.Clear();
            // Iterate over all dom nodes under this adapter
            foreach (DomNode domNode in DomNode.Subtree)
            {
                // The results of one DomNode query associate each predicate with matching dom node properties
                Dictionary <IQueryPredicate, IList <IQueryMatch> > predicateMatchResults
                    = new Dictionary <IQueryPredicate, IList <IQueryMatch> >();

                // For each queryable item (ie a DomNode) there may be 0 to many "query matches"
                // (ie a DomNode property).  On success, predicate.Test() will supply one
                // IQueryMatch per DomNode property that matched.
                IList <IQueryMatch> matchingPropertiesList;
                if (predicate.Test(domNode, out matchingPropertiesList))
                {
                    if (matchingPropertiesList != null)
                    {
                        predicateMatchResults[predicate] = matchingPropertiesList;
                    }

                    // For this queryable, a match is the DomNode that passed the predicate test,
                    // paired with all its properties that allowed it to satisfy the test
                    m_results.Add(new DomNodeQueryMatch(domNode, predicateMatchResults));
                }
            }

            // Announce that the search results have changed
            ResultsChanged.Raise(this, EventArgs.Empty);

            return(m_results);
        }
Пример #2
0
        /// <inheritdoc />
        public override void CastPoints()
        {
            if (!isActiveAndEnabled)
            {
                return;
            }

            Ray        ray = new Ray(transform.position, transform.forward);
            RaycastHit hitData;
            bool       hasCollided = PhysicsCast.Raycast(physicsCast, ray, out hitData, maximumLength, Physics.IgnoreRaycastLayer);

            TargetHit = (hasCollided ? hitData : (RaycastHit?)null);

            points[0] = transform.position;
            points[1] = (hasCollided ? hitData.point : transform.position + transform.forward * maximumLength);

            ResultsChanged?.Invoke(eventData.Set(TargetHit, Points));
        }
Пример #3
0
        /// <summary>
        /// Checks for collisions along the parabolic line segments and generates the final points.
        /// </summary>
        /// <param name="forward">The forward direction to use for the checks.</param>
        /// <param name="down">The downwards direction to use for the checks.</param>
        protected virtual void GeneratePointsIncludingSegments(Vector3 forward, Vector3 down)
        {
            GeneratePoints(forward, down);

            collisionCheckFrequency = Mathf.Clamp(collisionCheckFrequency, 0, segmentCount);
            int step = segmentCount / (collisionCheckFrequency > 0 ? collisionCheckFrequency : 1);

            for (int index = 0; index < segmentCount - step; index += step)
            {
                Vector3 currentPoint       = points[index];
                Vector3 nextPoint          = index + step < points.Count ? points[index + step] : points[points.Count - 1];
                Vector3 nextPointDirection = (nextPoint - currentPoint).normalized;
                float   nextPointDistance  = Vector3.Distance(currentPoint, nextPoint);

                Ray        pointsRay = new Ray(currentPoint, nextPointDirection);
                RaycastHit pointsHitData;

                if (!PhysicsCast.Raycast(physicsCast, pointsRay, out pointsHitData, nextPointDistance, Physics.IgnoreRaycastLayer))
                {
                    continue;
                }

                Vector3    collisionPoint = pointsRay.GetPoint(pointsHitData.distance);
                Ray        downwardRay    = new Ray(collisionPoint + Vector3.up * 0.01f, Vector3.down);
                RaycastHit downwardHitData;

                if (!PhysicsCast.Raycast(physicsCast, downwardRay, out downwardHitData, float.PositiveInfinity, Physics.IgnoreRaycastLayer))
                {
                    continue;
                }

                TargetHit = downwardHitData;

                Vector3 newDownPosition  = downwardRay.GetPoint(downwardHitData.distance);
                Vector3 newJointPosition = newDownPosition.y < forward.y ? new Vector3(newDownPosition.x, forward.y, newDownPosition.z) : forward;
                GeneratePoints(newJointPosition, newDownPosition);

                break;
            }

            ResultsChanged?.Invoke(eventData.Set(TargetHit, Points));
        }
Пример #4
0
 /// <inheritdoc />
 protected override void DoCastPoints()
 {
     GeneratePoints();
     ResultsChanged?.Invoke(eventData.Set(TargetHit, Points));
 }
        /// <summary>
        /// Applies a replacement on the results of the last Query</summary>
        /// <param name="replaceInfo">Replacement information</param>
        /// <returns>The list of objects on which we just performed a replacement</returns>
        public IEnumerable <object> Replace(object replaceInfo)
        {
            ITransactionContext currentTransaction = null;

            try
            {
                foreach (DomNodeQueryMatch match in m_results)
                {
                    DomNode domNode = match.DomNode;

                    // Set up undo/redo for the replacement operation
                    ITransactionContext newTransaction = domNode != null?domNode.GetRoot().As <ITransactionContext>() : null;

                    if (newTransaction != currentTransaction)
                    {
                        {
                            if (currentTransaction != null)
                            {
                                currentTransaction.End();
                            }
                            currentTransaction = newTransaction;
                            if (currentTransaction != null)
                            {
                                currentTransaction.Begin("Replace".Localize());
                            }
                        }
                    }

                    // Apply replacement to all matching items that were found on last search
                    foreach (IQueryPredicate predicateInfo in match.PredicateMatchResults.Keys)
                    {
                        predicateInfo.Replace(match.PredicateMatchResults[predicateInfo], replaceInfo);
                    }
                }
            }
            catch (InvalidTransactionException ex)
            {
                // cancel the replacement transaction in the undo/redo queue
                if (currentTransaction != null && currentTransaction.InTransaction)
                {
                    currentTransaction.Cancel();
                }

                if (ex.ReportError)
                {
                    Outputs.WriteLine(OutputMessageType.Error, ex.Message);
                }
            }
            finally
            {
                // finish the replacement transaction for the undo/redo queue
                if (currentTransaction != null && currentTransaction.InTransaction)
                {
                    currentTransaction.End();
                }
            }

            ResultsChanged.Raise(this, EventArgs.Empty);

            return(m_results);
        }