* Rex merge, environment/types

afrisby-3
Adam Frisby 2008-02-23 03:50:35 +00:00
parent f62f24bb70
commit ed9a866906
2 changed files with 439 additions and 428 deletions

View File

@ -1,269 +1,269 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System.Collections.Generic; using System.Collections.Generic;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.Environment.Types namespace OpenSim.Region.Environment.Types
{ {
public class BasicQuadTreeNode public class BasicQuadTreeNode
{ {
private List<SceneObjectGroup> m_objects = new List<SceneObjectGroup>(); private List<SceneObjectGroup> m_objects = new List<SceneObjectGroup>();
private BasicQuadTreeNode[] m_childNodes = null; private BasicQuadTreeNode[] m_childNodes = null;
private BasicQuadTreeNode m_parent = null; private BasicQuadTreeNode m_parent = null;
private short m_leftX; private short m_leftX;
private short m_leftY; private short m_leftY;
private short m_width; private short m_width;
private short m_height; private short m_height;
//private int m_quadNumber; //private int m_quadNumber;
private string m_quadID; private string m_quadID;
public BasicQuadTreeNode(BasicQuadTreeNode parent, string quadID, short leftX, short leftY, short width, public BasicQuadTreeNode(BasicQuadTreeNode parent, string quadID, short leftX, short leftY, short width,
short height) short height)
{ {
m_parent = parent; m_parent = parent;
m_quadID = quadID; m_quadID = quadID;
m_leftX = leftX; m_leftX = leftX;
m_leftY = leftY; m_leftY = leftY;
m_width = width; m_width = width;
m_height = height; m_height = height;
// Console.WriteLine("creating quadtree node " + m_quadID); // Console.WriteLine("creating quadtree node " + m_quadID);
} }
public void AddObject(SceneObjectGroup obj) public void AddObject(SceneObjectGroup obj)
{ {
if (m_childNodes == null) if (m_childNodes == null)
{ {
if (!m_objects.Contains(obj)) if (!m_objects.Contains(obj))
{ {
m_objects.Add(obj); m_objects.Add(obj);
} }
} }
else else
{ {
if (obj.AbsolutePosition.X < (m_leftX + (m_width/2))) if (obj.AbsolutePosition.X < (m_leftX + (m_width/2)))
{ {
if (obj.AbsolutePosition.Y < (m_leftY + (m_height/2))) if (obj.AbsolutePosition.Y < (m_leftY + (m_height/2)))
{ {
m_childNodes[0].AddObject(obj); m_childNodes[0].AddObject(obj);
} }
else else
{ {
m_childNodes[2].AddObject(obj); m_childNodes[2].AddObject(obj);
} }
} }
else else
{ {
if (obj.AbsolutePosition.Y < (m_leftY + (m_height/2))) if (obj.AbsolutePosition.Y < (m_leftY + (m_height/2)))
{ {
m_childNodes[1].AddObject(obj); m_childNodes[1].AddObject(obj);
} }
else else
{ {
m_childNodes[3].AddObject(obj); m_childNodes[3].AddObject(obj);
} }
} }
} }
} }
public void Subdivide() public void Subdivide()
{ {
if (m_childNodes == null) if (m_childNodes == null)
{ {
m_childNodes = new BasicQuadTreeNode[4]; m_childNodes = new BasicQuadTreeNode[4];
m_childNodes[0] = m_childNodes[0] =
new BasicQuadTreeNode(this, m_quadID + "1/", m_leftX, m_leftY, (short) (m_width/2), new BasicQuadTreeNode(this, m_quadID + "1/", m_leftX, m_leftY, (short) (m_width/2),
(short) (m_height/2)); (short) (m_height/2));
m_childNodes[1] = m_childNodes[1] =
new BasicQuadTreeNode(this, m_quadID + "2/", (short) (m_leftX + (m_width/2)), m_leftY, new BasicQuadTreeNode(this, m_quadID + "2/", (short) (m_leftX + (m_width/2)), m_leftY,
(short) (m_width/2), (short) (m_height/2)); (short) (m_width/2), (short) (m_height/2));
m_childNodes[2] = m_childNodes[2] =
new BasicQuadTreeNode(this, m_quadID + "3/", m_leftX, (short) (m_leftY + (m_height/2)), new BasicQuadTreeNode(this, m_quadID + "3/", m_leftX, (short) (m_leftY + (m_height/2)),
(short) (m_width/2), (short) (m_height/2)); (short) (m_width/2), (short) (m_height/2));
m_childNodes[3] = m_childNodes[3] =
new BasicQuadTreeNode(this, m_quadID + "4/", (short) (m_leftX + (m_width/2)), new BasicQuadTreeNode(this, m_quadID + "4/", (short) (m_leftX + (m_width/2)),
(short) (m_height + (m_height/2)), (short) (m_width/2), (short) (m_height/2)); (short) (m_height + (m_height/2)), (short) (m_width/2), (short) (m_height/2));
} }
else else
{ {
for (int i = 0; i < m_childNodes.Length; i++) for (int i = 0; i < m_childNodes.Length; i++)
{ {
m_childNodes[i].Subdivide(); m_childNodes[i].Subdivide();
} }
} }
} }
public List<SceneObjectGroup> GetObjectsFrom(float x, float y) public List<SceneObjectGroup> GetObjectsFrom(float x, float y)
{ {
if (m_childNodes == null) if (m_childNodes == null)
{ {
return new List<SceneObjectGroup>(m_objects); return new List<SceneObjectGroup>(m_objects);
} }
else else
{ {
if (x < m_leftX + (m_width/2)) if (x < m_leftX + (m_width/2))
{ {
if (y < m_leftY + (m_height/2)) if (y < m_leftY + (m_height/2))
{ {
return m_childNodes[0].GetObjectsFrom(x, y); return m_childNodes[0].GetObjectsFrom(x, y);
} }
else else
{ {
return m_childNodes[2].GetObjectsFrom(x, y); return m_childNodes[2].GetObjectsFrom(x, y);
} }
} }
else else
{ {
if (y < m_leftY + (m_height/2)) if (y < m_leftY + (m_height/2))
{ {
return m_childNodes[1].GetObjectsFrom(x, y); return m_childNodes[1].GetObjectsFrom(x, y);
} }
else else
{ {
return m_childNodes[3].GetObjectsFrom(x, y); return m_childNodes[3].GetObjectsFrom(x, y);
} }
} }
} }
} }
public List<SceneObjectGroup> GetObjectsFrom(string nodeName) public List<SceneObjectGroup> GetObjectsFrom(string nodeName)
{ {
if (nodeName == m_quadID) if (nodeName == m_quadID)
{ {
return new List<SceneObjectGroup>(m_objects); return new List<SceneObjectGroup>(m_objects);
} }
else if (m_childNodes != null) else if (m_childNodes != null)
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
List<SceneObjectGroup> retVal; List<SceneObjectGroup> retVal;
retVal = m_childNodes[i].GetObjectsFrom(nodeName); retVal = m_childNodes[i].GetObjectsFrom(nodeName);
if (retVal != null) if (retVal != null)
{ {
return retVal; return retVal;
} }
} }
} }
return null; return null;
} }
public string GetNodeID(float x, float y) public string GetNodeID(float x, float y)
{ {
if (m_childNodes == null) if (m_childNodes == null)
{ {
return m_quadID; return m_quadID;
} }
else else
{ {
if (x < m_leftX + (m_width/2)) if (x < m_leftX + (m_width/2))
{ {
if (y < m_leftY + (m_height/2)) if (y < m_leftY + (m_height/2))
{ {
return m_childNodes[0].GetNodeID(x, y); return m_childNodes[0].GetNodeID(x, y);
} }
else else
{ {
return m_childNodes[2].GetNodeID(x, y); return m_childNodes[2].GetNodeID(x, y);
} }
} }
else else
{ {
if (y < m_leftY + (m_height/2)) if (y < m_leftY + (m_height/2))
{ {
return m_childNodes[1].GetNodeID(x, y); return m_childNodes[1].GetNodeID(x, y);
} }
else else
{ {
return m_childNodes[3].GetNodeID(x, y); return m_childNodes[3].GetNodeID(x, y);
} }
} }
} }
} }
public void Update() public void Update()
{ {
if (m_childNodes != null) if (m_childNodes != null)
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
m_childNodes[i].Update(); m_childNodes[i].Update();
} }
} }
else else
{ {
List<SceneObjectGroup> outBounds = new List<SceneObjectGroup>(); List<SceneObjectGroup> outBounds = new List<SceneObjectGroup>();
foreach (SceneObjectGroup group in m_objects) foreach (SceneObjectGroup group in m_objects)
{ {
if (((group.AbsolutePosition.X > m_leftX) && (group.AbsolutePosition.X < (m_leftX + m_width))) && if (((group.AbsolutePosition.X > m_leftX) && (group.AbsolutePosition.X < (m_leftX + m_width))) &&
((group.AbsolutePosition.Y > m_leftY) && (group.AbsolutePosition.Y < (m_leftY + m_height)))) ((group.AbsolutePosition.Y > m_leftY) && (group.AbsolutePosition.Y < (m_leftY + m_height))))
{ {
//still in bounds //still in bounds
} }
else else
{ {
outBounds.Add(group); outBounds.Add(group);
} }
} }
foreach (SceneObjectGroup removee in outBounds) foreach (SceneObjectGroup removee in outBounds)
{ {
m_objects.Remove(removee); m_objects.Remove(removee);
if (m_parent != null) if (m_parent != null)
{ {
m_parent.PassUp(removee); m_parent.PassUp(removee);
} }
} }
outBounds.Clear(); outBounds.Clear();
} }
} }
public void PassUp(SceneObjectGroup group) public void PassUp(SceneObjectGroup group)
{ {
if (((group.AbsolutePosition.X > m_leftX) && (group.AbsolutePosition.X < (m_leftX + m_width))) && if (((group.AbsolutePosition.X > m_leftX) && (group.AbsolutePosition.X < (m_leftX + m_width))) &&
((group.AbsolutePosition.Y > m_leftY) && (group.AbsolutePosition.Y < (m_leftY + m_height)))) ((group.AbsolutePosition.Y > m_leftY) && (group.AbsolutePosition.Y < (m_leftY + m_height))))
{ {
AddObject(group); AddObject(group);
} }
else else
{ {
if (m_parent != null) if (m_parent != null)
{ {
m_parent.PassUp(group); m_parent.PassUp(group);
} }
} }
} }
public string[] GetNeighbours(string nodeName) public string[] GetNeighbours(string nodeName)
{ {
string[] retVal = new string[1]; string[] retVal = new string[1];
retVal[0] = ""; retVal[0] = System.String.Empty;
return retVal; return retVal;
} }
} }
} }

View File

@ -1,159 +1,170 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright * * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the * * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
using libsecondlife; using libsecondlife;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.Environment.Types namespace OpenSim.Region.Environment.Types
{ {
public class UpdateQueue public class UpdateQueue
{ {
class SceneObject class SceneObject
{ {
//The distance after to include object size as a priority factor //The distance after to include object size as a priority factor
static float m_maxSortDistance = 90 * 90; static float m_maxSortDistance = 90 * 90;
public SceneObjectPart m_part; public SceneObjectPart m_part;
public float m_priority; public float m_priority;
public SceneObject(SceneObjectPart part) public SceneObject(SceneObjectPart part)
{ {
m_part = part; m_part = part;
} }
public void DeterminePriority(LLVector3 pos) public void DeterminePriority(LLVector3 pos)
{ {
m_priority = LLVector3.MagSquared(pos - m_part.AbsolutePosition); m_priority = LLVector3.MagSquared(pos - m_part.AbsolutePosition);
m_priority -= LLVector3.MagSquared(m_part.Scale) * 12; m_priority -= LLVector3.MagSquared(m_part.Scale) * 12;
if (m_priority < 0) if (m_priority < 0)
{ {
m_priority = 0; m_priority = 0;
} }
else if (m_priority > m_maxSortDistance) else if (m_priority > m_maxSortDistance)
{ {
m_priority = m_maxSortDistance; m_priority = m_maxSortDistance;
} }
} }
} }
class SceneObjectComparer : IComparer<SceneObject> class SceneObjectComparer : IComparer<SceneObject>
{ {
int IComparer<SceneObject>.Compare(SceneObject a, SceneObject b) int IComparer<SceneObject>.Compare(SceneObject a, SceneObject b)
{ {
if (a.m_priority > b.m_priority) if (a.m_priority > b.m_priority)
return 1; return 1;
if (a.m_priority < b.m_priority) if (a.m_priority < b.m_priority)
return -1; return -1;
return 0; return 0;
} }
} }
private List<SceneObject> m_queue; private List<SceneObject> m_queue;
private Dictionary<LLUUID, LinkedListNode<SceneObjectPart>> m_ids; private Dictionary<LLUUID, LinkedListNode<SceneObjectPart>> m_ids;
float m_objectResortDistance = 15 * 15; float m_objectResortDistance = 15 * 15;
LLVector3 m_playerSpherePos = LLVector3.Zero; LLVector3 m_playerSpherePos = LLVector3.Zero;
DateTime m_forceRefreshTime; DateTime m_forceRefreshTime;
bool m_forceRefreshTimeSet = false; bool m_forceRefreshTimeSet = false;
public UpdateQueue() public UpdateQueue()
{ {
m_queue = new List<SceneObject>(); m_queue = new List<SceneObject>();
m_ids = new Dictionary<LLUUID, LinkedListNode<SceneObjectPart>>(); m_ids = new Dictionary<LLUUID, LinkedListNode<SceneObjectPart>>();
} }
public void Clear()
public bool HasUpdates() {
{ lock (m_ids)
if (m_queue.Count > 0) {
return true; m_ids.Clear();
}
return false; lock (m_queue)
} {
m_queue.Clear();
public void ObjectUpdated(SceneObjectPart part) }
{ }
lock (m_ids)
{ public bool HasUpdates()
if (!m_ids.ContainsKey(part.UUID)) {
{ if (m_queue.Count > 0)
m_queue.Add(new SceneObject(part)); return true;
m_ids[part.UUID] = null;
} return false;
else if (!m_forceRefreshTimeSet) }
{
m_forceRefreshTime = DateTime.Now; public void ObjectUpdated(SceneObjectPart part)
m_forceRefreshTime.AddSeconds(1); {
m_forceRefreshTimeSet = true; lock (m_ids)
} {
} if (!m_ids.ContainsKey(part.UUID))
} {
m_queue.Add(new SceneObject(part));
public void UpdateAvatarPosition(LLVector3 avatarPosition) m_ids[part.UUID] = null;
{ }
if (LLVector3.MagSquared(m_playerSpherePos - avatarPosition) > m_objectResortDistance) else if (!m_forceRefreshTimeSet)
{ {
m_playerSpherePos = avatarPosition; m_forceRefreshTime = DateTime.Now;
CollectNearestItems(); m_forceRefreshTime.AddSeconds(1);
} m_forceRefreshTimeSet = true;
else if (m_forceRefreshTimeSet && m_forceRefreshTime < DateTime.Now) }
{ }
m_playerSpherePos = avatarPosition; }
CollectNearestItems();
} public void UpdateAvatarPosition(LLVector3 avatarPosition)
} {
if (LLVector3.MagSquared(m_playerSpherePos - avatarPosition) > m_objectResortDistance)
public SceneObjectPart GetClosestUpdate() {
{ m_playerSpherePos = avatarPosition;
SceneObjectPart part = m_queue[0].m_part; CollectNearestItems();
}
lock (m_ids) else if (m_forceRefreshTimeSet && m_forceRefreshTime < DateTime.Now)
{ {
m_queue.RemoveAt(0); m_playerSpherePos = avatarPosition;
m_ids.Remove(part.UUID); CollectNearestItems();
} }
}
return part;
} public SceneObjectPart GetClosestUpdate()
{
protected void CollectNearestItems() SceneObjectPart part = m_queue[0].m_part;
{
m_queue.ForEach(delegate(SceneObject obj) { obj.DeterminePriority(m_playerSpherePos); }); lock (m_ids)
m_queue.Sort(new SceneObjectComparer()); {
m_queue.RemoveAt(0);
m_forceRefreshTimeSet = false; m_ids.Remove(part.UUID);
} }
}
} return part;
}
protected void CollectNearestItems()
{
m_queue.ForEach(delegate(SceneObject obj) { obj.DeterminePriority(m_playerSpherePos); });
m_queue.Sort(new SceneObjectComparer());
m_forceRefreshTimeSet = false;
}
}
}