Exemplo n.º 1
0
        // Advances search one step
        public SearchState SearchStep()
        {
            // Firstly break if the user has not initialised the search
            System.Diagnostics.Debug.Assert((m_State > SearchState.NotInitialized) && (m_State < SearchState.Invalid));

            // Next I want it to be safe to do a searchstep once the search has succeeded...
            if (m_State == SearchState.Succeeded || m_State == SearchState.Failed)
            {
                return(m_State);
            }

            // Failure is defined as emptying the open list as there is nothing left to
            // search...
            // New: Allow user abort
            if (m_OpenList.Count == 0 || m_CancelRequest || m_Steps > kiterationLimit)
            {
                FreeSolutionNodes();
                m_State = SearchState.Failed;
                return(m_State);
            }

            // Incremement step count
            m_Steps++;

            // Pop the best node (the one with the lowest f)
            Node n = m_OpenList[0]; // get pointer to the node

            m_OpenList.RemoveAt(0);

            //System.Console.WriteLine("Checking node at " + n.m_UserState.position + ", f: " + n.f);

            // Check for the goal, once we pop that we're done
            if (n.m_UserState.IsGoal(m_Goal.m_UserState))
            {
                // The user is going to use the Goal Node he passed in
                // so copy the parent pointer of n
                m_Goal.parent = n.parent;
                m_Goal.g      = n.g;

                // A special case is that the goal was passed in as the start state
                // so handle that here
                if (false == n.m_UserState.IsSameState(m_Start.m_UserState))
                {
                    // set the child pointers in each node (except Goal which has no child)
                    Node nodeChild  = m_Goal;
                    Node nodeParent = m_Goal.parent;

                    do
                    {
                        nodeParent.child = nodeChild;
                        nodeChild        = nodeParent;
                        nodeParent       = nodeParent.parent;
                    }while (nodeChild != m_Start); // Start is always the first node by definition
                }

                // delete nodes that aren't needed for the solution
                //FreeUnusedNodes();

#if PATHFIND_DEBUG
                System.Console.WriteLine("GOAL REACHED! Steps: " + m_Steps + ", allocated nodes: " + m_AllocateNodeCount + ", MapSearchNodes: " + allocatedMapSearchNodes);
                System.Console.WriteLine("High water marks - Open:" + openListHighWaterMark + ", Closed: " + closedListHighWaterMark + ", Successors: " + successorListHighWaterMark);
#endif

                m_State = SearchState.Succeeded;
                return(m_State);
            }
            else // not goal
            {
                // We now need to generate the successors of this node
                // The user helps us to do this, and we keep the new nodes in m_Successors ...
                m_Successors.Clear(); // empty vector of successor nodes to n

                // User provides this functions and uses AddSuccessor to add each successor of
                // node 'n' to m_Successors
                bool ret = false;
                if (n.parent != null)
                {
                    ret = n.m_UserState.GetSuccessors(this, n.parent.m_UserState);
                }
                else
                {
                    ret = n.m_UserState.GetSuccessors(this, null);
                }

                if (!ret)
                {
                    m_Successors.Clear(); // empty vector of successor nodes to n

                    // free up everything else we allocated
                    FreeSolutionNodes();

                    m_State = SearchState.OutOfMemory;
                    return(m_State);
                }

                // Now handle each successor to the current node ...
                Node successor       = null;
                int  successors_size = m_Successors.Count;
                for (int i = 0; i < successors_size; ++i)
                {
                    successor = m_Successors[i];

                    //  The g value for this successor ...
                    FP newg = n.g + n.m_UserState.GetCost(successor.m_UserState);

                    // Now we need to find whether the node is on the open or closed lists
                    // If it is but the node that is already on them is better (lower g)
                    // then we can forget about this successor

                    // First linear search of open list to find node
                    Node openlist_result = null;
                    int  openlist_size   = m_OpenList.Count;
                    bool foundOpenNode   = false;
                    for (int j = 0; j < openlist_size; ++j)
                    {
                        openlist_result = m_OpenList[j];
                        if (openlist_result.m_UserState.IsSameState(successor.m_UserState))
                        {
                            foundOpenNode = true;
                            break;
                        }
                    }

                    if (foundOpenNode)
                    {
                        // we found this state on open
                        if (openlist_result.g <= newg)
                        {
                            // the one on Open is cheaper than this one
                            continue;
                        }
                    }

                    Node closedlist_result = null;
                    int  closedlist_size   = m_ClosedList.Count;
                    bool foundClosedNode   = false;
                    for (int k = 0; k < closedlist_size; ++k)
                    {
                        closedlist_result = m_ClosedList[k];
                        if (closedlist_result.m_UserState.IsSameState(successor.m_UserState))
                        {
                            foundClosedNode = true;
                            break;
                        }
                    }

                    if (foundClosedNode)
                    {
                        // we found this state on closed
                        if (closedlist_result.g <= newg)
                        {
                            // the one on Closed is cheaper than this one
                            continue;
                        }
                    }

                    // This node is the best node so far with this particular state
                    // so lets keep it and set up its AStar specific data ...
                    successor.parent = n;
                    successor.g      = newg;
                    successor.h      = successor.m_UserState.GoalDistanceEstimate(m_Goal.m_UserState);
                    successor.f      = successor.g + successor.h;

                    // Remove successor from closed if it was on it
                    if (foundClosedNode)
                    {
                        // remove it from Closed
                        m_ClosedList.Remove(closedlist_result);
                    }

                    // Update old version of this node
                    if (foundOpenNode)
                    {
                        m_OpenList.Remove(openlist_result);
                    }

                    SortedAddToOpenList(successor);
                }

                // push n onto Closed, as we have expanded it now
                m_ClosedList.Add(n);

                if (m_ClosedList.Count > closedListHighWaterMark)
                {
                    closedListHighWaterMark = m_ClosedList.Count;
                }
            } // end else (not goal so expand)

            return(m_State); // 'Succeeded' bool is false at this point.
        }
Exemplo n.º 2
0
        public bool InvertMatrix4x4_Full(ref FPMatrix4x4 m, out FPMatrix4x4 output)
        {
            output = new FPMatrix4x4();
            output.Clear();

            FP[,] wtmp = new FP[4, 8];
            FP m0, m1, m2, m3, s;

            FP[] r0 = new FP[8];
            FP[] r1 = new FP[8];
            FP[] r2 = new FP[8];
            FP[] r3 = new FP[8];


            r0[0] = m.m00; r0[1] = m.m01;
            r0[2] = m.m02; r0[3] = m.m03;
            r0[4] = 1.0; r0[5] = r0[6] = r0[7] = 0.0;

            r1[0] = m.m00; r1[1] = m.m01;
            r1[2] = m.m02; r1[3] = m.m03;
            r1[5] = 1.0; r1[4] = r1[6] = r1[7] = 0.0;

            r2[0] = m.m00; r2[1] = m.m01;
            r2[2] = m.m02; r2[3] = m.m03;
            r2[6] = 1.0; r2[4] = r2[5] = r2[7] = 0.0;

            r3[0] = m.m00; r3[1] = m.m01;
            r3[2] = m.m02; r3[3] = m.m03;
            r3[7] = 1.0; r3[4] = r3[5] = r3[6] = 0.0;

            /* choose pivot - or die */
            if (FPMath.Abs(r3[0]) > FPMath.Abs(r2[0]))
            {
                swap_rows(ref r3, ref r2);
            }
            if (FPMath.Abs(r2[0]) > FPMath.Abs(r1[0]))
            {
                swap_rows(ref r2, ref r1);
            }
            if (FPMath.Abs(r1[0]) > FPMath.Abs(r0[0]))
            {
                swap_rows(ref r1, ref r0);
            }

            if (0.0F == r0[0])
            {
                return(false);
            }

            /* eliminate first variable     */
            m1 = r1[0] / r0[0]; m2 = r2[0] / r0[0]; m3 = r3[0] / r0[0];
            s  = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
            s  = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
            s  = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
            s  = r0[4];
            if (s != 0)
            {
                r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s;
            }
            s = r0[5];
            if (s != 0)
            {
                r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s;
            }
            s = r0[6];
            if (s != 0)
            {
                r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s;
            }
            s = r0[7];
            if (s != 0)
            {
                r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s;
            }

            /* choose pivot - or die */
            if (FPMath.Abs(r3[1]) > FPMath.Abs(r2[1]))
            {
                swap_rows(ref r3, ref r2);
            }
            if (FPMath.Abs(r2[1]) > FPMath.Abs(r1[1]))
            {
                swap_rows(ref r2, ref r1);
            }

            if (0 == r1[1])
            {
                return(false);
            }

            /* eliminate second variable */
            m2     = r2[1] / r1[1]; m3 = r3[1] / r1[1];
            r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
            r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
            s      = r1[4]; if (0.0F != s)
            {
                r2[4] -= m2 * s; r3[4] -= m3 * s;
            }
            s = r1[5]; if (0.0F != s)
            {
                r2[5] -= m2 * s; r3[5] -= m3 * s;
            }
            s = r1[6]; if (0.0F != s)
            {
                r2[6] -= m2 * s; r3[6] -= m3 * s;
            }
            s = r1[7]; if (0.0F != s)
            {
                r2[7] -= m2 * s; r3[7] -= m3 * s;
            }

            /* choose pivot - or die */
            if (FPMath.Abs(r3[2]) > FPMath.Abs(r2[2]))
            {
                swap_rows(ref r3, ref r2);
            }
            if (0.0F == r2[2])
            {
                return(false);
            }

            /* eliminate third variable */
            m3     = r3[2] / r2[2];
            r3[3] -= m3 * r2[3]; r3[4] -= m3 * r2[4];
            r3[5] -= m3 * r2[5]; r3[6] -= m3 * r2[6];
            r3[7] -= m3 * r2[7];

            /* last check */
            if (0.0F == r3[3])
            {
                return(false);
            }

            s      = 1.0F / r3[3];        /* now back substitute row 3 */
            r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;

            m2     = r2[3];             /* now back substitute row 2 */
            s      = 1.0F / r2[2];
            r2[4]  = s * (r2[4] - r3[4] * m2); r2[5] = s * (r2[5] - r3[5] * m2);
            r2[6]  = s * (r2[6] - r3[6] * m2); r2[7] = s * (r2[7] - r3[7] * m2);
            m1     = r1[3];
            r1[4] -= r3[4] * m1; r1[5] -= r3[5] * m1;
            r1[6] -= r3[6] * m1; r1[7] -= r3[7] * m1;
            m0     = r0[3];
            r0[4] -= r3[4] * m0; r0[5] -= r3[5] * m0;
            r0[6] -= r3[6] * m0; r0[7] -= r3[7] * m0;

            m1     = r1[2];             /* now back substitute row 1 */
            s      = 1.0F / r1[1];
            r1[4]  = s * (r1[4] - r2[4] * m1); r1[5] = s * (r1[5] - r2[5] * m1);
            r1[6]  = s * (r1[6] - r2[6] * m1); r1[7] = s * (r1[7] - r2[7] * m1);
            m0     = r0[2];
            r0[4] -= r2[4] * m0; r0[5] -= r2[5] * m0;
            r0[6] -= r2[6] * m0; r0[7] -= r2[7] * m0;

            m0    = r0[1];              /* now back substitute row 0 */
            s     = 1.0F / r0[0];
            r0[4] = s * (r0[4] - r1[4] * m0); r0[5] = s * (r0[5] - r1[5] * m0);
            r0[6] = s * (r0[6] - r1[6] * m0); r0[7] = s * (r0[7] - r1[7] * m0);

            output.m00 = r0[4]; output.m01 = r0[5]; output.m02 = r0[6]; output.m03 = r0[7];
            output.m10 = r1[4]; output.m11 = r1[5]; output.m12 = r1[6]; output.m13 = r1[7];
            output.m20 = r2[4]; output.m21 = r2[5]; output.m22 = r2[6]; output.m23 = r2[7];
            output.m30 = r3[4]; output.m31 = r3[5]; output.m32 = r3[6]; output.m33 = r3[7];

            return(true);
        }
Exemplo n.º 3
0
 public bool CompareApproximately(FP f0, FP f1)
 {
     return(CompareApproximately(f0, f1, FP.Epsilon));
 }
Exemplo n.º 4
0
        // Access element at sequential index (0..15 inclusive).
        public    FP this[int index]
        {
            get
            {
                switch (index)
                {
                case 0: return(m00);

                case 1: return(m10);

                case 2: return(m20);

                case 3: return(m30);

                case 4: return(m01);

                case 5: return(m11);

                case 6: return(m21);

                case 7: return(m31);

                case 8: return(m02);

                case 9: return(m12);

                case 10: return(m22);

                case 11: return(m32);

                case 12: return(m03);

                case 13: return(m13);

                case 14: return(m23);

                case 15: return(m33);

                default:
                    throw new IndexOutOfRangeException("Invalid matrix index!");
                }
            }

            set
            {
                switch (index)
                {
                case 0: m00 = value; break;

                case 1: m10 = value; break;

                case 2: m20 = value; break;

                case 3: m30 = value; break;

                case 4: m01 = value; break;

                case 5: m11 = value; break;

                case 6: m21 = value; break;

                case 7: m31 = value; break;

                case 8: m02 = value; break;

                case 9: m12 = value; break;

                case 10: m22 = value; break;

                case 11: m32 = value; break;

                case 12: m03 = value; break;

                case 13: m13 = value; break;

                case 14: m23 = value; break;

                case 15: m33 = value; break;

                default:
                    throw new IndexOutOfRangeException("Invalid matrix index!");
                }
            }
        }
Exemplo n.º 5
0
        public static FPQuaternion Lerp(FPQuaternion a, FPQuaternion b, FP t)
        {
            t = FPMath.Clamp(t, FP.Zero, FP.One);

            return(LerpUnclamped(a, b, t));
        }
Exemplo n.º 6
0
        public static FPQuaternion Inverse(FPQuaternion rotation)
        {
            FP invNorm = FP.One / ((rotation.x * rotation.x) + (rotation.y * rotation.y) + (rotation.z * rotation.z) + (rotation.w * rotation.w));

            return(FPQuaternion.Multiply(FPQuaternion.Conjugate(rotation), invNorm));
        }
Exemplo n.º 7
0
        public static FPQuaternion RotateTowards(FPQuaternion from, FPQuaternion to, FP maxDegreesDelta)
        {
            FP dot = Dot(from, to);

            if (dot < 0.0f)
            {
                to  = Multiply(to, -1);
                dot = -dot;
            }

            FP halfTheta = FP.Acos(dot);
            FP theta     = halfTheta * 2;

            maxDegreesDelta *= FP.Deg2Rad;

            if (maxDegreesDelta >= theta)
            {
                return(to);
            }

            maxDegreesDelta /= theta;

            return(Multiply(Multiply(from, FP.Sin((1 - maxDegreesDelta) * halfTheta)) + Multiply(to, FP.Sin(maxDegreesDelta * halfTheta)), 1 / FP.Sin(halfTheta)));
        }
Exemplo n.º 8
0
        public static FPQuaternion Slerp(FPQuaternion from, FPQuaternion to, FP t)
        {
            t = FPMath.Clamp(t, 0, 1);

            FP dot = Dot(from, to);

            if (dot < 0.0f)
            {
                to  = Multiply(to, -1);
                dot = -dot;
            }

            if (dot < 0.95f)
            {
                FP halfTheta = FP.Acos(dot);

                return(Multiply(Multiply(from, FP.Sin((1 - t) * halfTheta)) + Multiply(to, FP.Sin(t * halfTheta)), 1 / FP.Sin(halfTheta)));
            }
            else
            {
                return(Lerp(from, to, t));
            }
        }