From 1c697ef0d206445c6819e338626169fc6ef56432 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Thu, 1 May 2008 06:31:12 +0000 Subject: * You can now rez objects out of inventory at the correct offset from prim you rez it on. Including multi prim groups and prim that have different X/Y/Z scales. --- OpenSim/Region/Environment/Scenes/EntityBase.cs | 2 ++ OpenSim/Region/Environment/Scenes/InnerScene.cs | 4 +-- .../Region/Environment/Scenes/Scene.Inventory.cs | 15 ++++++++--- OpenSim/Region/Environment/Scenes/Scene.cs | 19 ++++++++----- .../Region/Environment/Scenes/SceneObjectGroup.cs | 31 ++++++++++++++++++++-- .../Region/Environment/Scenes/SceneObjectPart.cs | 13 +++++++-- 6 files changed, 69 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Environment/Scenes/EntityBase.cs b/OpenSim/Region/Environment/Scenes/EntityBase.cs index 1faba9a..11bafb7 100644 --- a/OpenSim/Region/Environment/Scenes/EntityBase.cs +++ b/OpenSim/Region/Environment/Scenes/EntityBase.cs @@ -222,6 +222,8 @@ namespace OpenSim.Region.Environment.Scenes { public Vector3 ipoint = new Vector3(0, 0, 0); public Vector3 normal = new Vector3(0, 0, 0); + public Vector3 AAfaceNormal = new Vector3(0, 0, 0); + public int face = -1; public bool HitTF = false; public SceneObjectPart obj; public float distance = 0; diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 8a48f6e..5434a88 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -853,7 +853,7 @@ namespace OpenSim.Region.Environment.Scenes return null; } - public EntityIntersection GetClosestIntersectingPrim(Ray hray) + public EntityIntersection GetClosestIntersectingPrim(Ray hray, bool frontFacesOnly) { // Primitive Ray Tracing float closestDistance = 280f; @@ -863,7 +863,7 @@ namespace OpenSim.Region.Environment.Scenes if (ent is SceneObjectGroup) { SceneObjectGroup reportingG = (SceneObjectGroup)ent; - EntityIntersection result = reportingG.TestIntersection(hray); + EntityIntersection result = reportingG.TestIntersection(hray, frontFacesOnly); if (result.HitTF) { if (result.distance < closestDistance) diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index 7e1b89f..7866b32 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1235,10 +1235,12 @@ namespace OpenSim.Region.Environment.Scenes bRayEndIsIntersection = (byte)0; } - LLVector3 pos - = GetNewRezLocation( + LLVector3 scale = new LLVector3(0.5f, 0.5f, 0.5f); + + + LLVector3 pos = GetNewRezLocation( RayStart, RayEnd, RayTargetID, new LLQuaternion(0, 0, 0, 1), - BypassRayCast, bRayEndIsIntersection); + BypassRayCast, bRayEndIsIntersection,true,scale); if (!PermissionsMngr.CanRezObject(remoteClient.AgentId, pos) && !attachment) { @@ -1266,9 +1268,16 @@ namespace OpenSim.Region.Environment.Scenes // if attachment we set it's asset id so object updates can reflect that // if not, we set it's position in world. if (!attachment) + { + pos = GetNewRezLocation( + RayStart, RayEnd, RayTargetID, new LLQuaternion(0, 0, 0, 1), + BypassRayCast, bRayEndIsIntersection, true, group.GroupScale()); group.AbsolutePosition = pos; + } else + { group.SetFromAssetID(itemID); + } SceneObjectPart rootPart = group.GetChildPart(group.UUID); diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index b5ead2a..203f6d3 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1172,7 +1172,7 @@ namespace OpenSim.Region.Environment.Scenes return myID; } - public LLVector3 GetNewRezLocation(LLVector3 RayStart, LLVector3 RayEnd, LLUUID RayTargetID, LLQuaternion rot, byte bypassRayCast, byte RayEndIsIntersection) + public LLVector3 GetNewRezLocation(LLVector3 RayStart, LLVector3 RayEnd, LLUUID RayTargetID, LLQuaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, LLVector3 scale) { LLVector3 pos = LLVector3.Zero; if (RayEndIsIntersection == (byte)1) @@ -1199,18 +1199,24 @@ namespace OpenSim.Region.Environment.Scenes Ray NewRay = new Ray(AXOrigin, AXdirection); // Ray Trace against target here - EntityIntersection ei = target.TestIntersectionOBB(NewRay, new Quaternion(1,0,0,0)); + EntityIntersection ei = target.TestIntersectionOBB(NewRay, new Quaternion(1,0,0,0), frontFacesOnly); // Un-comment out the following line to Get Raytrace results printed to the console. // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); - + float ScaleOffset = 0.5f; + // If we hit something if (ei.HitTF) { + LLVector3 scaleComponent = new LLVector3(ei.AAfaceNormal.x, ei.AAfaceNormal.y, ei.AAfaceNormal.z); + if (scaleComponent.X != 0) ScaleOffset = scale.X; + if (scaleComponent.Y != 0) ScaleOffset = scale.Y; + if (scaleComponent.Z != 0) ScaleOffset = scale.Z; + ScaleOffset = Math.Abs(ScaleOffset); LLVector3 intersectionpoint = new LLVector3(ei.ipoint.x, ei.ipoint.y, ei.ipoint.z); LLVector3 normal = new LLVector3(ei.normal.x, ei.normal.y, ei.normal.z); // Set the position to the intersection point - LLVector3 offset = (normal * (0.5f / 2f)); + LLVector3 offset = (normal * (ScaleOffset / 2f)); pos = (intersectionpoint + offset); // Un-offset the prim (it gets offset later by the consumer method) @@ -1225,7 +1231,7 @@ namespace OpenSim.Region.Environment.Scenes { // We don't have a target here, so we're going to raytrace all the objects in the scene. - EntityIntersection ei = m_innerScene.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); + EntityIntersection ei = m_innerScene.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true); // Un-comment the following line to print the raytrace results to the console. //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); @@ -1250,7 +1256,8 @@ namespace OpenSim.Region.Environment.Scenes byte bypassRaycast, LLVector3 RayStart, LLUUID RayTargetID, byte RayEndIsIntersection) { - LLVector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection); + + LLVector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new LLVector3(0.5f,0.5f,0.5f)); if (PermissionsMngr.CanRezObject(ownerID, pos)) { diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 863146c..5164d30 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -516,8 +516,35 @@ namespace OpenSim.Region.Environment.Scenes m_scene.EventManager.OnBackup += ProcessBackup; } } + public LLVector3 GroupScale() + { + LLVector3 minScale = new LLVector3(Constants.RegionSize,Constants.RegionSize,Constants.RegionSize); + LLVector3 maxScale = new LLVector3(0f,0f,0f); + LLVector3 finalScale = new LLVector3(0.5f, 0.5f, 0.5f); + + lock (m_parts) + { + foreach (SceneObjectPart part in m_parts.Values) + { + LLVector3 partscale = part.Scale; + LLVector3 partoffset = part.OffsetPosition; - public EntityIntersection TestIntersection(Ray hRay) + minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; + minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.X + partoffset.Y : minScale.Y; + minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.X + partoffset.Z : minScale.Z; + + 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; + } + } + 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; + return finalScale; + + } + public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly) { // We got a request from the inner_scene to raytrace along the Ray hRay // We're going to check all of the prim in this group for intersection with the ray @@ -539,7 +566,7 @@ namespace OpenSim.Region.Environment.Scenes // Telling the prim to raytrace. //EntityIntersection inter = part.TestIntersection(hRay, parentrotation); - EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation); + EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation,frontFacesOnly); // This may need to be updated to the maximum draw distance possible.. // We might (and probably will) be checking for prim creation from other sims diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 8d05987..5f91176 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -1061,7 +1061,7 @@ namespace OpenSim.Region.Environment.Scenes return Math.Sqrt(dx * dx + dy * dy + dz * dz); } - public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot) + public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool FrontFacesOnly) { // In this case we're using a rectangular prism, which has 6 faces and therefore 6 planes // This breaks down into the ray---> plane equation. @@ -1075,6 +1075,14 @@ namespace OpenSim.Region.Environment.Scenes Vector3[] FaceD = new Vector3[6]; // vertex D for Facei Vector3[] normals = new Vector3[6]; // Normal for Facei + Vector3[] AAfacenormals = new Vector3[6]; // Axis Aligned face normals + + AAfacenormals[0] = new Vector3(1, 0, 0); + AAfacenormals[1] = new Vector3(0, 1, 0); + AAfacenormals[2] = new Vector3(-1, 0, 0); + AAfacenormals[3] = new Vector3(0, -1, 0); + AAfacenormals[4] = new Vector3(0, 0, 1); + AAfacenormals[5] = new Vector3(0, 0, -1); Vector3 AmBa = new Vector3(0, 0, 0); // Vertex A - Vertex B Vector3 AmBb = new Vector3(0, 0, 0); // Vertex B - Vertex C @@ -1332,7 +1340,7 @@ namespace OpenSim.Region.Environment.Scenes continue; // If the normal is pointing outside the object - if (iray.Direction.Dot(normals[i]) < 0) + if (iray.Direction.Dot(normals[i]) < 0 || !FrontFacesOnly) { q = iray.Origin + a * iray.Direction; @@ -1349,6 +1357,7 @@ namespace OpenSim.Region.Environment.Scenes //m_log.Info("[FACE]:" + i.ToString()); //m_log.Info("[POINT]: " + q.ToString()); returnresult.normal = normals[i]; + returnresult.AAfaceNormal = AAfacenormals[i]; } } -- cgit v1.1