Example #1
0
        //  This partition algorithm is inspired by QuickSort; sorting on the
        //  split axis of the node in question.
        private void PartitionSmallerTriangles(CollisionContent cc, int[] tris, int lo, ref int mid, int hi, BoundingSphere[] tbs, Vector3 d, float r)
        {
            int ilo = lo;
            int ihi = hi;

            while (lo < hi && lo < ihi && hi > ilo)
            {
                //  if "lo" and "hi - 1" alias, then one of the first ifs will succeed, and
                //  I'll increment/decrement and break out of the loop!
                if (Vector3.Dot(tbs[tris[lo]].Center, d) < r)
                {
                    ++lo;
                }
                else if (!(Vector3.Dot(tbs[tris[hi - 1]].Center, d) < r))
                {
                    --hi;
                }
                else
                {
                    //  I know that "lo" points at a larger tri, and "hi-1" points at a lower tri; so swap them
                    int j = tris[lo];
                    tris[lo]     = tris[hi - 1];
                    tris[hi - 1] = j;
                    //  because of the failure of both of the first two tests, I know that
                    //  lo must be lower than hi-1.
                    Debug.Assert(lo < hi - 1);
                    ++lo;
                    --hi;
                }
            }
            // "lo" points at the first "high" value; "hi" points at the last "lo" value
            Debug.Assert(lo == hi);
            Debug.Assert(lo == ihi || !(Vector3.Dot(tbs[tris[lo]].Center, d) < r));
            mid = lo;
        }
Example #2
0
        public override TOutput Process(TInput input, ContentProcessorContext context)
        {
            this.context = context;
            CollisionContent cc = ProcessCollision(input);
            ModelContent     mc = base.Process(input, context);

            ((Dictionary <string, object>)mc.Tag).Add("Collision", cc);
            return(mc);
        }
Example #3
0
 void GatherLargeTriangles(ref TreeNode tn, CollisionContent cc, int[] tris, ref int lo, int hi, float r, BoundingSphere[] tbs)
 {
     for (int i = lo; i < hi; ++i)
     {
         if (tbs[tris[i]].Radius >= r)
         {
             int j = tris[i];
             tris[i]  = tris[lo];
             tris[lo] = j;
             ++lo;
         }
     }
 }
Example #4
0
        public virtual CollisionContent MakeCollisionContent(Gather g)
        {
            //  todo: I really should find the major modes, and align the AABB to
            //  those by rotating. Then counter-rotate when collision testing.
            //  Oh, well.
            CollisionContent cc = new CollisionContent();

            cc.Bounds = g.Bounds;
            Vector3 hd = cc.Bounds.HalfDim;
            Vector3 hc = cc.Bounds.Center;

            hd.X         = Math.Max(hd.X, Math.Max(hd.Y, hd.Z));
            hd.Y         = hd.X;
            hd.Z         = hd.X;
            cc.Bounds.Lo = hc - hd;
            cc.Bounds.Hi = hc + hd;
            cc.Triangles = g.Triangles.ToArray();
            cc.Vertices  = g.Vertices.ToArray();
            List <TreeNode> TreeNodes = new List <TreeNode>();

            int[] ixs = new int[cc.Triangles.Length];
            for (int i = 0; i < ixs.Length; ++i)
            {
                ixs[i] = i;
            }
            BuildNodes(cc, ixs, 0, ixs.Length, TreeNodes, cc.Bounds,
                       g.BoundingSpheres.ToArray());
            cc.Nodes = TreeNodes.ToArray();
            for (int i = 0; i < ixs.Length; ++i)
            {
                cc.Triangles[i] = g.Triangles[ixs[i]];
                cc.Triangles[i].CalcColl(cc);
            }
            context.Logger.LogImportantMessage("Built CollisionContent with {0} triangles, {1} vertices, {2} cells",
                                               cc.Triangles.Length, cc.Vertices.Length, cc.Nodes.Length);
            return(cc);
        }
Example #5
0
        void BuildNodes(CollisionContent cc, int[] tris, int lo, int hi, List <TreeNode> nodes, AABB bounds,
                        BoundingSphere[] tbs)
        {
            TreeNode tn = new TreeNode();

            tn.TriStart  = lo;
            tn.Expansion = (bounds.Hi - bounds.Lo).Length() * ExpansionFactor;
            GatherLargeTriangles(ref tn, cc, tris, ref lo, hi, tn.Expansion, tbs);
            tn.TriEnd = lo;
            int ix = nodes.Count;

            nodes.Add(tn);
            Vector3 lb = bounds.Lo;
            Vector3 ub = bounds.Hi;
            Vector3 cb = lb + (ub - lb) * 0.5f;

            if (hi > lo + 4)
            {
                int midX = lo;
                PartitionSmallerTriangles(cc, tris, lo, ref midX, hi, tbs, Vector3.Right, cb.X);
                int midXlo = lo;
                PartitionSmallerTriangles(cc, tris, lo, ref midXlo, midX, tbs, Vector3.Up, cb.Y);
                int midXhi = midX;
                PartitionSmallerTriangles(cc, tris, midX, ref midXhi, hi, tbs, Vector3.Up, cb.Y);
                int midXloYlo = lo;
                PartitionSmallerTriangles(cc, tris, lo, ref midXloYlo, midXlo, tbs, Vector3.Backward, cb.Z);
                int midXloYhi = midXlo;
                PartitionSmallerTriangles(cc, tris, midXlo, ref midXloYhi, midX, tbs, Vector3.Backward, cb.Z);
                int midXhiYlo = midX;
                PartitionSmallerTriangles(cc, tris, midX, ref midXhiYlo, midXhi, tbs, Vector3.Backward, cb.Z);
                int midXhiYhi = midXhi;
                PartitionSmallerTriangles(cc, tris, midXhi, ref midXhiYhi, hi, tbs, Vector3.Backward, cb.Z);
                if (lo < midXloYlo)
                {
                    tn.Child000 = nodes.Count;
                    BuildNodes(cc, tris, lo, midXloYlo, nodes, new AABB(lb, cb),
                               tbs);
                }
                if (midXloYlo < midXlo)
                {
                    tn.Child001 = nodes.Count;
                    BuildNodes(cc, tris, midXloYlo, midXlo, nodes,
                               new AABB(new Vector3(lb.X, lb.Y, cb.Z), new Vector3(cb.X, cb.Y, ub.Z)),
                               tbs);
                }
                if (midXlo < midXloYhi)
                {
                    tn.Child010 = nodes.Count;
                    BuildNodes(cc, tris, midXlo, midXloYhi, nodes,
                               new AABB(new Vector3(lb.X, cb.Y, lb.Z), new Vector3(cb.X, ub.Y, cb.Z)),
                               tbs);
                }
                if (midXloYhi < midX)
                {
                    tn.Child011 = nodes.Count;
                    BuildNodes(cc, tris, midXloYhi, midX, nodes,
                               new AABB(new Vector3(lb.X, cb.Y, cb.Z), new Vector3(cb.X, ub.Y, ub.Z)),
                               tbs);
                }
                if (midX < midXhiYlo)
                {
                    tn.Child100 = nodes.Count;
                    BuildNodes(cc, tris, midX, midXhiYlo, nodes,
                               new AABB(new Vector3(cb.X, lb.Y, lb.Z), new Vector3(ub.X, cb.Y, cb.Z)),
                               tbs);
                }
                if (midXhiYlo < midXhi)
                {
                    tn.Child101 = nodes.Count;
                    BuildNodes(cc, tris, midXhiYlo, midXhi, nodes,
                               new AABB(new Vector3(cb.X, lb.Y, cb.Z), new Vector3(ub.X, cb.Y, ub.Z)),
                               tbs);
                }
                if (midXhi < midXhiYhi)
                {
                    tn.Child110 = nodes.Count;
                    BuildNodes(cc, tris, midXhi, midXhiYhi, nodes,
                               new AABB(new Vector3(cb.X, cb.Y, lb.Z), new Vector3(ub.X, ub.Y, cb.Z)),
                               tbs);
                }
                if (midXhiYhi < hi)
                {
                    tn.Child111 = nodes.Count;
                    BuildNodes(cc, tris, midXhiYhi, hi, nodes,
                               new AABB(new Vector3(cb.X, cb.Y, cb.Z), new Vector3(ub.X, ub.Y, ub.Z)),
                               tbs);
                }
            }
            else
            {
                //  include them all!
                tn.TriEnd = hi;
            }
            nodes[ix] = tn;
        }