aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorUbitUmarov2015-09-24 06:46:07 +0100
committerUbitUmarov2015-09-24 06:46:07 +0100
commitaf34bfddd18b5253d9c57dd9191329c159dbd45e (patch)
tree37996a525802f84a581dfb587ec3d99323a20724
parent bug fix, let ubODE see more than one mesh on cast ray (diff)
downloadopensim-SC-af34bfddd18b5253d9c57dd9191329c159dbd45e.zip
opensim-SC-af34bfddd18b5253d9c57dd9191329c159dbd45e.tar.gz
opensim-SC-af34bfddd18b5253d9c57dd9191329c159dbd45e.tar.bz2
opensim-SC-af34bfddd18b5253d9c57dd9191329c159dbd45e.tar.xz
add physics assistance on placement of a new object. This may help on mantis 7727, but may still need more work
-rwxr-xr-xOpenSim/Region/Framework/Scenes/Scene.cs162
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs9
2 files changed, 104 insertions, 67 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index cbaf803..fced0cc 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2283,99 +2283,139 @@ namespace OpenSim.Region.Framework.Scenes
2283 /// <returns></returns> 2283 /// <returns></returns>
2284 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) 2284 public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter)
2285 { 2285 {
2286 2286
2287 float wheight = (float)RegionInfo.RegionSettings.WaterHeight; 2287 float wheight = (float)RegionInfo.RegionSettings.WaterHeight;
2288 Vector3 wpos = Vector3.Zero; 2288 Vector3 wpos = Vector3.Zero;
2289 // Check for water surface intersection from above 2289 // Check for water surface intersection from above
2290 if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) ) 2290 if ((RayStart.Z > wheight) && (RayEnd.Z < wheight))
2291 { 2291 {
2292 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z); 2292 float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z);
2293 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X)); 2293 wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X));
2294 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y)); 2294 wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y));
2295 wpos.Z = wheight; 2295 wpos.Z = wheight;
2296 } 2296 }
2297 2297
2298 Vector3 pos = Vector3.Zero; 2298 Vector3 pos = Vector3.Zero;
2299 if (RayEndIsIntersection == (byte)1) 2299 if (RayEndIsIntersection == (byte)1)
2300 { 2300 {
2301 pos = RayEnd; 2301 pos = RayEnd;
2302 } 2302 }
2303 else if (RayTargetID != UUID.Zero) 2303 else
2304 { 2304 {
2305 SceneObjectPart target = GetSceneObjectPart(RayTargetID); 2305 Vector3 rayEnd = RayEnd;
2306
2307 Vector3 dir = rayEnd - RayStart;
2308 float dist = Vector3.Mag(dir) + 2.0f;
2306 2309
2307 Vector3 direction = Vector3.Normalize(RayEnd - RayStart); 2310 Vector3 direction = dir * (1 / dist);
2308 Vector3 AXOrigin = RayStart;
2309 Vector3 AXdirection = direction;
2310 2311
2311 if (target != null) 2312 if (SupportsRayCastFiltered())
2312 { 2313 {
2313 pos = target.AbsolutePosition; 2314 RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
2314 //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()); 2315 rayfilter |= RayFilterFlags.land;
2315 2316 rayfilter |= RayFilterFlags.physical;
2316 // TODO: Raytrace better here 2317 rayfilter |= RayFilterFlags.nonphysical;
2317 2318 rayfilter |= RayFilterFlags.LSLPhantom; // ubODE will only see volume detectors
2318 //EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection));
2319 Ray NewRay = new Ray(AXOrigin, AXdirection);
2320
2321 // Ray Trace against target here
2322 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
2323 2319
2324 // Un-comment out the following line to Get Raytrace results printed to the console. 2320 // get some more contacts ???
2325 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); 2321 int physcount = 4;
2326 float ScaleOffset = 0.5f;
2327 2322
2328 // If we hit something 2323 List<ContactResult> physresults =
2329 if (ei.HitTF) 2324 (List<ContactResult>)RayCastFiltered(RayStart, direction, dist, physcount, rayfilter);
2325 if (physresults != null && physresults.Count > 0)
2330 { 2326 {
2331 Vector3 scaleComponent = ei.AAfaceNormal; 2327 if (physresults[0].ConsumerID == 0 || RayTargetID == UUID.Zero)
2332 if (scaleComponent.X != 0) ScaleOffset = scale.X; 2328 {
2333 if (scaleComponent.Y != 0) ScaleOffset = scale.Y; 2329 // found something
2334 if (scaleComponent.Z != 0) ScaleOffset = scale.Z; 2330 pos = physresults[0].Normal * scale ;
2335 ScaleOffset = Math.Abs(ScaleOffset); 2331 pos *= 0.5f;
2336 Vector3 intersectionpoint = ei.ipoint; 2332 pos = physresults[0].Pos +pos;
2337 Vector3 normal = ei.normal; 2333 return pos;
2338 // Set the position to the intersection point 2334 }
2339 Vector3 offset = (normal * (ScaleOffset / 2f)); 2335 foreach (ContactResult r in physresults)
2340 pos = (intersectionpoint + offset); 2336 {
2341 2337 SceneObjectPart part = GetSceneObjectPart(r.ConsumerID);
2342 //Seems to make no sense to do this as this call is used for rezzing from inventory as well, and with inventory items their size is not always 0.5f 2338 if (part == null)
2343 //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method 2339 continue;
2344 // Un-offset the prim (it gets offset later by the consumer method) 2340 if (part.UUID == RayTargetID)
2345 //pos.Z -= 0.25F; 2341 {
2346 2342 pos = physresults[0].Normal * scale;
2343 pos *= 0.5f;
2344 pos = physresults[0].Pos + pos;
2345 return pos;
2346 }
2347 }
2347 } 2348 }
2348 } 2349 }
2349 else 2350 if (RayTargetID != UUID.Zero)
2350 { 2351 {
2351 // We don't have a target here, so we're going to raytrace all the objects in the scene. 2352 SceneObjectPart target = GetSceneObjectPart(RayTargetID);
2352 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false);
2353 2353
2354 // Un-comment the following line to print the raytrace results to the console. 2354 Ray NewRay = new Ray(RayStart, direction);
2355 //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
2356 2355
2357 if (ei.HitTF) 2356 if (target != null)
2358 { 2357 {
2359 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); 2358 pos = target.AbsolutePosition;
2360 } 2359
2360 // Ray Trace against target here
2361 EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter);
2362
2363 // Un-comment out the following line to Get Raytrace results printed to the console.
2364 // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
2365 float ScaleOffset = 0.5f;
2366
2367 // If we hit something
2368 if (ei.HitTF)
2369 {
2370 Vector3 scaleComponent = ei.AAfaceNormal;
2371 if (scaleComponent.X != 0) ScaleOffset = scale.X;
2372 if (scaleComponent.Y != 0) ScaleOffset = scale.Y;
2373 if (scaleComponent.Z != 0) ScaleOffset = scale.Z;
2374 ScaleOffset = Math.Abs(ScaleOffset);
2375 Vector3 intersectionpoint = ei.ipoint;
2376 Vector3 normal = ei.normal;
2377 // Set the position to the intersection point
2378 Vector3 offset = (normal * (ScaleOffset / 2f));
2379 pos = (intersectionpoint + offset);
2380
2381 //Seems to make no sense to do this as this call is used for rezzing from inventory as well, and with inventory items their size is not always 0.5f
2382 //And in cases when we weren't rezzing from inventory we were re-adding the 0.25 straight after calling this method
2383 // Un-offset the prim (it gets offset later by the consumer method)
2384 //pos.Z -= 0.25F;
2385
2386 }
2387 }
2361 else 2388 else
2362 { 2389 {
2363 // fall back to our stupid functionality 2390 // We don't have a target here, so we're going to raytrace all the objects in the scene.
2364 pos = RayEnd; 2391 EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(NewRay, true, false);
2392
2393 // Un-comment the following line to print the raytrace results to the console.
2394 //m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString());
2395
2396 if (ei.HitTF)
2397 {
2398 pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z);
2399 }
2400 else
2401 {
2402 // fall back to our stupid functionality
2403 pos = RayEnd;
2404 }
2365 } 2405 }
2366 } 2406 }
2367 }
2368 else
2369 {
2370 // fall back to our stupid functionality
2371 pos = RayEnd;
2372 2407
2373 //increase height so its above the ground. 2408 else
2374 //should be getting the normal of the ground at the rez point and using that? 2409 {
2375 pos.Z += scale.Z / 2f; 2410 // fall back to our stupid functionality
2376// return pos; 2411 pos = RayEnd;
2412
2413 //increase height so its above the ground.
2414 //should be getting the normal of the ground at the rez point and using that?
2415 pos.Z += scale.Z / 2f;
2416 // return pos;
2417 }
2377 } 2418 }
2378
2379 // check against posible water intercept 2419 // check against posible water intercept
2380 if (wpos.Z > pos.Z) pos = wpos; 2420 if (wpos.Z > pos.Z) pos = wpos;
2381 return pos; 2421 return pos;
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs b/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs
index ef1e57c..b82d593 100644
--- a/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs
@@ -139,8 +139,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
139 continue; 139 continue;
140 } 140 }
141 } 141 }
142 142
143
144 CurrentRayFilter = req.filter; 143 CurrentRayFilter = req.filter;
145 CurrentMaxCount = req.Count; 144 CurrentMaxCount = req.Count;
146 145
@@ -186,7 +185,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
186 d.GeomRaySetLength(ray, req.length); 185 d.GeomRaySetLength(ray, req.length);
187 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); 186 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
188 d.GeomRaySetParams(ray, 0, backfacecull); 187 d.GeomRaySetParams(ray, 0, backfacecull);
189 d.GeomRaySetClosestHit(ray, closestHit);
190 188
191 if (req.callbackMethod is RaycastCallback) 189 if (req.callbackMethod is RaycastCallback)
192 { 190 {
@@ -318,9 +316,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
318 { 316 {
319 // current ode land to ray collisions is very bad 317 // current ode land to ray collisions is very bad
320 // so for now limit its range badly 318 // so for now limit its range badly
321 319 if (req.length > 60.0f)
322 if (req.length > 30.0f) 320 d.GeomRaySetLength(ray, 60.0f);
323 d.GeomRaySetLength(ray, 30.0f);
324 321
325 d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback); 322 d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
326 } 323 }