aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorTeravus Ovares (Dan Olivares)2009-08-20 23:26:40 -0400
committerTeravus Ovares (Dan Olivares)2009-08-20 23:26:40 -0400
commit64dcb71c1430f4b97f4e8af944662c182bc1ef64 (patch)
treefc5e28216286c70617fa24a0c2b5ae3862ca069f /OpenSim
parent* Adds PhysicsCombiner Module (diff)
downloadopensim-SC-64dcb71c1430f4b97f4e8af944662c182bc1ef64.zip
opensim-SC-64dcb71c1430f4b97f4e8af944662c182bc1ef64.tar.gz
opensim-SC-64dcb71c1430f4b97f4e8af944662c182bc1ef64.tar.bz2
opensim-SC-64dcb71c1430f4b97f4e8af944662c182bc1ef64.tar.xz
* Fixes Terrain issues with combined regions.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs13
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs198
2 files changed, 137 insertions, 74 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
index c4cb250..d9f4951 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -232,17 +232,12 @@ namespace OpenSim.Region.Physics.OdePlugin
232 */ 232 */
233 233
234 // Exclude heightfield geom 234 // Exclude heightfield geom
235 if (g1 == m_scene.LandGeom) 235
236 return; 236 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
237 if (g2 == m_scene.LandGeom)
238 return;
239 if (g1 == m_scene.WaterGeom)
240 return; 237 return;
241 if (g2 == m_scene.WaterGeom) 238 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
242 return; 239 return;
243 240
244
245
246 // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. 241 // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
247 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) 242 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
248 { 243 {
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index f97b49b..de9b196 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -232,8 +232,6 @@ namespace OpenSim.Region.Physics.OdePlugin
232 private float[] _watermap; 232 private float[] _watermap;
233 private bool m_filterCollisions = true; 233 private bool m_filterCollisions = true;
234 234
235 private float[] _origheightmap; // Used for Fly height. Kitto Flora
236
237 private d.NearCallback nearCallback; 235 private d.NearCallback nearCallback;
238 public d.TriCallback triCallback; 236 public d.TriCallback triCallback;
239 public d.TriArrayCallback triArrayCallback; 237 public d.TriArrayCallback triArrayCallback;
@@ -257,6 +255,8 @@ namespace OpenSim.Region.Physics.OdePlugin
257 private Object externalJointRequestsLock = new Object(); 255 private Object externalJointRequestsLock = new Object();
258 private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>(); 256 private readonly Dictionary<String, PhysicsJoint> SOPName_to_activeJoint = new Dictionary<String, PhysicsJoint>();
259 private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>(); 257 private readonly Dictionary<String, PhysicsJoint> SOPName_to_pendingJoint = new Dictionary<String, PhysicsJoint>();
258 private readonly DoubleDictionary<Vector3, IntPtr, IntPtr> RegionTerrain = new DoubleDictionary<Vector3, IntPtr, IntPtr>();
259 private readonly Dictionary<IntPtr,float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>();
260 260
261 private d.Contact contact; 261 private d.Contact contact;
262 private d.Contact TerrainContact; 262 private d.Contact TerrainContact;
@@ -313,6 +313,7 @@ namespace OpenSim.Region.Physics.OdePlugin
313 313
314 private Vector3 m_worldOffset = Vector3.Zero; 314 private Vector3 m_worldOffset = Vector3.Zero;
315 public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); 315 public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize);
316 private PhysicsScene m_parentScene = null;
316 317
317 private ODERayCastRequestManager m_rayCastManager; 318 private ODERayCastRequestManager m_rayCastManager;
318 319
@@ -351,7 +352,7 @@ namespace OpenSim.Region.Physics.OdePlugin
351 } 352 }
352 353
353 // zero out a heightmap array float array (single dimension [flattened])) 354 // zero out a heightmap array float array (single dimension [flattened]))
354 if ((int)WorldExtents.X == 256 && (int)m_worldOffset.Y == 256) 355 if ((int)Constants.RegionSize == 256)
355 _heightmap = new float[514*514]; 356 _heightmap = new float[514*514];
356 else 357 else
357 _heightmap = new float[(((int)WorldExtents.Y + 2) * ((int)WorldExtents.X + 2))]; 358 _heightmap = new float[(((int)WorldExtents.Y + 2) * ((int)WorldExtents.X + 2))];
@@ -1564,28 +1565,60 @@ namespace OpenSim.Region.Physics.OdePlugin
1564 { 1565 {
1565 m_worldOffset = offset; 1566 m_worldOffset = offset;
1566 WorldExtents = new Vector2(extents.X, extents.Y); 1567 WorldExtents = new Vector2(extents.X, extents.Y);
1568 m_parentScene = pScene;
1569
1567 } 1570 }
1568// Recovered for use by fly height. Kitto Flora 1571// Recovered for use by fly height. Kitto Flora
1569 public float GetTerrainHeightAtXY(float x, float y) 1572 public float GetTerrainHeightAtXY(float x, float y)
1570 { 1573 {
1571 1574
1572 int index; 1575 int offsetX = ((int) (x/256)) * 256;
1576 int offsetY = ((int) (y/256)) * 256;
1577
1578 IntPtr heightFieldGeom = IntPtr.Zero;
1579
1580 if (RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom))
1581 {
1582 if (heightFieldGeom != IntPtr.Zero)
1583 {
1584 if (TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
1585 {
1586
1587 int index;
1588
1589
1590 if ((int)x > WorldExtents.X || (int)y > WorldExtents.Y ||
1591 (int)x < 0.001f || (int)y < 0.001f)
1592 return 0;
1573 1593
1574 // Teravus: Kitto, this code causes recurring errors that stall physics permenantly unless 1594 x = x - offsetX;
1575 // the values are checked, so checking below. 1595 y = y - offsetY;
1576 // Is there any reason that we don't do this in ScenePresence?
1577 // The only physics engine that benefits from it in the physics plugin is this one
1578 1596
1579 if ((int)x > WorldExtents.X || (int)y > WorldExtents.Y || 1597 index = (int)((int)y * (int)Constants.RegionSize + (int)x);
1580 (int)x < 0.001f || (int)y < 0.001f)
1581 return 0;
1582 1598
1583 index = (int)((int)y * WorldExtents.Y + (int)x); 1599 if (index < TerrainHeightFieldHeights[heightFieldGeom].Length)
1600 return (float)TerrainHeightFieldHeights[heightFieldGeom][(int)y * (int)Constants.RegionSize + (int)x];
1601 else
1602 return 0f;
1603 }
1604 else
1605 {
1606 return 0f;
1607 }
1584 1608
1585 if (index < _origheightmap.Length) 1609 }
1586 return (float)_origheightmap[(int)y * (int)WorldExtents.Y + (int)x]; 1610 else
1611 {
1612 return 0f;
1613 }
1614
1615 }
1587 else 1616 else
1588 return 0; 1617 {
1618 return 0f;
1619 }
1620
1621
1589 } 1622 }
1590// End recovered. Kitto Flora 1623// End recovered. Kitto Flora
1591 1624
@@ -2557,8 +2590,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2557 if (framecount >= int.MaxValue) 2590 if (framecount >= int.MaxValue)
2558 framecount = 0; 2591 framecount = 0;
2559 2592
2560 if (m_worldOffset != Vector3.Zero) 2593 //if (m_worldOffset != Vector3.Zero)
2561 return 0; 2594 // return 0;
2562 2595
2563 framecount++; 2596 framecount++;
2564 2597
@@ -3131,14 +3164,14 @@ namespace OpenSim.Region.Physics.OdePlugin
3131 public float[] ResizeTerrain512Interpolation(float[] heightMap) 3164 public float[] ResizeTerrain512Interpolation(float[] heightMap)
3132 { 3165 {
3133 float[] returnarr = new float[262144]; 3166 float[] returnarr = new float[262144];
3134 float[,] resultarr = new float[(int)WorldExtents.X,(int)WorldExtents.Y]; 3167 float[,] resultarr = new float[512,512];
3135 3168
3136 // Filling out the array into its multi-dimensional components 3169 // Filling out the array into its multi-dimensional components
3137 for (int y = 0; y < WorldExtents.Y; y++) 3170 for (int y = 0; y < 256; y++)
3138 { 3171 {
3139 for (int x = 0; x < WorldExtents.X; x++) 3172 for (int x = 0; x < 256; x++)
3140 { 3173 {
3141 resultarr[y, x] = heightMap[y*(int)WorldExtents.Y + x]; 3174 resultarr[y, x] = heightMap[y * 256 + x];
3142 } 3175 }
3143 } 3176 }
3144 3177
@@ -3202,17 +3235,17 @@ namespace OpenSim.Region.Physics.OdePlugin
3202 // on single loop. 3235 // on single loop.
3203 3236
3204 float[,] resultarr2 = new float[512,512]; 3237 float[,] resultarr2 = new float[512,512];
3205 for (int y = 0; y < WorldExtents.Y; y++) 3238 for (int y = 0; y < (int)Constants.RegionSize; y++)
3206 { 3239 {
3207 for (int x = 0; x < WorldExtents.X; x++) 3240 for (int x = 0; x < (int)Constants.RegionSize; x++)
3208 { 3241 {
3209 resultarr2[y*2, x*2] = resultarr[y, x]; 3242 resultarr2[y*2, x*2] = resultarr[y, x];
3210 3243
3211 if (y < WorldExtents.Y) 3244 if (y < (int)Constants.RegionSize)
3212 { 3245 {
3213 if (y + 1 < WorldExtents.Y) 3246 if (y + 1 < (int)Constants.RegionSize)
3214 { 3247 {
3215 if (x + 1 < WorldExtents.X) 3248 if (x + 1 < (int)Constants.RegionSize)
3216 { 3249 {
3217 resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] + 3250 resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
3218 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); 3251 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
@@ -3227,11 +3260,11 @@ namespace OpenSim.Region.Physics.OdePlugin
3227 resultarr2[(y*2) + 1, x*2] = resultarr[y, x]; 3260 resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
3228 } 3261 }
3229 } 3262 }
3230 if (x < WorldExtents.X) 3263 if (x < (int)Constants.RegionSize)
3231 { 3264 {
3232 if (x + 1 < WorldExtents.X) 3265 if (x + 1 < (int)Constants.RegionSize)
3233 { 3266 {
3234 if (y + 1 < WorldExtents.Y) 3267 if (y + 1 < (int)Constants.RegionSize)
3235 { 3268 {
3236 resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + 3269 resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
3237 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); 3270 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
@@ -3246,9 +3279,9 @@ namespace OpenSim.Region.Physics.OdePlugin
3246 resultarr2[y*2, (x*2) + 1] = resultarr[y, x]; 3279 resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
3247 } 3280 }
3248 } 3281 }
3249 if (x < WorldExtents.X && y < WorldExtents.Y) 3282 if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize)
3250 { 3283 {
3251 if ((x + 1 < WorldExtents.X) && (y + 1 < WorldExtents.Y)) 3284 if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize))
3252 { 3285 {
3253 resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + 3286 resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
3254 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); 3287 resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
@@ -3283,43 +3316,59 @@ namespace OpenSim.Region.Physics.OdePlugin
3283 3316
3284 public override void SetTerrain(float[] heightMap) 3317 public override void SetTerrain(float[] heightMap)
3285 { 3318 {
3319 if (m_worldOffset != Vector3.Zero && m_parentScene != null)
3320 {
3321 if (m_parentScene is OdeScene)
3322 {
3323 ((OdeScene)m_parentScene).SetTerrain(heightMap, m_worldOffset);
3324 }
3325 }
3326 else
3327 {
3328 SetTerrain(heightMap, m_worldOffset);
3329 }
3330 }
3331
3332 public void SetTerrain(float[] heightMap, Vector3 pOffset)
3333 {
3286 // this._heightmap[i] = (double)heightMap[i]; 3334 // this._heightmap[i] = (double)heightMap[i];
3287 // dbm (danx0r) -- creating a buffer zone of one extra sample all around 3335 // dbm (danx0r) -- creating a buffer zone of one extra sample all around
3288 _origheightmap = heightMap; // Used for Fly height. Kitto Flora 3336 //_origheightmap = heightMap;
3289 uint heightmapWidth = (uint)WorldExtents.X + 1; 3337
3290 uint heightmapHeight = (uint)WorldExtents.Y + 1; 3338 uint heightmapWidth = Constants.RegionSize + 1;
3339 uint heightmapHeight = Constants.RegionSize + 1;
3340
3341 uint heightmapWidthSamples;
3291 3342
3292 uint heightmapWidthSamples;
3293
3294 uint heightmapHeightSamples; 3343 uint heightmapHeightSamples;
3295 /* 3344
3296 if (((int)m_worldExtents.X) == 256 && (int)m_worldExtents.Y == 256) 3345 if (((int)Constants.RegionSize) == 256)
3297 { 3346 {
3298 heightmapWidthSamples = 2 * (uint)m_worldExtents.X + 2; 3347 heightmapWidthSamples = 2 * (uint)Constants.RegionSize + 2;
3299 heightmapHeightSamples = 2*(uint)m_worldExtents.Y + 2; 3348 heightmapHeightSamples = 2 * (uint)Constants.RegionSize + 2;
3300 heightmapWidth++; 3349 heightmapWidth++;
3301 heightmapHeight++; 3350 heightmapHeight++;
3302 } 3351 }
3303 else 3352 else
3304 { 3353 {
3305 */ 3354
3306 heightmapWidthSamples = (uint)WorldExtents.X + 1; 3355 heightmapWidthSamples = (uint)Constants.RegionSize + 1;
3307 heightmapHeightSamples = (uint)WorldExtents.Y + 1; 3356 heightmapHeightSamples = (uint)Constants.RegionSize + 1;
3308 //} 3357 }
3309 3358
3310 const float scale = 1.0f; 3359 const float scale = 1.0f;
3311 const float offset = 0.0f; 3360 const float offset = 0.0f;
3312 const float thickness = 0.2f; 3361 const float thickness = 0.2f;
3313 const int wrap = 0; 3362 const int wrap = 0;
3314
3315 3363
3364 int regionsize = (int) Constants.RegionSize;
3316 //Double resolution 3365 //Double resolution
3317 //if (((int)m_worldExtents.X) == 256 && (int)m_worldExtents.Y == 256) 3366 if (((int)Constants.RegionSize) == 256)
3318 // heightMap = ResizeTerrain512Interpolation(heightMap); 3367 heightMap = ResizeTerrain512Interpolation(heightMap);
3319 3368
3320 3369
3321 //if (((int)m_worldExtents.X) == 256 && (int)m_worldExtents.Y == 256) 3370 if (((int)Constants.RegionSize) == 256 && (int)Constants.RegionSize == 256)
3322 // regionsize = 512; 3371 regionsize = 512;
3323 3372
3324 float hfmin = 2000; 3373 float hfmin = 2000;
3325 float hfmax = -2000; 3374 float hfmax = -2000;
@@ -3327,11 +3376,11 @@ namespace OpenSim.Region.Physics.OdePlugin
3327 { 3376 {
3328 for (int y = 0; y < heightmapHeightSamples; y++) 3377 for (int y = 0; y < heightmapHeightSamples; y++)
3329 { 3378 {
3330 int xx = Util.Clip(x - 1, 0, (int)WorldExtents.X - 1); 3379 int xx = Util.Clip(x - 1, 0, regionsize - 1);
3331 int yy = Util.Clip(y - 1, 0, (int)WorldExtents.Y - 1); 3380 int yy = Util.Clip(y - 1, 0, regionsize - 1);
3332 3381
3333 float val = heightMap[yy*(int)WorldExtents.Y + xx]; 3382 float val = heightMap[yy * regionsize + xx];
3334 _heightmap[x*heightmapHeightSamples + y] = val; 3383 _heightmap[x * heightmapHeightSamples + y] = val;
3335 hfmin = (val < hfmin) ? val : hfmin; 3384 hfmin = (val < hfmin) ? val : hfmin;
3336 hfmax = (val > hfmax) ? val : hfmax; 3385 hfmax = (val > hfmax) ? val : hfmax;
3337 } 3386 }
@@ -3339,23 +3388,34 @@ namespace OpenSim.Region.Physics.OdePlugin
3339 3388
3340 lock (OdeLock) 3389 lock (OdeLock)
3341 { 3390 {
3342 if (LandGeom != IntPtr.Zero) 3391 IntPtr GroundGeom = IntPtr.Zero;
3392 if (RegionTerrain.TryGetValue(pOffset, out GroundGeom))
3343 { 3393 {
3344 d.SpaceRemove(space, LandGeom); 3394 RegionTerrain.Remove(pOffset);
3395 if (GroundGeom != IntPtr.Zero)
3396 {
3397 if (TerrainHeightFieldHeights.ContainsKey(GroundGeom))
3398 {
3399 TerrainHeightFieldHeights.Remove(GroundGeom);
3400 }
3401 d.SpaceRemove(space, GroundGeom);
3402 d.GeomDestroy(GroundGeom);
3403 }
3404
3345 } 3405 }
3346 IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); 3406 IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
3347 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight, 3407 d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight,
3348 (int) heightmapWidthSamples, (int) heightmapHeightSamples, scale, 3408 (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale,
3349 offset, thickness, wrap); 3409 offset, thickness, wrap);
3350 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1 , hfmax + 1); 3410 d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1);
3351 LandGeom = d.CreateHeightfield(space, HeightmapData, 1); 3411 GroundGeom = d.CreateHeightfield(space, HeightmapData, 1);
3352 if (LandGeom != IntPtr.Zero) 3412 if (GroundGeom != IntPtr.Zero)
3353 { 3413 {
3354 d.GeomSetCategoryBits(LandGeom, (int)(CollisionCategories.Land)); 3414 d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land));
3355 d.GeomSetCollideBits(LandGeom, (int)(CollisionCategories.Space)); 3415 d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space));
3356 3416
3357 } 3417 }
3358 geom_name_map[LandGeom] = "Terrain"; 3418 geom_name_map[GroundGeom] = "Terrain";
3359 3419
3360 d.Matrix3 R = new d.Matrix3(); 3420 d.Matrix3 R = new d.Matrix3();
3361 3421
@@ -3363,15 +3423,23 @@ namespace OpenSim.Region.Physics.OdePlugin
3363 Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); 3423 Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f);
3364 //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); 3424 //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1));
3365 3425
3366 q1 = q1*q2; 3426 q1 = q1 * q2;
3367 //q1 = q1 * q3; 3427 //q1 = q1 * q3;
3368 Vector3 v3; 3428 Vector3 v3;
3369 float angle; 3429 float angle;
3370 q1.GetAxisAngle(out v3, out angle); 3430 q1.GetAxisAngle(out v3, out angle);
3371 3431
3372 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 3432 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
3373 d.GeomSetRotation(LandGeom, ref R); 3433 d.GeomSetRotation(GroundGeom, ref R);
3374 d.GeomSetPosition(LandGeom, (int)WorldExtents.X * 0.5f, (int)WorldExtents.Y * 0.5f, 0); 3434 d.GeomSetPosition(GroundGeom, pOffset.X + ((int)Constants.RegionSize * 0.5f), (pOffset.Y + (int)Constants.RegionSize * 0.5f), 0);
3435 IntPtr testGround = IntPtr.Zero;
3436 if (RegionTerrain.TryGetValue(pOffset, out testGround))
3437 {
3438 RegionTerrain.Remove(pOffset);
3439 }
3440 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
3441 TerrainHeightFieldHeights.Add(GroundGeom,heightMap);
3442
3375 } 3443 }
3376 } 3444 }
3377 3445