问题描述
我正在用 C# 为 2D 游戏创建一个四叉树,以加快渲染速度。一些对象(行星)正在移动,这就是为什么我创建了一个名为 removeAndUpdate
的方法来更新树,方法是从叶子(而不是从根)删除和重新插入特定对象,因为我已经读过在link。不幸的是,在重新插入部分一段时间后我得到了 System.OutOfMemoryException
。我很确定,removeAndUpdate
方法存在一些问题。
也许值得一提的是,当一个四边形被细分时(以防万一,当四边形的存储容量已满时),内容将不会在子四边形之间分布。我这样做是为了提高一些性能。不过我觉得和上面的问题没有关系。
我猜,某处有一个无限循环,导致内存不足。如果我从根插入新对象,则没有问题。
我在异常发生的地方写了评论。
这里可以看到 QuadTree 类的重要部分:
public class QuadTree
{
BoundingBox boundary;
int capacity;
List<Worldobject> leafContent;
public QuadTree parent;
bool divided;
public List<QuadTree> childQuadTrees;
public QuadTree(BoundingBox _boundary,int _capacity,QuadTree _parent)
{
this.boundary = _boundary;
this.capacity = _capacity;
this.leafContent = new List<Worldobject>();
this.childQuadTrees = new List<QuadTree>();
this.divided = false;
this.parent = _parent;
}
// Subdividing the quad,if its storing capacity is full.
public void subdivide()
{
// north-East
this.childQuadTrees.Add(new QuadTree(new BoundingBox(new Vector3(boundary.Center.X,boundary.Min.Z),new Vector3(boundary.Max.X,boundary.Center.Z)),this.capacity,this));
// north-West
this.childQuadTrees.Add(new QuadTree(new BoundingBox(new Vector3(boundary.Min.X,new Vector3(boundary.Center.X,this));
// South-East
this.childQuadTrees.Add(new QuadTree(new BoundingBox(boundary.Center,boundary.Max),this));
// South-West
this.childQuadTrees.Add(new QuadTree(new BoundingBox(new Vector3(boundary.Min.X,boundary.Center.Z),boundary.Max.Z)),this));
this.divided = true;
}
public void insert(Worldobject wO)
{
// Checking,whether the quad contains the Box at all.
if (!this.ContainorOverlap(wO.BoundingBox))
{
return;
}
// If there is space,insert the Box.
if (this.leafContent.Count < this.capacity && this.divided == false)
{
/*This is the instruction,where System.OutOfMemoryException occures*/
this.leafContent.Add(wO); // <-------
return;
}
// If not,subdivide the quad then insert the obj to the subquads.
else
{
if (this.divided == false)
{
this.subdivide();
}
this.childQuadTrees[0].insert(wO);
this.childQuadTrees[1].insert(wO);
this.childQuadTrees[2].insert(wO);
this.childQuadTrees[3].insert(wO);
}
}
/* Here is the method to update the moving objects bounding volume.
It first removes the element from the tree,updates the boundingBox,then reinsert the object from the leaves*/
public void removeAndUpdate(Worldobject obj,Vector3 displacement)
{
if (!this.ContainorOverlap(obj.BoundingBox))
{
return;
}
if (this.divided)
{
this.childQuadTrees[0].removeAndUpdate(obj,displacement);
this.childQuadTrees[1].removeAndUpdate(obj,displacement);
this.childQuadTrees[2].removeAndUpdate(obj,displacement);
this.childQuadTrees[3].removeAndUpdate(obj,displacement);
}
/* if the obj is found,remove it,the try to reinsert it to its parent. If its parent does not contain it,move upwards in the hierarchy and try again to insert*/
if (leafContent.Contains(obj))
{
this.leafContent.Remove(obj);
QuadTree q = this.parent;
while (q.ContainorOverlap(obj.BoundingBox) == false)
{
q = q.parent;
}
obj.BoundingBox.Translate(displacement);
q.insert(obj);
}
}
public void query(BoundingBox range,List<Worldobject> resultList)
{
if (!this.ContainorOverlap(range))
{
return;
}
if (this.divided)
{
this.childQuadTrees[0].query(range,resultList);
this.childQuadTrees[1].query(range,resultList);
this.childQuadTrees[2].query(range,resultList);
this.childQuadTrees[3].query(range,resultList);
}
resultList.AddList(this.leafContent);
}
}
以下是异常中断时调试的一些信息:
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)