diff options
author | Tom | 2011-09-04 07:06:36 -0700 |
---|---|---|
committer | Tom | 2011-09-04 07:06:36 -0700 |
commit | 66dec3b8742eff04fbbcc6e3249fe4ba87986500 (patch) | |
tree | 76cc708a821d35fac5cdbbce2de304b47064e732 /OpenSim/Region/Physics/OdePlugin | |
parent | Guard another nullref (diff) | |
parent | Fixed BulletSim config files for Linux *.so libraries. (diff) | |
download | opensim-SC_OLD-66dec3b8742eff04fbbcc6e3249fe4ba87986500.zip opensim-SC_OLD-66dec3b8742eff04fbbcc6e3249fe4ba87986500.tar.gz opensim-SC_OLD-66dec3b8742eff04fbbcc6e3249fe4ba87986500.tar.bz2 opensim-SC_OLD-66dec3b8742eff04fbbcc6e3249fe4ba87986500.tar.xz |
Resolve merge commits, stage 1
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 18 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 303 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs | 92 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 834 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs | 5 |
5 files changed, 683 insertions, 569 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 0e7dd81..c165a41 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | |||
@@ -258,7 +258,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
258 | public override bool Flying | 258 | public override bool Flying |
259 | { | 259 | { |
260 | get { return flying; } | 260 | get { return flying; } |
261 | set { flying = value; } | 261 | set |
262 | { | ||
263 | flying = value; | ||
264 | // m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying); | ||
265 | } | ||
262 | } | 266 | } |
263 | 267 | ||
264 | /// <summary> | 268 | /// <summary> |
@@ -305,10 +309,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
305 | { | 309 | { |
306 | m_iscolliding = true; | 310 | m_iscolliding = true; |
307 | } | 311 | } |
312 | |||
308 | if (m_wascolliding != m_iscolliding) | 313 | if (m_wascolliding != m_iscolliding) |
309 | { | 314 | { |
310 | //base.SendCollisionUpdate(new CollisionEventUpdate()); | 315 | //base.SendCollisionUpdate(new CollisionEventUpdate()); |
311 | } | 316 | } |
317 | |||
312 | m_wascolliding = m_iscolliding; | 318 | m_wascolliding = m_iscolliding; |
313 | } | 319 | } |
314 | } | 320 | } |
@@ -1219,18 +1225,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1219 | { | 1225 | { |
1220 | m_requestedUpdateFrequency = ms; | 1226 | m_requestedUpdateFrequency = ms; |
1221 | m_eventsubscription = ms; | 1227 | m_eventsubscription = ms; |
1222 | _parent_scene.addCollisionEventReporting(this); | 1228 | _parent_scene.AddCollisionEventReporting(this); |
1223 | } | 1229 | } |
1230 | |||
1224 | public override void UnSubscribeEvents() | 1231 | public override void UnSubscribeEvents() |
1225 | { | 1232 | { |
1226 | _parent_scene.remCollisionEventReporting(this); | 1233 | _parent_scene.RemoveCollisionEventReporting(this); |
1227 | m_requestedUpdateFrequency = 0; | 1234 | m_requestedUpdateFrequency = 0; |
1228 | m_eventsubscription = 0; | 1235 | m_eventsubscription = 0; |
1229 | } | 1236 | } |
1237 | |||
1230 | public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) | 1238 | public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) |
1231 | { | 1239 | { |
1232 | if (m_eventsubscription > 0) | 1240 | if (m_eventsubscription > 0) |
1233 | { | 1241 | { |
1242 | // m_log.DebugFormat( | ||
1243 | // "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact); | ||
1244 | |||
1234 | CollisionEventsThisFrame.addCollider(CollidedWith, contact); | 1245 | CollisionEventsThisFrame.addCollider(CollidedWith, contact); |
1235 | } | 1246 | } |
1236 | } | 1247 | } |
@@ -1247,6 +1258,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1247 | m_eventsubscription = 0; | 1258 | m_eventsubscription = 0; |
1248 | } | 1259 | } |
1249 | } | 1260 | } |
1261 | |||
1250 | public override bool SubscribedEvents() | 1262 | public override bool SubscribedEvents() |
1251 | { | 1263 | { |
1252 | if (m_eventsubscription > 0) | 1264 | if (m_eventsubscription > 0) |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 5fe0775..0a4fc51 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | |||
@@ -61,6 +61,22 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
61 | { | 61 | { |
62 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 62 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
63 | 63 | ||
64 | private bool m_isphysical; | ||
65 | |||
66 | /// <summary> | ||
67 | /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. | ||
68 | /// </summary> | ||
69 | public override bool IsPhysical | ||
70 | { | ||
71 | get { return m_isphysical; } | ||
72 | set | ||
73 | { | ||
74 | m_isphysical = value; | ||
75 | if (!m_isphysical) // Zero the remembered last velocity | ||
76 | m_lastVelocity = Vector3.Zero; | ||
77 | } | ||
78 | } | ||
79 | |||
64 | private Vector3 _position; | 80 | private Vector3 _position; |
65 | private Vector3 _velocity; | 81 | private Vector3 _velocity; |
66 | private Vector3 _torque; | 82 | private Vector3 _torque; |
@@ -138,12 +154,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
138 | private List<Vector3> m_forcelist = new List<Vector3>(); | 154 | private List<Vector3> m_forcelist = new List<Vector3>(); |
139 | private List<Vector3> m_angularforcelist = new List<Vector3>(); | 155 | private List<Vector3> m_angularforcelist = new List<Vector3>(); |
140 | 156 | ||
141 | private IMesh _mesh; | ||
142 | private PrimitiveBaseShape _pbs; | 157 | private PrimitiveBaseShape _pbs; |
143 | private OdeScene _parent_scene; | 158 | private OdeScene _parent_scene; |
159 | |||
160 | /// <summary> | ||
161 | /// The physics space which contains prim geometries | ||
162 | /// </summary> | ||
144 | public IntPtr m_targetSpace = IntPtr.Zero; | 163 | public IntPtr m_targetSpace = IntPtr.Zero; |
164 | |||
145 | public IntPtr prim_geom; | 165 | public IntPtr prim_geom; |
146 | public IntPtr prev_geom; | ||
147 | public IntPtr _triMeshData; | 166 | public IntPtr _triMeshData; |
148 | 167 | ||
149 | private IntPtr _linkJointGroup = IntPtr.Zero; | 168 | private IntPtr _linkJointGroup = IntPtr.Zero; |
@@ -153,7 +172,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
153 | private List<OdePrim> childrenPrim = new List<OdePrim>(); | 172 | private List<OdePrim> childrenPrim = new List<OdePrim>(); |
154 | 173 | ||
155 | private bool iscolliding; | 174 | private bool iscolliding; |
156 | private bool m_isphysical; | ||
157 | private bool m_isSelected; | 175 | private bool m_isSelected; |
158 | 176 | ||
159 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively | 177 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively |
@@ -188,7 +206,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
188 | internal int m_material = (int)Material.Wood; | 206 | internal int m_material = (int)Material.Wood; |
189 | 207 | ||
190 | public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, | 208 | public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, |
191 | Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) | 209 | Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) |
192 | { | 210 | { |
193 | Name = primName; | 211 | Name = primName; |
194 | m_vehicle = new ODEDynamics(); | 212 | m_vehicle = new ODEDynamics(); |
@@ -208,9 +226,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
208 | // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; | 226 | // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; |
209 | body_autodisable_frames = parent_scene.bodyFramesAutoDisable; | 227 | body_autodisable_frames = parent_scene.bodyFramesAutoDisable; |
210 | 228 | ||
211 | |||
212 | prim_geom = IntPtr.Zero; | 229 | prim_geom = IntPtr.Zero; |
213 | prev_geom = IntPtr.Zero; | ||
214 | 230 | ||
215 | if (!pos.IsFinite()) | 231 | if (!pos.IsFinite()) |
216 | { | 232 | { |
@@ -233,20 +249,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
233 | 249 | ||
234 | _orientation = rotation; | 250 | _orientation = rotation; |
235 | m_taintrot = _orientation; | 251 | m_taintrot = _orientation; |
236 | _mesh = mesh; | ||
237 | _pbs = pbs; | 252 | _pbs = pbs; |
238 | 253 | ||
239 | _parent_scene = parent_scene; | 254 | _parent_scene = parent_scene; |
240 | m_targetSpace = (IntPtr)0; | 255 | m_targetSpace = (IntPtr)0; |
241 | 256 | ||
242 | if (pos.Z < 0) | 257 | if (pos.Z < 0) |
243 | m_isphysical = false; | 258 | { |
259 | IsPhysical = false; | ||
260 | } | ||
244 | else | 261 | else |
245 | { | 262 | { |
246 | m_isphysical = pisPhysical; | 263 | IsPhysical = pisPhysical; |
247 | // If we're physical, we need to be in the master space for now. | 264 | // If we're physical, we need to be in the master space for now. |
248 | // linksets *should* be in a space together.. but are not currently | 265 | // linksets *should* be in a space together.. but are not currently |
249 | if (m_isphysical) | 266 | if (IsPhysical) |
250 | m_targetSpace = _parent_scene.space; | 267 | m_targetSpace = _parent_scene.space; |
251 | } | 268 | } |
252 | 269 | ||
@@ -289,7 +306,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
289 | // through it while it's selected | 306 | // through it while it's selected |
290 | m_collisionscore = 0; | 307 | m_collisionscore = 0; |
291 | 308 | ||
292 | if ((m_isphysical && !_zeroFlag) || !value) | 309 | if ((IsPhysical && !_zeroFlag) || !value) |
293 | { | 310 | { |
294 | m_taintselected = value; | 311 | m_taintselected = value; |
295 | _parent_scene.AddPhysicsActorTaint(this); | 312 | _parent_scene.AddPhysicsActorTaint(this); |
@@ -305,15 +322,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
305 | } | 322 | } |
306 | } | 323 | } |
307 | 324 | ||
325 | /// <summary> | ||
326 | /// Set a new geometry for this prim. | ||
327 | /// </summary> | ||
328 | /// <param name="geom"></param> | ||
308 | public void SetGeom(IntPtr geom) | 329 | public void SetGeom(IntPtr geom) |
309 | { | 330 | { |
310 | prev_geom = prim_geom; | ||
311 | prim_geom = geom; | 331 | prim_geom = geom; |
312 | //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); | 332 | //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); |
313 | if (prim_geom != IntPtr.Zero) | 333 | if (prim_geom != IntPtr.Zero) |
314 | { | 334 | { |
315 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 335 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
316 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 336 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
337 | |||
338 | _parent_scene.geom_name_map[prim_geom] = Name; | ||
339 | _parent_scene.actor_name_map[prim_geom] = this; | ||
317 | } | 340 | } |
318 | 341 | ||
319 | if (childPrim) | 342 | if (childPrim) |
@@ -332,7 +355,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
332 | { | 355 | { |
333 | if (!childPrim) | 356 | if (!childPrim) |
334 | { | 357 | { |
335 | if (m_isphysical && Body != IntPtr.Zero) | 358 | if (IsPhysical && Body != IntPtr.Zero) |
336 | { | 359 | { |
337 | d.BodyEnable(Body); | 360 | d.BodyEnable(Body); |
338 | if (m_vehicle.Type != Vehicle.TYPE_NONE) | 361 | if (m_vehicle.Type != Vehicle.TYPE_NONE) |
@@ -347,12 +370,15 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
347 | { | 370 | { |
348 | m_disabled = true; | 371 | m_disabled = true; |
349 | 372 | ||
350 | if (m_isphysical && Body != IntPtr.Zero) | 373 | if (IsPhysical && Body != IntPtr.Zero) |
351 | { | 374 | { |
352 | d.BodyDisable(Body); | 375 | d.BodyDisable(Body); |
353 | } | 376 | } |
354 | } | 377 | } |
355 | 378 | ||
379 | /// <summary> | ||
380 | /// Make a prim subject to physics. | ||
381 | /// </summary> | ||
356 | public void enableBody() | 382 | public void enableBody() |
357 | { | 383 | { |
358 | // Don't enable this body if we're a child prim | 384 | // Don't enable this body if we're a child prim |
@@ -638,7 +664,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
638 | float profileEnd; | 664 | float profileEnd; |
639 | 665 | ||
640 | if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) | 666 | if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) |
641 | { | 667 | { |
642 | taperX1 = _pbs.PathScaleX * 0.01f; | 668 | taperX1 = _pbs.PathScaleX * 0.01f; |
643 | if (taperX1 > 1.0f) | 669 | if (taperX1 > 1.0f) |
644 | taperX1 = 2.0f - taperX1; | 670 | taperX1 = 2.0f - taperX1; |
@@ -648,9 +674,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
648 | if (taperY1 > 1.0f) | 674 | if (taperY1 > 1.0f) |
649 | taperY1 = 2.0f - taperY1; | 675 | taperY1 = 2.0f - taperY1; |
650 | taperY = 1.0f - taperY1; | 676 | taperY = 1.0f - taperY1; |
651 | } | 677 | } |
652 | else | 678 | else |
653 | { | 679 | { |
654 | taperX = _pbs.PathTaperX * 0.01f; | 680 | taperX = _pbs.PathTaperX * 0.01f; |
655 | if (taperX < 0.0f) | 681 | if (taperX < 0.0f) |
656 | taperX = -taperX; | 682 | taperX = -taperX; |
@@ -660,9 +686,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
660 | if (taperY < 0.0f) | 686 | if (taperY < 0.0f) |
661 | taperY = -taperY; | 687 | taperY = -taperY; |
662 | taperY1 = 1.0f - taperY; | 688 | taperY1 = 1.0f - taperY; |
663 | 689 | } | |
664 | } | ||
665 | |||
666 | 690 | ||
667 | volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); | 691 | volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); |
668 | 692 | ||
@@ -730,6 +754,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
730 | } | 754 | } |
731 | } | 755 | } |
732 | 756 | ||
757 | /// <summary> | ||
758 | /// Stop a prim from being subject to physics. | ||
759 | /// </summary> | ||
733 | public void disableBody() | 760 | public void disableBody() |
734 | { | 761 | { |
735 | //this kills the body so things like 'mesh' can re-create it. | 762 | //this kills the body so things like 'mesh' can re-create it. |
@@ -780,6 +807,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
780 | Body = IntPtr.Zero; | 807 | Body = IntPtr.Zero; |
781 | } | 808 | } |
782 | } | 809 | } |
810 | |||
783 | m_disabled = true; | 811 | m_disabled = true; |
784 | m_collisionscore = 0; | 812 | m_collisionscore = 0; |
785 | } | 813 | } |
@@ -846,7 +874,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
846 | return; | 874 | return; |
847 | } | 875 | } |
848 | 876 | ||
849 | |||
850 | // if (IsPhysical && Body == (IntPtr) 0) | 877 | // if (IsPhysical && Body == (IntPtr) 0) |
851 | // { | 878 | // { |
852 | // Recreate the body | 879 | // Recreate the body |
@@ -859,7 +886,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
859 | 886 | ||
860 | public void ProcessTaints(float timestep) | 887 | public void ProcessTaints(float timestep) |
861 | { | 888 | { |
862 | Console.WriteLine("ProcessTaints for " + Name); | 889 | #if SPAM |
890 | Console.WriteLine("ZProcessTaints for " + Name); | ||
891 | #endif | ||
863 | if (m_taintadd) | 892 | if (m_taintadd) |
864 | { | 893 | { |
865 | changeadd(timestep); | 894 | changeadd(timestep); |
@@ -887,7 +916,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
887 | } | 916 | } |
888 | } | 917 | } |
889 | 918 | ||
890 | if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) | 919 | if (m_taintPhysics != IsPhysical && !(m_taintparent != _parent)) |
891 | changePhysicsStatus(timestep); | 920 | changePhysicsStatus(timestep); |
892 | 921 | ||
893 | if (!_size.ApproxEquals(m_taintsize, 0f)) | 922 | if (!_size.ApproxEquals(m_taintsize, 0f)) |
@@ -969,7 +998,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
969 | OdePrim obj = (OdePrim)m_taintparent; | 998 | OdePrim obj = (OdePrim)m_taintparent; |
970 | //obj.disableBody(); | 999 | //obj.disableBody(); |
971 | //Console.WriteLine("changelink calls ParentPrim"); | 1000 | //Console.WriteLine("changelink calls ParentPrim"); |
972 | obj.ParentPrim(this); | 1001 | obj.AddChildPrim(this); |
973 | 1002 | ||
974 | /* | 1003 | /* |
975 | if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body) | 1004 | if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body) |
@@ -1006,14 +1035,16 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1006 | } | 1035 | } |
1007 | 1036 | ||
1008 | _parent = m_taintparent; | 1037 | _parent = m_taintparent; |
1009 | m_taintPhysics = m_isphysical; | 1038 | m_taintPhysics = IsPhysical; |
1010 | } | 1039 | } |
1011 | 1040 | ||
1012 | // I'm the parent | 1041 | /// <summary> |
1013 | // prim is the child | 1042 | /// Add a child prim to this parent prim. |
1014 | public void ParentPrim(OdePrim prim) | 1043 | /// </summary> |
1044 | /// <param name="prim">Child prim</param> | ||
1045 | public void AddChildPrim(OdePrim prim) | ||
1015 | { | 1046 | { |
1016 | //Console.WriteLine("ParentPrim " + Name); | 1047 | //Console.WriteLine("AddChildPrim " + Name); |
1017 | if (this.m_localID != prim.m_localID) | 1048 | if (this.m_localID != prim.m_localID) |
1018 | { | 1049 | { |
1019 | if (Body == IntPtr.Zero) | 1050 | if (Body == IntPtr.Zero) |
@@ -1036,7 +1067,6 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1036 | d.MassSetZero(out m2); | 1067 | d.MassSetZero(out m2); |
1037 | d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); | 1068 | d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); |
1038 | 1069 | ||
1039 | |||
1040 | d.Quaternion quat = new d.Quaternion(); | 1070 | d.Quaternion quat = new d.Quaternion(); |
1041 | quat.W = prm._orientation.W; | 1071 | quat.W = prm._orientation.W; |
1042 | quat.X = prm._orientation.X; | 1072 | quat.X = prm._orientation.X; |
@@ -1106,6 +1136,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1106 | prm.Body = Body; | 1136 | prm.Body = Body; |
1107 | _parent_scene.addActivePrim(prm); | 1137 | _parent_scene.addActivePrim(prm); |
1108 | } | 1138 | } |
1139 | |||
1109 | m_collisionCategories |= CollisionCategories.Body; | 1140 | m_collisionCategories |= CollisionCategories.Body; |
1110 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1141 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1111 | 1142 | ||
@@ -1114,7 +1145,6 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1114 | //Console.WriteLine(" Post GeomSetCategoryBits 2"); | 1145 | //Console.WriteLine(" Post GeomSetCategoryBits 2"); |
1115 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1146 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1116 | 1147 | ||
1117 | |||
1118 | d.Quaternion quat2 = new d.Quaternion(); | 1148 | d.Quaternion quat2 = new d.Quaternion(); |
1119 | quat2.W = _orientation.W; | 1149 | quat2.W = _orientation.W; |
1120 | quat2.X = _orientation.X; | 1150 | quat2.X = _orientation.X; |
@@ -1136,7 +1166,6 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1136 | d.BodySetAutoDisableFlag(Body, true); | 1166 | d.BodySetAutoDisableFlag(Body, true); |
1137 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 1167 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); |
1138 | 1168 | ||
1139 | |||
1140 | m_interpenetrationcount = 0; | 1169 | m_interpenetrationcount = 0; |
1141 | m_collisionscore = 0; | 1170 | m_collisionscore = 0; |
1142 | m_disabled = false; | 1171 | m_disabled = false; |
@@ -1147,7 +1176,9 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1147 | createAMotor(m_angularlock); | 1176 | createAMotor(m_angularlock); |
1148 | } | 1177 | } |
1149 | d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); | 1178 | d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); |
1150 | if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); | 1179 | if (m_vehicle.Type != Vehicle.TYPE_NONE) |
1180 | m_vehicle.Enable(Body, _parent_scene); | ||
1181 | |||
1151 | _parent_scene.addActivePrim(this); | 1182 | _parent_scene.addActivePrim(this); |
1152 | } | 1183 | } |
1153 | } | 1184 | } |
@@ -1157,7 +1188,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1157 | 1188 | ||
1158 | private void ChildSetGeom(OdePrim odePrim) | 1189 | private void ChildSetGeom(OdePrim odePrim) |
1159 | { | 1190 | { |
1160 | //if (m_isphysical && Body != IntPtr.Zero) | 1191 | //if (IsPhysical && Body != IntPtr.Zero) |
1161 | lock (childrenPrim) | 1192 | lock (childrenPrim) |
1162 | { | 1193 | { |
1163 | foreach (OdePrim prm in childrenPrim) | 1194 | foreach (OdePrim prm in childrenPrim) |
@@ -1173,7 +1204,6 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1173 | } | 1204 | } |
1174 | disableBody(); | 1205 | disableBody(); |
1175 | 1206 | ||
1176 | |||
1177 | if (Body != IntPtr.Zero) | 1207 | if (Body != IntPtr.Zero) |
1178 | { | 1208 | { |
1179 | _parent_scene.remActivePrim(this); | 1209 | _parent_scene.remActivePrim(this); |
@@ -1184,10 +1214,9 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1184 | foreach (OdePrim prm in childrenPrim) | 1214 | foreach (OdePrim prm in childrenPrim) |
1185 | { | 1215 | { |
1186 | //Console.WriteLine("ChildSetGeom calls ParentPrim"); | 1216 | //Console.WriteLine("ChildSetGeom calls ParentPrim"); |
1187 | ParentPrim(prm); | 1217 | AddChildPrim(prm); |
1188 | } | 1218 | } |
1189 | } | 1219 | } |
1190 | |||
1191 | } | 1220 | } |
1192 | 1221 | ||
1193 | private void ChildDelink(OdePrim odePrim) | 1222 | private void ChildDelink(OdePrim odePrim) |
@@ -1224,7 +1253,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1224 | foreach (OdePrim prm in childrenPrim) | 1253 | foreach (OdePrim prm in childrenPrim) |
1225 | { | 1254 | { |
1226 | //Console.WriteLine("ChildDelink calls ParentPrim"); | 1255 | //Console.WriteLine("ChildDelink calls ParentPrim"); |
1227 | ParentPrim(prm); | 1256 | AddChildPrim(prm); |
1228 | } | 1257 | } |
1229 | } | 1258 | } |
1230 | } | 1259 | } |
@@ -1258,7 +1287,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1258 | // first 50 again. then the last 50 are disabled. then the first 50, which were just woken | 1287 | // first 50 again. then the last 50 are disabled. then the first 50, which were just woken |
1259 | // up, start simulating again, which in turn wakes up the last 50. | 1288 | // up, start simulating again, which in turn wakes up the last 50. |
1260 | 1289 | ||
1261 | if (m_isphysical) | 1290 | if (IsPhysical) |
1262 | { | 1291 | { |
1263 | disableBodySoft(); | 1292 | disableBodySoft(); |
1264 | } | 1293 | } |
@@ -1269,7 +1298,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1269 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1298 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1270 | } | 1299 | } |
1271 | 1300 | ||
1272 | if (m_isphysical) | 1301 | if (IsPhysical) |
1273 | { | 1302 | { |
1274 | disableBodySoft(); | 1303 | disableBodySoft(); |
1275 | } | 1304 | } |
@@ -1278,7 +1307,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1278 | { | 1307 | { |
1279 | m_collisionCategories = CollisionCategories.Geom; | 1308 | m_collisionCategories = CollisionCategories.Geom; |
1280 | 1309 | ||
1281 | if (m_isphysical) | 1310 | if (IsPhysical) |
1282 | m_collisionCategories |= CollisionCategories.Body; | 1311 | m_collisionCategories |= CollisionCategories.Body; |
1283 | 1312 | ||
1284 | m_collisionFlags = m_default_collisionFlags; | 1313 | m_collisionFlags = m_default_collisionFlags; |
@@ -1293,7 +1322,8 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1293 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1322 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
1294 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1323 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1295 | } | 1324 | } |
1296 | if (m_isphysical) | 1325 | |
1326 | if (IsPhysical) | ||
1297 | { | 1327 | { |
1298 | if (Body != IntPtr.Zero) | 1328 | if (Body != IntPtr.Zero) |
1299 | { | 1329 | { |
@@ -1312,7 +1342,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1312 | { | 1342 | { |
1313 | m_taintposition = _position; | 1343 | m_taintposition = _position; |
1314 | m_taintrot = _orientation; | 1344 | m_taintrot = _orientation; |
1315 | m_taintPhysics = m_isphysical; | 1345 | m_taintPhysics = IsPhysical; |
1316 | m_taintselected = m_isSelected; | 1346 | m_taintselected = m_isSelected; |
1317 | m_taintsize = _size; | 1347 | m_taintsize = _size; |
1318 | m_taintshape = false; | 1348 | m_taintshape = false; |
@@ -1321,12 +1351,19 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1321 | m_taintVelocity = Vector3.Zero; | 1351 | m_taintVelocity = Vector3.Zero; |
1322 | } | 1352 | } |
1323 | 1353 | ||
1324 | public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) | 1354 | /// <summary> |
1355 | /// Create a geometry for the given mesh in the given target space. | ||
1356 | /// </summary> | ||
1357 | /// <param name="m_targetSpace"></param> | ||
1358 | /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param> | ||
1359 | public void CreateGeom(IntPtr m_targetSpace, IMesh mesh) | ||
1325 | { | 1360 | { |
1326 | //Console.WriteLine("CreateGeom:"); | 1361 | #if SPAM |
1327 | if (_mesh != null) | 1362 | Console.WriteLine("CreateGeom:"); |
1363 | #endif | ||
1364 | if (mesh != null) | ||
1328 | { | 1365 | { |
1329 | setMesh(_parent_scene, _mesh); | 1366 | setMesh(_parent_scene, mesh); |
1330 | } | 1367 | } |
1331 | else | 1368 | else |
1332 | { | 1369 | { |
@@ -1399,6 +1436,39 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1399 | } | 1436 | } |
1400 | } | 1437 | } |
1401 | 1438 | ||
1439 | /// <summary> | ||
1440 | /// Remove the existing geom from this prim. | ||
1441 | /// </summary> | ||
1442 | /// <param name="m_targetSpace"></param> | ||
1443 | /// <param name="mesh">If null, then a mesh is used that is based on the profile shape data.</param> | ||
1444 | /// <returns>true if the geom was successfully removed, false if it was already gone or the remove failed.</returns> | ||
1445 | public bool RemoveGeom() | ||
1446 | { | ||
1447 | if (prim_geom != IntPtr.Zero) | ||
1448 | { | ||
1449 | try | ||
1450 | { | ||
1451 | _parent_scene.geom_name_map.Remove(prim_geom); | ||
1452 | _parent_scene.actor_name_map.Remove(prim_geom); | ||
1453 | d.GeomDestroy(prim_geom); | ||
1454 | prim_geom = IntPtr.Zero; | ||
1455 | } | ||
1456 | catch (System.AccessViolationException) | ||
1457 | { | ||
1458 | prim_geom = IntPtr.Zero; | ||
1459 | m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); | ||
1460 | |||
1461 | return false; | ||
1462 | } | ||
1463 | |||
1464 | return true; | ||
1465 | } | ||
1466 | else | ||
1467 | { | ||
1468 | return false; | ||
1469 | } | ||
1470 | } | ||
1471 | |||
1402 | public void changeadd(float timestep) | 1472 | public void changeadd(float timestep) |
1403 | { | 1473 | { |
1404 | int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); | 1474 | int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); |
@@ -1409,15 +1479,14 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1409 | 1479 | ||
1410 | m_targetSpace = targetspace; | 1480 | m_targetSpace = targetspace; |
1411 | 1481 | ||
1412 | if (_mesh == null) | 1482 | IMesh mesh = null; |
1483 | |||
1484 | if (_parent_scene.needsMeshing(_pbs)) | ||
1413 | { | 1485 | { |
1414 | if (_parent_scene.needsMeshing(_pbs)) | 1486 | // Don't need to re-enable body.. it's done in SetMesh |
1415 | { | 1487 | mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); |
1416 | // Don't need to re-enable body.. it's done in SetMesh | 1488 | // createmesh returns null when it's a shape that isn't a cube. |
1417 | _mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); | 1489 | // m_log.Debug(m_localID); |
1418 | // createmesh returns null when it's a shape that isn't a cube. | ||
1419 | // m_log.Debug(m_localID); | ||
1420 | } | ||
1421 | } | 1490 | } |
1422 | 1491 | ||
1423 | lock (_parent_scene.OdeLock) | 1492 | lock (_parent_scene.OdeLock) |
@@ -1425,7 +1494,7 @@ Console.WriteLine("ProcessTaints for " + Name); | |||
1425 | #if SPAM | 1494 | #if SPAM |
1426 | Console.WriteLine("changeadd 1"); | 1495 | Console.WriteLine("changeadd 1"); |
1427 | #endif | 1496 | #endif |
1428 | CreateGeom(m_targetSpace, _mesh); | 1497 | CreateGeom(m_targetSpace, mesh); |
1429 | 1498 | ||
1430 | if (prim_geom != IntPtr.Zero) | 1499 | if (prim_geom != IntPtr.Zero) |
1431 | { | 1500 | { |
@@ -1438,15 +1507,12 @@ Console.WriteLine("changeadd 1"); | |||
1438 | d.GeomSetQuaternion(prim_geom, ref myrot); | 1507 | d.GeomSetQuaternion(prim_geom, ref myrot); |
1439 | } | 1508 | } |
1440 | 1509 | ||
1441 | if (m_isphysical && Body == IntPtr.Zero) | 1510 | if (IsPhysical && Body == IntPtr.Zero) |
1442 | { | 1511 | { |
1443 | enableBody(); | 1512 | enableBody(); |
1444 | } | 1513 | } |
1445 | } | 1514 | } |
1446 | 1515 | ||
1447 | _parent_scene.geom_name_map[prim_geom] = this.Name; | ||
1448 | _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; | ||
1449 | |||
1450 | changeSelectedStatus(timestep); | 1516 | changeSelectedStatus(timestep); |
1451 | 1517 | ||
1452 | m_taintadd = false; | 1518 | m_taintadd = false; |
@@ -1454,9 +1520,8 @@ Console.WriteLine("changeadd 1"); | |||
1454 | 1520 | ||
1455 | public void changemove(float timestep) | 1521 | public void changemove(float timestep) |
1456 | { | 1522 | { |
1457 | if (m_isphysical) | 1523 | if (IsPhysical) |
1458 | { | 1524 | { |
1459 | |||
1460 | if (!m_disabled && !m_taintremove && !childPrim) | 1525 | if (!m_disabled && !m_taintremove && !childPrim) |
1461 | { | 1526 | { |
1462 | if (Body == IntPtr.Zero) | 1527 | if (Body == IntPtr.Zero) |
@@ -1788,7 +1853,7 @@ Console.WriteLine(" JointCreateFixed"); | |||
1788 | { | 1853 | { |
1789 | // KF: If this is a root prim do BodySet | 1854 | // KF: If this is a root prim do BodySet |
1790 | d.BodySetQuaternion(Body, ref myrot); | 1855 | d.BodySetQuaternion(Body, ref myrot); |
1791 | if (m_isphysical) | 1856 | if (IsPhysical) |
1792 | { | 1857 | { |
1793 | if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) | 1858 | if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) |
1794 | createAMotor(m_angularlock); | 1859 | createAMotor(m_angularlock); |
@@ -1825,7 +1890,7 @@ Console.WriteLine(" JointCreateFixed"); | |||
1825 | 1890 | ||
1826 | public void changePhysicsStatus(float timestep) | 1891 | public void changePhysicsStatus(float timestep) |
1827 | { | 1892 | { |
1828 | if (m_isphysical == true) | 1893 | if (IsPhysical) |
1829 | { | 1894 | { |
1830 | if (Body == IntPtr.Zero) | 1895 | if (Body == IntPtr.Zero) |
1831 | { | 1896 | { |
@@ -1845,25 +1910,12 @@ Console.WriteLine(" JointCreateFixed"); | |||
1845 | { | 1910 | { |
1846 | if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) | 1911 | if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) |
1847 | { | 1912 | { |
1848 | 1913 | RemoveGeom(); | |
1849 | 1914 | ||
1850 | if (prim_geom != IntPtr.Zero) | ||
1851 | { | ||
1852 | try | ||
1853 | { | ||
1854 | d.GeomDestroy(prim_geom); | ||
1855 | prim_geom = IntPtr.Zero; | ||
1856 | _mesh = null; | ||
1857 | } | ||
1858 | catch (System.AccessViolationException) | ||
1859 | { | ||
1860 | prim_geom = IntPtr.Zero; | ||
1861 | m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); | ||
1862 | } | ||
1863 | } | ||
1864 | //Console.WriteLine("changePhysicsStatus for " + Name); | 1915 | //Console.WriteLine("changePhysicsStatus for " + Name); |
1865 | changeadd(2f); | 1916 | changeadd(2f); |
1866 | } | 1917 | } |
1918 | |||
1867 | if (childPrim) | 1919 | if (childPrim) |
1868 | { | 1920 | { |
1869 | if (_parent != null) | 1921 | if (_parent != null) |
@@ -1882,7 +1934,7 @@ Console.WriteLine(" JointCreateFixed"); | |||
1882 | changeSelectedStatus(timestep); | 1934 | changeSelectedStatus(timestep); |
1883 | 1935 | ||
1884 | resetCollisionAccounting(); | 1936 | resetCollisionAccounting(); |
1885 | m_taintPhysics = m_isphysical; | 1937 | m_taintPhysics = IsPhysical; |
1886 | } | 1938 | } |
1887 | 1939 | ||
1888 | public void changesize(float timestamp) | 1940 | public void changesize(float timestamp) |
@@ -1891,18 +1943,10 @@ Console.WriteLine(" JointCreateFixed"); | |||
1891 | m_log.DebugFormat("[ODE PRIM]: Called changesize"); | 1943 | m_log.DebugFormat("[ODE PRIM]: Called changesize"); |
1892 | #endif | 1944 | #endif |
1893 | 1945 | ||
1894 | string oldname = _parent_scene.geom_name_map[prim_geom]; | ||
1895 | |||
1896 | if (_size.X <= 0) _size.X = 0.01f; | 1946 | if (_size.X <= 0) _size.X = 0.01f; |
1897 | if (_size.Y <= 0) _size.Y = 0.01f; | 1947 | if (_size.Y <= 0) _size.Y = 0.01f; |
1898 | if (_size.Z <= 0) _size.Z = 0.01f; | 1948 | if (_size.Z <= 0) _size.Z = 0.01f; |
1899 | 1949 | ||
1900 | // Cleanup of old prim geometry | ||
1901 | if (_mesh != null) | ||
1902 | { | ||
1903 | // TODO: Cleanup meshing here | ||
1904 | } | ||
1905 | |||
1906 | //kill body to rebuild | 1950 | //kill body to rebuild |
1907 | if (IsPhysical && Body != IntPtr.Zero) | 1951 | if (IsPhysical && Body != IntPtr.Zero) |
1908 | { | 1952 | { |
@@ -1926,10 +1970,12 @@ Console.WriteLine(" JointCreateFixed"); | |||
1926 | d.SpaceRemove(m_targetSpace, prim_geom); | 1970 | d.SpaceRemove(m_targetSpace, prim_geom); |
1927 | } | 1971 | } |
1928 | 1972 | ||
1929 | d.GeomDestroy(prim_geom); | 1973 | RemoveGeom(); |
1930 | prim_geom = IntPtr.Zero; | 1974 | |
1931 | // we don't need to do space calculation because the client sends a position update also. | 1975 | // we don't need to do space calculation because the client sends a position update also. |
1932 | 1976 | ||
1977 | IMesh mesh = null; | ||
1978 | |||
1933 | // Construction of new prim | 1979 | // Construction of new prim |
1934 | if (_parent_scene.needsMeshing(_pbs)) | 1980 | if (_parent_scene.needsMeshing(_pbs)) |
1935 | { | 1981 | { |
@@ -1939,28 +1985,11 @@ Console.WriteLine(" JointCreateFixed"); | |||
1939 | meshlod = _parent_scene.MeshSculptphysicalLOD; | 1985 | meshlod = _parent_scene.MeshSculptphysicalLOD; |
1940 | // Don't need to re-enable body.. it's done in SetMesh | 1986 | // Don't need to re-enable body.. it's done in SetMesh |
1941 | 1987 | ||
1942 | IMesh mesh = null; | ||
1943 | |||
1944 | if (_parent_scene.needsMeshing(_pbs)) | 1988 | if (_parent_scene.needsMeshing(_pbs)) |
1945 | mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); | 1989 | mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); |
1946 | |||
1947 | //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); | ||
1948 | #if SPAM | ||
1949 | Console.WriteLine("changesize 1"); | ||
1950 | #endif | ||
1951 | CreateGeom(m_targetSpace, mesh); | ||
1952 | } | ||
1953 | else | ||
1954 | { | ||
1955 | _mesh = null; | ||
1956 | |||
1957 | #if SPAM | ||
1958 | Console.WriteLine("changesize 2"); | ||
1959 | #endif | ||
1960 | |||
1961 | CreateGeom(m_targetSpace, _mesh); | ||
1962 | } | 1990 | } |
1963 | 1991 | ||
1992 | CreateGeom(m_targetSpace, mesh); | ||
1964 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 1993 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
1965 | d.Quaternion myrot = new d.Quaternion(); | 1994 | d.Quaternion myrot = new d.Quaternion(); |
1966 | myrot.X = _orientation.X; | 1995 | myrot.X = _orientation.X; |
@@ -1978,8 +2007,6 @@ Console.WriteLine("changesize 2"); | |||
1978 | d.BodyEnable(Body); | 2007 | d.BodyEnable(Body); |
1979 | } | 2008 | } |
1980 | 2009 | ||
1981 | _parent_scene.geom_name_map[prim_geom] = oldname; | ||
1982 | |||
1983 | changeSelectedStatus(timestamp); | 2010 | changeSelectedStatus(timestamp); |
1984 | if (childPrim) | 2011 | if (childPrim) |
1985 | { | 2012 | { |
@@ -2013,8 +2040,6 @@ Console.WriteLine("changesize 2"); | |||
2013 | 2040 | ||
2014 | public void changeshape(float timestamp) | 2041 | public void changeshape(float timestamp) |
2015 | { | 2042 | { |
2016 | string oldname = _parent_scene.geom_name_map[prim_geom]; | ||
2017 | |||
2018 | // Cleanup of old prim geometry and Bodies | 2043 | // Cleanup of old prim geometry and Bodies |
2019 | if (IsPhysical && Body != IntPtr.Zero) | 2044 | if (IsPhysical && Body != IntPtr.Zero) |
2020 | { | 2045 | { |
@@ -2031,23 +2056,17 @@ Console.WriteLine("changesize 2"); | |||
2031 | disableBody(); | 2056 | disableBody(); |
2032 | } | 2057 | } |
2033 | } | 2058 | } |
2034 | try | ||
2035 | { | ||
2036 | d.GeomDestroy(prim_geom); | ||
2037 | } | ||
2038 | catch (System.AccessViolationException) | ||
2039 | { | ||
2040 | prim_geom = IntPtr.Zero; | ||
2041 | m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); | ||
2042 | } | ||
2043 | 2059 | ||
2044 | prim_geom = IntPtr.Zero; | 2060 | RemoveGeom(); |
2061 | |||
2045 | // we don't need to do space calculation because the client sends a position update also. | 2062 | // we don't need to do space calculation because the client sends a position update also. |
2046 | if (_size.X <= 0) _size.X = 0.01f; | 2063 | if (_size.X <= 0) _size.X = 0.01f; |
2047 | if (_size.Y <= 0) _size.Y = 0.01f; | 2064 | if (_size.Y <= 0) _size.Y = 0.01f; |
2048 | if (_size.Z <= 0) _size.Z = 0.01f; | 2065 | if (_size.Z <= 0) _size.Z = 0.01f; |
2049 | // Construction of new prim | 2066 | // Construction of new prim |
2050 | 2067 | ||
2068 | IMesh mesh = null; | ||
2069 | |||
2051 | if (_parent_scene.needsMeshing(_pbs)) | 2070 | if (_parent_scene.needsMeshing(_pbs)) |
2052 | { | 2071 | { |
2053 | // Don't need to re-enable body.. it's done in CreateMesh | 2072 | // Don't need to re-enable body.. it's done in CreateMesh |
@@ -2056,23 +2075,11 @@ Console.WriteLine("changesize 2"); | |||
2056 | if (IsPhysical) | 2075 | if (IsPhysical) |
2057 | meshlod = _parent_scene.MeshSculptphysicalLOD; | 2076 | meshlod = _parent_scene.MeshSculptphysicalLOD; |
2058 | 2077 | ||
2059 | IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); | ||
2060 | // createmesh returns null when it doesn't mesh. | 2078 | // createmesh returns null when it doesn't mesh. |
2061 | #if SPAM | 2079 | mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); |
2062 | Console.WriteLine("changeshape needed meshing"); | ||
2063 | #endif | ||
2064 | CreateGeom(m_targetSpace, mesh); | ||
2065 | } | ||
2066 | else | ||
2067 | { | ||
2068 | _mesh = null; | ||
2069 | |||
2070 | #if SPAM | ||
2071 | Console.WriteLine("changeshape not need meshing"); | ||
2072 | #endif | ||
2073 | CreateGeom(m_targetSpace, null); | ||
2074 | } | 2080 | } |
2075 | 2081 | ||
2082 | CreateGeom(m_targetSpace, mesh); | ||
2076 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 2083 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
2077 | d.Quaternion myrot = new d.Quaternion(); | 2084 | d.Quaternion myrot = new d.Quaternion(); |
2078 | //myrot.W = _orientation.w; | 2085 | //myrot.W = _orientation.w; |
@@ -2093,7 +2100,6 @@ Console.WriteLine("changeshape not need meshing"); | |||
2093 | d.BodyEnable(Body); | 2100 | d.BodyEnable(Body); |
2094 | } | 2101 | } |
2095 | } | 2102 | } |
2096 | _parent_scene.geom_name_map[prim_geom] = oldname; | ||
2097 | 2103 | ||
2098 | changeSelectedStatus(timestamp); | 2104 | changeSelectedStatus(timestamp); |
2099 | if (childPrim) | 2105 | if (childPrim) |
@@ -2104,6 +2110,7 @@ Console.WriteLine("changeshape not need meshing"); | |||
2104 | parent.ChildSetGeom(this); | 2110 | parent.ChildSetGeom(this); |
2105 | } | 2111 | } |
2106 | } | 2112 | } |
2113 | |||
2107 | resetCollisionAccounting(); | 2114 | resetCollisionAccounting(); |
2108 | m_taintshape = false; | 2115 | m_taintshape = false; |
2109 | } | 2116 | } |
@@ -2215,16 +2222,6 @@ Console.WriteLine("changeshape not need meshing"); | |||
2215 | m_taintVelocity = Vector3.Zero; | 2222 | m_taintVelocity = Vector3.Zero; |
2216 | } | 2223 | } |
2217 | 2224 | ||
2218 | public override bool IsPhysical | ||
2219 | { | ||
2220 | get { return m_isphysical; } | ||
2221 | set { | ||
2222 | m_isphysical = value; | ||
2223 | if (!m_isphysical) // Zero the remembered last velocity | ||
2224 | m_lastVelocity = Vector3.Zero; | ||
2225 | } | ||
2226 | } | ||
2227 | |||
2228 | public void setPrimForRemoval() | 2225 | public void setPrimForRemoval() |
2229 | { | 2226 | { |
2230 | m_taintremove = true; | 2227 | m_taintremove = true; |
@@ -2283,6 +2280,7 @@ Console.WriteLine("changeshape not need meshing"); | |||
2283 | if (value.IsFinite()) | 2280 | if (value.IsFinite()) |
2284 | { | 2281 | { |
2285 | _size = value; | 2282 | _size = value; |
2283 | // m_log.DebugFormat("[PHYSICS]: Set size on {0} to {1}", Name, value); | ||
2286 | } | 2284 | } |
2287 | else | 2285 | else |
2288 | { | 2286 | { |
@@ -2343,7 +2341,7 @@ Console.WriteLine("changeshape not need meshing"); | |||
2343 | { | 2341 | { |
2344 | lock (_parent_scene.OdeLock) | 2342 | lock (_parent_scene.OdeLock) |
2345 | { | 2343 | { |
2346 | m_isVolumeDetect = (param!=0); | 2344 | m_isVolumeDetect = (param != 0); |
2347 | } | 2345 | } |
2348 | } | 2346 | } |
2349 | 2347 | ||
@@ -2402,7 +2400,7 @@ Console.WriteLine("changeshape not need meshing"); | |||
2402 | { | 2400 | { |
2403 | get | 2401 | get |
2404 | { | 2402 | { |
2405 | if (!m_isphysical || Body == IntPtr.Zero) | 2403 | if (!IsPhysical || Body == IntPtr.Zero) |
2406 | return Vector3.Zero; | 2404 | return Vector3.Zero; |
2407 | 2405 | ||
2408 | return _torque; | 2406 | return _torque; |
@@ -2984,12 +2982,12 @@ Console.WriteLine("changeshape not need meshing"); | |||
2984 | public override void SubscribeEvents(int ms) | 2982 | public override void SubscribeEvents(int ms) |
2985 | { | 2983 | { |
2986 | m_eventsubscription = ms; | 2984 | m_eventsubscription = ms; |
2987 | _parent_scene.addCollisionEventReporting(this); | 2985 | _parent_scene.AddCollisionEventReporting(this); |
2988 | } | 2986 | } |
2989 | 2987 | ||
2990 | public override void UnSubscribeEvents() | 2988 | public override void UnSubscribeEvents() |
2991 | { | 2989 | { |
2992 | _parent_scene.remCollisionEventReporting(this); | 2990 | _parent_scene.RemoveCollisionEventReporting(this); |
2993 | m_eventsubscription = 0; | 2991 | m_eventsubscription = 0; |
2994 | } | 2992 | } |
2995 | 2993 | ||
@@ -2997,6 +2995,7 @@ Console.WriteLine("changeshape not need meshing"); | |||
2997 | { | 2995 | { |
2998 | if (CollisionEventsThisFrame == null) | 2996 | if (CollisionEventsThisFrame == null) |
2999 | CollisionEventsThisFrame = new CollisionEventUpdate(); | 2997 | CollisionEventsThisFrame = new CollisionEventUpdate(); |
2998 | |||
3000 | CollisionEventsThisFrame.addCollider(CollidedWith, contact); | 2999 | CollisionEventsThisFrame.addCollider(CollidedWith, contact); |
3001 | } | 3000 | } |
3002 | 3001 | ||
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs index 15ccddc..9d7aa94 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs | |||
@@ -45,11 +45,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
45 | public class ODERayCastRequestManager | 45 | public class ODERayCastRequestManager |
46 | { | 46 | { |
47 | /// <summary> | 47 | /// <summary> |
48 | /// Pending Raycast Requests | 48 | /// Pending raycast requests |
49 | /// </summary> | 49 | /// </summary> |
50 | protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>(); | 50 | protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>(); |
51 | 51 | ||
52 | /// <summary> | 52 | /// <summary> |
53 | /// Pending ray requests | ||
54 | /// </summary> | ||
55 | protected List<ODERayRequest> m_PendingRayRequests = new List<ODERayRequest>(); | ||
56 | |||
57 | /// <summary> | ||
53 | /// Scene that created this object. | 58 | /// Scene that created this object. |
54 | /// </summary> | 59 | /// </summary> |
55 | private OdeScene m_scene; | 60 | private OdeScene m_scene; |
@@ -96,6 +101,29 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
96 | } | 101 | } |
97 | 102 | ||
98 | /// <summary> | 103 | /// <summary> |
104 | /// Queues a raycast | ||
105 | /// </summary> | ||
106 | /// <param name="position">Origin of Ray</param> | ||
107 | /// <param name="direction">Ray normal</param> | ||
108 | /// <param name="length">Ray length</param> | ||
109 | /// <param name="count"></param> | ||
110 | /// <param name="retMethod">Return method to send the results</param> | ||
111 | public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) | ||
112 | { | ||
113 | lock (m_PendingRequests) | ||
114 | { | ||
115 | ODERayRequest req = new ODERayRequest(); | ||
116 | req.callbackMethod = retMethod; | ||
117 | req.length = length; | ||
118 | req.Normal = direction; | ||
119 | req.Origin = position; | ||
120 | req.Count = count; | ||
121 | |||
122 | m_PendingRayRequests.Add(req); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | /// <summary> | ||
99 | /// Process all queued raycast requests | 127 | /// Process all queued raycast requests |
100 | /// </summary> | 128 | /// </summary> |
101 | /// <returns>Time in MS the raycasts took to process.</returns> | 129 | /// <returns>Time in MS the raycasts took to process.</returns> |
@@ -119,15 +147,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
119 | //Fail silently | 147 | //Fail silently |
120 | } | 148 | } |
121 | } | 149 | } |
122 | /* | 150 | |
123 | foreach (ODERayCastRequest req in m_PendingRequests) | 151 | m_PendingRequests.Clear(); |
152 | } | ||
153 | } | ||
154 | |||
155 | lock (m_PendingRayRequests) | ||
156 | { | ||
157 | if (m_PendingRayRequests.Count > 0) | ||
158 | { | ||
159 | ODERayRequest[] reqs = m_PendingRayRequests.ToArray(); | ||
160 | for (int i = 0; i < reqs.Length; i++) | ||
124 | { | 161 | { |
125 | if (req.callbackMethod != null) // quick optimization here, don't raycast | 162 | if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast |
126 | RayCast(req); // if there isn't anyone to send results to | 163 | RayCast(reqs[i]); // if there isn't anyone to send results |
127 | |||
128 | } | 164 | } |
129 | */ | 165 | |
130 | m_PendingRequests.Clear(); | 166 | m_PendingRayRequests.Clear(); |
131 | } | 167 | } |
132 | } | 168 | } |
133 | 169 | ||
@@ -153,7 +189,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
153 | // Remove Ray | 189 | // Remove Ray |
154 | d.GeomDestroy(ray); | 190 | d.GeomDestroy(ray); |
155 | 191 | ||
156 | |||
157 | // Define default results | 192 | // Define default results |
158 | bool hitYN = false; | 193 | bool hitYN = false; |
159 | uint hitConsumerID = 0; | 194 | uint hitConsumerID = 0; |
@@ -184,6 +219,31 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
184 | req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal); | 219 | req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal); |
185 | } | 220 | } |
186 | 221 | ||
222 | /// <summary> | ||
223 | /// Method that actually initiates the raycast | ||
224 | /// </summary> | ||
225 | /// <param name="req"></param> | ||
226 | private void RayCast(ODERayRequest req) | ||
227 | { | ||
228 | // Create the ray | ||
229 | IntPtr ray = d.CreateRay(m_scene.space, req.length); | ||
230 | d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); | ||
231 | |||
232 | // Collide test | ||
233 | d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback); | ||
234 | |||
235 | // Remove Ray | ||
236 | d.GeomDestroy(ray); | ||
237 | |||
238 | // Find closest contact and object. | ||
239 | lock (m_contactResults) | ||
240 | { | ||
241 | // Return results | ||
242 | if (req.callbackMethod != null) | ||
243 | req.callbackMethod(m_contactResults); | ||
244 | } | ||
245 | } | ||
246 | |||
187 | // This is the standard Near. Uses space AABBs to speed up detection. | 247 | // This is the standard Near. Uses space AABBs to speed up detection. |
188 | private void near(IntPtr space, IntPtr g1, IntPtr g2) | 248 | private void near(IntPtr space, IntPtr g1, IntPtr g2) |
189 | { | 249 | { |
@@ -349,10 +409,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
349 | m_contactResults.Add(collisionresult); | 409 | m_contactResults.Add(collisionresult); |
350 | } | 410 | } |
351 | } | 411 | } |
352 | |||
353 | |||
354 | } | 412 | } |
355 | |||
356 | } | 413 | } |
357 | 414 | ||
358 | /// <summary> | 415 | /// <summary> |
@@ -372,11 +429,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
372 | public RaycastCallback callbackMethod; | 429 | public RaycastCallback callbackMethod; |
373 | } | 430 | } |
374 | 431 | ||
375 | public struct ContactResult | 432 | public struct ODERayRequest |
376 | { | 433 | { |
377 | public Vector3 Pos; | 434 | public Vector3 Origin; |
378 | public float Depth; | ||
379 | public uint ConsumerID; | ||
380 | public Vector3 Normal; | 435 | public Vector3 Normal; |
436 | public int Count; | ||
437 | public float length; | ||
438 | public RayCallback callbackMethod; | ||
381 | } | 439 | } |
382 | } | 440 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 88902b0..6e603e8 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs | |||
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | //#define USE_DRAWSTUFF | 28 | //#define USE_DRAWSTUFF |
29 | #define SPAM | 29 | //#define SPAM |
30 | 30 | ||
31 | using System; | 31 | using System; |
32 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
@@ -100,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
100 | Rubber = 6 | 100 | Rubber = 6 |
101 | } | 101 | } |
102 | 102 | ||
103 | public sealed class OdeScene : PhysicsScene | 103 | public class OdeScene : PhysicsScene |
104 | { | 104 | { |
105 | private readonly ILog m_log; | 105 | private readonly ILog m_log; |
106 | // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); | 106 | // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); |
@@ -198,7 +198,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
198 | private readonly List<OdePrim> _taintedPrimL = new List<OdePrim>(); | 198 | private readonly List<OdePrim> _taintedPrimL = new List<OdePrim>(); |
199 | private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); | 199 | private readonly HashSet<OdeCharacter> _taintedActors = new HashSet<OdeCharacter>(); |
200 | private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); | 200 | private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); |
201 | |||
202 | /// <summary> | ||
203 | /// A list of actors that should receive collision events. | ||
204 | /// </summary> | ||
201 | private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); | 205 | private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); |
206 | |||
202 | private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); | 207 | private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); |
203 | public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); | 208 | public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); |
204 | public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); | 209 | public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); |
@@ -299,7 +304,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
299 | // Create the world and the first space | 304 | // Create the world and the first space |
300 | world = d.WorldCreate(); | 305 | world = d.WorldCreate(); |
301 | space = d.HashSpaceCreate(IntPtr.Zero); | 306 | space = d.HashSpaceCreate(IntPtr.Zero); |
302 | |||
303 | 307 | ||
304 | contactgroup = d.JointGroupCreate(0); | 308 | contactgroup = d.JointGroupCreate(0); |
305 | //contactgroup | 309 | //contactgroup |
@@ -952,7 +956,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
952 | character.SetPidStatus(true); | 956 | character.SetPidStatus(true); |
953 | } | 957 | } |
954 | } | 958 | } |
955 | |||
956 | 959 | ||
957 | if (p1.PhysicsActorType == (int) ActorTypes.Agent) | 960 | if (p1.PhysicsActorType == (int) ActorTypes.Agent) |
958 | { | 961 | { |
@@ -1053,9 +1056,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1053 | { | 1056 | { |
1054 | joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); | 1057 | joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); |
1055 | m_global_contactcount++; | 1058 | m_global_contactcount++; |
1056 | |||
1057 | } | 1059 | } |
1058 | |||
1059 | } | 1060 | } |
1060 | else | 1061 | else |
1061 | { | 1062 | { |
@@ -1078,7 +1079,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1078 | { | 1079 | { |
1079 | joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); | 1080 | joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); |
1080 | m_global_contactcount++; | 1081 | m_global_contactcount++; |
1081 | |||
1082 | } | 1082 | } |
1083 | } | 1083 | } |
1084 | } | 1084 | } |
@@ -1290,6 +1290,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1290 | 1290 | ||
1291 | //returncollisions = true; | 1291 | //returncollisions = true; |
1292 | break; | 1292 | break; |
1293 | |||
1293 | case ActorTypes.Prim: | 1294 | case ActorTypes.Prim: |
1294 | if (p1 is OdePrim) | 1295 | if (p1 is OdePrim) |
1295 | { | 1296 | { |
@@ -1317,6 +1318,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1317 | 1318 | ||
1318 | cc2.AddCollisionEvent(obj2LocalID, contact); | 1319 | cc2.AddCollisionEvent(obj2LocalID, contact); |
1319 | break; | 1320 | break; |
1321 | |||
1320 | case ActorTypes.Prim: | 1322 | case ActorTypes.Prim: |
1321 | 1323 | ||
1322 | if (p2 is OdePrim) | 1324 | if (p2 is OdePrim) |
@@ -1421,18 +1423,18 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1421 | 1423 | ||
1422 | public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) | 1424 | public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) |
1423 | { | 1425 | { |
1424 | String name1 = null; | 1426 | // String name1 = null; |
1425 | String name2 = null; | 1427 | // String name2 = null; |
1426 | 1428 | // | |
1427 | if (!geom_name_map.TryGetValue(trimesh, out name1)) | 1429 | // if (!geom_name_map.TryGetValue(trimesh, out name1)) |
1428 | { | 1430 | // { |
1429 | name1 = "null"; | 1431 | // name1 = "null"; |
1430 | } | 1432 | // } |
1431 | 1433 | // | |
1432 | if (!geom_name_map.TryGetValue(refObject, out name2)) | 1434 | // if (!geom_name_map.TryGetValue(refObject, out name2)) |
1433 | { | 1435 | // { |
1434 | name2 = "null"; | 1436 | // name2 = "null"; |
1435 | } | 1437 | // } |
1436 | 1438 | ||
1437 | // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); | 1439 | // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); |
1438 | 1440 | ||
@@ -1604,7 +1606,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1604 | } | 1606 | } |
1605 | // End recovered. Kitto Flora | 1607 | // End recovered. Kitto Flora |
1606 | 1608 | ||
1607 | public void addCollisionEventReporting(PhysicsActor obj) | 1609 | /// <summary> |
1610 | /// Add actor to the list that should receive collision events in the simulate loop. | ||
1611 | /// </summary> | ||
1612 | /// <param name="obj"></param> | ||
1613 | public void AddCollisionEventReporting(PhysicsActor obj) | ||
1608 | { | 1614 | { |
1609 | lock (_collisionEventPrim) | 1615 | lock (_collisionEventPrim) |
1610 | { | 1616 | { |
@@ -1613,7 +1619,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1613 | } | 1619 | } |
1614 | } | 1620 | } |
1615 | 1621 | ||
1616 | public void remCollisionEventReporting(PhysicsActor obj) | 1622 | /// <summary> |
1623 | /// Remove actor from the list that should receive collision events in the simulate loop. | ||
1624 | /// </summary> | ||
1625 | /// <param name="obj"></param> | ||
1626 | public void RemoveCollisionEventReporting(PhysicsActor obj) | ||
1617 | { | 1627 | { |
1618 | lock (_collisionEventPrim) | 1628 | lock (_collisionEventPrim) |
1619 | { | 1629 | { |
@@ -1677,7 +1687,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1677 | } | 1687 | } |
1678 | 1688 | ||
1679 | private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, | 1689 | private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, |
1680 | IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) | 1690 | PrimitiveBaseShape pbs, bool isphysical, uint localID) |
1681 | { | 1691 | { |
1682 | Vector3 pos = position; | 1692 | Vector3 pos = position; |
1683 | Vector3 siz = size; | 1693 | Vector3 siz = size; |
@@ -1686,12 +1696,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1686 | OdePrim newPrim; | 1696 | OdePrim newPrim; |
1687 | lock (OdeLock) | 1697 | lock (OdeLock) |
1688 | { | 1698 | { |
1689 | newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); | 1699 | newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, ode); |
1690 | 1700 | ||
1691 | lock (_prims) | 1701 | lock (_prims) |
1692 | _prims.Add(newPrim); | 1702 | _prims.Add(newPrim); |
1693 | } | 1703 | } |
1694 | 1704 | newPrim.LocalID = localID; | |
1695 | return newPrim; | 1705 | return newPrim; |
1696 | } | 1706 | } |
1697 | 1707 | ||
@@ -1714,27 +1724,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1714 | m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); | 1724 | m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); |
1715 | #endif | 1725 | #endif |
1716 | 1726 | ||
1717 | PhysicsActor result; | 1727 | return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); |
1718 | IMesh mesh = null; | ||
1719 | |||
1720 | if (needsMeshing(pbs)) | ||
1721 | { | ||
1722 | try | ||
1723 | { | ||
1724 | mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); | ||
1725 | } | ||
1726 | catch(Exception e) | ||
1727 | { | ||
1728 | m_log.ErrorFormat("[PHYSICS]: Exception while meshing prim {0}.", primName); | ||
1729 | m_log.Debug(e.ToString()); | ||
1730 | mesh = null; | ||
1731 | return null; | ||
1732 | } | ||
1733 | } | ||
1734 | |||
1735 | result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); | ||
1736 | |||
1737 | return result; | ||
1738 | } | 1728 | } |
1739 | 1729 | ||
1740 | public override float TimeDilation | 1730 | public override float TimeDilation |
@@ -2104,6 +2094,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2104 | 2094 | ||
2105 | public override void RemovePrim(PhysicsActor prim) | 2095 | public override void RemovePrim(PhysicsActor prim) |
2106 | { | 2096 | { |
2097 | // As with all ODE physics operations, we don't remove the prim immediately but signal that it should be | ||
2098 | // removed in the next physics simulate pass. | ||
2107 | if (prim is OdePrim) | 2099 | if (prim is OdePrim) |
2108 | { | 2100 | { |
2109 | lock (OdeLock) | 2101 | lock (OdeLock) |
@@ -2120,6 +2112,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2120 | /// <summary> | 2112 | /// <summary> |
2121 | /// This is called from within simulate but outside the locked portion | 2113 | /// This is called from within simulate but outside the locked portion |
2122 | /// We need to do our own locking here | 2114 | /// We need to do our own locking here |
2115 | /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in | ||
2116 | /// Simulate() -- justincc). | ||
2117 | /// | ||
2123 | /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. | 2118 | /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. |
2124 | /// | 2119 | /// |
2125 | /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory | 2120 | /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory |
@@ -2131,7 +2126,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2131 | //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); | 2126 | //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); |
2132 | lock (prim) | 2127 | lock (prim) |
2133 | { | 2128 | { |
2134 | remCollisionEventReporting(prim); | 2129 | RemoveCollisionEventReporting(prim); |
2135 | lock (ode) | 2130 | lock (ode) |
2136 | { | 2131 | { |
2137 | if (prim.prim_geom != IntPtr.Zero) | 2132 | if (prim.prim_geom != IntPtr.Zero) |
@@ -2176,24 +2171,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2176 | //} | 2171 | //} |
2177 | //} | 2172 | //} |
2178 | //m_log.Warn(prim.prim_geom); | 2173 | //m_log.Warn(prim.prim_geom); |
2179 | try | 2174 | |
2180 | { | 2175 | if (!prim.RemoveGeom()) |
2181 | if (prim.prim_geom != IntPtr.Zero) | 2176 | m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); |
2182 | { | 2177 | |
2183 | d.GeomDestroy(prim.prim_geom); | ||
2184 | prim.prim_geom = IntPtr.Zero; | ||
2185 | } | ||
2186 | else | ||
2187 | { | ||
2188 | m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); | ||
2189 | } | ||
2190 | } | ||
2191 | catch (AccessViolationException) | ||
2192 | { | ||
2193 | m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); | ||
2194 | } | ||
2195 | lock (_prims) | 2178 | lock (_prims) |
2196 | _prims.Remove(prim); | 2179 | _prims.Remove(prim); |
2197 | 2180 | ||
2198 | //If there are no more geometries in the sub-space, we don't need it in the main space anymore | 2181 | //If there are no more geometries in the sub-space, we don't need it in the main space anymore |
2199 | //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) | 2182 | //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) |
@@ -2584,7 +2567,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2584 | { | 2567 | { |
2585 | if (!(_taintedPrimH.Contains(taintedprim))) | 2568 | if (!(_taintedPrimH.Contains(taintedprim))) |
2586 | { | 2569 | { |
2587 | //Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.m_primName); | 2570 | #if SPAM |
2571 | Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | ||
2572 | #endif | ||
2588 | _taintedPrimH.Add(taintedprim); // HashSet for searching | 2573 | _taintedPrimH.Add(taintedprim); // HashSet for searching |
2589 | _taintedPrimL.Add(taintedprim); // List for ordered readout | 2574 | _taintedPrimL.Add(taintedprim); // List for ordered readout |
2590 | } | 2575 | } |
@@ -2684,320 +2669,148 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2684 | //if (!ode.lockquery()) | 2669 | //if (!ode.lockquery()) |
2685 | //{ | 2670 | //{ |
2686 | // ode.dlock(world); | 2671 | // ode.dlock(world); |
2687 | try | ||
2688 | { | ||
2689 | // Insert, remove Characters | ||
2690 | bool processedtaints = false; | ||
2691 | 2672 | ||
2692 | lock (_taintedActors) | 2673 | try |
2693 | { | 2674 | { |
2694 | if (_taintedActors.Count > 0) | 2675 | // Insert, remove Characters |
2695 | { | 2676 | bool processedtaints = false; |
2696 | foreach (OdeCharacter character in _taintedActors) | ||
2697 | { | ||
2698 | character.ProcessTaints(timeStep); | ||
2699 | 2677 | ||
2700 | processedtaints = true; | 2678 | lock (_taintedActors) |
2701 | //character.m_collisionscore = 0; | 2679 | { |
2702 | } | 2680 | if (_taintedActors.Count > 0) |
2681 | { | ||
2682 | foreach (OdeCharacter character in _taintedActors) | ||
2683 | { | ||
2684 | character.ProcessTaints(timeStep); | ||
2703 | 2685 | ||
2704 | if (processedtaints) | 2686 | processedtaints = true; |
2705 | _taintedActors.Clear(); | 2687 | //character.m_collisionscore = 0; |
2706 | } | ||
2707 | } | 2688 | } |
2708 | 2689 | ||
2709 | // Modify other objects in the scene. | 2690 | if (processedtaints) |
2710 | processedtaints = false; | 2691 | _taintedActors.Clear(); |
2692 | } | ||
2693 | } | ||
2694 | |||
2695 | // Modify other objects in the scene. | ||
2696 | processedtaints = false; | ||
2711 | 2697 | ||
2712 | lock (_taintedPrimLock) | 2698 | lock (_taintedPrimLock) |
2699 | { | ||
2700 | foreach (OdePrim prim in _taintedPrimL) | ||
2701 | { | ||
2702 | if (prim.m_taintremove) | ||
2713 | { | 2703 | { |
2714 | foreach (OdePrim prim in _taintedPrimL) | 2704 | // Console.WriteLine("Simulate calls RemovePrimThreadLocked for {0}", prim.Name); |
2715 | { | 2705 | RemovePrimThreadLocked(prim); |
2716 | if (prim.m_taintremove) | 2706 | } |
2717 | { | 2707 | else |
2718 | //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); | 2708 | { |
2719 | RemovePrimThreadLocked(prim); | 2709 | // Console.WriteLine("Simulate calls ProcessTaints for {0}", prim.Name); |
2720 | } | 2710 | prim.ProcessTaints(timeStep); |
2721 | else | 2711 | } |
2722 | { | ||
2723 | //Console.WriteLine("Simulate calls ProcessTaints"); | ||
2724 | prim.ProcessTaints(timeStep); | ||
2725 | } | ||
2726 | processedtaints = true; | ||
2727 | prim.m_collisionscore = 0; | ||
2728 | |||
2729 | // This loop can block up the Heartbeat for a very long time on large regions. | ||
2730 | // We need to let the Watchdog know that the Heartbeat is not dead | ||
2731 | // NOTE: This is currently commented out, but if things like OAR loading are | ||
2732 | // timing the heartbeat out we will need to uncomment it | ||
2733 | //Watchdog.UpdateThread(); | ||
2734 | } | ||
2735 | 2712 | ||
2736 | if (SupportsNINJAJoints) | 2713 | processedtaints = true; |
2737 | { | 2714 | prim.m_collisionscore = 0; |
2738 | // Create pending joints, if possible | ||
2739 | 2715 | ||
2740 | // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating | 2716 | // This loop can block up the Heartbeat for a very long time on large regions. |
2741 | // a joint requires specifying the body id of both involved bodies | 2717 | // We need to let the Watchdog know that the Heartbeat is not dead |
2742 | if (pendingJoints.Count > 0) | 2718 | // NOTE: This is currently commented out, but if things like OAR loading are |
2743 | { | 2719 | // timing the heartbeat out we will need to uncomment it |
2744 | List<PhysicsJoint> successfullyProcessedPendingJoints = new List<PhysicsJoint>(); | 2720 | //Watchdog.UpdateThread(); |
2745 | //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); | 2721 | } |
2746 | foreach (PhysicsJoint joint in pendingJoints) | 2722 | |
2747 | { | 2723 | if (SupportsNINJAJoints) |
2748 | //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); | 2724 | SimulatePendingNINJAJoints(); |
2749 | string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); | ||
2750 | List<IntPtr> jointBodies = new List<IntPtr>(); | ||
2751 | bool allJointBodiesAreReady = true; | ||
2752 | foreach (string jointParam in jointParams) | ||
2753 | { | ||
2754 | if (jointParam == "NULL") | ||
2755 | { | ||
2756 | //DoJointErrorMessage(joint, "attaching NULL joint to world"); | ||
2757 | jointBodies.Add(IntPtr.Zero); | ||
2758 | } | ||
2759 | else | ||
2760 | { | ||
2761 | //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); | ||
2762 | bool foundPrim = false; | ||
2763 | lock (_prims) | ||
2764 | { | ||
2765 | foreach (OdePrim prim in _prims) // FIXME: inefficient | ||
2766 | { | ||
2767 | if (prim.SOPName == jointParam) | ||
2768 | { | ||
2769 | //DoJointErrorMessage(joint, "found for prim name: " + jointParam); | ||
2770 | if (prim.IsPhysical && prim.Body != IntPtr.Zero) | ||
2771 | { | ||
2772 | jointBodies.Add(prim.Body); | ||
2773 | foundPrim = true; | ||
2774 | break; | ||
2775 | } | ||
2776 | else | ||
2777 | { | ||
2778 | DoJointErrorMessage(joint, "prim name " + jointParam + | ||
2779 | " exists but is not (yet) physical; deferring joint creation. " + | ||
2780 | "IsPhysical property is " + prim.IsPhysical + | ||
2781 | " and body is " + prim.Body); | ||
2782 | foundPrim = false; | ||
2783 | break; | ||
2784 | } | ||
2785 | } | ||
2786 | } | ||
2787 | } | ||
2788 | if (foundPrim) | ||
2789 | { | ||
2790 | // all is fine | ||
2791 | } | ||
2792 | else | ||
2793 | { | ||
2794 | allJointBodiesAreReady = false; | ||
2795 | break; | ||
2796 | } | ||
2797 | } | ||
2798 | } | ||
2799 | if (allJointBodiesAreReady) | ||
2800 | { | ||
2801 | //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); | ||
2802 | if (jointBodies[0] == jointBodies[1]) | ||
2803 | { | ||
2804 | DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); | ||
2805 | } | ||
2806 | else | ||
2807 | { | ||
2808 | switch (joint.Type) | ||
2809 | { | ||
2810 | case PhysicsJointType.Ball: | ||
2811 | { | ||
2812 | IntPtr odeJoint; | ||
2813 | //DoJointErrorMessage(joint, "ODE creating ball joint "); | ||
2814 | odeJoint = d.JointCreateBall(world, IntPtr.Zero); | ||
2815 | //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); | ||
2816 | d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); | ||
2817 | //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); | ||
2818 | d.JointSetBallAnchor(odeJoint, | ||
2819 | joint.Position.X, | ||
2820 | joint.Position.Y, | ||
2821 | joint.Position.Z); | ||
2822 | //DoJointErrorMessage(joint, "ODE joint setting OK"); | ||
2823 | //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); | ||
2824 | //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); | ||
2825 | //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); | ||
2826 | //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); | ||
2827 | |||
2828 | if (joint is OdePhysicsJoint) | ||
2829 | { | ||
2830 | ((OdePhysicsJoint)joint).jointID = odeJoint; | ||
2831 | } | ||
2832 | else | ||
2833 | { | ||
2834 | DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); | ||
2835 | } | ||
2836 | } | ||
2837 | break; | ||
2838 | case PhysicsJointType.Hinge: | ||
2839 | { | ||
2840 | IntPtr odeJoint; | ||
2841 | //DoJointErrorMessage(joint, "ODE creating hinge joint "); | ||
2842 | odeJoint = d.JointCreateHinge(world, IntPtr.Zero); | ||
2843 | //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); | ||
2844 | d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); | ||
2845 | //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); | ||
2846 | d.JointSetHingeAnchor(odeJoint, | ||
2847 | joint.Position.X, | ||
2848 | joint.Position.Y, | ||
2849 | joint.Position.Z); | ||
2850 | // We use the orientation of the x-axis of the joint's coordinate frame | ||
2851 | // as the axis for the hinge. | ||
2852 | |||
2853 | // Therefore, we must get the joint's coordinate frame based on the | ||
2854 | // joint.Rotation field, which originates from the orientation of the | ||
2855 | // joint's proxy object in the scene. | ||
2856 | |||
2857 | // The joint's coordinate frame is defined as the transformation matrix | ||
2858 | // that converts a vector from joint-local coordinates into world coordinates. | ||
2859 | // World coordinates are defined as the XYZ coordinate system of the sim, | ||
2860 | // as shown in the top status-bar of the viewer. | ||
2861 | |||
2862 | // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) | ||
2863 | // and use that as the hinge axis. | ||
2864 | |||
2865 | //joint.Rotation.Normalize(); | ||
2866 | Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); | ||
2867 | |||
2868 | // Now extract the X axis of the joint's coordinate frame. | ||
2869 | |||
2870 | // Do not try to use proxyFrame.AtAxis or you will become mired in the | ||
2871 | // tar pit of transposed, inverted, and generally messed-up orientations. | ||
2872 | // (In other words, Matrix4.AtAxis() is borked.) | ||
2873 | // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness | ||
2874 | |||
2875 | // Instead, compute the X axis of the coordinate frame by transforming | ||
2876 | // the (1,0,0) vector. At least that works. | ||
2877 | |||
2878 | //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); | ||
2879 | Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); | ||
2880 | //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); | ||
2881 | //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); | ||
2882 | d.JointSetHingeAxis(odeJoint, | ||
2883 | jointAxis.X, | ||
2884 | jointAxis.Y, | ||
2885 | jointAxis.Z); | ||
2886 | //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); | ||
2887 | if (joint is OdePhysicsJoint) | ||
2888 | { | ||
2889 | ((OdePhysicsJoint)joint).jointID = odeJoint; | ||
2890 | } | ||
2891 | else | ||
2892 | { | ||
2893 | DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); | ||
2894 | } | ||
2895 | } | ||
2896 | break; | ||
2897 | } | ||
2898 | successfullyProcessedPendingJoints.Add(joint); | ||
2899 | } | ||
2900 | } | ||
2901 | else | ||
2902 | { | ||
2903 | DoJointErrorMessage(joint, "joint could not yet be created; still pending"); | ||
2904 | } | ||
2905 | } | ||
2906 | foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) | ||
2907 | { | ||
2908 | //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); | ||
2909 | //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); | ||
2910 | InternalRemovePendingJoint(successfullyProcessedJoint); | ||
2911 | //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); | ||
2912 | InternalAddActiveJoint(successfullyProcessedJoint); | ||
2913 | //DoJointErrorMessage(successfullyProcessedJoint, "done"); | ||
2914 | } | ||
2915 | } | ||
2916 | } | ||
2917 | 2725 | ||
2918 | if (processedtaints) | 2726 | if (processedtaints) |
2727 | { | ||
2919 | //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); | 2728 | //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); |
2920 | _taintedPrimH.Clear(); | 2729 | _taintedPrimH.Clear(); |
2921 | _taintedPrimL.Clear(); | 2730 | _taintedPrimL.Clear(); |
2922 | } | 2731 | } |
2732 | } | ||
2923 | 2733 | ||
2924 | // Move characters | 2734 | // Move characters |
2925 | lock (_characters) | 2735 | lock (_characters) |
2736 | { | ||
2737 | List<OdeCharacter> defects = new List<OdeCharacter>(); | ||
2738 | foreach (OdeCharacter actor in _characters) | ||
2739 | { | ||
2740 | if (actor != null) | ||
2741 | actor.Move(timeStep, defects); | ||
2742 | } | ||
2743 | if (0 != defects.Count) | ||
2744 | { | ||
2745 | foreach (OdeCharacter defect in defects) | ||
2926 | { | 2746 | { |
2927 | List<OdeCharacter> defects = new List<OdeCharacter>(); | 2747 | RemoveCharacter(defect); |
2928 | foreach (OdeCharacter actor in _characters) | ||
2929 | { | ||
2930 | if (actor != null) | ||
2931 | actor.Move(timeStep, defects); | ||
2932 | } | ||
2933 | if (0 != defects.Count) | ||
2934 | { | ||
2935 | foreach (OdeCharacter defect in defects) | ||
2936 | { | ||
2937 | RemoveCharacter(defect); | ||
2938 | } | ||
2939 | } | ||
2940 | } | 2748 | } |
2749 | } | ||
2750 | } | ||
2941 | 2751 | ||
2942 | // Move other active objects | 2752 | // Move other active objects |
2943 | lock (_activeprims) | 2753 | lock (_activeprims) |
2944 | { | 2754 | { |
2945 | foreach (OdePrim prim in _activeprims) | 2755 | foreach (OdePrim prim in _activeprims) |
2946 | { | 2756 | { |
2947 | prim.m_collisionscore = 0; | 2757 | prim.m_collisionscore = 0; |
2948 | prim.Move(timeStep); | 2758 | prim.Move(timeStep); |
2949 | } | 2759 | } |
2950 | } | 2760 | } |
2951 | 2761 | ||
2952 | //if ((framecount % m_randomizeWater) == 0) | 2762 | //if ((framecount % m_randomizeWater) == 0) |
2953 | // randomizeWater(waterlevel); | 2763 | // randomizeWater(waterlevel); |
2954 | 2764 | ||
2955 | //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); | 2765 | //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); |
2956 | m_rayCastManager.ProcessQueuedRequests(); | 2766 | m_rayCastManager.ProcessQueuedRequests(); |
2767 | |||
2768 | collision_optimized(timeStep); | ||
2769 | |||
2770 | lock (_collisionEventPrim) | ||
2771 | { | ||
2772 | foreach (PhysicsActor obj in _collisionEventPrim) | ||
2773 | { | ||
2774 | if (obj == null) | ||
2775 | continue; | ||
2957 | 2776 | ||
2958 | collision_optimized(timeStep); | 2777 | // m_log.DebugFormat("[PHYSICS]: Assessing {0} for collision events", obj.SOPName); |
2959 | 2778 | ||
2960 | lock (_collisionEventPrim) | 2779 | switch ((ActorTypes)obj.PhysicsActorType) |
2961 | { | 2780 | { |
2962 | foreach (PhysicsActor obj in _collisionEventPrim) | 2781 | case ActorTypes.Agent: |
2963 | { | 2782 | OdeCharacter cobj = (OdeCharacter)obj; |
2964 | if (obj == null) | 2783 | cobj.AddCollisionFrameTime(100); |
2965 | continue; | 2784 | cobj.SendCollisions(); |
2785 | break; | ||
2966 | 2786 | ||
2967 | switch ((ActorTypes)obj.PhysicsActorType) | 2787 | case ActorTypes.Prim: |
2968 | { | 2788 | OdePrim pobj = (OdePrim)obj; |
2969 | case ActorTypes.Agent: | 2789 | pobj.SendCollisions(); |
2970 | OdeCharacter cobj = (OdeCharacter)obj; | 2790 | break; |
2971 | cobj.AddCollisionFrameTime(100); | ||
2972 | cobj.SendCollisions(); | ||
2973 | break; | ||
2974 | case ActorTypes.Prim: | ||
2975 | OdePrim pobj = (OdePrim)obj; | ||
2976 | pobj.SendCollisions(); | ||
2977 | break; | ||
2978 | } | ||
2979 | } | ||
2980 | } | 2791 | } |
2792 | } | ||
2793 | } | ||
2981 | 2794 | ||
2982 | //if (m_global_contactcount > 5) | 2795 | //if (m_global_contactcount > 5) |
2983 | //{ | 2796 | //{ |
2984 | // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); | 2797 | // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); |
2985 | //} | 2798 | //} |
2986 | 2799 | ||
2987 | m_global_contactcount = 0; | 2800 | m_global_contactcount = 0; |
2988 | 2801 | ||
2989 | d.WorldQuickStep(world, ODE_STEPSIZE); | 2802 | d.WorldQuickStep(world, ODE_STEPSIZE); |
2990 | d.JointGroupEmpty(contactgroup); | 2803 | d.JointGroupEmpty(contactgroup); |
2991 | //ode.dunlock(world); | 2804 | //ode.dunlock(world); |
2992 | } | 2805 | } |
2993 | catch (Exception e) | 2806 | catch (Exception e) |
2994 | { | 2807 | { |
2995 | m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); | 2808 | m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); |
2996 | ode.dunlock(world); | 2809 | ode.dunlock(world); |
2997 | } | 2810 | } |
2998 | 2811 | ||
2999 | step_time -= ODE_STEPSIZE; | 2812 | step_time -= ODE_STEPSIZE; |
3000 | i++; | 2813 | i++; |
3001 | //} | 2814 | //} |
3002 | //else | 2815 | //else |
3003 | //{ | 2816 | //{ |
@@ -3014,6 +2827,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3014 | { | 2827 | { |
3015 | if (actor.bad) | 2828 | if (actor.bad) |
3016 | m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); | 2829 | m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); |
2830 | |||
3017 | actor.UpdatePositionAndVelocity(); | 2831 | actor.UpdatePositionAndVelocity(); |
3018 | } | 2832 | } |
3019 | } | 2833 | } |
@@ -3027,6 +2841,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3027 | { | 2841 | { |
3028 | RemoveCharacter(chr); | 2842 | RemoveCharacter(chr); |
3029 | } | 2843 | } |
2844 | |||
3030 | _badCharacter.Clear(); | 2845 | _badCharacter.Clear(); |
3031 | } | 2846 | } |
3032 | } | 2847 | } |
@@ -3042,30 +2857,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3042 | actor.UpdatePositionAndVelocity(); | 2857 | actor.UpdatePositionAndVelocity(); |
3043 | 2858 | ||
3044 | if (SupportsNINJAJoints) | 2859 | if (SupportsNINJAJoints) |
3045 | { | 2860 | SimulateActorPendingJoints(actor); |
3046 | // If an actor moved, move its joint proxy objects as well. | ||
3047 | // There seems to be an event PhysicsActor.OnPositionUpdate that could be used | ||
3048 | // for this purpose but it is never called! So we just do the joint | ||
3049 | // movement code here. | ||
3050 | |||
3051 | if (actor.SOPName != null && | ||
3052 | joints_connecting_actor.ContainsKey(actor.SOPName) && | ||
3053 | joints_connecting_actor[actor.SOPName] != null && | ||
3054 | joints_connecting_actor[actor.SOPName].Count > 0) | ||
3055 | { | ||
3056 | foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) | ||
3057 | { | ||
3058 | if (affectedJoint.IsInPhysicsEngine) | ||
3059 | { | ||
3060 | DoJointMoved(affectedJoint); | ||
3061 | } | ||
3062 | else | ||
3063 | { | ||
3064 | DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); | ||
3065 | } | ||
3066 | } | ||
3067 | } | ||
3068 | } | ||
3069 | } | 2861 | } |
3070 | } | 2862 | } |
3071 | } | 2863 | } |
@@ -3076,7 +2868,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3076 | // Finished with all sim stepping. If requested, dump world state to file for debugging. | 2868 | // Finished with all sim stepping. If requested, dump world state to file for debugging. |
3077 | // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? | 2869 | // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? |
3078 | // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? | 2870 | // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? |
3079 | if (physics_logging && (physics_logging_interval>0) && (framecount % physics_logging_interval == 0)) | 2871 | if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0)) |
3080 | { | 2872 | { |
3081 | string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename | 2873 | string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename |
3082 | string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file | 2874 | string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file |
@@ -3088,8 +2880,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3088 | fwriter.WriteLine(header); | 2880 | fwriter.WriteLine(header); |
3089 | fwriter.Close(); | 2881 | fwriter.Close(); |
3090 | } | 2882 | } |
2883 | |||
3091 | d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); | 2884 | d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); |
3092 | } | 2885 | } |
2886 | |||
3093 | latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; | 2887 | latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; |
3094 | 2888 | ||
3095 | // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics | 2889 | // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics |
@@ -3098,7 +2892,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3098 | // If Physics stalls, it takes longer which makes the tick count ms larger. | 2892 | // If Physics stalls, it takes longer which makes the tick count ms larger. |
3099 | 2893 | ||
3100 | if (latertickcount < 100) | 2894 | if (latertickcount < 100) |
2895 | { | ||
3101 | m_timeDilation = 1.0f; | 2896 | m_timeDilation = 1.0f; |
2897 | } | ||
3102 | else | 2898 | else |
3103 | { | 2899 | { |
3104 | m_timeDilation = 100f / latertickcount; | 2900 | m_timeDilation = 100f / latertickcount; |
@@ -3111,6 +2907,229 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3111 | return fps; | 2907 | return fps; |
3112 | } | 2908 | } |
3113 | 2909 | ||
2910 | /// <summary> | ||
2911 | /// Simulate pending NINJA joints. | ||
2912 | /// </summary> | ||
2913 | /// <remarks> | ||
2914 | /// Called by the main Simulate() loop if NINJA joints are active. Should not be called from anywhere else. | ||
2915 | /// </remarks> | ||
2916 | protected void SimulatePendingNINJAJoints() | ||
2917 | { | ||
2918 | // Create pending joints, if possible | ||
2919 | |||
2920 | // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating | ||
2921 | // a joint requires specifying the body id of both involved bodies | ||
2922 | if (pendingJoints.Count > 0) | ||
2923 | { | ||
2924 | List<PhysicsJoint> successfullyProcessedPendingJoints = new List<PhysicsJoint>(); | ||
2925 | //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); | ||
2926 | foreach (PhysicsJoint joint in pendingJoints) | ||
2927 | { | ||
2928 | //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); | ||
2929 | string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); | ||
2930 | List<IntPtr> jointBodies = new List<IntPtr>(); | ||
2931 | bool allJointBodiesAreReady = true; | ||
2932 | foreach (string jointParam in jointParams) | ||
2933 | { | ||
2934 | if (jointParam == "NULL") | ||
2935 | { | ||
2936 | //DoJointErrorMessage(joint, "attaching NULL joint to world"); | ||
2937 | jointBodies.Add(IntPtr.Zero); | ||
2938 | } | ||
2939 | else | ||
2940 | { | ||
2941 | //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); | ||
2942 | bool foundPrim = false; | ||
2943 | lock (_prims) | ||
2944 | { | ||
2945 | foreach (OdePrim prim in _prims) // FIXME: inefficient | ||
2946 | { | ||
2947 | if (prim.SOPName == jointParam) | ||
2948 | { | ||
2949 | //DoJointErrorMessage(joint, "found for prim name: " + jointParam); | ||
2950 | if (prim.IsPhysical && prim.Body != IntPtr.Zero) | ||
2951 | { | ||
2952 | jointBodies.Add(prim.Body); | ||
2953 | foundPrim = true; | ||
2954 | break; | ||
2955 | } | ||
2956 | else | ||
2957 | { | ||
2958 | DoJointErrorMessage(joint, "prim name " + jointParam + | ||
2959 | " exists but is not (yet) physical; deferring joint creation. " + | ||
2960 | "IsPhysical property is " + prim.IsPhysical + | ||
2961 | " and body is " + prim.Body); | ||
2962 | foundPrim = false; | ||
2963 | break; | ||
2964 | } | ||
2965 | } | ||
2966 | } | ||
2967 | } | ||
2968 | if (foundPrim) | ||
2969 | { | ||
2970 | // all is fine | ||
2971 | } | ||
2972 | else | ||
2973 | { | ||
2974 | allJointBodiesAreReady = false; | ||
2975 | break; | ||
2976 | } | ||
2977 | } | ||
2978 | } | ||
2979 | |||
2980 | if (allJointBodiesAreReady) | ||
2981 | { | ||
2982 | //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); | ||
2983 | if (jointBodies[0] == jointBodies[1]) | ||
2984 | { | ||
2985 | DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); | ||
2986 | } | ||
2987 | else | ||
2988 | { | ||
2989 | switch (joint.Type) | ||
2990 | { | ||
2991 | case PhysicsJointType.Ball: | ||
2992 | { | ||
2993 | IntPtr odeJoint; | ||
2994 | //DoJointErrorMessage(joint, "ODE creating ball joint "); | ||
2995 | odeJoint = d.JointCreateBall(world, IntPtr.Zero); | ||
2996 | //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); | ||
2997 | d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); | ||
2998 | //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); | ||
2999 | d.JointSetBallAnchor(odeJoint, | ||
3000 | joint.Position.X, | ||
3001 | joint.Position.Y, | ||
3002 | joint.Position.Z); | ||
3003 | //DoJointErrorMessage(joint, "ODE joint setting OK"); | ||
3004 | //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); | ||
3005 | //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); | ||
3006 | //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); | ||
3007 | //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); | ||
3008 | |||
3009 | if (joint is OdePhysicsJoint) | ||
3010 | { | ||
3011 | ((OdePhysicsJoint)joint).jointID = odeJoint; | ||
3012 | } | ||
3013 | else | ||
3014 | { | ||
3015 | DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); | ||
3016 | } | ||
3017 | } | ||
3018 | break; | ||
3019 | case PhysicsJointType.Hinge: | ||
3020 | { | ||
3021 | IntPtr odeJoint; | ||
3022 | //DoJointErrorMessage(joint, "ODE creating hinge joint "); | ||
3023 | odeJoint = d.JointCreateHinge(world, IntPtr.Zero); | ||
3024 | //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); | ||
3025 | d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); | ||
3026 | //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); | ||
3027 | d.JointSetHingeAnchor(odeJoint, | ||
3028 | joint.Position.X, | ||
3029 | joint.Position.Y, | ||
3030 | joint.Position.Z); | ||
3031 | // We use the orientation of the x-axis of the joint's coordinate frame | ||
3032 | // as the axis for the hinge. | ||
3033 | |||
3034 | // Therefore, we must get the joint's coordinate frame based on the | ||
3035 | // joint.Rotation field, which originates from the orientation of the | ||
3036 | // joint's proxy object in the scene. | ||
3037 | |||
3038 | // The joint's coordinate frame is defined as the transformation matrix | ||
3039 | // that converts a vector from joint-local coordinates into world coordinates. | ||
3040 | // World coordinates are defined as the XYZ coordinate system of the sim, | ||
3041 | // as shown in the top status-bar of the viewer. | ||
3042 | |||
3043 | // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) | ||
3044 | // and use that as the hinge axis. | ||
3045 | |||
3046 | //joint.Rotation.Normalize(); | ||
3047 | Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); | ||
3048 | |||
3049 | // Now extract the X axis of the joint's coordinate frame. | ||
3050 | |||
3051 | // Do not try to use proxyFrame.AtAxis or you will become mired in the | ||
3052 | // tar pit of transposed, inverted, and generally messed-up orientations. | ||
3053 | // (In other words, Matrix4.AtAxis() is borked.) | ||
3054 | // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness | ||
3055 | |||
3056 | // Instead, compute the X axis of the coordinate frame by transforming | ||
3057 | // the (1,0,0) vector. At least that works. | ||
3058 | |||
3059 | //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); | ||
3060 | Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); | ||
3061 | //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); | ||
3062 | //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); | ||
3063 | d.JointSetHingeAxis(odeJoint, | ||
3064 | jointAxis.X, | ||
3065 | jointAxis.Y, | ||
3066 | jointAxis.Z); | ||
3067 | //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); | ||
3068 | if (joint is OdePhysicsJoint) | ||
3069 | { | ||
3070 | ((OdePhysicsJoint)joint).jointID = odeJoint; | ||
3071 | } | ||
3072 | else | ||
3073 | { | ||
3074 | DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); | ||
3075 | } | ||
3076 | } | ||
3077 | break; | ||
3078 | } | ||
3079 | successfullyProcessedPendingJoints.Add(joint); | ||
3080 | } | ||
3081 | } | ||
3082 | else | ||
3083 | { | ||
3084 | DoJointErrorMessage(joint, "joint could not yet be created; still pending"); | ||
3085 | } | ||
3086 | } | ||
3087 | |||
3088 | foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) | ||
3089 | { | ||
3090 | //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); | ||
3091 | //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); | ||
3092 | InternalRemovePendingJoint(successfullyProcessedJoint); | ||
3093 | //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); | ||
3094 | InternalAddActiveJoint(successfullyProcessedJoint); | ||
3095 | //DoJointErrorMessage(successfullyProcessedJoint, "done"); | ||
3096 | } | ||
3097 | } | ||
3098 | } | ||
3099 | |||
3100 | /// <summary> | ||
3101 | /// Simulate the joint proxies of a NINJA actor. | ||
3102 | /// </summary> | ||
3103 | /// <remarks> | ||
3104 | /// Called as part of the Simulate() loop if NINJA physics is active. Must only be called from there. | ||
3105 | /// </remarks> | ||
3106 | /// <param name="actor"></param> | ||
3107 | protected void SimulateActorPendingJoints(OdePrim actor) | ||
3108 | { | ||
3109 | // If an actor moved, move its joint proxy objects as well. | ||
3110 | // There seems to be an event PhysicsActor.OnPositionUpdate that could be used | ||
3111 | // for this purpose but it is never called! So we just do the joint | ||
3112 | // movement code here. | ||
3113 | |||
3114 | if (actor.SOPName != null && | ||
3115 | joints_connecting_actor.ContainsKey(actor.SOPName) && | ||
3116 | joints_connecting_actor[actor.SOPName] != null && | ||
3117 | joints_connecting_actor[actor.SOPName].Count > 0) | ||
3118 | { | ||
3119 | foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) | ||
3120 | { | ||
3121 | if (affectedJoint.IsInPhysicsEngine) | ||
3122 | { | ||
3123 | DoJointMoved(affectedJoint); | ||
3124 | } | ||
3125 | else | ||
3126 | { | ||
3127 | DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); | ||
3128 | } | ||
3129 | } | ||
3130 | } | ||
3131 | } | ||
3132 | |||
3114 | public override void GetResults() | 3133 | public override void GetResults() |
3115 | { | 3134 | { |
3116 | } | 3135 | } |
@@ -3456,24 +3475,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3456 | float hfmin = 2000; | 3475 | float hfmin = 2000; |
3457 | float hfmax = -2000; | 3476 | float hfmax = -2000; |
3458 | 3477 | ||
3459 | for (int x = 0; x < heightmapWidthSamples; x++) | 3478 | for (int x = 0; x < heightmapWidthSamples; x++) |
3479 | { | ||
3480 | for (int y = 0; y < heightmapHeightSamples; y++) | ||
3460 | { | 3481 | { |
3461 | for (int y = 0; y < heightmapHeightSamples; y++) | 3482 | int xx = Util.Clip(x - 1, 0, regionsize - 1); |
3462 | { | 3483 | int yy = Util.Clip(y - 1, 0, regionsize - 1); |
3463 | int xx = Util.Clip(x - 1, 0, regionsize - 1); | 3484 | |
3464 | int yy = Util.Clip(y - 1, 0, regionsize - 1); | 3485 | |
3465 | 3486 | float val= heightMap[yy * (int)Constants.RegionSize + xx]; | |
3466 | 3487 | _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; | |
3467 | float val= heightMap[yy * (int)Constants.RegionSize + xx]; | 3488 | |
3468 | _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; | 3489 | hfmin = (val < hfmin) ? val : hfmin; |
3469 | 3490 | hfmax = (val > hfmax) ? val : hfmax; | |
3470 | hfmin = (val < hfmin) ? val : hfmin; | ||
3471 | hfmax = (val > hfmax) ? val : hfmax; | ||
3472 | } | ||
3473 | } | 3491 | } |
3474 | 3492 | } | |
3475 | |||
3476 | |||
3477 | 3493 | ||
3478 | lock (OdeLock) | 3494 | lock (OdeLock) |
3479 | { | 3495 | { |
@@ -3528,7 +3544,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3528 | } | 3544 | } |
3529 | RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); | 3545 | RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); |
3530 | TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); | 3546 | TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); |
3531 | |||
3532 | } | 3547 | } |
3533 | } | 3548 | } |
3534 | 3549 | ||
@@ -3691,6 +3706,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3691 | //d.CloseODE(); | 3706 | //d.CloseODE(); |
3692 | } | 3707 | } |
3693 | } | 3708 | } |
3709 | |||
3694 | public override Dictionary<uint, float> GetTopColliders() | 3710 | public override Dictionary<uint, float> GetTopColliders() |
3695 | { | 3711 | { |
3696 | Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); | 3712 | Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); |
@@ -3727,6 +3743,34 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3727 | } | 3743 | } |
3728 | } | 3744 | } |
3729 | 3745 | ||
3746 | public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) | ||
3747 | { | ||
3748 | if (retMethod != null) | ||
3749 | { | ||
3750 | m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); | ||
3751 | } | ||
3752 | } | ||
3753 | |||
3754 | public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count) | ||
3755 | { | ||
3756 | ContactResult[] ourResults = null; | ||
3757 | RayCallback retMethod = delegate(List<ContactResult> results) | ||
3758 | { | ||
3759 | ourResults = new ContactResult[results.Count]; | ||
3760 | results.CopyTo(ourResults, 0); | ||
3761 | }; | ||
3762 | int waitTime = 0; | ||
3763 | m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod); | ||
3764 | while (ourResults == null && waitTime < 1000) | ||
3765 | { | ||
3766 | Thread.Sleep(1); | ||
3767 | waitTime++; | ||
3768 | } | ||
3769 | if (ourResults == null) | ||
3770 | return new List<ContactResult> (); | ||
3771 | return new List<ContactResult>(ourResults); | ||
3772 | } | ||
3773 | |||
3730 | #if USE_DRAWSTUFF | 3774 | #if USE_DRAWSTUFF |
3731 | // Keyboard callback | 3775 | // Keyboard callback |
3732 | public void command(int cmd) | 3776 | public void command(int cmd) |
diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs index 5dcd6f5..2ea810f 100644 --- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs +++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs | |||
@@ -31,17 +31,18 @@ using NUnit.Framework; | |||
31 | using OpenMetaverse; | 31 | using OpenMetaverse; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Physics.Manager; | 33 | using OpenSim.Region.Physics.Manager; |
34 | using OpenSim.Region.Physics.OdePlugin; | ||
34 | using log4net; | 35 | using log4net; |
35 | using System.Reflection; | 36 | using System.Reflection; |
36 | 37 | ||
37 | namespace OpenSim.Region.Physics.OdePlugin | 38 | namespace OpenSim.Region.Physics.OdePlugin.Tests |
38 | { | 39 | { |
39 | [TestFixture] | 40 | [TestFixture] |
40 | public class ODETestClass | 41 | public class ODETestClass |
41 | { | 42 | { |
42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
43 | 44 | ||
44 | private OdePlugin cbt; | 45 | private OpenSim.Region.Physics.OdePlugin.OdePlugin cbt; |
45 | private PhysicsScene ps; | 46 | private PhysicsScene ps; |
46 | private IMeshingPlugin imp; | 47 | private IMeshingPlugin imp; |
47 | 48 | ||