diff options
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODEPrim.cs')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 243 |
1 files changed, 209 insertions, 34 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 50087a5..6da2296 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |||
@@ -52,12 +52,30 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
52 | private PhysicsVector m_taintsize; | 52 | private PhysicsVector m_taintsize; |
53 | private PhysicsVector m_taintVelocity = PhysicsVector.Zero; | 53 | private PhysicsVector m_taintVelocity = PhysicsVector.Zero; |
54 | private Quaternion m_taintrot; | 54 | private Quaternion m_taintrot; |
55 | private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom | ||
56 | | CollisionCategories.Space | ||
57 | | CollisionCategories.Body | ||
58 | | CollisionCategories.Character); | ||
55 | private bool m_taintshape = false; | 59 | private bool m_taintshape = false; |
56 | private bool m_taintPhysics = false; | 60 | private bool m_taintPhysics = false; |
61 | private bool m_collidesLand = true; | ||
62 | private bool m_collidesWater = false; | ||
63 | |||
64 | // Default we're a Geometry | ||
65 | private CollisionCategories m_collisionCategories = (CollisionCategories.Geom ); | ||
66 | |||
67 | // Default, Collide with Other Geometries, spaces and Bodies | ||
68 | private CollisionCategories m_collisionFlags = m_default_collisionFlags; | ||
69 | |||
57 | public bool m_taintremove = false; | 70 | public bool m_taintremove = false; |
58 | public bool m_taintdisable = false; | 71 | public bool m_taintdisable = false; |
59 | public bool m_disabled = false; | 72 | public bool m_disabled = false; |
60 | public bool m_taintadd = false; | 73 | public bool m_taintadd = false; |
74 | public bool m_taintselected = false; | ||
75 | |||
76 | |||
77 | public uint m_localID = 0; | ||
78 | |||
61 | public GCHandle gc; | 79 | public GCHandle gc; |
62 | private CollisionLocker ode; | 80 | private CollisionLocker ode; |
63 | 81 | ||
@@ -74,6 +92,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
74 | 92 | ||
75 | private bool iscolliding = false; | 93 | private bool iscolliding = false; |
76 | private bool m_isphysical = false; | 94 | private bool m_isphysical = false; |
95 | private bool m_isSelected = false; | ||
96 | |||
77 | private bool m_throttleUpdates = false; | 97 | private bool m_throttleUpdates = false; |
78 | private int throttleCounter = 0; | 98 | private int throttleCounter = 0; |
79 | public int m_interpenetrationcount = 0; | 99 | public int m_interpenetrationcount = 0; |
@@ -172,6 +192,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
172 | set { return; } | 192 | set { return; } |
173 | } | 193 | } |
174 | 194 | ||
195 | public override uint LocalID | ||
196 | { | ||
197 | set { m_localID = value; } | ||
198 | } | ||
199 | |||
175 | public override bool Grabbed | 200 | public override bool Grabbed |
176 | { | 201 | { |
177 | set { return; } | 202 | set { return; } |
@@ -179,17 +204,59 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
179 | 204 | ||
180 | public override bool Selected | 205 | public override bool Selected |
181 | { | 206 | { |
182 | set { return; } | 207 | set { |
208 | // This only makes the object not collidable if the object | ||
209 | // is physical or the object is modified somehow *IN THE FUTURE* | ||
210 | // without this, if an avatar selects prim, they can walk right | ||
211 | // through it while it's selected | ||
212 | |||
213 | if (m_isphysical || !value) | ||
214 | { | ||
215 | m_taintselected = value; | ||
216 | _parent_scene.AddPhysicsActorTaint(this); | ||
217 | } | ||
218 | else | ||
219 | { | ||
220 | |||
221 | m_taintselected = value; | ||
222 | m_isSelected = value; | ||
223 | } | ||
224 | |||
225 | } | ||
183 | } | 226 | } |
184 | 227 | ||
185 | public void SetGeom(IntPtr geom) | 228 | public void SetGeom(IntPtr geom) |
186 | { | 229 | { |
187 | prev_geom = prim_geom; | 230 | prev_geom = prim_geom; |
188 | prim_geom = geom; | 231 | prim_geom = geom; |
232 | if (prim_geom != (IntPtr)0) | ||
233 | { | ||
234 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
235 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
236 | } | ||
189 | //m_log.Warn("Setting Geom to: " + prim_geom); | 237 | //m_log.Warn("Setting Geom to: " + prim_geom); |
190 | 238 | ||
191 | } | 239 | } |
192 | 240 | ||
241 | public void enableBodySoft() | ||
242 | { | ||
243 | if (m_isphysical) | ||
244 | if (Body != (IntPtr)0) | ||
245 | d.BodyEnable(Body); | ||
246 | |||
247 | m_disabled = false; | ||
248 | } | ||
249 | |||
250 | public void disableBodySoft() | ||
251 | { | ||
252 | m_disabled = true; | ||
253 | |||
254 | if (m_isphysical) | ||
255 | if (Body != (IntPtr)0) | ||
256 | d.BodyDisable(Body); | ||
257 | } | ||
258 | |||
259 | |||
193 | public void enableBody() | 260 | public void enableBody() |
194 | { | 261 | { |
195 | // Sets the geom to a body | 262 | // Sets the geom to a body |
@@ -204,6 +271,13 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
204 | myrot.Z = _orientation.z; | 271 | myrot.Z = _orientation.z; |
205 | d.BodySetQuaternion(Body, ref myrot); | 272 | d.BodySetQuaternion(Body, ref myrot); |
206 | d.GeomSetBody(prim_geom, Body); | 273 | d.GeomSetBody(prim_geom, Body); |
274 | m_collisionCategories |= CollisionCategories.Body; | ||
275 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | ||
276 | |||
277 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
278 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
279 | |||
280 | |||
207 | d.BodySetAutoDisableFlag(Body, true); | 281 | d.BodySetAutoDisableFlag(Body, true); |
208 | d.BodySetAutoDisableSteps(Body, 20); | 282 | d.BodySetAutoDisableSteps(Body, 20); |
209 | 283 | ||
@@ -332,6 +406,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
332 | //this kills the body so things like 'mesh' can re-create it. | 406 | //this kills the body so things like 'mesh' can re-create it. |
333 | if (Body != (IntPtr) 0) | 407 | if (Body != (IntPtr) 0) |
334 | { | 408 | { |
409 | m_collisionCategories &= ~CollisionCategories.Body; | ||
410 | m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); | ||
411 | |||
412 | if (prim_geom != (IntPtr)0) | ||
413 | { | ||
414 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
415 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
416 | } | ||
417 | |||
335 | _parent_scene.remActivePrim(this); | 418 | _parent_scene.remActivePrim(this); |
336 | d.BodyDestroy(Body); | 419 | d.BodyDestroy(Body); |
337 | Body = (IntPtr) 0; | 420 | Body = (IntPtr) 0; |
@@ -425,10 +508,81 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
425 | if (m_taintdisable) | 508 | if (m_taintdisable) |
426 | changedisable(timestep); | 509 | changedisable(timestep); |
427 | 510 | ||
511 | if (m_taintselected != m_isSelected) | ||
512 | changeSelectedStatus(timestep); | ||
513 | |||
428 | if (m_taintVelocity != PhysicsVector.Zero) | 514 | if (m_taintVelocity != PhysicsVector.Zero) |
429 | changevelocity(timestep); | 515 | changevelocity(timestep); |
430 | } | 516 | } |
431 | 517 | ||
518 | private void changeSelectedStatus(float timestep) | ||
519 | { | ||
520 | while (ode.lockquery()) | ||
521 | { | ||
522 | } | ||
523 | ode.dlock(_parent_scene.world); | ||
524 | |||
525 | if (m_taintselected) | ||
526 | { | ||
527 | |||
528 | |||
529 | m_collisionCategories = CollisionCategories.Selected; | ||
530 | m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); | ||
531 | |||
532 | // We do the body disable soft twice because 'in theory' a collision could have happened | ||
533 | // in between the disabling and the collision properties setting | ||
534 | // which would wake the physical body up from a soft disabling and potentially cause it to fall | ||
535 | // through the ground. | ||
536 | |||
537 | if (m_isphysical) | ||
538 | { | ||
539 | disableBodySoft(); | ||
540 | } | ||
541 | |||
542 | if (prim_geom != (IntPtr)0) | ||
543 | { | ||
544 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
545 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
546 | } | ||
547 | |||
548 | if (m_isphysical) | ||
549 | { | ||
550 | disableBodySoft(); | ||
551 | } | ||
552 | |||
553 | } | ||
554 | else | ||
555 | { | ||
556 | |||
557 | m_collisionCategories = CollisionCategories.Geom; | ||
558 | |||
559 | if (m_isphysical) | ||
560 | m_collisionCategories |= CollisionCategories.Body; | ||
561 | |||
562 | |||
563 | m_collisionFlags = m_default_collisionFlags; | ||
564 | |||
565 | if (m_collidesLand) | ||
566 | m_collisionFlags |= CollisionCategories.Land; | ||
567 | if (m_collidesWater) | ||
568 | m_collisionFlags |= CollisionCategories.Water; | ||
569 | |||
570 | if (prim_geom != (IntPtr)0) | ||
571 | { | ||
572 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | ||
573 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | ||
574 | } | ||
575 | if (m_isphysical) | ||
576 | enableBodySoft(); | ||
577 | |||
578 | |||
579 | } | ||
580 | |||
581 | ode.dunlock(_parent_scene.world); | ||
582 | resetCollisionAccounting(); | ||
583 | m_isSelected = m_taintselected; | ||
584 | } | ||
585 | |||
432 | public void ResetTaints() | 586 | public void ResetTaints() |
433 | { | 587 | { |
434 | 588 | ||
@@ -438,6 +592,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
438 | 592 | ||
439 | m_taintPhysics = m_isphysical; | 593 | m_taintPhysics = m_isphysical; |
440 | 594 | ||
595 | m_taintselected = m_isSelected; | ||
596 | |||
441 | m_taintsize = _size; | 597 | m_taintsize = _size; |
442 | 598 | ||
443 | 599 | ||
@@ -586,6 +742,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
586 | ode.dunlock(_parent_scene.world); | 742 | ode.dunlock(_parent_scene.world); |
587 | _parent_scene.geom_name_map[prim_geom] = this.m_primName; | 743 | _parent_scene.geom_name_map[prim_geom] = this.m_primName; |
588 | _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; | 744 | _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; |
745 | |||
746 | changeSelectedStatus(timestep); | ||
747 | |||
589 | m_taintadd = false; | 748 | m_taintadd = false; |
590 | 749 | ||
591 | 750 | ||
@@ -630,6 +789,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
630 | } | 789 | } |
631 | ode.dunlock(_parent_scene.world); | 790 | ode.dunlock(_parent_scene.world); |
632 | 791 | ||
792 | changeSelectedStatus(timestep); | ||
793 | |||
633 | resetCollisionAccounting(); | 794 | resetCollisionAccounting(); |
634 | m_taintposition = _position; | 795 | m_taintposition = _position; |
635 | } | 796 | } |
@@ -682,7 +843,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
682 | m_taintdisable = false; | 843 | m_taintdisable = false; |
683 | } | 844 | } |
684 | 845 | ||
685 | public void changePhysicsStatus(float timestap) | 846 | public void changePhysicsStatus(float timestep) |
686 | { | 847 | { |
687 | lock (ode) | 848 | lock (ode) |
688 | { | 849 | { |
@@ -709,6 +870,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
709 | ode.dunlock(_parent_scene.world); | 870 | ode.dunlock(_parent_scene.world); |
710 | } | 871 | } |
711 | 872 | ||
873 | changeSelectedStatus(timestep); | ||
874 | |||
712 | resetCollisionAccounting(); | 875 | resetCollisionAccounting(); |
713 | m_taintPhysics = m_isphysical; | 876 | m_taintPhysics = m_isphysical; |
714 | } | 877 | } |
@@ -880,6 +1043,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
880 | 1043 | ||
881 | ode.dunlock(_parent_scene.world); | 1044 | ode.dunlock(_parent_scene.world); |
882 | 1045 | ||
1046 | changeSelectedStatus(timestamp); | ||
1047 | |||
883 | resetCollisionAccounting(); | 1048 | resetCollisionAccounting(); |
884 | m_taintsize = _size; | 1049 | m_taintsize = _size; |
885 | } | 1050 | } |
@@ -927,7 +1092,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
927 | // Re creates body on size. | 1092 | // Re creates body on size. |
928 | // EnableBody also does setMass() | 1093 | // EnableBody also does setMass() |
929 | enableBody(); | 1094 | enableBody(); |
930 | d.BodyEnable(Body); | 1095 | |
931 | } | 1096 | } |
932 | } | 1097 | } |
933 | else | 1098 | else |
@@ -1032,66 +1197,76 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1032 | d.BodyEnable(Body); | 1197 | d.BodyEnable(Body); |
1033 | } | 1198 | } |
1034 | } | 1199 | } |
1200 | |||
1201 | |||
1035 | _parent_scene.geom_name_map[prim_geom] = oldname; | 1202 | _parent_scene.geom_name_map[prim_geom] = oldname; |
1036 | 1203 | ||
1037 | ode.dunlock(_parent_scene.world); | 1204 | ode.dunlock(_parent_scene.world); |
1038 | 1205 | ||
1206 | changeSelectedStatus(timestamp); | ||
1207 | |||
1039 | resetCollisionAccounting(); | 1208 | resetCollisionAccounting(); |
1040 | m_taintshape = false; | 1209 | m_taintshape = false; |
1041 | } | 1210 | } |
1042 | 1211 | ||
1043 | public void changeAddForce(float timestamp) | 1212 | public void changeAddForce(float timestamp) |
1044 | { | 1213 | { |
1045 | while (ode.lockquery()) | 1214 | if (!m_isSelected) |
1046 | { | 1215 | { |
1047 | } | 1216 | while (ode.lockquery()) |
1048 | ode.dlock(_parent_scene.world); | 1217 | { |
1218 | } | ||
1219 | ode.dlock(_parent_scene.world); | ||
1049 | 1220 | ||
1050 | 1221 | ||
1051 | lock (m_forcelist) | 1222 | lock (m_forcelist) |
1052 | { | ||
1053 | //m_log.Info("[PHYSICS]: dequeing forcelist"); | ||
1054 | if (IsPhysical) | ||
1055 | { | 1223 | { |
1056 | PhysicsVector iforce = new PhysicsVector(); | 1224 | //m_log.Info("[PHYSICS]: dequeing forcelist"); |
1057 | for (int i = 0; i < m_forcelist.Count; i++) | 1225 | if (IsPhysical) |
1058 | { | 1226 | { |
1059 | iforce = iforce + (m_forcelist[i]*100); | 1227 | PhysicsVector iforce = new PhysicsVector(); |
1060 | } | 1228 | for (int i = 0; i < m_forcelist.Count; i++) |
1061 | d.BodyEnable(Body); | 1229 | { |
1062 | d.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z); | 1230 | iforce = iforce + (m_forcelist[i] * 100); |
1231 | } | ||
1232 | d.BodyEnable(Body); | ||
1233 | d.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z); | ||
1234 | } | ||
1235 | m_forcelist.Clear(); | ||
1063 | } | 1236 | } |
1064 | m_forcelist.Clear(); | ||
1065 | } | ||
1066 | 1237 | ||
1067 | ode.dunlock(_parent_scene.world); | 1238 | ode.dunlock(_parent_scene.world); |
1068 | 1239 | ||
1069 | m_collisionscore = 0; | 1240 | m_collisionscore = 0; |
1070 | m_interpenetrationcount = 0; | 1241 | m_interpenetrationcount = 0; |
1242 | } | ||
1071 | m_taintforce = false; | 1243 | m_taintforce = false; |
1072 | 1244 | ||
1073 | } | 1245 | } |
1074 | private void changevelocity(float timestep) | 1246 | private void changevelocity(float timestep) |
1075 | { | 1247 | { |
1076 | lock (ode) | 1248 | if (!m_isSelected) |
1077 | { | 1249 | { |
1078 | while (ode.lockquery()) | 1250 | lock (ode) |
1079 | { | 1251 | { |
1080 | } | 1252 | while (ode.lockquery()) |
1081 | ode.dlock(_parent_scene.world); | 1253 | { |
1254 | } | ||
1255 | ode.dlock(_parent_scene.world); | ||
1082 | 1256 | ||
1083 | System.Threading.Thread.Sleep(20); | 1257 | System.Threading.Thread.Sleep(20); |
1084 | if (IsPhysical) | 1258 | if (IsPhysical) |
1085 | { | ||
1086 | if (Body != (IntPtr)0) | ||
1087 | { | 1259 | { |
1088 | d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); | 1260 | if (Body != (IntPtr)0) |
1261 | { | ||
1262 | d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); | ||
1263 | } | ||
1089 | } | 1264 | } |
1090 | } | ||
1091 | 1265 | ||
1092 | ode.dunlock(_parent_scene.world); | 1266 | ode.dunlock(_parent_scene.world); |
1267 | } | ||
1268 | //resetCollisionAccounting(); | ||
1093 | } | 1269 | } |
1094 | //resetCollisionAccounting(); | ||
1095 | m_taintVelocity = PhysicsVector.Zero; | 1270 | m_taintVelocity = PhysicsVector.Zero; |
1096 | } | 1271 | } |
1097 | public override bool IsPhysical | 1272 | public override bool IsPhysical |