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,6 +1525,73 @@ namespace OpenSim.Region.Framework.Scenes
return result;
}
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
@ -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)
{
result.Add(new LSL_Vector());
result.Add(new LSL_Vector());
return result;
}
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);
// 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);
return result;
}
// Not found so return empty values
result.Add(new LSL_Vector());
result.Add(new LSL_Vector());
result.Add(new LSL_Vector(minX, minY, minZ));
result.Add(new LSL_Vector(maxX, maxY, maxZ));
return result;
}