changes on sog boundingbox and other cleanup

0.9.1.0-post-fixes
UbitUmarov 2019-01-25 20:52:46 +00:00
parent cb94991acb
commit 8048746759
2 changed files with 192 additions and 326 deletions

View File

@ -431,29 +431,47 @@ namespace OpenSim.Region.Framework.Scenes
{
get
{
Vector3 minScale = new Vector3(Constants.MaximumRegionSize, Constants.MaximumRegionSize, Constants.MaximumRegionSize);
Vector3 maxScale = Vector3.Zero;
Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
Vector3 finalScale = new Vector3();
SceneObjectPart[] parts = m_parts.GetArray();
SceneObjectPart part;
Vector3 partscale;
float ftmp;
float minScaleX = float.MaxValue;
float minScaleY = float.MaxValue;
float minScaleZ = float.MaxValue;
float maxScaleX = 0f;
float maxScaleY = 0f;
float maxScaleZ = 0f;
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
Vector3 partscale = part.Scale;
Vector3 partoffset = part.OffsetPosition;
part = parts[i];
partscale = part.Scale + part.OffsetPosition;
minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X;
minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y;
minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z;
ftmp = partscale.X;
if (ftmp < minScaleX)
minScaleX = ftmp;
if (ftmp > maxScaleX)
maxScaleX = ftmp;
maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
ftmp = partscale.Y;
if (ftmp < minScaleY)
minScaleY = ftmp;
if (ftmp > maxScaleY)
maxScaleY = ftmp;
ftmp = partscale.Z;
if (ftmp < minScaleZ)
minScaleZ = ftmp;
if (ftmp > maxScaleZ)
maxScaleZ = ftmp;
}
finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
finalScale.X = (minScaleX > maxScaleX) ? minScaleX : maxScaleX;
finalScale.Y = (minScaleY > maxScaleY) ? minScaleY : maxScaleY;
finalScale.Z = (minScaleZ > maxScaleZ) ? minScaleZ : maxScaleZ;
return finalScale;
}
@ -1507,13 +1525,80 @@ namespace OpenSim.Region.Framework.Scenes
return result;
}
/// <summary>
/// Gets a vector representing the size of the bounding box containing all the prims in the group
/// Treats all prims as rectangular, so no shape (cut etc) is taken into account
/// offsetHeight is the offset in the Z axis from the centre of the bounding box to the centre of the root prim
/// </summary>
/// <returns></returns>
public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
public void GetBoundingBox(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
{
uint rootid = RootPart.LocalId;
Vector3 scale = RootPart.Scale * 0.5f;
minX = -scale.X;
maxX = scale.X;
minY = -scale.Y;
maxY = scale.Y;
minZ = -scale.Z;
maxZ = scale.Z;
SceneObjectPart[] parts = m_parts.GetArray();
SceneObjectPart part;
for (int i = 0; i < parts.Length; ++i)
{
part = parts[i];
if(part.LocalId == rootid)
continue;
Vector3 offset = part.OffsetPosition;
scale = part.Scale * 0.5f;
Matrix4 m = Matrix4.CreateFromQuaternion(part.RotationOffset);
Vector3 a = m.AtAxis;
a.X = Math.Abs(a.X);
a.Y = Math.Abs(a.Y);
a.Z = Math.Abs(a.Z);
float tmpS = Vector3.Dot(a, scale);
float tmp = offset.X - tmpS;
if (tmp < minX)
minX = tmp;
tmp = offset.X + tmpS;
if (tmp > maxX)
maxX = tmp;
a = m.LeftAxis;
a.X = Math.Abs(a.X);
a.Y = Math.Abs(a.Y);
a.Z = Math.Abs(a.Z);
tmpS = Vector3.Dot(a, scale);
tmp = offset.Y - tmpS;
if (tmp < minY)
minY = tmp;
tmp = offset.Y + tmpS;
if (tmp > maxY)
maxY = tmp;
a = m.UpAxis;
a.X = Math.Abs(a.X);
a.Y = Math.Abs(a.Y);
a.Z = Math.Abs(a.Z);
tmpS = Vector3.Dot(a, scale);
tmp = offset.Z - tmpS;
if (tmp < minZ)
minZ = tmp;
tmp = offset.Z + tmpS;
if (tmp > maxZ)
maxZ = tmp;
}
}
/// <summary>
/// Gets a vector representing the size of the bounding box containing all the prims in the group
/// Treats all prims as rectangular, so no shape (cut etc) is taken into account
/// offsetHeight is the offset in the Z axis from the centre of the bounding box to the centre of the root prim
/// </summary>
/// <returns></returns>
public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
{
maxX = float.MinValue;
maxY = float.MinValue;
@ -1522,238 +1607,57 @@ namespace OpenSim.Region.Framework.Scenes
minY = float.MaxValue;
minZ = float.MaxValue;
Vector3 absPos = AbsolutePosition;
SceneObjectPart[] parts = m_parts.GetArray();
foreach (SceneObjectPart part in parts)
SceneObjectPart part;
for(int i = 0; i< parts.Length; ++i)
{
Vector3 worldPos = part.GetWorldPosition();
Vector3 offset = worldPos - AbsolutePosition;
Quaternion worldRot;
if (part.ParentID == 0)
{
worldRot = part.RotationOffset;
}
else
{
worldRot = part.GetWorldRotation();
}
part = parts[i];
Vector3 offset = part.GetWorldPosition() - absPos;
Vector3 scale = part.Scale * 0.5f;
Vector3 frontTopLeft;
Vector3 frontTopRight;
Vector3 frontBottomLeft;
Vector3 frontBottomRight;
Matrix4 m = Matrix4.CreateFromQuaternion(part.GetWorldRotation());
Vector3 a = m.AtAxis;
a.X = Math.Abs(a.X);
a.Y = Math.Abs(a.Y);
a.Z = Math.Abs(a.Z);
Vector3 backTopLeft;
Vector3 backTopRight;
Vector3 backBottomLeft;
Vector3 backBottomRight;
float tmpS = Vector3.Dot(a, scale);
float tmp = offset.X - tmpS;
if (tmp < minX)
minX = tmp;
// Vector3[] corners = new Vector3[8];
tmp = offset.X + tmpS;
if (tmp > maxX)
maxX = tmp;
Vector3 orig = Vector3.Zero;
a = m.LeftAxis;
a.X = Math.Abs(a.X);
a.Y = Math.Abs(a.Y);
a.Z = Math.Abs(a.Z);
tmpS = Vector3.Dot(a, scale);
frontTopLeft.X = orig.X - (part.Scale.X / 2);
frontTopLeft.Y = orig.Y - (part.Scale.Y / 2);
frontTopLeft.Z = orig.Z + (part.Scale.Z / 2);
tmp = offset.Y - tmpS;
if (tmp < minY)
minY = tmp;
frontTopRight.X = orig.X - (part.Scale.X / 2);
frontTopRight.Y = orig.Y + (part.Scale.Y / 2);
frontTopRight.Z = orig.Z + (part.Scale.Z / 2);
tmp = offset.Y + tmpS;
if (tmp > maxY)
maxY = tmp;
frontBottomLeft.X = orig.X - (part.Scale.X / 2);
frontBottomLeft.Y = orig.Y - (part.Scale.Y / 2);
frontBottomLeft.Z = orig.Z - (part.Scale.Z / 2);
a = m.UpAxis;
a.X = Math.Abs(a.X);
a.Y = Math.Abs(a.Y);
a.Z = Math.Abs(a.Z);
frontBottomRight.X = orig.X - (part.Scale.X / 2);
frontBottomRight.Y = orig.Y + (part.Scale.Y / 2);
frontBottomRight.Z = orig.Z - (part.Scale.Z / 2);
tmpS = Vector3.Dot(a, scale);
tmp = offset.Z - tmpS;
if (tmp < minZ)
minZ = tmp;
backTopLeft.X = orig.X + (part.Scale.X / 2);
backTopLeft.Y = orig.Y - (part.Scale.Y / 2);
backTopLeft.Z = orig.Z + (part.Scale.Z / 2);
backTopRight.X = orig.X + (part.Scale.X / 2);
backTopRight.Y = orig.Y + (part.Scale.Y / 2);
backTopRight.Z = orig.Z + (part.Scale.Z / 2);
backBottomLeft.X = orig.X + (part.Scale.X / 2);
backBottomLeft.Y = orig.Y - (part.Scale.Y / 2);
backBottomLeft.Z = orig.Z - (part.Scale.Z / 2);
backBottomRight.X = orig.X + (part.Scale.X / 2);
backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
//m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
//m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
//m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
//m_log.InfoFormat("pre corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z);
//m_log.InfoFormat("pre corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z);
//m_log.InfoFormat("pre corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z);
//m_log.InfoFormat("pre corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z);
//m_log.InfoFormat("pre corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z);
//for (int i = 0; i < 8; i++)
//{
// corners[i] = corners[i] * worldRot;
// corners[i] += offset;
// if (corners[i].X > maxX)
// maxX = corners[i].X;
// if (corners[i].X < minX)
// minX = corners[i].X;
// if (corners[i].Y > maxY)
// maxY = corners[i].Y;
// if (corners[i].Y < minY)
// minY = corners[i].Y;
// if (corners[i].Z > maxZ)
// maxZ = corners[i].Y;
// if (corners[i].Z < minZ)
// minZ = corners[i].Z;
//}
frontTopLeft = frontTopLeft * worldRot;
frontTopRight = frontTopRight * worldRot;
frontBottomLeft = frontBottomLeft * worldRot;
frontBottomRight = frontBottomRight * worldRot;
backBottomLeft = backBottomLeft * worldRot;
backBottomRight = backBottomRight * worldRot;
backTopLeft = backTopLeft * worldRot;
backTopRight = backTopRight * worldRot;
frontTopLeft += offset;
frontTopRight += offset;
frontBottomLeft += offset;
frontBottomRight += offset;
backBottomLeft += offset;
backBottomRight += offset;
backTopLeft += offset;
backTopRight += offset;
//m_log.InfoFormat("corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
//m_log.InfoFormat("corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
//m_log.InfoFormat("corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
//m_log.InfoFormat("corner 4 is {0} {1} {2}", frontBottomLeft.X, frontBottomLeft.Y, frontBottomLeft.Z);
//m_log.InfoFormat("corner 5 is {0} {1} {2}", backTopLeft.X, backTopLeft.Y, backTopLeft.Z);
//m_log.InfoFormat("corner 6 is {0} {1} {2}", backTopRight.X, backTopRight.Y, backTopRight.Z);
//m_log.InfoFormat("corner 7 is {0} {1} {2}", backBottomRight.X, backBottomRight.Y, backBottomRight.Z);
//m_log.InfoFormat("corner 8 is {0} {1} {2}", backBottomLeft.X, backBottomLeft.Y, backBottomLeft.Z);
if (frontTopRight.X > maxX)
maxX = frontTopRight.X;
if (frontTopLeft.X > maxX)
maxX = frontTopLeft.X;
if (frontBottomRight.X > maxX)
maxX = frontBottomRight.X;
if (frontBottomLeft.X > maxX)
maxX = frontBottomLeft.X;
if (backTopRight.X > maxX)
maxX = backTopRight.X;
if (backTopLeft.X > maxX)
maxX = backTopLeft.X;
if (backBottomRight.X > maxX)
maxX = backBottomRight.X;
if (backBottomLeft.X > maxX)
maxX = backBottomLeft.X;
if (frontTopRight.X < minX)
minX = frontTopRight.X;
if (frontTopLeft.X < minX)
minX = frontTopLeft.X;
if (frontBottomRight.X < minX)
minX = frontBottomRight.X;
if (frontBottomLeft.X < minX)
minX = frontBottomLeft.X;
if (backTopRight.X < minX)
minX = backTopRight.X;
if (backTopLeft.X < minX)
minX = backTopLeft.X;
if (backBottomRight.X < minX)
minX = backBottomRight.X;
if (backBottomLeft.X < minX)
minX = backBottomLeft.X;
//
if (frontTopRight.Y > maxY)
maxY = frontTopRight.Y;
if (frontTopLeft.Y > maxY)
maxY = frontTopLeft.Y;
if (frontBottomRight.Y > maxY)
maxY = frontBottomRight.Y;
if (frontBottomLeft.Y > maxY)
maxY = frontBottomLeft.Y;
if (backTopRight.Y > maxY)
maxY = backTopRight.Y;
if (backTopLeft.Y > maxY)
maxY = backTopLeft.Y;
if (backBottomRight.Y > maxY)
maxY = backBottomRight.Y;
if (backBottomLeft.Y > maxY)
maxY = backBottomLeft.Y;
if (frontTopRight.Y < minY)
minY = frontTopRight.Y;
if (frontTopLeft.Y < minY)
minY = frontTopLeft.Y;
if (frontBottomRight.Y < minY)
minY = frontBottomRight.Y;
if (frontBottomLeft.Y < minY)
minY = frontBottomLeft.Y;
if (backTopRight.Y < minY)
minY = backTopRight.Y;
if (backTopLeft.Y < minY)
minY = backTopLeft.Y;
if (backBottomRight.Y < minY)
minY = backBottomRight.Y;
if (backBottomLeft.Y < minY)
minY = backBottomLeft.Y;
//
if (frontTopRight.Z > maxZ)
maxZ = frontTopRight.Z;
if (frontTopLeft.Z > maxZ)
maxZ = frontTopLeft.Z;
if (frontBottomRight.Z > maxZ)
maxZ = frontBottomRight.Z;
if (frontBottomLeft.Z > maxZ)
maxZ = frontBottomLeft.Z;
if (backTopRight.Z > maxZ)
maxZ = backTopRight.Z;
if (backTopLeft.Z > maxZ)
maxZ = backTopLeft.Z;
if (backBottomRight.Z > maxZ)
maxZ = backBottomRight.Z;
if (backBottomLeft.Z > maxZ)
maxZ = backBottomLeft.Z;
if (frontTopRight.Z < minZ)
minZ = frontTopRight.Z;
if (frontTopLeft.Z < minZ)
minZ = frontTopLeft.Z;
if (frontBottomRight.Z < minZ)
minZ = frontBottomRight.Z;
if (frontBottomLeft.Z < minZ)
minZ = frontBottomLeft.Z;
if (backTopRight.Z < minZ)
minZ = backTopRight.Z;
if (backTopLeft.Z < minZ)
minZ = backTopLeft.Z;
if (backBottomRight.Z < minZ)
minZ = backBottomRight.Z;
if (backBottomLeft.Z < minZ)
minZ = backBottomLeft.Z;
tmp = offset.Z + tmpS;
if (tmp > maxZ)
maxZ = tmp;
}
}
@ -1795,12 +1699,26 @@ namespace OpenSim.Region.Framework.Scenes
}
private Vector3 m_boundsCenter;
public Vector3 getBoundsCenter()
private Vector3 m_LastCenterOffset;
private Vector3 last_boundsRot = new Vector3(-10, -10, -10);
public Vector3 getCenterOffset()
{
// math is done in GetBoundsRadius();
if(m_boundsRadius == null)
GetBoundsRadius();
return m_boundsCenter;
Quaternion rot = m_rootPart.RotationOffset;
if (last_boundsRot.X != rot.X ||
last_boundsRot.Y != rot.Y ||
last_boundsRot.Z != rot.Z)
{
m_LastCenterOffset = m_boundsCenter * rot;
last_boundsRot.X = rot.X;
last_boundsRot.Y = rot.Y;
last_boundsRot.Z = rot.Z;
}
return m_rootPart.GroupPosition + m_LastCenterOffset;
}
private float m_areaFactor;
@ -1819,14 +1737,10 @@ namespace OpenSim.Region.Framework.Scenes
{
float res = 0;
float areaF = 0;
SceneObjectPart p;
SceneObjectPart[] parts;
float partR;
Vector3 offset = Vector3.Zero;
lock (m_parts)
{
parts = m_parts.GetArray();
}
SceneObjectPart p;
SceneObjectPart[] parts = m_parts.GetArray();
int nparts = parts.Length;
for (int i = 0; i < nparts; i++)
@ -1846,11 +1760,10 @@ namespace OpenSim.Region.Framework.Scenes
if(parts.Length > 1)
{
offset /= parts.Length; // basicly geometric center
offset = offset * RootPart.RotationOffset;
}
areaF = 10.0f / areaF; // scale it
areaF = Util.Clamp(areaF, 0.001f, 1000f); // clamp it
areaF = 0.5f / areaF; // scale it
areaF = Util.Clamp(areaF, 0.05f, 100f); // clamp it
m_areaFactor = (float)Math.Sqrt(areaF);
m_boundsCenter = offset;
@ -1872,16 +1785,9 @@ namespace OpenSim.Region.Framework.Scenes
bool ComplexCost = false;
SceneObjectPart p;
SceneObjectPart[] parts;
lock (m_parts)
{
parts = m_parts.GetArray();
}
SceneObjectPart[] parts = m_parts.GetArray();
int nparts = parts.Length;
for (int i = 0; i < nparts; i++)
{
p = parts[i];
@ -2478,7 +2384,6 @@ namespace OpenSim.Region.Framework.Scenes
backup_group.RootPart.Velocity = RootPart.Velocity;
backup_group.RootPart.Acceleration = RootPart.Acceleration;
backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity;
backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem;
HasGroupChanged = false;
GroupContainsForeignPrims = false;
@ -2588,30 +2493,10 @@ namespace OpenSim.Region.Framework.Scenes
{
newPart = dupe.m_rootPart;
}
/*
bool isphys = ((newPart.Flags & PrimFlags.Physics) != 0);
bool isphan = ((newPart.Flags & PrimFlags.Phantom) != 0);
// Need to duplicate the physics actor as well
if (userExposed && (isphys || !isphan || newPart.VolumeDetectActive))
{
PrimitiveBaseShape pbs = newPart.Shape;
newPart.PhysActor
= m_scene.PhysicsScene.AddPrimShape(
string.Format("{0}/{1}", newPart.Name, newPart.UUID),
pbs,
newPart.AbsolutePosition,
newPart.Scale,
newPart.GetWorldRotation(),
isphys,
isphan,
newPart.LocalId);
newPart.DoPhysicsPropertyUpdate(isphys, true);
*/
if (userExposed)
newPart.ApplyPhysics((uint)newPart.Flags,newPart.VolumeDetectActive,true);
// }
// copy keyframemotion
if (part.KeyframeMotion != null)
newPart.KeyframeMotion = part.KeyframeMotion.Copy(dupe);
@ -2619,8 +2504,6 @@ namespace OpenSim.Region.Framework.Scenes
if (userExposed)
{
// done above dupe.UpdateParentIDs();
if (dupe.m_rootPart.PhysActor != null)
dupe.m_rootPart.PhysActor.Building = false; // tell physics to finish building
@ -4015,7 +3898,7 @@ namespace OpenSim.Region.Framework.Scenes
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].LocalId != m_rootPart.LocalId)
if (parts[i].UUID != m_rootPart.UUID)
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
}

View File

@ -11240,50 +11240,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
part = World.GetSceneObjectPart(objID);
// Currently only works for single prims without a sitting avatar
if (part != null)
if (part == null)
{
float minX;
float maxX;
float minY;
float maxY;
float minZ;
float maxZ;
// This BBox is in sim coordinates, with the offset being
// a contained point.
Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
minX -= offsets[0].X;
maxX -= offsets[0].X;
minY -= offsets[0].Y;
maxY -= offsets[0].Y;
minZ -= offsets[0].Z;
maxZ -= offsets[0].Z;
LSL_Vector lower;
LSL_Vector upper;
// Adjust to the documented error offsets (see LSL Wiki)
lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
if (lower.x > upper.x)
lower.x = upper.x;
if (lower.y > upper.y)
lower.y = upper.y;
if (lower.z > upper.z)
lower.z = upper.z;
result.Add(lower);
result.Add(upper);
result.Add(new LSL_Vector());
result.Add(new LSL_Vector());
return result;
}
// Not found so return empty values
result.Add(new LSL_Vector());
result.Add(new LSL_Vector());
SceneObjectGroup sog = part.ParentGroup;
if(sog.IsDeleted)
{
result.Add(new LSL_Vector());
result.Add(new LSL_Vector());
return result;
}
float minX;
float maxX;
float minY;
float maxY;
float minZ;
float maxZ;
sog.GetBoundingBox(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
result.Add(new LSL_Vector(minX, minY, minZ));
result.Add(new LSL_Vector(maxX, maxY, maxZ));
return result;
}