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)); }
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); }
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); }
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)); }
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); }
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); }
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); }
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]); } }
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); }
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); }
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); }
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); }
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); }
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); } } } }
public virtual bool TestAABBIntersect(GeoAABB2 aabb) { return(false); }
public void ExpandToInclude(GeoAABB2 b) { mMin = Vector2.Min(mMin, b.mMin); mMax = Vector2.Max(mMax, b.mMax); mExtent = mMax - mMin; }
public bool TestAABBIntersect(GeoAABB2 aabb) { return(GeoAABBUtils.IsAABBInsectAABB2(aabb.mMin, aabb.mMax, mAABB2.mMin, mAABB2.mMax)); }
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)); }
public abstract void AddRect(ref GeoAABB2 aabb);
/// <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); }
public override void AddRect(ref GeoAABB2 aabb) { mWrapper.AddRectIfCan(ref aabb, false); }