예제 #1
0
 public BVHAABB2Object(Vector2 min, Vector2 max)
     : base(GeoShape.GeoAABB2)
 {
     mAABB2  = new GeoAABB2(min, max);
     mCenter = (min + max) * 0.5f;
     mExtent = max - min;
 }
 public BVHSegment2Object(Vector2 p1, Vector2 p2)
     : base(GeoShape.GeoSegment2)
 {
     mSeg    = new GeoSegment2(p1, p2);
     mCenter = (p1 + p2) * 0.5f;
     mAABB   = new GeoAABB2(Vector2.Min(p1, p2), Vector2.Max(p1, p2));
 }
예제 #3
0
        public List <GeoAABB2> GetRect()
        {
            List <GeoAABB2>    results = new List <GeoAABB2>();
            HashSet <Vector2i> tempSet = new HashSet <Vector2i>();
            int counter = 0;

            while (true)
            {
                counter = 0;
                for (int i = 0; i < SizeList.Count; ++i)
                {
                    Vector2i size = SizeList[i];
                    GeoAABB2 aabb = GetRect(size[0], size[1], i, ref tempSet);
                    if (aabb == null)
                    {
                        counter++;
                    }
                    else
                    {
                        results.Add(aabb);
                    }
                }
                if (counter == SizeList.Count)
                {
                    break;
                }
            }
            return(results);
        }
예제 #4
0
        public bool TestIntersection(GeoAABB2 aabb)
        {
            if (mFlatTreeList == null || mFlatTreeList.Count == 0)
            {
                return(false);
            }
            int closer, other;

            BVHTraversal[] todo = new BVHTraversal[64];
            todo[0] = new BVHTraversal();
            int stackptr = 0;

            todo[stackptr].mIndex  = 0;
            todo[stackptr].mLength = -9999999.0f;
            while (stackptr >= 0)
            {
                int   ni   = todo[stackptr].mIndex;
                float near = todo[stackptr].mLength;
                stackptr--;
                BVHFlatNode2 node = mFlatTreeList[ni];
                // 对叶节点做相交测试
                if (node.mRightOffset == 0)
                {
                    bool hit = false;
                    for (int o = 0; o < node.mLeafCount; ++o)
                    {
                        BVHObject2 obj = mBuildPrims[(int)node.mStartIndex + o];
                        hit = obj.TestAABBIntersect(aabb);
                        if (hit)
                        {
                            return(true);
                        }
                    }
                }
                else
                {
                    closer = ni + 1;
                    other  = ni + (int)node.mRightOffset;
                    // 对父结点做测试
                    bool hitc0 = GeoAABBUtils.IsAABBInsectAABB2(aabb.mMin, aabb.mMax, mFlatTreeList[closer].mBox.mMin, mFlatTreeList[closer].mBox.mMax);
                    bool hitc1 = GeoAABBUtils.IsAABBInsectAABB2(aabb.mMin, aabb.mMax, mFlatTreeList[other].mBox.mMin, mFlatTreeList[other].mBox.mMax);
                    if (hitc0 && hitc1)
                    {
                        todo[++stackptr] = new BVHTraversal(other, -9999);
                        todo[++stackptr] = new BVHTraversal(closer, -9999);
                    }
                    else if (hitc0)
                    {
                        todo[++stackptr] = new BVHTraversal(closer, -9999);
                    }
                    else if (hitc1)
                    {
                        todo[++stackptr] = new BVHTraversal(other, -9999);
                    }
                }
            }
            return(false);
        }
예제 #5
0
 public BVHTriangle2Object(Vector2 p1, Vector2 p2, Vector2 p3)
     : base(GeoShape.GeoTriangle2)
 {
     mP1     = p1;
     mP2     = p2;
     mP3     = p3;
     mCenter = (mP1 + mP2 + mP3) * 0.333333f;
     mAABB   = new GeoAABB2(Vector2.Min(Vector2.Min(mP1, mP2), mP3), Vector2.Max(Vector2.Max(mP1, mP2), mP3));
 }
예제 #6
0
 public GeoAABB2 GetRectangle(float sw, float sh)
 {
     for (int i = 0; i < mRegionPeocessors.Count; ++i)
     {
         GeoAABB2 aabb = mRegionPeocessors[i].GetRectangle(sw, sh);
         if (aabb != null)
         {
             return(aabb);
         }
     }
     return(null);
 }
예제 #7
0
 public override GeoAABB2 GetRectangle(float sizew, float sizeh)
 {
     foreach (AbstractRegionProcessor unit in mUnitsProcessor)
     {
         GeoAABB2 aabb = unit.GetRectangle(sizew, sizeh);
         if (aabb != null)
         {
             return(aabb);
         }
     }
     return(null);
 }
예제 #8
0
        public bool AddRectIfCan(ref GeoAABB2 rect, bool needCheck)
        {
            bool can = true;

            if (needCheck)
            {
                Vector2 size = rect.mMax - rect.mMin;
                can = CheckRectangleValid(rect.mMin, rect.mMax, size[0], size[1]);
            }
            if (can)
            {
                AddRectangle(ref rect);
            }
            return(can);
        }
예제 #9
0
        private void RemovePointsInRectangle(GeoAABB2 rect)
        {
            List <int> needRemoved = new List <int>();

            for (int i = 0; i < mCenterList.Count; ++i)
            {
                Vector2 v = mCenterList[i];
                if (GeoAABBUtils.IsPointInAABB2(rect.mMin, rect.mMax, ref v))
                {
                    needRemoved.Add(i);
                }
            }
            for (int i = needRemoved.Count - 1; i >= 0; --i)
            {
                mCenterList.RemoveAt(needRemoved[i]);
            }
        }
예제 #10
0
 public GeoAABB2 GetRectangle(float sizew, float sizeh, int index)
 {
     if (CanContinue())
     {
         Vector2i temp = new Vector2i((int)(sizew * 100), (int)(sizeh * 100));
         if (!mCacheWH.Contains(temp))
         {
             GeoAABB2 aabb = new GeoAABB2();
             if (!mWrapper.GetRectangle(sizew, sizeh, ref aabb))
             {
                 mCacheWH.Add(temp);
                 if (!mCacheIndex.Add(index))
                 {
                     mInsertedCount++;
                 }
             }
             else
             {
                 // mResults[index].Add(aabb);
                 float aabbArea = aabb.Area();
                 mResultsArea[index] += aabbArea;
                 mCacheIndex.Clear();
                 mInsertedCount = 0;
                 mAreaProb.Clear();
                 mProbTotal = 0.0f;
                 for (int a = 0; a < mProb; ++a)
                 {
                     float newProb = mResultsArea[a] / mArea - mProbs[a].mProbablity;
                     newProb = newProb > 0 ? 0 : -newProb;
                     mAreaProb.Add(newProb);
                     mProbTotal += newProb;
                 }
                 return(aabb);
             }
         }
         else
         {
             if (!mCacheIndex.Add(index))
             {
                 mInsertedCount++;
             }
         }
     }
     return(null);
 }
예제 #11
0
        public bool GetRectangle(float w, float h, ref GeoAABB2 rect)
        {
            if (IsFull())
            {
                return(false);
            }
            Vector2 center;
            bool    isExist = ExistRectangle(w, h, out center);

            if (isExist)
            {
                Vector2 temp = new Vector2(w * 0.5f, h * 0.5f);
                rect.mMin = center - temp;
                rect.mMax = center + temp;
                AddRectangle(ref rect);
            }
            return(isExist);
        }
예제 #12
0
        public GeoAABB2 GetRectangle(float sizew, float sizeh)
        {
            Vector2i temp = new Vector2i((int)(sizew * 10), (int)(sizeh * 10));

            if (!mCacheWH.Contains(temp))
            {
                GeoAABB2 aabb = new GeoAABB2();
                if (!mWrapper.GetRectangle(sizew, sizeh, ref aabb))
                {
                    mCacheWH.Add(temp);
                }
                else
                {
                    mMissCount = 0;
                    return(aabb);
                }
            }
            mMissCount++;
            return(null);
        }
예제 #13
0
        private float AddRectangle(ref GeoAABB2 rect)
        {
            Vector2 temp = rect.mMax - rect.mMin;
            float   area = temp[0] * temp[1];

            mOccupied += area;
            mRectangleList.Add(rect);
            bool isbeyond = mLeftRectangle.Count > mMaxLeftCount;

            mBvh.AddObject(new BVHAABB2Object(rect.mMin, rect.mMax), isbeyond);
            if (isbeyond)
            {
                mLeftRectangle.Clear();
            }
            else
            {
                mLeftRectangle.Add(rect);
            }
            RemovePointsInRectangle(rect);
            return(mOccupied / mArea);
        }
예제 #14
0
        public GeoAABB2 GetRect(float w, float h, int i, ref HashSet <Vector2i> record)
        {
            GeoAABB2 rect = new GeoAABB2();

            for (int j = 0; j < mPolygonPartition.Count; ++j)
            {
                Vector2i       key  = Vector2i.GetVector2i(i, j);
                PolygonWrapper poly = mPolygonPartition[j];
                if (!record.Contains(key))
                {
                    if (poly.GetRectangle(w, h, ref rect))
                    {
                        return(rect);
                    }
                    else
                    {
                        record.Add(key);
                    }
                }
            }
            return(null);
        }
예제 #15
0
        public void FindMaxBinary(bool recursive)
        {
            float   ws        = 0.3f;
            float   we        = mMaxSize[0];
            Vector2 center    = new Vector2();
            Vector2 maxCenter = new Vector2();
            Vector2 maxSize   = new Vector2();
            float   maxArea   = -1.0f;

            while (ws < we)
            {
                float   wmid       = (ws + we) * 0.5f;
                float   hs         = 0.3f;
                float   he         = mMaxSize[1];
                bool    flag       = false;
                Vector2 lastCenter = new Vector2();
                float   hmid       = (hs + he) * 0.5f;
                float   angle;
                while (hs < he)
                {
                    if (ExistRectangle(wmid, hmid, out angle, out center))
                    {
                        flag       = true;
                        lastCenter = center;
                        hs         = hmid + 0.01f;
                    }
                    else
                    {
                        he = hmid - 0.01f;
                    }
                    hmid = (hs + he) * 0.5f;
                }
                if (flag)
                {
                    if (wmid * hmid > maxArea)
                    {
                        maxArea    = wmid * hs;
                        maxCenter  = lastCenter;
                        maxSize[0] = wmid;
                        maxSize[1] = hmid;
                    }
                    ws = wmid + 0.01f;
                }
                else
                {
                    we = wmid - 0.01f;
                }
            }
            if (maxArea > 0)
            {
                bool flag = false;
                if ((maxArea / mArea) > PartitionParameters.globalParamter.selfArea)
                {
                    GeoAABB2 maxRect = new GeoAABB2(maxCenter - maxSize * 0.5f, maxCenter + maxSize * 0.5f);
                    mMaxSize = maxSize;
                    float total = AddRectangle(ref maxRect);
                    flag = recursive && total < PartitionParameters.globalParamter.maxArea;
                }
                if (flag)
                {
                    mMaxDepth--;
                    if (mMaxDepth > 0)
                    {
                        FindMaxBinary(recursive);
                    }
                }
            }
        }
예제 #16
0
 public virtual bool TestAABBIntersect(GeoAABB2 aabb)
 {
     return(false);
 }
예제 #17
0
 public void ExpandToInclude(GeoAABB2 b)
 {
     mMin    = Vector2.Min(mMin, b.mMin);
     mMax    = Vector2.Max(mMax, b.mMax);
     mExtent = mMax - mMin;
 }
예제 #18
0
 public bool TestAABBIntersect(GeoAABB2 aabb)
 {
     return(GeoAABBUtils.IsAABBInsectAABB2(aabb.mMin, aabb.mMax, mAABB2.mMin, mAABB2.mMax));
 }
예제 #19
0
 public void AddRect(ref GeoAABB2 aabb)
 {
     // to do
 }
        public bool TestAABBIntersect(GeoAABB2 aabb)
        {
            GeoInsectPointArrayInfo insect = new GeoInsectPointArrayInfo();

            return(GeoSegmentUtils.IsSegmentInsectAABB2(mSeg.mP1, mSeg.mP2, aabb.mMin, aabb.mMax, ref insect));
        }
예제 #21
0
 public abstract void AddRect(ref GeoAABB2 aabb);
예제 #22
0
        /// <summary>
        /// 1 在某一个段内找不到时,并且找的概率为1,容易出现死循环 nowCount insertMaxCount 来控制 退出循环
        /// 2 wrapper.IsFull() 设置占比,退出循环
        /// 3 cacheIndex.Count < prob 退出循环
        /// </summary>
        /// <param name="original"></param>
        /// <param name="probablities"></param>
        /// <param name="connects"></param>
        /// <returns></returns>
        private static List <List <GeoAABB2> > PolygonPartition(List <Vector2> original, List <PartitionUnit> probablities, List <Vector4> connects = null)
        {
            List <PartitionUnit> newUnits = new List <PartitionUnit>();

            newUnits.AddRange(probablities);
            PolygonWrapper          wrapper     = PolygonWrapper.Create(original, true, connects, 2);
            float                   total       = wrapper.Area;
            int                     prob        = newUnits.Count;
            List <List <GeoAABB2> > results     = new List <List <GeoAABB2> >();
            List <float>            resultsArea = new List <float>();
            List <float>            areaProb    = new List <float>();
            // 更新概率
            float proSum = 0.0f;

            for (int i = 0; i < prob; ++i)
            {
                results.Add(new List <GeoAABB2>());
                resultsArea.Add(0.0f);
                areaProb.Add(newUnits[i].mProbablity);
                proSum += newUnits[i].mProbablity;
            }
            int insertMaxCount            = prob * 10;
            int nowCount                  = 0;
            HashSet <Vector2i> cacheWH    = new HashSet <Vector2i>();
            HashSet <int>      cacheIndex = new HashSet <int>();
            int index = RandomInt(areaProb, proSum);

            while (!wrapper.IsFull() && cacheIndex.Count < prob && nowCount < insertMaxCount)
            {
                float    sizew = RandomUtils.GetRandomFloat(newUnits[index].mMinW, newUnits[index].mMaxW);
                float    sizeh = RandomUtils.GetRandomFloat(newUnits[index].mMinH, newUnits[index].mMaxH);
                Vector2i temp  = new Vector2i((int)(sizew * 100), (int)(sizeh * 100));
                if (!cacheWH.Contains(temp))
                {
                    GeoAABB2 aabb = new GeoAABB2();
                    if (!wrapper.GetRectangle(sizew, sizeh, ref aabb))
                    {
                        cacheWH.Add(temp);
                        if (!cacheIndex.Add(index))
                        {
                            nowCount++;
                        }
                    }
                    else
                    {
                        results[index].Add(aabb);
                        float aabbArea = aabb.Area();
                        resultsArea[index] += aabbArea;
                        cacheIndex.Clear();
                        nowCount = 0;
                        areaProb.Clear();
                        proSum = 0.0f;
                        for (int a = 0; a < prob; ++a)
                        {
                            float newProb = resultsArea[a] / total - newUnits[a].mProbablity;
                            newProb = newProb > 0 ? 0 : -newProb;
                            areaProb.Add(newProb);
                            proSum += newProb;
                        }
                        if (proSum == 0)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    if (!cacheIndex.Add(index))
                    {
                        nowCount++;
                    }
                }
                index = RandomInt(areaProb, proSum);
            }
            for (int a = 0; a < resultsArea.Count; ++a)
            {
                float abs = resultsArea[a] / total;
                Debug.Log(string.Format("count: {0}, xLen: {1}", results[a].Count, abs));
            }
            return(results);
        }
예제 #23
0
 public override void AddRect(ref GeoAABB2 aabb)
 {
     mWrapper.AddRectIfCan(ref aabb, false);
 }