From 56b4f5a2ea582d347c69ce30405e078270090dfa Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Thu, 1 May 2008 15:17:49 +0000 Subject: * committing what I've got so far for DuplicateOnRay so I don't fight the conflict monster later. Not done yet, doesn't crash the server. --- OpenSim/Region/Environment/Scenes/InnerScene.cs | 4 +- .../Region/Environment/Scenes/Scene.Inventory.cs | 4 +- OpenSim/Region/Environment/Scenes/Scene.cs | 96 ++++++++++++++++++++-- .../Region/Environment/Scenes/SceneObjectGroup.cs | 4 +- .../Region/Environment/Scenes/SceneObjectPart.cs | 23 ++++-- 5 files changed, 114 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region/Environment/Scenes') diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 5434a88..da286ad 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, bool frontFacesOnly) + public EntityIntersection GetClosestIntersectingPrim(Ray hray, bool frontFacesOnly, bool faceCenters) { // 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, frontFacesOnly); + EntityIntersection result = reportingG.TestIntersection(hray, frontFacesOnly, faceCenters); 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 7866b32..6bd5d1a 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1240,7 +1240,7 @@ namespace OpenSim.Region.Environment.Scenes LLVector3 pos = GetNewRezLocation( RayStart, RayEnd, RayTargetID, new LLQuaternion(0, 0, 0, 1), - BypassRayCast, bRayEndIsIntersection,true,scale); + BypassRayCast, bRayEndIsIntersection,true,scale, false); if (!PermissionsMngr.CanRezObject(remoteClient.AgentId, pos) && !attachment) { @@ -1271,7 +1271,7 @@ namespace OpenSim.Region.Environment.Scenes { pos = GetNewRezLocation( RayStart, RayEnd, RayTargetID, new LLQuaternion(0, 0, 0, 1), - BypassRayCast, bRayEndIsIntersection, true, group.GroupScale()); + BypassRayCast, bRayEndIsIntersection, true, group.GroupScale(), false); group.AbsolutePosition = pos; } else diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 30e3815..60d6293 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1169,7 +1169,7 @@ namespace OpenSim.Region.Environment.Scenes return myID; } - public LLVector3 GetNewRezLocation(LLVector3 RayStart, LLVector3 RayEnd, LLUUID RayTargetID, LLQuaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, LLVector3 scale) + public LLVector3 GetNewRezLocation(LLVector3 RayStart, LLVector3 RayEnd, LLUUID RayTargetID, LLQuaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, LLVector3 scale, bool FaceCenter) { LLVector3 pos = LLVector3.Zero; if (RayEndIsIntersection == (byte)1) @@ -1196,7 +1196,7 @@ 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), frontFacesOnly); + EntityIntersection ei = target.TestIntersectionOBB(NewRay, new Quaternion(1,0,0,0), frontFacesOnly, FaceCenter); // 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()); @@ -1228,7 +1228,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), true); + EntityIntersection ei = m_innerScene.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); // 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()); @@ -1254,7 +1254,7 @@ namespace OpenSim.Region.Environment.Scenes byte RayEndIsIntersection) { - LLVector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new LLVector3(0.5f,0.5f,0.5f)); + LLVector3 pos = GetNewRezLocation(RayStart, RayEnd, RayTargetID, rot, bypassRaycast, RayEndIsIntersection, true, new LLVector3(0.5f,0.5f,0.5f), false); if (PermissionsMngr.CanRezObject(ownerID, pos)) { @@ -1560,6 +1560,7 @@ namespace OpenSim.Region.Environment.Scenes client.OnLinkObjects += m_innerScene.LinkObjects; client.OnDelinkObjects += m_innerScene.DelinkObjects; client.OnObjectDuplicate += m_innerScene.DuplicateObject; + client.OnObjectDuplicateOnRay += doObjectDuplicateOnRay; client.OnUpdatePrimFlags += m_innerScene.UpdatePrimFlags; client.OnRequestObjectPropertiesFamily += m_innerScene.RequestObjectPropertiesFamily; client.OnParcelPropertiesRequest += new ParcelPropertiesRequest(LandChannel.handleParcelPropertiesRequest); @@ -1632,7 +1633,92 @@ namespace OpenSim.Region.Environment.Scenes } - + public void doObjectDuplicateOnRay(uint localID, uint dupeFlags, LLUUID AgentID, LLUUID GroupID, + LLUUID RayTargetObj, LLVector3 RayEnd, LLVector3 RayStart, + bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates) + { + + LLVector3 pos = LLVector3.Zero; + bool frontFacesOnly = true; + + SceneObjectPart target = GetSceneObjectPart(localID); + + if (target != null) + { + + LLVector3 direction = LLVector3.Norm(RayEnd - RayStart); + Vector3 AXOrigin = new Vector3(RayStart.X, RayStart.Y, RayStart.Z); + Vector3 AXdirection = new Vector3(direction.X, direction.Y, direction.Z); + + + if (target != null) + { + if (target.ParentGroup != null) + { + pos = target.AbsolutePosition; + //m_log.Info("[OBJECT_REZ]: TargetPos: " + pos.ToString() + ", RayStart: " + RayStart.ToString() + ", RayEnd: " + RayEnd.ToString() + ", Volume: " + Util.GetDistanceTo(RayStart,RayEnd).ToString() + ", mag1: " + Util.GetMagnitude(RayStart).ToString() + ", mag2: " + Util.GetMagnitude(RayEnd).ToString()); + + // TODO: Raytrace better here + + //EntityIntersection ei = m_innerScene.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection)); + Ray NewRay = new Ray(AXOrigin, AXdirection); + + // Ray Trace against target here + EntityIntersection ei = target.TestIntersectionOBB(NewRay, new Quaternion(1, 0, 0, 0), frontFacesOnly, false); + + // 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 scale = target.Scale; + 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); + + + + if (CopyCenters) + { + // now we cast a ray from inside the prim(absolute position) to one of it's faces along the face normal. + LLVector3 direction2 = LLVector3.Norm(pos - target.AbsolutePosition); + Vector3 AXOrigin2 = new Vector3(target.AbsolutePosition.X, target.AbsolutePosition.Y, target.AbsolutePosition.Z); + Vector3 AXdirection2 = ei.AAfaceNormal; + Ray NewRay2 = new Ray(AXOrigin2, AXdirection2); + EntityIntersection ei2 = target.TestIntersectionOBB(NewRay2, new Quaternion(1, 0, 0, 0), false, CopyCenters); + if (ei2.HitTF) + { + //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei2.HitTF.ToString() + " Point: " + ei2.ipoint.ToString() + " Normal: " + ei2.normal.ToString()); + pos = new LLVector3(ei2.ipoint.x,ei2.ipoint.y,ei2.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 * (ScaleOffset / 2f)); + pos = (intersectionpoint + offset); + + // stick in offset format from the original prim + pos = pos - target.ParentGroup.AbsolutePosition; + m_innerScene.DuplicateObject(target.ParentGroup.LocalId, pos, target.GetEffectiveObjectFlags(), AgentID, GroupID); + } + + + return; + } + return; + } + + } + + + + + } public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, LLVector3 lookAt, uint flags) { UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(remoteClient.AgentId); diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index e53cfaa..5d39790 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -543,7 +543,7 @@ namespace OpenSim.Region.Environment.Scenes return finalScale; } - public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly) + public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) { // 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 @@ -565,7 +565,7 @@ namespace OpenSim.Region.Environment.Scenes // Telling the prim to raytrace. //EntityIntersection inter = part.TestIntersection(hRay, parentrotation); - EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation,frontFacesOnly); + EntityIntersection inter = part.TestIntersectionOBB(hRay, parentrotation,frontFacesOnly, faceCenters); // 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 18cae48..3dbd809 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -1060,7 +1060,7 @@ namespace OpenSim.Region.Environment.Scenes return Math.Sqrt(dx * dx + dy * dy + dz * dz); } - public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool FrontFacesOnly) + public EntityIntersection TestIntersectionOBB(Ray iray, Quaternion parentrot, bool frontFacesOnly, bool faceCenters) { // 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. @@ -1339,14 +1339,25 @@ namespace OpenSim.Region.Environment.Scenes continue; // If the normal is pointing outside the object - if (iray.Direction.Dot(normals[i]) < 0 || !FrontFacesOnly) + if (iray.Direction.Dot(normals[i]) < 0 || !frontFacesOnly) { - - q = iray.Origin + a * iray.Direction; - // Is this the closest hit to the object's origin? - //float distance2 = (float)GetDistanceTo(q, iray.Origin); + if (faceCenters) + { + q = AXpos + a * AAfacenormals[i]; //(FaceA[i] + FaceB[i] + FaceC[1] + FaceD[i]) / 4f; + } + else + { + q = iray.Origin + a * iray.Direction; + } + float distance2 = (float)GetDistanceTo(q, AXpos); + // Is this the closest hit to the object's origin? + if (faceCenters) + { + distance2 = (float)GetDistanceTo(q, iray.Origin); + } + if (distance2 < returnresult.distance) { -- cgit v1.1