add physics assistance on placement of a new object. This may help on mantis 7727, but may still need more work

avinationmerge
UbitUmarov 2015-09-24 06:46:07 +01:00
parent 5ca610d56a
commit af34bfddd1
2 changed files with 119 additions and 82 deletions

View File

@ -2300,23 +2300,62 @@ namespace OpenSim.Region.Framework.Scenes
{ {
pos = RayEnd; pos = RayEnd;
} }
else if (RayTargetID != UUID.Zero) else
{
Vector3 rayEnd = RayEnd;
Vector3 dir = rayEnd - RayStart;
float dist = Vector3.Mag(dir) + 2.0f;
Vector3 direction = dir * (1 / dist);
if (SupportsRayCastFiltered())
{
RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
rayfilter |= RayFilterFlags.land;
rayfilter |= RayFilterFlags.physical;
rayfilter |= RayFilterFlags.nonphysical;
rayfilter |= RayFilterFlags.LSLPhantom; // ubODE will only see volume detectors
// get some more contacts ???
int physcount = 4;
List<ContactResult> physresults =
(List<ContactResult>)RayCastFiltered(RayStart, direction, dist, physcount, rayfilter);
if (physresults != null && physresults.Count > 0)
{
if (physresults[0].ConsumerID == 0 || RayTargetID == UUID.Zero)
{
// found something
pos = physresults[0].Normal * scale ;
pos *= 0.5f;
pos = physresults[0].Pos +pos;
return pos;
}
foreach (ContactResult r in physresults)
{
SceneObjectPart part = GetSceneObjectPart(r.ConsumerID);
if (part == null)
continue;
if (part.UUID == RayTargetID)
{
pos = physresults[0].Normal * scale;
pos *= 0.5f;
pos = physresults[0].Pos + pos;
return pos;
}
}
}
}
if (RayTargetID != UUID.Zero)
{ {
SceneObjectPart target = GetSceneObjectPart(RayTargetID); SceneObjectPart target = GetSceneObjectPart(RayTargetID);
Vector3 direction = Vector3.Normalize(RayEnd - RayStart); Ray NewRay = new Ray(RayStart, direction);
Vector3 AXOrigin = RayStart;
Vector3 AXdirection = direction;
if (target != null) if (target != null)
{ {
pos = target.AbsolutePosition; 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_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
Ray NewRay = new Ray(AXOrigin, AXdirection);
// Ray Trace against target here // Ray Trace against target here
EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
@ -2349,7 +2388,7 @@ namespace OpenSim.Region.Framework.Scenes
else else
{ {
// We don't have a target here, so we're going to raytrace all the objects in the scene. // We don't have a target here, so we're going to raytrace all the objects in the scene.
EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(NewRay, true, false);
// Un-comment the following line to print the raytrace results to the console. // 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()); //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
@ -2365,6 +2404,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
} }
else else
{ {
// fall back to our stupid functionality // fall back to our stupid functionality
@ -2375,7 +2415,7 @@ namespace OpenSim.Region.Framework.Scenes
pos.Z += scale.Z / 2f; pos.Z += scale.Z / 2f;
// return pos; // return pos;
} }
}
// check against posible water intercept // check against posible water intercept
if (wpos.Z > pos.Z) pos = wpos; if (wpos.Z > pos.Z) pos = wpos;
return pos; return pos;

View File

@ -140,7 +140,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
} }
} }
CurrentRayFilter = req.filter; CurrentRayFilter = req.filter;
CurrentMaxCount = req.Count; CurrentMaxCount = req.Count;
@ -186,7 +185,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
d.GeomRaySetLength(ray, req.length); d.GeomRaySetLength(ray, req.length);
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
d.GeomRaySetParams(ray, 0, backfacecull); d.GeomRaySetParams(ray, 0, backfacecull);
d.GeomRaySetClosestHit(ray, closestHit);
if (req.callbackMethod is RaycastCallback) if (req.callbackMethod is RaycastCallback)
{ {
@ -318,9 +316,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
{ {
// current ode land to ray collisions is very bad // current ode land to ray collisions is very bad
// so for now limit its range badly // so for now limit its range badly
if (req.length > 60.0f)
if (req.length > 30.0f) d.GeomRaySetLength(ray, 60.0f);
d.GeomRaySetLength(ray, 30.0f);
d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback); d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
} }