Annotation of /trunk/ModularRex/RexOdePlugin/RexOdePlugin.cs
Parent Directory
|
Revision Log
Revision 50 - (view) (download)
| 1 : | tuco | 50 | using System; |
| 2 : | using System.Collections.Generic; | ||
| 3 : | |||
| 4 : | using OpenSim.Region.Physics.Manager; | ||
| 5 : | using OpenSim.Region.Physics.OdePlugin; | ||
| 6 : | |||
| 7 : | using System.Runtime.InteropServices; | ||
| 8 : | using Nini.Config; | ||
| 9 : | using Ode.NET; | ||
| 10 : | using OpenMetaverse; | ||
| 11 : | using OpenSim.Framework; | ||
| 12 : | |||
| 13 : | namespace ModularRex.RexOdePlugin | ||
| 14 : | { | ||
| 15 : | /* tucofixme, uncomment later | ||
| 16 : | |||
| 17 : | public class RexOdePlugin : IPhysicsPlugin | ||
| 18 : | { | ||
| 19 : | //protected static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
| 20 : | |||
| 21 : | protected CollisionLocker ode; | ||
| 22 : | protected OdeScene _mScene; | ||
| 23 : | |||
| 24 : | public RexOdePlugin() | ||
| 25 : | { | ||
| 26 : | ode = new CollisionLocker(); | ||
| 27 : | } | ||
| 28 : | |||
| 29 : | public bool Init() | ||
| 30 : | { | ||
| 31 : | return true; | ||
| 32 : | } | ||
| 33 : | |||
| 34 : | public PhysicsScene GetScene(String sceneIdentifier) | ||
| 35 : | { | ||
| 36 : | if (_mScene == null) | ||
| 37 : | { | ||
| 38 : | // Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to | ||
| 39 : | // http://opensimulator.org/mantis/view.php?id=2750). | ||
| 40 : | d.InitODE(); | ||
| 41 : | |||
| 42 : | _mScene = new RexOdeScene(ode, sceneIdentifier); | ||
| 43 : | } | ||
| 44 : | return (_mScene); | ||
| 45 : | } | ||
| 46 : | |||
| 47 : | public string GetName() | ||
| 48 : | { | ||
| 49 : | return ("RexOpenDynamicsEngine"); | ||
| 50 : | } | ||
| 51 : | |||
| 52 : | public void Dispose() | ||
| 53 : | { | ||
| 54 : | } | ||
| 55 : | } | ||
| 56 : | |||
| 57 : | |||
| 58 : | |||
| 59 : | |||
| 60 : | |||
| 61 : | |||
| 62 : | |||
| 63 : | |||
| 64 : | |||
| 65 : | |||
| 66 : | public class RexOdeScene : OdeScene | ||
| 67 : | { | ||
| 68 : | public float m_flightCeilingHeight = 2048.0f; | ||
| 69 : | |||
| 70 : | protected IntPtr mCollisionRay; | ||
| 71 : | protected uint mCollisionRayObjId, mCollisionRayIgnoreId; | ||
| 72 : | |||
| 73 : | public RexOdeScene(CollisionLocker dode, string sceneIdentifier):base(dode,sceneIdentifier) | ||
| 74 : | { | ||
| 75 : | nearCallback = Rexnear; | ||
| 76 : | } | ||
| 77 : | |||
| 78 : | public override void Initialise(IMesher meshmerizer, IConfigSource config) | ||
| 79 : | { | ||
| 80 : | base.Initialise(meshmerizer,config); | ||
| 81 : | |||
| 82 : | mCollisionRay = d.CreateRay(IntPtr.Zero, 1); | ||
| 83 : | } | ||
| 84 : | |||
| 85 : | |||
| 86 : | PhysicsActor AddRexPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, | ||
| 87 : | IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) | ||
| 88 : | { | ||
| 89 : | PhysicsVector pos = new PhysicsVector(position.X, position.Y, position.Z); | ||
| 90 : | PhysicsVector siz = new PhysicsVector(); | ||
| 91 : | siz.X = size.X; | ||
| 92 : | siz.Y = size.Y; | ||
| 93 : | siz.Z = size.Z; | ||
| 94 : | Quaternion rot = rotation; | ||
| 95 : | |||
| 96 : | RexOdePrim newPrim; | ||
| 97 : | lock (OdeLock) | ||
| 98 : | { | ||
| 99 : | newPrim = new RexOdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); | ||
| 100 : | |||
| 101 : | lock (_prims) | ||
| 102 : | _prims.Add(newPrim); | ||
| 103 : | } | ||
| 104 : | |||
| 105 : | return newPrim; | ||
| 106 : | } | ||
| 107 : | |||
| 108 : | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, | ||
| 109 : | PhysicsVector size, Quaternion rotation, bool isPhysical) | ||
| 110 : | { | ||
| 111 : | PhysicsActor result; | ||
| 112 : | IMesh mesh = null; | ||
| 113 : | |||
| 114 : | if (needsMeshing(pbs)) | ||
| 115 : | mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); | ||
| 116 : | |||
| 117 : | result = AddRexPrim(primName, position, size, rotation, mesh, pbs, isPhysical); | ||
| 118 : | |||
| 119 : | return result; | ||
| 120 : | } | ||
| 121 : | |||
| 122 : | public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size) | ||
| 123 : | { | ||
| 124 : | PhysicsVector pos = new PhysicsVector(); | ||
| 125 : | pos.X = position.X; | ||
| 126 : | pos.Y = position.Y; | ||
| 127 : | pos.Z = position.Z; | ||
| 128 : | OdeCharacter newAv = new RexOdeCharacter(avName, this, pos, ode, size, avPIDD, avPIDP, avCapRadius, avStandupTensor, avDensity, avHeightFudgeFactor, avMovementDivisorWalk, avMovementDivisorRun); | ||
| 129 : | _characters.Add(newAv); | ||
| 130 : | return newAv; | ||
| 131 : | } | ||
| 132 : | |||
| 133 : | protected void Rexnear(IntPtr space, IntPtr g1, IntPtr g2) | ||
| 134 : | { | ||
| 135 : | // no lock here! It's invoked from within Simulate(), which is thread-locked | ||
| 136 : | |||
| 137 : | // Test if we're colliding a geom with a space. | ||
| 138 : | // If so we have to drill down into the space recursively | ||
| 139 : | |||
| 140 : | if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) | ||
| 141 : | { | ||
| 142 : | if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) | ||
| 143 : | return; | ||
| 144 : | |||
| 145 : | // Separating static prim geometry spaces. | ||
| 146 : | // We'll be calling near recursivly if one | ||
| 147 : | // of them is a space to find all of the | ||
| 148 : | // contact points in the space | ||
| 149 : | try | ||
| 150 : | { | ||
| 151 : | d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); | ||
| 152 : | } | ||
| 153 : | catch (AccessViolationException) | ||
| 154 : | { | ||
| 155 : | m_log.Warn("[PHYSICS]: Unable to collide test a space"); | ||
| 156 : | return; | ||
| 157 : | } | ||
| 158 : | //Colliding a space or a geom with a space or a geom. so drill down | ||
| 159 : | |||
| 160 : | //Collide all geoms in each space.. | ||
| 161 : | //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); | ||
| 162 : | //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); | ||
| 163 : | return; | ||
| 164 : | } | ||
| 165 : | |||
| 166 : | if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) | ||
| 167 : | return; | ||
| 168 : | |||
| 169 : | IntPtr b1 = d.GeomGetBody(g1); | ||
| 170 : | IntPtr b2 = d.GeomGetBody(g2); | ||
| 171 : | |||
| 172 : | // d.GeomClassID id = d.GeomGetClass(g1); | ||
| 173 : | |||
| 174 : | String name1 = null; | ||
| 175 : | String name2 = null; | ||
| 176 : | |||
| 177 : | if (!geom_name_map.TryGetValue(g1, out name1)) | ||
| 178 : | { | ||
| 179 : | name1 = "null"; | ||
| 180 : | } | ||
| 181 : | if (!geom_name_map.TryGetValue(g2, out name2)) | ||
| 182 : | { | ||
| 183 : | name2 = "null"; | ||
| 184 : | } | ||
| 185 : | |||
| 186 : | //if (id == d.GeomClassId.TriMeshClass) | ||
| 187 : | //{ | ||
| 188 : | // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
| 189 : | //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
| 190 : | //} | ||
| 191 : | |||
| 192 : | // Figure out how many contact points we have | ||
| 193 : | int count = 0; | ||
| 194 : | try | ||
| 195 : | { | ||
| 196 : | // Colliding Geom To Geom | ||
| 197 : | // This portion of the function 'was' blatantly ripped off from BoxStack.cs | ||
| 198 : | |||
| 199 : | if (g1 == g2) | ||
| 200 : | return; // Can't collide with yourself | ||
| 201 : | |||
| 202 : | if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) | ||
| 203 : | return; | ||
| 204 : | |||
| 205 : | lock (contacts) | ||
| 206 : | { | ||
| 207 : | count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); | ||
| 208 : | } | ||
| 209 : | } | ||
| 210 : | catch (SEHException) | ||
| 211 : | { | ||
| 212 : | m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); | ||
| 213 : | ode.drelease(world); | ||
| 214 : | base.TriggerPhysicsBasedRestart(); | ||
| 215 : | } | ||
| 216 : | catch (AccessViolationException) | ||
| 217 : | { | ||
| 218 : | m_log.Warn("[PHYSICS]: Unable to collide test an object"); | ||
| 219 : | return; | ||
| 220 : | } | ||
| 221 : | |||
| 222 : | PhysicsActor p1; | ||
| 223 : | PhysicsActor p2; | ||
| 224 : | |||
| 225 : | if (!actor_name_map.TryGetValue(g1, out p1)) | ||
| 226 : | { | ||
| 227 : | p1 = PANull; | ||
| 228 : | } | ||
| 229 : | |||
| 230 : | if (!actor_name_map.TryGetValue(g2, out p2)) | ||
| 231 : | { | ||
| 232 : | p2 = PANull; | ||
| 233 : | } | ||
| 234 : | |||
| 235 : | float max_collision_depth = 0f; | ||
| 236 : | if (p1.CollisionScore + count >= float.MaxValue) | ||
| 237 : | p1.CollisionScore = 0; | ||
| 238 : | p1.CollisionScore += count; | ||
| 239 : | |||
| 240 : | if (p2.CollisionScore + count >= float.MaxValue) | ||
| 241 : | p2.CollisionScore = 0; | ||
| 242 : | p2.CollisionScore += count; | ||
| 243 : | |||
| 244 : | // rex, rayclass collision stop here | ||
| 245 : | if (d.GeomGetClass(g1) == d.GeomClassID.RayClass || d.GeomGetClass(g2) == d.GeomClassID.RayClass) | ||
| 246 : | { | ||
| 247 : | if (g1 != WaterGeom && g2 != WaterGeom) | ||
| 248 : | { | ||
| 249 : | if (count >= 1) | ||
| 250 : | { | ||
| 251 : | if (d.GeomGetClass(g1) == d.GeomClassID.RayClass) | ||
| 252 : | { | ||
| 253 : | if (p2 is RexOdePrim) | ||
| 254 : | { | ||
| 255 : | if (mCollisionRayIgnoreId != ((RexOdePrim)p2).m_localID) | ||
| 256 : | mCollisionRayObjId = ((RexOdePrim)p2).m_localID; | ||
| 257 : | } | ||
| 258 : | else if (p2 is OdeCharacter) | ||
| 259 : | { | ||
| 260 : | if (mCollisionRayIgnoreId != ((OdeCharacter)p2).m_localID) | ||
| 261 : | mCollisionRayObjId = ((OdeCharacter)p2).m_localID; | ||
| 262 : | } | ||
| 263 : | } | ||
| 264 : | else | ||
| 265 : | { | ||
| 266 : | if (p1 is RexOdePrim) | ||
| 267 : | { | ||
| 268 : | if (mCollisionRayIgnoreId != ((RexOdePrim)p1).m_localID) | ||
| 269 : | mCollisionRayObjId = ((RexOdePrim)p1).m_localID; | ||
| 270 : | } | ||
| 271 : | else if (p1 is OdeCharacter) | ||
| 272 : | { | ||
| 273 : | if (mCollisionRayIgnoreId != ((OdeCharacter)p1).m_localID) | ||
| 274 : | mCollisionRayObjId = ((OdeCharacter)p1).m_localID; | ||
| 275 : | } | ||
| 276 : | } | ||
| 277 : | } | ||
| 278 : | return; | ||
| 279 : | } | ||
| 280 : | } // endrex | ||
| 281 : | |||
| 282 : | for (int i = 0; i < count; i++) | ||
| 283 : | { | ||
| 284 : | |||
| 285 : | |||
| 286 : | max_collision_depth = (contacts[i].depth > max_collision_depth) ? contacts[i].depth : max_collision_depth; | ||
| 287 : | //m_log.Warn("[CCOUNT]: " + count); | ||
| 288 : | IntPtr joint; | ||
| 289 : | // If we're colliding with terrain, use 'TerrainContact' instead of contact. | ||
| 290 : | // allows us to have different settings | ||
| 291 : | |||
| 292 : | // We only need to test p2 for 'jump crouch purposes' | ||
| 293 : | p2.IsColliding = true; | ||
| 294 : | |||
| 295 : | //if ((framecount % m_returncollisions) == 0) | ||
| 296 : | |||
| 297 : | switch (p1.PhysicsActorType) | ||
| 298 : | { | ||
| 299 : | case (int)ActorTypes.Agent: | ||
| 300 : | p2.CollidingObj = true; | ||
| 301 : | break; | ||
| 302 : | case (int)ActorTypes.Prim: | ||
| 303 : | if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0) | ||
| 304 : | p2.CollidingObj = true; | ||
| 305 : | break; | ||
| 306 : | case (int)ActorTypes.Unknown: | ||
| 307 : | p2.CollidingGround = true; | ||
| 308 : | break; | ||
| 309 : | default: | ||
| 310 : | p2.CollidingGround = true; | ||
| 311 : | break; | ||
| 312 : | } | ||
| 313 : | |||
| 314 : | // we don't want prim or avatar to explode | ||
| 315 : | |||
| 316 : | #region InterPenetration Handling - Unintended physics explosions | ||
| 317 : | |||
| 318 : | if (contacts[i].depth >= 0.08f) | ||
| 319 : | { | ||
| 320 : | //This is disabled at the moment only because it needs more tweaking | ||
| 321 : | //It will eventually be uncommented | ||
| 322 : | |||
| 323 : | if (contacts[i].depth >= 1.00f) | ||
| 324 : | { | ||
| 325 : | //m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString()); | ||
| 326 : | } | ||
| 327 : | |||
| 328 : | //If you interpenetrate a prim with an agent | ||
| 329 : | if ((p2.PhysicsActorType == (int)ActorTypes.Agent && | ||
| 330 : | p1.PhysicsActorType == (int)ActorTypes.Prim) || | ||
| 331 : | (p1.PhysicsActorType == (int)ActorTypes.Agent && | ||
| 332 : | p2.PhysicsActorType == (int)ActorTypes.Prim)) | ||
| 333 : | { | ||
| 334 : | # region disabled code1 | ||
| 335 : | //contacts[i].depth = contacts[i].depth * 4.15f; | ||
| 336 : | |||
| 337 : | //if (p2.PhysicsActorType == (int) ActorTypes.Agent) | ||
| 338 : | //{ | ||
| 339 : | // p2.CollidingObj = true; | ||
| 340 : | // contacts[i].depth = 0.003f; | ||
| 341 : | // p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); | ||
| 342 : | // OdeCharacter character = (OdeCharacter) p2; | ||
| 343 : | // character.SetPidStatus(true); | ||
| 344 : | // contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2)); | ||
| 345 : | // | ||
| 346 : | //} | ||
| 347 : | //else | ||
| 348 : | //{ | ||
| 349 : | // | ||
| 350 : | //contacts[i].depth = 0.0000000f; | ||
| 351 : | //} | ||
| 352 : | //if (p1.PhysicsActorType == (int) ActorTypes.Agent) | ||
| 353 : | //{ | ||
| 354 : | |||
| 355 : | //p1.CollidingObj = true; | ||
| 356 : | //contacts[i].depth = 0.003f; | ||
| 357 : | //p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); | ||
| 358 : | //contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2)); | ||
| 359 : | //OdeCharacter character = (OdeCharacter)p1; | ||
| 360 : | //character.SetPidStatus(true); | ||
| 361 : | //} | ||
| 362 : | //else | ||
| 363 : | //{ | ||
| 364 : | |||
| 365 : | //contacts[i].depth = 0.0000000f; | ||
| 366 : | //} | ||
| 367 : | |||
| 368 : | #endregion | ||
| 369 : | } | ||
| 370 : | |||
| 371 : | // If you interpenetrate a prim with another prim | ||
| 372 : | if (p1.PhysicsActorType == (int)ActorTypes.Prim && p2.PhysicsActorType == (int)ActorTypes.Prim) | ||
| 373 : | { | ||
| 374 : | #region disabledcode2 | ||
| 375 : | //OdePrim op1 = (OdePrim)p1; | ||
| 376 : | //OdePrim op2 = (OdePrim)p2; | ||
| 377 : | //op1.m_collisionscore++; | ||
| 378 : | //op2.m_collisionscore++; | ||
| 379 : | |||
| 380 : | //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000) | ||
| 381 : | //{ | ||
| 382 : | //op1.m_taintdisable = true; | ||
| 383 : | //AddPhysicsActorTaint(p1); | ||
| 384 : | //op2.m_taintdisable = true; | ||
| 385 : | //AddPhysicsActorTaint(p2); | ||
| 386 : | //} | ||
| 387 : | |||
| 388 : | //if (contacts[i].depth >= 0.25f) | ||
| 389 : | //{ | ||
| 390 : | // Don't collide, one or both prim will expld. | ||
| 391 : | |||
| 392 : | //op1.m_interpenetrationcount++; | ||
| 393 : | //op2.m_interpenetrationcount++; | ||
| 394 : | //interpenetrations_before_disable = 200; | ||
| 395 : | //if (op1.m_interpenetrationcount >= interpenetrations_before_disable) | ||
| 396 : | //{ | ||
| 397 : | //op1.m_taintdisable = true; | ||
| 398 : | //AddPhysicsActorTaint(p1); | ||
| 399 : | //} | ||
| 400 : | //if (op2.m_interpenetrationcount >= interpenetrations_before_disable) | ||
| 401 : | //{ | ||
| 402 : | // op2.m_taintdisable = true; | ||
| 403 : | //AddPhysicsActorTaint(p2); | ||
| 404 : | //} | ||
| 405 : | |||
| 406 : | //contacts[i].depth = contacts[i].depth / 8f; | ||
| 407 : | //contacts[i].normal = new d.Vector3(0, 0, 1); | ||
| 408 : | //} | ||
| 409 : | //if (op1.m_disabled || op2.m_disabled) | ||
| 410 : | //{ | ||
| 411 : | //Manually disabled objects stay disabled | ||
| 412 : | //contacts[i].depth = 0f; | ||
| 413 : | //} | ||
| 414 : | #endregion | ||
| 415 : | } | ||
| 416 : | |||
| 417 : | if (contacts[i].depth >= 1.00f) | ||
| 418 : | { | ||
| 419 : | //m_log.Info("[P]: " + contacts[i].depth.ToString()); | ||
| 420 : | if ((p2.PhysicsActorType == (int)ActorTypes.Agent && | ||
| 421 : | p1.PhysicsActorType == (int)ActorTypes.Unknown) || | ||
| 422 : | (p1.PhysicsActorType == (int)ActorTypes.Agent && | ||
| 423 : | p2.PhysicsActorType == (int)ActorTypes.Unknown)) | ||
| 424 : | { | ||
| 425 : | if (p2.PhysicsActorType == (int)ActorTypes.Agent) | ||
| 426 : | { | ||
| 427 : | OdeCharacter character = (OdeCharacter)p2; | ||
| 428 : | |||
| 429 : | //p2.CollidingObj = true; | ||
| 430 : | contacts[i].depth = 0.00000003f; | ||
| 431 : | p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 0.5f); | ||
| 432 : | contacts[i].pos = | ||
| 433 : | new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), | ||
| 434 : | contacts[i].pos.Y + (p1.Size.Y / 2), | ||
| 435 : | contacts[i].pos.Z + (p1.Size.Z / 2)); | ||
| 436 : | character.SetPidStatus(true); | ||
| 437 : | } | ||
| 438 : | else | ||
| 439 : | { | ||
| 440 : | } | ||
| 441 : | |||
| 442 : | if (p1.PhysicsActorType == (int)ActorTypes.Agent) | ||
| 443 : | { | ||
| 444 : | OdeCharacter character = (OdeCharacter)p1; | ||
| 445 : | |||
| 446 : | //p2.CollidingObj = true; | ||
| 447 : | contacts[i].depth = 0.00000003f; | ||
| 448 : | p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 0.5f); | ||
| 449 : | contacts[i].pos = | ||
| 450 : | new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), | ||
| 451 : | contacts[i].pos.Y + (p1.Size.Y / 2), | ||
| 452 : | contacts[i].pos.Z + (p1.Size.Z / 2)); | ||
| 453 : | character.SetPidStatus(true); | ||
| 454 : | } | ||
| 455 : | else | ||
| 456 : | { | ||
| 457 : | //contacts[i].depth = 0.0000000f; | ||
| 458 : | } | ||
| 459 : | } | ||
| 460 : | } | ||
| 461 : | } | ||
| 462 : | |||
| 463 : | #endregion | ||
| 464 : | |||
| 465 : | // Logic for collision handling | ||
| 466 : | // Note, that if *all* contacts are skipped (VolumeDetect) | ||
| 467 : | // The prim still detects (and forwards) collision events but | ||
| 468 : | // appears to be phantom for the world | ||
| 469 : | Boolean skipThisContact = false; | ||
| 470 : | |||
| 471 : | if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect)) | ||
| 472 : | skipThisContact = true; // No collision on volume detect prims | ||
| 473 : | |||
| 474 : | if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) | ||
| 475 : | skipThisContact = true; // No collision on volume detect prims | ||
| 476 : | |||
| 477 : | if (!skipThisContact && contacts[i].depth < 0f) | ||
| 478 : | skipThisContact = true; | ||
| 479 : | |||
| 480 : | if (!skipThisContact && checkDupe(contacts[i], p2.PhysicsActorType)) | ||
| 481 : | skipThisContact = true; | ||
| 482 : | |||
| 483 : | if (!skipThisContact) | ||
| 484 : | { | ||
| 485 : | // If we're colliding against terrain | ||
| 486 : | if (name1 == "Terrain" || name2 == "Terrain") | ||
| 487 : | { | ||
| 488 : | // If we're moving | ||
| 489 : | if ((p2.PhysicsActorType == (int)ActorTypes.Agent) && | ||
| 490 : | (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) | ||
| 491 : | { | ||
| 492 : | // Use the movement terrain contact | ||
| 493 : | AvatarMovementTerrainContact.geom = contacts[i]; | ||
| 494 : | _perloopContact.Add(contacts[i]); | ||
| 495 : | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); | ||
| 496 : | } | ||
| 497 : | else | ||
| 498 : | { | ||
| 499 : | // Use the non moving terrain contact | ||
| 500 : | TerrainContact.geom = contacts[i]; | ||
| 501 : | _perloopContact.Add(contacts[i]); | ||
| 502 : | joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); | ||
| 503 : | } | ||
| 504 : | //if (p2.PhysicsActorType == (int)ActorTypes.Prim) | ||
| 505 : | //{ | ||
| 506 : | //m_log.Debug("[PHYSICS]: prim contacting with ground"); | ||
| 507 : | //} | ||
| 508 : | } | ||
| 509 : | else if (name1 == "Water" || name2 == "Water") | ||
| 510 : | { | ||
| 511 : | if ((p2.PhysicsActorType == (int)ActorTypes.Prim)) | ||
| 512 : | { | ||
| 513 : | } | ||
| 514 : | else | ||
| 515 : | { | ||
| 516 : | } | ||
| 517 : | |||
| 518 : | //WaterContact.surface.soft_cfm = 0.0000f; | ||
| 519 : | //WaterContact.surface.soft_erp = 0.00000f; | ||
| 520 : | if (contacts[i].depth > 0.1f) | ||
| 521 : | { | ||
| 522 : | contacts[i].depth *= 52; | ||
| 523 : | //contacts[i].normal = new d.Vector3(0, 0, 1); | ||
| 524 : | //contacts[i].pos = new d.Vector3(0, 0, contacts[i].pos.Z - 5f); | ||
| 525 : | } | ||
| 526 : | WaterContact.geom = contacts[i]; | ||
| 527 : | _perloopContact.Add(contacts[i]); | ||
| 528 : | joint = d.JointCreateContact(world, contactgroup, ref WaterContact); | ||
| 529 : | |||
| 530 : | //m_log.Info("[PHYSICS]: Prim Water Contact" + contacts[i].depth); | ||
| 531 : | } | ||
| 532 : | else | ||
| 533 : | { // we're colliding with prim or avatar | ||
| 534 : | // check if we're moving | ||
| 535 : | if ((p2.PhysicsActorType == (int)ActorTypes.Agent) && | ||
| 536 : | (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) | ||
| 537 : | { | ||
| 538 : | // Use the Movement prim contact | ||
| 539 : | AvatarMovementprimContact.geom = contacts[i]; | ||
| 540 : | _perloopContact.Add(contacts[i]); | ||
| 541 : | joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); | ||
| 542 : | } | ||
| 543 : | else | ||
| 544 : | { // Use the non movement contact | ||
| 545 : | contact.geom = contacts[i]; | ||
| 546 : | _perloopContact.Add(contacts[i]); | ||
| 547 : | joint = d.JointCreateContact(world, contactgroup, ref contact); | ||
| 548 : | } | ||
| 549 : | } | ||
| 550 : | d.JointAttach(joint, b1, b2); | ||
| 551 : | } | ||
| 552 : | collision_accounting_events(p1, p2, max_collision_depth); | ||
| 553 : | if (count > geomContactPointsStartthrottle) | ||
| 554 : | { | ||
| 555 : | // If there are more then 3 contact points, it's likely | ||
| 556 : | // that we've got a pile of objects, so ... | ||
| 557 : | // We don't want to send out hundreds of terse updates over and over again | ||
| 558 : | // so lets throttle them and send them again after it's somewhat sorted out. | ||
| 559 : | p2.ThrottleUpdates = true; | ||
| 560 : | } | ||
| 561 : | //System.Console.WriteLine(count.ToString()); | ||
| 562 : | //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2); | ||
| 563 : | } | ||
| 564 : | } | ||
| 565 : | |||
| 566 : | public override uint Raycast(PhysicsVector pos, PhysicsVector dir, float rayLength, uint ignoreId) | ||
| 567 : | { | ||
| 568 : | try | ||
| 569 : | { | ||
| 570 : | mCollisionRayObjId = 0; | ||
| 571 : | mCollisionRayIgnoreId = ignoreId; | ||
| 572 : | |||
| 573 : | lock (OdeLock) | ||
| 574 : | { | ||
| 575 : | d.GeomRaySet(mCollisionRay, pos.X, pos.Y, pos.Z, dir.X, dir.Y, dir.Z); | ||
| 576 : | d.GeomRaySetLength(mCollisionRay, rayLength); | ||
| 577 : | try | ||
| 578 : | { | ||
| 579 : | d.SpaceCollide2(space, mCollisionRay, IntPtr.Zero, nearCallback); | ||
| 580 : | } | ||
| 581 : | catch (Exception e) | ||
| 582 : | { | ||
| 583 : | m_log.Warn("[PHYSICS]: Unable to Raycast:" + e.ToString()); | ||
| 584 : | } | ||
| 585 : | d.GeomRaySetLength(mCollisionRay, 0); | ||
| 586 : | } | ||
| 587 : | } | ||
| 588 : | catch (Exception e) | ||
| 589 : | { | ||
| 590 : | m_log.Warn("[PHYSICS]: RexRaycast error:" + e.ToString()); | ||
| 591 : | } | ||
| 592 : | return mCollisionRayObjId; | ||
| 593 : | } | ||
| 594 : | |||
| 595 : | public override void SetMaxFlightHeight(float maxheight) | ||
| 596 : | { | ||
| 597 : | m_flightCeilingHeight = maxheight; | ||
| 598 : | } | ||
| 599 : | } | ||
| 600 : | */ | ||
| 601 : | } |
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

