diff options
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | 110 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 321 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 514 |
4 files changed, 378 insertions, 568 deletions
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index 80218e7..c9d0909 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | |||
@@ -83,7 +83,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
83 | private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); | 83 | private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); |
84 | private float m_linearMotorDecayTimescale = 120; | 84 | private float m_linearMotorDecayTimescale = 120; |
85 | private float m_linearMotorTimescale = 1000; | 85 | private float m_linearMotorTimescale = 1000; |
86 | private Vector3 m_lastLinearVelocityVector = Vector3.Zero; | ||
87 | private Vector3 m_linearMotorOffset = Vector3.Zero; | 86 | private Vector3 m_linearMotorOffset = Vector3.Zero; |
88 | 87 | ||
89 | //Angular properties | 88 | //Angular properties |
@@ -91,7 +90,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
91 | private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate | 90 | private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate |
92 | private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate | 91 | private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate |
93 | private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate | 92 | private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate |
94 | private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body | ||
95 | 93 | ||
96 | //Deflection properties | 94 | //Deflection properties |
97 | private float m_angularDeflectionEfficiency = 0; | 95 | private float m_angularDeflectionEfficiency = 0; |
@@ -102,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
102 | //Banking properties | 100 | //Banking properties |
103 | private float m_bankingEfficiency = 0; | 101 | private float m_bankingEfficiency = 0; |
104 | private float m_bankingMix = 0; | 102 | private float m_bankingMix = 0; |
105 | private float m_bankingTimescale = 0; | 103 | private float m_bankingTimescale = 1000; |
106 | 104 | ||
107 | //Hover and Buoyancy properties | 105 | //Hover and Buoyancy properties |
108 | private float m_VhoverHeight = 0f; | 106 | private float m_VhoverHeight = 0f; |
@@ -117,9 +115,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
117 | private float m_verticalAttractionEfficiency = 1.0f; // damped | 115 | private float m_verticalAttractionEfficiency = 1.0f; // damped |
118 | private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor. | 116 | private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor. |
119 | 117 | ||
120 | // auxiliar | ||
121 | private Vector3 m_dir = Vector3.Zero; // velocity applied to body | ||
122 | 118 | ||
119 | // auxiliar | ||
123 | private float m_lmEfect = 0; // current linear motor eficiency | 120 | private float m_lmEfect = 0; // current linear motor eficiency |
124 | private float m_amEfect = 0; // current angular motor eficiency | 121 | private float m_amEfect = 0; // current angular motor eficiency |
125 | 122 | ||
@@ -130,6 +127,82 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
130 | _pParentScene = rootPrim._parent_scene; | 127 | _pParentScene = rootPrim._parent_scene; |
131 | } | 128 | } |
132 | 129 | ||
130 | |||
131 | public void DoSetVehicle(VehicleData vd) | ||
132 | { | ||
133 | |||
134 | float timestep = _pParentScene.ODE_STEPSIZE; | ||
135 | float invtimestep = 1.0f / timestep; | ||
136 | |||
137 | m_type = vd.m_type; | ||
138 | m_flags = vd.m_flags; | ||
139 | |||
140 | // Linear properties | ||
141 | m_linearMotorDirection = vd.m_linearMotorDirection; | ||
142 | |||
143 | m_linearFrictionTimescale = vd.m_linearFrictionTimescale; | ||
144 | if (m_linearFrictionTimescale.X < timestep) m_linearFrictionTimescale.X = timestep; | ||
145 | if (m_linearFrictionTimescale.Y < timestep) m_linearFrictionTimescale.Y = timestep; | ||
146 | if (m_linearFrictionTimescale.Z < timestep) m_linearFrictionTimescale.Z = timestep; | ||
147 | |||
148 | m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale; | ||
149 | if (m_linearMotorDecayTimescale < 0.5f) m_linearMotorDecayTimescale = 0.5f; | ||
150 | m_linearMotorDecayTimescale *= invtimestep; | ||
151 | |||
152 | m_linearMotorTimescale = vd.m_linearMotorTimescale; | ||
153 | if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep; | ||
154 | |||
155 | m_linearMotorOffset = vd.m_linearMotorOffset; | ||
156 | |||
157 | //Angular properties | ||
158 | m_angularMotorDirection = vd.m_angularMotorDirection; | ||
159 | m_angularMotorTimescale = vd.m_angularMotorTimescale; | ||
160 | if (m_angularMotorTimescale < timestep) m_angularMotorTimescale = timestep; | ||
161 | |||
162 | m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale; | ||
163 | if (m_angularMotorDecayTimescale < 0.5f) m_angularMotorDecayTimescale = 0.5f; | ||
164 | m_angularMotorDecayTimescale *= invtimestep; | ||
165 | |||
166 | m_angularFrictionTimescale = vd.m_angularFrictionTimescale; | ||
167 | if (m_angularFrictionTimescale.X < timestep) m_angularFrictionTimescale.X = timestep; | ||
168 | if (m_angularFrictionTimescale.Y < timestep) m_angularFrictionTimescale.Y = timestep; | ||
169 | if (m_angularFrictionTimescale.Z < timestep) m_angularFrictionTimescale.Z = timestep; | ||
170 | |||
171 | //Deflection properties | ||
172 | m_angularDeflectionEfficiency = vd.m_angularDeflectionEfficiency; | ||
173 | m_angularDeflectionTimescale = vd.m_angularDeflectionTimescale; | ||
174 | if (m_angularDeflectionTimescale < timestep) m_angularDeflectionTimescale = timestep; | ||
175 | |||
176 | m_linearDeflectionEfficiency = vd.m_linearDeflectionEfficiency; | ||
177 | m_linearDeflectionTimescale = vd.m_linearDeflectionTimescale; | ||
178 | if (m_linearDeflectionTimescale < timestep) m_linearDeflectionTimescale = timestep; | ||
179 | |||
180 | //Banking properties | ||
181 | m_bankingEfficiency = vd.m_bankingEfficiency; | ||
182 | m_bankingMix = vd.m_bankingMix; | ||
183 | m_bankingTimescale = vd.m_bankingTimescale; | ||
184 | if (m_bankingTimescale < timestep) m_bankingTimescale = timestep; | ||
185 | |||
186 | //Hover and Buoyancy properties | ||
187 | m_VhoverHeight = vd.m_VhoverHeight; | ||
188 | m_VhoverEfficiency = vd.m_VhoverEfficiency; | ||
189 | m_VhoverTimescale = vd.m_VhoverTimescale; | ||
190 | if (m_VhoverTimescale < timestep) m_VhoverTimescale = timestep; | ||
191 | |||
192 | m_VehicleBuoyancy = vd.m_VehicleBuoyancy; | ||
193 | |||
194 | //Attractor properties | ||
195 | m_verticalAttractionEfficiency = vd.m_verticalAttractionEfficiency; | ||
196 | m_verticalAttractionTimescale = vd.m_verticalAttractionTimescale; | ||
197 | if (m_verticalAttractionTimescale < timestep) m_verticalAttractionTimescale = timestep; | ||
198 | |||
199 | // Axis | ||
200 | m_referenceFrame = vd.m_referenceFrame; | ||
201 | |||
202 | m_lmEfect = 0; | ||
203 | m_amEfect = 0; | ||
204 | } | ||
205 | |||
133 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) | 206 | internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) |
134 | { | 207 | { |
135 | float len; | 208 | float len; |
@@ -231,6 +304,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
231 | if (len > 12.566f) | 304 | if (len > 12.566f) |
232 | m_angularMotorDirection *= (12.566f / len); | 305 | m_angularMotorDirection *= (12.566f / len); |
233 | m_amEfect = 1.0f; // turn it on | 306 | m_amEfect = 1.0f; // turn it on |
307 | if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) | ||
308 | && !rootPrim.m_isSelected && !rootPrim.m_disabled) | ||
309 | d.BodyEnable(rootPrim.Body); | ||
234 | break; | 310 | break; |
235 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 311 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
236 | if (pValue < timestep) pValue = timestep; | 312 | if (pValue < timestep) pValue = timestep; |
@@ -242,6 +318,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
242 | if (len > 30.0f) | 318 | if (len > 30.0f) |
243 | m_linearMotorDirection *= (30.0f / len); | 319 | m_linearMotorDirection *= (30.0f / len); |
244 | m_lmEfect = 1.0f; // turn it on | 320 | m_lmEfect = 1.0f; // turn it on |
321 | if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) | ||
322 | && !rootPrim.m_isSelected && !rootPrim.m_disabled) | ||
323 | d.BodyEnable(rootPrim.Body); | ||
245 | break; | 324 | break; |
246 | case Vehicle.LINEAR_MOTOR_OFFSET: | 325 | case Vehicle.LINEAR_MOTOR_OFFSET: |
247 | m_linearMotorOffset = new Vector3(pValue, pValue, pValue); | 326 | m_linearMotorOffset = new Vector3(pValue, pValue, pValue); |
@@ -273,6 +352,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
273 | if (len > 12.566f) | 352 | if (len > 12.566f) |
274 | m_angularMotorDirection *= (12.566f / len); | 353 | m_angularMotorDirection *= (12.566f / len); |
275 | m_amEfect = 1.0f; // turn it on | 354 | m_amEfect = 1.0f; // turn it on |
355 | if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) | ||
356 | && !rootPrim.m_isSelected && !rootPrim.m_disabled) | ||
357 | d.BodyEnable(rootPrim.Body); | ||
276 | break; | 358 | break; |
277 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 359 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
278 | if (pValue.X < timestep) pValue.X = timestep; | 360 | if (pValue.X < timestep) pValue.X = timestep; |
@@ -286,6 +368,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
286 | if (len > 30.0f) | 368 | if (len > 30.0f) |
287 | m_linearMotorDirection *= (30.0f / len); | 369 | m_linearMotorDirection *= (30.0f / len); |
288 | m_lmEfect = 1.0f; // turn it on | 370 | m_lmEfect = 1.0f; // turn it on |
371 | if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) | ||
372 | && !rootPrim.m_isSelected && !rootPrim.m_disabled) | ||
373 | d.BodyEnable(rootPrim.Body); | ||
289 | break; | 374 | break; |
290 | case Vehicle.LINEAR_MOTOR_OFFSET: | 375 | case Vehicle.LINEAR_MOTOR_OFFSET: |
291 | m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); | 376 | m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); |
@@ -347,12 +432,23 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
347 | m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); | 432 | m_linearFrictionTimescale = new Vector3(1000, 1000, 1000); |
348 | m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); | 433 | m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); |
349 | m_linearMotorTimescale = 1000; | 434 | m_linearMotorTimescale = 1000; |
350 | m_linearMotorDecayTimescale = 120 * invtimestep; | 435 | m_linearMotorDecayTimescale = 120; |
351 | m_angularMotorTimescale = 1000; | 436 | m_angularMotorTimescale = 1000; |
352 | m_angularMotorDecayTimescale = 1000 * invtimestep; | 437 | m_angularMotorDecayTimescale = 1000; |
353 | m_VhoverHeight = 0; | 438 | m_VhoverHeight = 0; |
439 | m_VhoverEfficiency = 1; | ||
354 | m_VhoverTimescale = 1000; | 440 | m_VhoverTimescale = 1000; |
355 | m_VehicleBuoyancy = 0; | 441 | m_VehicleBuoyancy = 0; |
442 | m_linearDeflectionEfficiency = 0; | ||
443 | m_linearDeflectionTimescale = 1000; | ||
444 | m_angularDeflectionEfficiency = 0; | ||
445 | m_angularDeflectionTimescale = 1000; | ||
446 | m_bankingEfficiency = 0; | ||
447 | m_bankingMix = 1; | ||
448 | m_bankingTimescale = 1000; | ||
449 | m_verticalAttractionEfficiency = 0; | ||
450 | m_verticalAttractionTimescale = 1000; | ||
451 | |||
356 | m_flags = (VehicleFlag)0; | 452 | m_flags = (VehicleFlag)0; |
357 | break; | 453 | break; |
358 | 454 | ||
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 3b7f562..0ccdbc0 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | |||
@@ -111,7 +111,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
111 | | CollisionCategories.Body | 111 | | CollisionCategories.Body |
112 | | CollisionCategories.Character | 112 | | CollisionCategories.Character |
113 | ); | 113 | ); |
114 | private bool m_collidesLand = true; | 114 | // private bool m_collidesLand = true; |
115 | private bool m_collidesWater; | 115 | private bool m_collidesWater; |
116 | public bool m_returnCollisions; | 116 | public bool m_returnCollisions; |
117 | 117 | ||
@@ -122,7 +122,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
122 | private CollisionCategories m_collisionFlags = m_default_collisionFlags; | 122 | private CollisionCategories m_collisionFlags = m_default_collisionFlags; |
123 | 123 | ||
124 | public bool m_disabled; | 124 | public bool m_disabled; |
125 | public bool m_taintselected; | 125 | |
126 | 126 | ||
127 | public uint m_localID; | 127 | public uint m_localID; |
128 | 128 | ||
@@ -142,20 +142,19 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
142 | private List<OdePrim> childrenPrim = new List<OdePrim>(); | 142 | private List<OdePrim> childrenPrim = new List<OdePrim>(); |
143 | 143 | ||
144 | private bool m_iscolliding; | 144 | private bool m_iscolliding; |
145 | private bool m_wascolliding; | 145 | |
146 | private bool m_isSelected; | 146 | public bool m_isSelected; |
147 | private bool m_delaySelect; | ||
148 | private bool m_lastdoneSelected; | ||
149 | public bool m_outbounds; | ||
147 | 150 | ||
148 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively | 151 | internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively |
149 | 152 | ||
150 | private bool m_throttleUpdates; | 153 | private bool m_throttleUpdates; |
151 | private int throttleCounter; | 154 | private int throttleCounter; |
152 | public int m_interpenetrationcount; | ||
153 | public float m_collisionscore; | 155 | public float m_collisionscore; |
154 | int m_colliderfilter = 0; | 156 | int m_colliderfilter = 0; |
155 | public int m_roundsUnderMotionThreshold; | ||
156 | private int m_crossingfailures; | ||
157 | 157 | ||
158 | public bool outofBounds; | ||
159 | private float m_density = 10.000006836f; // Aluminum g/cm3; | 158 | private float m_density = 10.000006836f; // Aluminum g/cm3; |
160 | 159 | ||
161 | public bool _zeroFlag; | 160 | public bool _zeroFlag; |
@@ -166,12 +165,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
166 | private Vector3 _target_velocity; | 165 | private Vector3 _target_velocity; |
167 | 166 | ||
168 | public Vector3 primOOBsize; // prim real dimensions from mesh | 167 | public Vector3 primOOBsize; // prim real dimensions from mesh |
169 | public Vector3 primOOBoffset; // is centroid out of mesh or rest aabb | 168 | public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb |
170 | public float primOOBradiusSQ; | 169 | public float primOOBradiusSQ; |
171 | public d.Mass primdMass; // prim inertia information on it's own referencial | 170 | public d.Mass primdMass; // prim inertia information on it's own referencial |
172 | float primMass; // prim own mass | 171 | float primMass; // prim own mass |
173 | float _mass; // object mass acording to case | 172 | float _mass; // object mass acording to case |
174 | public d.Mass objectpMass; // object last computed inertia | ||
175 | private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb | 173 | private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb |
176 | 174 | ||
177 | public int givefakepos = 0; | 175 | public int givefakepos = 0; |
@@ -182,9 +180,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
182 | public int m_eventsubscription; | 180 | public int m_eventsubscription; |
183 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); | 181 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); |
184 | 182 | ||
185 | private IntPtr m_linkJoint = IntPtr.Zero; | ||
186 | private IntPtr _linkJointGroup = IntPtr.Zero; | ||
187 | |||
188 | public volatile bool childPrim; | 183 | public volatile bool childPrim; |
189 | 184 | ||
190 | public ODEDynamics m_vehicle; | 185 | public ODEDynamics m_vehicle; |
@@ -264,7 +259,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
264 | set | 259 | set |
265 | { | 260 | { |
266 | if (value) | 261 | if (value) |
267 | m_isSelected = value; | 262 | m_isSelected = value; // if true set imediatly to stop moves etc |
268 | AddChange(changes.Selected, value); | 263 | AddChange(changes.Selected, value); |
269 | } | 264 | } |
270 | } | 265 | } |
@@ -298,13 +293,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
298 | m_iscolliding = false; | 293 | m_iscolliding = false; |
299 | else | 294 | else |
300 | m_iscolliding = true; | 295 | m_iscolliding = true; |
301 | |||
302 | if (m_wascolliding != m_iscolliding) | ||
303 | { | ||
304 | if (m_wascolliding && !m_isSelected && Body != IntPtr.Zero) | ||
305 | d.BodyEnable(Body); | ||
306 | m_wascolliding = m_iscolliding; | ||
307 | } | ||
308 | } | 296 | } |
309 | } | 297 | } |
310 | 298 | ||
@@ -665,19 +653,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
665 | strVehicleQuatParam fp = new strVehicleQuatParam(); | 653 | strVehicleQuatParam fp = new strVehicleQuatParam(); |
666 | fp.param = param; | 654 | fp.param = param; |
667 | fp.value = value; | 655 | fp.value = value; |
668 | AddChange(changes.VehicleVectorParam, fp); | 656 | AddChange(changes.VehicleRotationParam, fp); |
669 | } | 657 | } |
670 | 658 | ||
671 | public override void VehicleFlags(int param, bool value) | 659 | public override void VehicleFlags(int param, bool value) |
672 | { | 660 | { |
673 | if (m_vehicle == null) | ||
674 | return; | ||
675 | strVehicleBoolParam bp = new strVehicleBoolParam(); | 661 | strVehicleBoolParam bp = new strVehicleBoolParam(); |
676 | bp.param = param; | 662 | bp.param = param; |
677 | bp.value = value; | 663 | bp.value = value; |
678 | AddChange(changes.VehicleFlags, bp); | 664 | AddChange(changes.VehicleFlags, bp); |
679 | } | 665 | } |
680 | 666 | ||
667 | public override void SetVehicle(object vdata) | ||
668 | { | ||
669 | AddChange(changes.SetVehicle, vdata); | ||
670 | } | ||
681 | public void SetAcceleration(Vector3 accel) | 671 | public void SetAcceleration(Vector3 accel) |
682 | { | 672 | { |
683 | _acceleration = accel; | 673 | _acceleration = accel; |
@@ -710,8 +700,30 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
710 | 700 | ||
711 | public override void CrossingFailure() | 701 | public override void CrossingFailure() |
712 | { | 702 | { |
713 | m_crossingfailures++; | 703 | if (m_outbounds) |
714 | changeDisable(false); | 704 | { |
705 | _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); | ||
706 | _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); | ||
707 | _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); | ||
708 | |||
709 | m_lastposition = _position; | ||
710 | _velocity.X = 0; | ||
711 | _velocity.Y = 0; | ||
712 | _velocity.Z = 0; | ||
713 | |||
714 | m_lastVelocity = _velocity; | ||
715 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | ||
716 | m_vehicle.Stop(); | ||
717 | |||
718 | if(Body != IntPtr.Zero) | ||
719 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | ||
720 | if (prim_geom != IntPtr.Zero) | ||
721 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | ||
722 | |||
723 | m_outbounds = false; | ||
724 | changeDisable(false); | ||
725 | base.RequestPhysicsterseUpdate(); | ||
726 | } | ||
715 | } | 727 | } |
716 | 728 | ||
717 | public override void SetMomentum(Vector3 momentum) | 729 | public override void SetMomentum(Vector3 momentum) |
@@ -865,12 +877,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
865 | m_force = Vector3.Zero; | 877 | m_force = Vector3.Zero; |
866 | 878 | ||
867 | m_iscolliding = false; | 879 | m_iscolliding = false; |
868 | m_wascolliding = false; | ||
869 | m_colliderfilter = 0; | 880 | m_colliderfilter = 0; |
870 | 881 | ||
871 | hasOOBoffsetFromMesh = false; | 882 | hasOOBoffsetFromMesh = false; |
872 | _triMeshData = IntPtr.Zero; | 883 | _triMeshData = IntPtr.Zero; |
873 | 884 | ||
885 | m_lastdoneSelected = false; | ||
886 | m_isSelected = false; | ||
887 | m_delaySelect = false; | ||
874 | 888 | ||
875 | primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; | 889 | primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; |
876 | primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; | 890 | primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; |
@@ -885,8 +899,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
885 | private void resetCollisionAccounting() | 899 | private void resetCollisionAccounting() |
886 | { | 900 | { |
887 | m_collisionscore = 0; | 901 | m_collisionscore = 0; |
888 | m_interpenetrationcount = 0; | ||
889 | m_disabled = false; | ||
890 | } | 902 | } |
891 | 903 | ||
892 | private void createAMotor(Vector3 axis) | 904 | private void createAMotor(Vector3 axis) |
@@ -926,9 +938,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
926 | curr.W = dcur.W; | 938 | curr.W = dcur.W; |
927 | Vector3 ax; | 939 | Vector3 ax; |
928 | 940 | ||
929 | const int StopERP = 7; | ||
930 | const int StopCFM = 8; | ||
931 | |||
932 | int i = 0; | 941 | int i = 0; |
933 | int j = 0; | 942 | int j = 0; |
934 | if (axis.X == 0) | 943 | if (axis.X == 0) |
@@ -943,10 +952,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
943 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); | 952 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); |
944 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); | 953 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); |
945 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); | 954 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); |
946 | d.JointSetAMotorParam(Amotor, (int)StopCFM, 0f); | 955 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f); |
947 | d.JointSetAMotorParam(Amotor, (int)StopERP, 0.8f); | 956 | d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f); |
948 | i++; | 957 | i++; |
949 | j = 256; // odeplugin.cs doesn't have all parameters so this moves to next axis set | 958 | j = 256; // move to next axis set |
950 | } | 959 | } |
951 | 960 | ||
952 | if (axis.Y == 0) | 961 | if (axis.Y == 0) |
@@ -960,8 +969,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
960 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); | 969 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); |
961 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); | 970 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); |
962 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); | 971 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); |
963 | d.JointSetAMotorParam(Amotor, j + (int)StopCFM, 0f); | 972 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); |
964 | d.JointSetAMotorParam(Amotor, j + (int)StopERP, 0.8f); | 973 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); |
965 | i++; | 974 | i++; |
966 | j += 256; | 975 | j += 256; |
967 | } | 976 | } |
@@ -977,8 +986,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
977 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); | 986 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); |
978 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); | 987 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); |
979 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); | 988 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); |
980 | d.JointSetAMotorParam(Amotor, j + (int)StopCFM, 0f); | 989 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); |
981 | d.JointSetAMotorParam(Amotor, j + (int)StopERP, 0.8f); | 990 | d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); |
982 | } | 991 | } |
983 | } | 992 | } |
984 | 993 | ||
@@ -1186,24 +1195,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1186 | 1195 | ||
1187 | public void enableBodySoft() | 1196 | public void enableBodySoft() |
1188 | { | 1197 | { |
1189 | if (!childPrim) | 1198 | if (!childPrim && !m_isSelected) |
1190 | { | 1199 | { |
1191 | if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) | 1200 | if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) |
1192 | { | 1201 | { |
1193 | if (m_targetSpace != _parent_scene.ActiveSpace) | ||
1194 | { | ||
1195 | m_targetSpace = _parent_scene.ActiveSpace; | ||
1196 | |||
1197 | foreach (OdePrim prm in childrenPrim) | ||
1198 | { | ||
1199 | if (prm.prim_geom != IntPtr.Zero) | ||
1200 | { | ||
1201 | d.SpaceAdd(m_targetSpace, prm.prim_geom); | ||
1202 | prm.m_targetSpace = m_targetSpace; | ||
1203 | } | ||
1204 | } | ||
1205 | d.SpaceAdd(m_targetSpace, prim_geom); | ||
1206 | } | ||
1207 | d.GeomEnable(prim_geom); | 1202 | d.GeomEnable(prim_geom); |
1208 | foreach (OdePrim prm in childrenPrim) | 1203 | foreach (OdePrim prm in childrenPrim) |
1209 | d.GeomEnable(prm.prim_geom); | 1204 | d.GeomEnable(prm.prim_geom); |
@@ -1211,6 +1206,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1211 | d.BodyEnable(Body); | 1206 | d.BodyEnable(Body); |
1212 | } | 1207 | } |
1213 | } | 1208 | } |
1209 | m_disabled = false; | ||
1214 | resetCollisionAccounting(); // this sets m_disable to false | 1210 | resetCollisionAccounting(); // this sets m_disable to false |
1215 | } | 1211 | } |
1216 | 1212 | ||
@@ -1221,19 +1217,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1221 | { | 1217 | { |
1222 | if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) | 1218 | if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) |
1223 | { | 1219 | { |
1224 | if (m_targetSpace == _parent_scene.ActiveSpace) | ||
1225 | { | ||
1226 | foreach (OdePrim prm in childrenPrim) | ||
1227 | { | ||
1228 | if (prm.m_targetSpace != IntPtr.Zero && prm.prim_geom != IntPtr.Zero) | ||
1229 | { | ||
1230 | d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); | ||
1231 | prm.m_targetSpace = IntPtr.Zero; | ||
1232 | } | ||
1233 | } | ||
1234 | d.SpaceRemove(m_targetSpace, prim_geom); | ||
1235 | m_targetSpace = IntPtr.Zero; | ||
1236 | } | ||
1237 | d.GeomDisable(prim_geom); | 1220 | d.GeomDisable(prim_geom); |
1238 | foreach (OdePrim prm in childrenPrim) | 1221 | foreach (OdePrim prm in childrenPrim) |
1239 | d.GeomDisable(prm.prim_geom); | 1222 | d.GeomDisable(prm.prim_geom); |
@@ -1369,9 +1352,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1369 | d.BodySetMass(Body, ref objdmass); | 1352 | d.BodySetMass(Body, ref objdmass); |
1370 | _mass = objdmass.mass; | 1353 | _mass = objdmass.mass; |
1371 | 1354 | ||
1372 | m_collisionCategories |= CollisionCategories.Body; | ||
1373 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | ||
1374 | |||
1375 | // disconnect from world gravity so we can apply buoyancy | 1355 | // disconnect from world gravity so we can apply buoyancy |
1376 | d.BodySetGravityMode(Body, false); | 1356 | d.BodySetGravityMode(Body, false); |
1377 | 1357 | ||
@@ -1379,16 +1359,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1379 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); | 1359 | d.BodySetAutoDisableSteps(Body, body_autodisable_frames); |
1380 | // d.BodySetLinearDampingThreshold(Body, 0.01f); | 1360 | // d.BodySetLinearDampingThreshold(Body, 0.01f); |
1381 | // d.BodySetAngularDampingThreshold(Body, 0.001f); | 1361 | // d.BodySetAngularDampingThreshold(Body, 0.001f); |
1382 | d.BodySetDamping(Body, .001f, .0002f); | 1362 | d.BodySetDamping(Body, .002f, .002f); |
1383 | 1363 | ||
1364 | m_collisionCategories |= CollisionCategories.Body; | ||
1365 | m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | ||
1384 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 1366 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); |
1385 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 1367 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); |
1386 | |||
1387 | m_interpenetrationcount = 0; | ||
1388 | m_collisionscore = 0; | 1368 | m_collisionscore = 0; |
1389 | 1369 | ||
1390 | m_disabled = false; | ||
1391 | |||
1392 | if (m_targetSpace != _parent_scene.ActiveSpace) | 1370 | if (m_targetSpace != _parent_scene.ActiveSpace) |
1393 | { | 1371 | { |
1394 | if (m_targetSpace != IntPtr.Zero) | 1372 | if (m_targetSpace != IntPtr.Zero) |
@@ -1416,6 +1394,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1416 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); | 1394 | prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); |
1417 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); | 1395 | d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); |
1418 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); | 1396 | d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); |
1397 | prm.m_collisionscore = 0; | ||
1419 | 1398 | ||
1420 | if (prm.m_targetSpace != _parent_scene.ActiveSpace) | 1399 | if (prm.m_targetSpace != _parent_scene.ActiveSpace) |
1421 | { | 1400 | { |
@@ -1428,10 +1407,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1428 | prm.m_targetSpace = _parent_scene.ActiveSpace; | 1407 | prm.m_targetSpace = _parent_scene.ActiveSpace; |
1429 | d.SpaceAdd(m_targetSpace, prm.prim_geom); | 1408 | d.SpaceAdd(m_targetSpace, prm.prim_geom); |
1430 | } | 1409 | } |
1431 | d.GeomEnable(prm.prim_geom); | 1410 | |
1411 | if (m_isSelected || m_disabled) | ||
1412 | d.GeomDisable(prm.prim_geom); | ||
1413 | |||
1432 | prm.m_disabled = false; | 1414 | prm.m_disabled = false; |
1433 | prm.m_interpenetrationcount = 0; | ||
1434 | prm.m_collisionscore = 0; | ||
1435 | _parent_scene.addActivePrim(prm); | 1415 | _parent_scene.addActivePrim(prm); |
1436 | } | 1416 | } |
1437 | } | 1417 | } |
@@ -1442,8 +1422,12 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1442 | createAMotor(m_angularlock); | 1422 | createAMotor(m_angularlock); |
1443 | } | 1423 | } |
1444 | 1424 | ||
1445 | d.GeomEnable(prim_geom); | 1425 | if (m_isSelected || m_disabled) |
1446 | m_disabled = false; | 1426 | { |
1427 | d.GeomDisable(prim_geom); | ||
1428 | d.BodyDisable(Body); | ||
1429 | } | ||
1430 | |||
1447 | _parent_scene.addActivePrim(this); | 1431 | _parent_scene.addActivePrim(this); |
1448 | } | 1432 | } |
1449 | 1433 | ||
@@ -1484,12 +1468,16 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1484 | prm.m_collisionscore = 0; | 1468 | prm.m_collisionscore = 0; |
1485 | } | 1469 | } |
1486 | } | 1470 | } |
1471 | if (Amotor != IntPtr.Zero) | ||
1472 | { | ||
1473 | d.JointDestroy(Amotor); | ||
1474 | Amotor = IntPtr.Zero; | ||
1475 | } | ||
1487 | d.BodyDestroy(Body); | 1476 | d.BodyDestroy(Body); |
1488 | } | 1477 | } |
1489 | Body = IntPtr.Zero; | 1478 | Body = IntPtr.Zero; |
1490 | } | 1479 | } |
1491 | _mass = primMass; | 1480 | _mass = primMass; |
1492 | m_disabled = true; | ||
1493 | m_collisionscore = 0; | 1481 | m_collisionscore = 0; |
1494 | } | 1482 | } |
1495 | 1483 | ||
@@ -2115,49 +2103,72 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2115 | d.BodySetTorque(Body, 0f, 0f, 0f); | 2103 | d.BodySetTorque(Body, 0f, 0f, 0f); |
2116 | d.BodySetLinearVel(Body, 0f, 0f, 0f); | 2104 | d.BodySetLinearVel(Body, 0f, 0f, 0f); |
2117 | d.BodySetAngularVel(Body, 0f, 0f, 0f); | 2105 | d.BodySetAngularVel(Body, 0f, 0f, 0f); |
2118 | |||
2119 | } | 2106 | } |
2120 | } | 2107 | } |
2121 | 2108 | ||
2122 | private void changeSelectedStatus(bool newval) | 2109 | private void changeSelectedStatus(bool newval) |
2123 | { | 2110 | { |
2111 | if (m_lastdoneSelected == newval) | ||
2112 | return; | ||
2113 | |||
2114 | m_lastdoneSelected = newval; | ||
2115 | DoSelectedStatus(newval); | ||
2116 | } | ||
2117 | |||
2118 | private void CheckDelaySelect() | ||
2119 | { | ||
2120 | if (m_delaySelect) | ||
2121 | { | ||
2122 | DoSelectedStatus(m_isSelected); | ||
2123 | } | ||
2124 | } | ||
2125 | |||
2126 | private void DoSelectedStatus(bool newval) | ||
2127 | { | ||
2124 | m_isSelected = newval; | 2128 | m_isSelected = newval; |
2125 | Stop(); | 2129 | Stop(); |
2126 | 2130 | ||
2127 | if (newval) | 2131 | if (newval) |
2128 | { | 2132 | { |
2129 | m_collisionCategories = CollisionCategories.Selected; | 2133 | if (!childPrim && Body != IntPtr.Zero) |
2130 | m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); | 2134 | d.BodyDisable(Body); |
2131 | 2135 | ||
2132 | if (prim_geom != IntPtr.Zero) | 2136 | if (m_delaySelect) |
2133 | { | 2137 | { |
2134 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 2138 | if (!childPrim) |
2135 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 2139 | { |
2140 | foreach (OdePrim prm in childrenPrim) | ||
2141 | { | ||
2142 | d.GeomDisable(prm.prim_geom); | ||
2143 | prm.m_delaySelect = false; | ||
2144 | } | ||
2145 | } | ||
2146 | d.GeomDisable(prim_geom); | ||
2147 | m_delaySelect = false; | ||
2148 | } | ||
2149 | else | ||
2150 | { | ||
2151 | m_delaySelect = true; | ||
2136 | } | 2152 | } |
2137 | |||
2138 | disableBodySoft(); | ||
2139 | } | 2153 | } |
2140 | else | 2154 | else |
2141 | { | 2155 | { |
2142 | m_collisionCategories = CollisionCategories.Geom; | 2156 | if (!childPrim && Body != IntPtr.Zero && !m_disabled) |
2143 | 2157 | d.BodyEnable(Body); | |
2144 | if (m_isphysical) | ||
2145 | m_collisionCategories |= CollisionCategories.Body; | ||
2146 | |||
2147 | m_collisionFlags = m_default_collisionFlags; | ||
2148 | |||
2149 | if (m_collidesLand) | ||
2150 | m_collisionFlags |= CollisionCategories.Land; | ||
2151 | if (m_collidesWater) | ||
2152 | m_collisionFlags |= CollisionCategories.Water; | ||
2153 | 2158 | ||
2154 | if (prim_geom != IntPtr.Zero) | 2159 | if (!childPrim) |
2155 | { | 2160 | { |
2156 | d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); | 2161 | foreach (OdePrim prm in childrenPrim) |
2157 | d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); | 2162 | { |
2163 | if(!prm.m_disabled) | ||
2164 | d.GeomEnable(prm.prim_geom); | ||
2165 | prm.m_delaySelect = false; | ||
2166 | } | ||
2158 | } | 2167 | } |
2168 | if(!m_disabled) | ||
2169 | d.GeomEnable(prim_geom); | ||
2159 | 2170 | ||
2160 | enableBodySoft(); | 2171 | m_delaySelect = false; |
2161 | } | 2172 | } |
2162 | 2173 | ||
2163 | resetCollisionAccounting(); | 2174 | resetCollisionAccounting(); |
@@ -2165,6 +2176,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2165 | 2176 | ||
2166 | private void changePosition(Vector3 newPos) | 2177 | private void changePosition(Vector3 newPos) |
2167 | { | 2178 | { |
2179 | CheckDelaySelect(); | ||
2168 | if (m_isphysical) | 2180 | if (m_isphysical) |
2169 | { | 2181 | { |
2170 | if (childPrim) // inertia is messed, must rebuild | 2182 | if (childPrim) // inertia is messed, must rebuild |
@@ -2207,6 +2219,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2207 | 2219 | ||
2208 | private void changeOrientation(Quaternion newOri) | 2220 | private void changeOrientation(Quaternion newOri) |
2209 | { | 2221 | { |
2222 | CheckDelaySelect(); | ||
2210 | if (m_isphysical) | 2223 | if (m_isphysical) |
2211 | { | 2224 | { |
2212 | if (childPrim) // inertia is messed, must rebuild | 2225 | if (childPrim) // inertia is messed, must rebuild |
@@ -2258,6 +2271,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2258 | 2271 | ||
2259 | private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri) | 2272 | private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri) |
2260 | { | 2273 | { |
2274 | CheckDelaySelect(); | ||
2261 | if (m_isphysical) | 2275 | if (m_isphysical) |
2262 | { | 2276 | { |
2263 | if (childPrim && m_building) // inertia is messed, must rebuild | 2277 | if (childPrim && m_building) // inertia is messed, must rebuild |
@@ -2342,6 +2356,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2342 | 2356 | ||
2343 | private void changePhysicsStatus(bool NewStatus) | 2357 | private void changePhysicsStatus(bool NewStatus) |
2344 | { | 2358 | { |
2359 | CheckDelaySelect(); | ||
2360 | |||
2345 | m_isphysical = NewStatus; | 2361 | m_isphysical = NewStatus; |
2346 | 2362 | ||
2347 | if (!childPrim) | 2363 | if (!childPrim) |
@@ -2384,6 +2400,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2384 | 2400 | ||
2385 | private void changeprimsizeshape() | 2401 | private void changeprimsizeshape() |
2386 | { | 2402 | { |
2403 | CheckDelaySelect(); | ||
2404 | |||
2387 | OdePrim parent = (OdePrim)_parent; | 2405 | OdePrim parent = (OdePrim)_parent; |
2388 | 2406 | ||
2389 | bool chp = childPrim; | 2407 | bool chp = childPrim; |
@@ -2508,7 +2526,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2508 | } | 2526 | } |
2509 | 2527 | ||
2510 | m_collisionscore = 0; | 2528 | m_collisionscore = 0; |
2511 | m_interpenetrationcount = 0; | ||
2512 | } | 2529 | } |
2513 | } | 2530 | } |
2514 | 2531 | ||
@@ -2528,7 +2545,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2528 | } | 2545 | } |
2529 | } | 2546 | } |
2530 | m_collisionscore = 0; | 2547 | m_collisionscore = 0; |
2531 | m_interpenetrationcount = 0; | ||
2532 | } | 2548 | } |
2533 | } | 2549 | } |
2534 | 2550 | ||
@@ -2565,6 +2581,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2565 | else | 2581 | else |
2566 | { | 2582 | { |
2567 | m_building = false; | 2583 | m_building = false; |
2584 | CheckDelaySelect(); | ||
2568 | if (!childPrim) | 2585 | if (!childPrim) |
2569 | MakeBody(); | 2586 | MakeBody(); |
2570 | } | 2587 | } |
@@ -2575,18 +2592,26 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2575 | } | 2592 | } |
2576 | } | 2593 | } |
2577 | 2594 | ||
2578 | private void changeVehicleType(int value) | 2595 | public void changeSetVehicle(VehicleData vdata) |
2579 | { | 2596 | { |
2580 | if (m_vehicle == null) | 2597 | if (m_vehicle == null) |
2598 | m_vehicle = new ODEDynamics(this); | ||
2599 | m_vehicle.DoSetVehicle(vdata); | ||
2600 | } | ||
2601 | private void changeVehicleType(int value) | ||
2602 | { | ||
2603 | if (value == (int)Vehicle.TYPE_NONE) | ||
2581 | { | 2604 | { |
2582 | if (value != (int)Vehicle.TYPE_NONE) | 2605 | if (m_vehicle != null) |
2583 | { | 2606 | m_vehicle = null; |
2584 | m_vehicle = new ODEDynamics(this); | ||
2585 | m_vehicle.ProcessTypeChange((Vehicle)value); | ||
2586 | } | ||
2587 | } | 2607 | } |
2588 | else | 2608 | else |
2609 | { | ||
2610 | if (m_vehicle == null) | ||
2611 | m_vehicle = new ODEDynamics(this); | ||
2612 | |||
2589 | m_vehicle.ProcessTypeChange((Vehicle)value); | 2613 | m_vehicle.ProcessTypeChange((Vehicle)value); |
2614 | } | ||
2590 | } | 2615 | } |
2591 | 2616 | ||
2592 | private void changeVehicleFloatParam(strVehicleFloatParam fp) | 2617 | private void changeVehicleFloatParam(strVehicleFloatParam fp) |
@@ -2595,8 +2620,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2595 | return; | 2620 | return; |
2596 | 2621 | ||
2597 | m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value); | 2622 | m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value); |
2598 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | ||
2599 | d.BodyEnable(Body); | ||
2600 | } | 2623 | } |
2601 | 2624 | ||
2602 | private void changeVehicleVectorParam(strVehicleVectorParam vp) | 2625 | private void changeVehicleVectorParam(strVehicleVectorParam vp) |
@@ -2604,8 +2627,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2604 | if (m_vehicle == null) | 2627 | if (m_vehicle == null) |
2605 | return; | 2628 | return; |
2606 | m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value); | 2629 | m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value); |
2607 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | ||
2608 | d.BodyEnable(Body); | ||
2609 | } | 2630 | } |
2610 | 2631 | ||
2611 | private void changeVehicleRotationParam(strVehicleQuatParam qp) | 2632 | private void changeVehicleRotationParam(strVehicleQuatParam qp) |
@@ -2613,8 +2634,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2613 | if (m_vehicle == null) | 2634 | if (m_vehicle == null) |
2614 | return; | 2635 | return; |
2615 | m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value); | 2636 | m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value); |
2616 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | ||
2617 | d.BodyEnable(Body); | ||
2618 | } | 2637 | } |
2619 | 2638 | ||
2620 | private void changeVehicleFlags(strVehicleBoolParam bp) | 2639 | private void changeVehicleFlags(strVehicleBoolParam bp) |
@@ -2622,8 +2641,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2622 | if (m_vehicle == null) | 2641 | if (m_vehicle == null) |
2623 | return; | 2642 | return; |
2624 | m_vehicle.ProcessVehicleFlags(bp.param, bp.value); | 2643 | m_vehicle.ProcessVehicleFlags(bp.param, bp.value); |
2625 | if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) | ||
2626 | d.BodyEnable(Body); | ||
2627 | } | 2644 | } |
2628 | 2645 | ||
2629 | #endregion | 2646 | #endregion |
@@ -2849,41 +2866,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2849 | { | 2866 | { |
2850 | if (Body != IntPtr.Zero) | 2867 | if (Body != IntPtr.Zero) |
2851 | { | 2868 | { |
2852 | if (m_crossingfailures != 0 && m_crossingfailures < 5) | ||
2853 | { | ||
2854 | _position.X = Util.Clip(_position.X, 0.4f, _parent_scene.WorldExtents.X - 0.4f); | ||
2855 | _position.Y = Util.Clip(_position.Y, 0.4f, _parent_scene.WorldExtents.Y - 0.4f); | ||
2856 | _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); | ||
2857 | |||
2858 | float tmp = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y); | ||
2859 | if (_position.Z < tmp) | ||
2860 | _position.Z = tmp + 0.2f; | ||
2861 | |||
2862 | m_lastposition = _position; | ||
2863 | m_lastorientation = _orientation; | ||
2864 | _velocity.X = 0; | ||
2865 | _velocity.Y = 0; | ||
2866 | _velocity.Z = 0; | ||
2867 | |||
2868 | m_lastVelocity = _velocity; | ||
2869 | m_rotationalVelocity = _velocity; | ||
2870 | if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) | ||
2871 | m_vehicle.Stop(); | ||
2872 | |||
2873 | m_crossingfailures = 0; // do this only once | ||
2874 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | ||
2875 | d.BodySetAngularVel(Body, 0, 0, 0); | ||
2876 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | ||
2877 | enableBodySoft(); | ||
2878 | base.RequestPhysicsterseUpdate(); | ||
2879 | return; | ||
2880 | } | ||
2881 | |||
2882 | else if (m_crossingfailures != 0) | ||
2883 | { | ||
2884 | return; | ||
2885 | } | ||
2886 | |||
2887 | Vector3 pv = Vector3.Zero; | 2869 | Vector3 pv = Vector3.Zero; |
2888 | bool lastZeroFlag = _zeroFlag; | 2870 | bool lastZeroFlag = _zeroFlag; |
2889 | 2871 | ||
@@ -2899,24 +2881,21 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2899 | // we can't let it keeping moving and having colisions | 2881 | // we can't let it keeping moving and having colisions |
2900 | // since it can be stucked between something like terrain and edge | 2882 | // since it can be stucked between something like terrain and edge |
2901 | // so lets stop and disable it until something else kicks it | 2883 | // so lets stop and disable it until something else kicks it |
2902 | if (m_crossingfailures == 0) | ||
2903 | { | ||
2904 | 2884 | ||
2905 | _position.X = Util.Clip(lpos.X, -0.5f, _parent_scene.WorldExtents.X + 0.5f); | 2885 | _position.X = Util.Clip(lpos.X, -0.2f, _parent_scene.WorldExtents.X + 0.2f); |
2906 | _position.Y = Util.Clip(lpos.Y, -0.5f, _parent_scene.WorldExtents.Y + 0.5f); | 2886 | _position.Y = Util.Clip(lpos.Y, -0.2f, _parent_scene.WorldExtents.Y + 0.2f); |
2907 | _position.Z = Util.Clip(lpos.Z, -100f, 50000f); | 2887 | _position.Z = Util.Clip(lpos.Z, -100f, 50000f); |
2908 | 2888 | ||
2909 | m_lastposition = _position; | 2889 | m_lastposition = _position; |
2910 | m_lastorientation = _orientation; | 2890 | // m_lastorientation = _orientation; |
2911 | 2891 | ||
2912 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it | 2892 | d.BodySetLinearVel(Body, 0, 0, 0); // stop it |
2913 | d.BodySetAngularVel(Body, 0, 0, 0); | 2893 | // d.BodySetAngularVel(Body, 0, 0, 0); |
2914 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | 2894 | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); |
2915 | disableBodySoft(); // stop collisions | 2895 | disableBodySoft(); // stop collisions |
2916 | m_crossingfailures++; // do this only once | 2896 | m_outbounds = true; |
2917 | base.RequestPhysicsterseUpdate(); | 2897 | base.RequestPhysicsterseUpdate(); |
2918 | return; | 2898 | return; |
2919 | } | ||
2920 | } | 2899 | } |
2921 | 2900 | ||
2922 | if (lpos.Z < -100 || lpos.Z > 100000f) | 2901 | if (lpos.Z < -100 || lpos.Z > 100000f) |
@@ -3159,6 +3138,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3159 | else | 3138 | else |
3160 | ChildRemove(this, false); | 3139 | ChildRemove(this, false); |
3161 | 3140 | ||
3141 | m_vehicle = null; | ||
3162 | RemoveGeom(); | 3142 | RemoveGeom(); |
3163 | m_targetSpace = IntPtr.Zero; | 3143 | m_targetSpace = IntPtr.Zero; |
3164 | if (m_eventsubscription > 0) | 3144 | if (m_eventsubscription > 0) |
@@ -3273,6 +3253,9 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3273 | changeVehicleRotationParam((strVehicleQuatParam) arg); | 3253 | changeVehicleRotationParam((strVehicleQuatParam) arg); |
3274 | break; | 3254 | break; |
3275 | 3255 | ||
3256 | case changes.SetVehicle: | ||
3257 | changeSetVehicle((VehicleData) arg); | ||
3258 | break; | ||
3276 | case changes.Null: | 3259 | case changes.Null: |
3277 | donullchange(); | 3260 | donullchange(); |
3278 | break; | 3261 | break; |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index e62746e..2b6bc59 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | /* | 1 | /* |
3 | * based on: | 2 | * based on: |
4 | * Ode.NET - .NET bindings for ODE | 3 | * Ode.NET - .NET bindings for ODE |
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 56f3786..6e4c373 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | |||
@@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
137 | VehicleVectorParam, | 137 | VehicleVectorParam, |
138 | VehicleRotationParam, | 138 | VehicleRotationParam, |
139 | VehicleFlags, | 139 | VehicleFlags, |
140 | SetVehicle, | ||
140 | 141 | ||
141 | Null //keep this last used do dim the methods array. does nothing but pulsing the prim | 142 | Null //keep this last used do dim the methods array. does nothing but pulsing the prim |
142 | } | 143 | } |
@@ -166,8 +167,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
166 | 167 | ||
167 | float frictionMovementMult = 0.3f; | 168 | float frictionMovementMult = 0.3f; |
168 | 169 | ||
169 | float TerrainBounce = 0.3f; | 170 | float TerrainBounce = 0.1f; |
170 | float TerrainFriction = 0.3f; | 171 | float TerrainFriction = 0.1f; |
171 | 172 | ||
172 | public float AvatarBounce = 0.3f; | 173 | public float AvatarBounce = 0.3f; |
173 | public float AvatarFriction = 0;// 0.9f * 0.5f; | 174 | public float AvatarFriction = 0;// 0.9f * 0.5f; |
@@ -989,145 +990,62 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
989 | /// <param name="timeStep"></param> | 990 | /// <param name="timeStep"></param> |
990 | private void collision_optimized() | 991 | private void collision_optimized() |
991 | { | 992 | { |
992 | // _perloopContact.Clear(); | ||
993 | // clear characts IsColliding until we do it some other way | ||
994 | |||
995 | lock (_characters) | 993 | lock (_characters) |
996 | { | 994 | { |
997 | foreach (OdeCharacter chr in _characters) | 995 | try |
996 | { | ||
997 | foreach (OdeCharacter chr in _characters) | ||
998 | { | 998 | { |
999 | // this are odd checks if they are needed something is wrong elsewhere | 999 | if (chr == null || chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) |
1000 | // keep for now | 1000 | continue; |
1001 | if (chr == null) | 1001 | |
1002 | continue; | 1002 | chr.IsColliding = false; |
1003 | 1003 | // chr.CollidingGround = false; not done here | |
1004 | if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) | 1004 | chr.CollidingObj = false; |
1005 | continue; | 1005 | // do colisions with static space |
1006 | 1006 | d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback); | |
1007 | chr.IsColliding = false; | ||
1008 | // chr.CollidingGround = false; not done here | ||
1009 | chr.CollidingObj = false; | ||
1010 | } | 1007 | } |
1011 | } | 1008 | } |
1012 | 1009 | catch (AccessViolationException) | |
1013 | // now let ode do its job | ||
1014 | // colide active things amoung them | ||
1015 | |||
1016 | int st = Util.EnvironmentTickCount(); | ||
1017 | int ta; | ||
1018 | int ts; | ||
1019 | try | ||
1020 | { | ||
1021 | d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); | ||
1022 | } | ||
1023 | catch (AccessViolationException) | ||
1024 | { | 1010 | { |
1025 | m_log.Warn("[PHYSICS]: Unable to Active space collide"); | 1011 | m_log.Warn("[PHYSICS]: Unable to collide Character to static space"); |
1026 | } | 1012 | } |
1027 | ta = Util.EnvironmentTickCountSubtract(st); | 1013 | |
1028 | // then active things with static enviroment | 1014 | } |
1029 | try | 1015 | |
1016 | // collide active prims with static enviroment | ||
1017 | lock (_activeprims) | ||
1018 | { | ||
1019 | try | ||
1030 | { | 1020 | { |
1031 | d.SpaceCollide2(ActiveSpace,StaticSpace, IntPtr.Zero, nearCallback); | 1021 | foreach (OdePrim prm in _activeprims) |
1022 | { | ||
1023 | if (d.BodyIsEnabled(prm.Body)) | ||
1024 | d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback); | ||
1025 | } | ||
1032 | } | 1026 | } |
1033 | catch (AccessViolationException) | 1027 | catch (AccessViolationException) |
1034 | { | 1028 | { |
1035 | m_log.Warn("[PHYSICS]: Unable to Active to static space collide"); | 1029 | m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space"); |
1036 | } | 1030 | } |
1037 | ts = Util.EnvironmentTickCountSubtract(st); | ||
1038 | // _perloopContact.Clear(); | ||
1039 | } | ||
1040 | |||
1041 | #endregion | ||
1042 | |||
1043 | |||
1044 | public float GetTerrainHeightAtXY(float x, float y) | ||
1045 | { | ||
1046 | // assumes 1m size grid and constante size square regions | ||
1047 | // region offset in mega position | ||
1048 | |||
1049 | int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; | ||
1050 | int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; | ||
1051 | |||
1052 | IntPtr heightFieldGeom = IntPtr.Zero; | ||
1053 | |||
1054 | // get region map | ||
1055 | if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom)) | ||
1056 | return 0f; | ||
1057 | |||
1058 | if (heightFieldGeom == IntPtr.Zero) | ||
1059 | return 0f; | ||
1060 | |||
1061 | if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) | ||
1062 | return 0f; | ||
1063 | |||
1064 | // TerrainHeightField for ODE as offset 1m | ||
1065 | x += 1f - offsetX; | ||
1066 | y += 1f - offsetY; | ||
1067 | |||
1068 | // make position fit into array | ||
1069 | if (x < 0) | ||
1070 | x = 0; | ||
1071 | if (y < 0) | ||
1072 | y = 0; | ||
1073 | |||
1074 | // integer indexs | ||
1075 | int ix; | ||
1076 | int iy; | ||
1077 | // interpolators offset | ||
1078 | float dx; | ||
1079 | float dy; | ||
1080 | |||
1081 | int regsize = (int)Constants.RegionSize + 2; // map size see setterrain | ||
1082 | |||
1083 | // we still have square fixed size regions | ||
1084 | // also flip x and y because of how map is done for ODE fliped axis | ||
1085 | // so ix,iy,dx and dy are inter exchanged | ||
1086 | if (x < regsize - 1) | ||
1087 | { | ||
1088 | iy = (int)x; | ||
1089 | dy = x - (float)iy; | ||
1090 | } | ||
1091 | else // out world use external height | ||
1092 | { | ||
1093 | iy = regsize - 1; | ||
1094 | dy = 0; | ||
1095 | } | 1031 | } |
1096 | if (y < regsize - 1) | 1032 | |
1033 | // finally colide active things amoung them | ||
1034 | try | ||
1097 | { | 1035 | { |
1098 | ix = (int)y; | 1036 | d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); |
1099 | dx = y - (float)ix; | ||
1100 | } | 1037 | } |
1101 | else | 1038 | catch (AccessViolationException) |
1102 | { | 1039 | { |
1103 | ix = regsize - 1; | 1040 | m_log.Warn("[PHYSICS]: Unable to collide in Active space"); |
1104 | dx = 0; | ||
1105 | } | 1041 | } |
1106 | 1042 | ||
1107 | float h0; | 1043 | // _perloopContact.Clear(); |
1108 | float h1; | 1044 | } |
1109 | float h2; | ||
1110 | |||
1111 | iy *= regsize; | ||
1112 | iy += ix; // all indexes have iy + ix | ||
1113 | 1045 | ||
1114 | float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; | 1046 | #endregion |
1115 | 1047 | ||
1116 | if ((dx + dy) <= 1.0f) | ||
1117 | { | ||
1118 | h0 = ((float)heights[iy]); // 0,0 vertice | ||
1119 | h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0 | ||
1120 | h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0 | ||
1121 | } | ||
1122 | else | ||
1123 | { | ||
1124 | h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice | ||
1125 | h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0 | ||
1126 | h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1 | ||
1127 | } | ||
1128 | 1048 | ||
1129 | return h0 + h1 + h2; | ||
1130 | } | ||
1131 | 1049 | ||
1132 | /// <summary> | 1050 | /// <summary> |
1133 | /// Add actor to the list that should receive collision events in the simulate loop. | 1051 | /// Add actor to the list that should receive collision events in the simulate loop. |
@@ -1835,273 +1753,94 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1835 | get { return (false); } | 1753 | get { return (false); } |
1836 | } | 1754 | } |
1837 | 1755 | ||
1838 | #region ODE Specific Terrain Fixes | 1756 | public float GetTerrainHeightAtXY(float x, float y) |
1839 | public float[] ResizeTerrain512NearestNeighbour(float[] heightMap) | ||
1840 | { | 1757 | { |
1841 | float[] returnarr = new float[262144]; | 1758 | // assumes 1m size grid and constante size square regions |
1842 | float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y]; | 1759 | // needs to know about sims around in future |
1760 | // region offset in mega position | ||
1843 | 1761 | ||
1844 | // Filling out the array into its multi-dimensional components | 1762 | int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; |
1845 | for (int y = 0; y < WorldExtents.Y; y++) | 1763 | int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; |
1846 | { | ||
1847 | for (int x = 0; x < WorldExtents.X; x++) | ||
1848 | { | ||
1849 | resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x]; | ||
1850 | } | ||
1851 | } | ||
1852 | 1764 | ||
1853 | // Resize using Nearest Neighbour | 1765 | IntPtr heightFieldGeom = IntPtr.Zero; |
1854 | |||
1855 | // This particular way is quick but it only works on a multiple of the original | ||
1856 | |||
1857 | // The idea behind this method can be described with the following diagrams | ||
1858 | // second pass and third pass happen in the same loop really.. just separated | ||
1859 | // them to show what this does. | ||
1860 | |||
1861 | // First Pass | ||
1862 | // ResultArr: | ||
1863 | // 1,1,1,1,1,1 | ||
1864 | // 1,1,1,1,1,1 | ||
1865 | // 1,1,1,1,1,1 | ||
1866 | // 1,1,1,1,1,1 | ||
1867 | // 1,1,1,1,1,1 | ||
1868 | // 1,1,1,1,1,1 | ||
1869 | |||
1870 | // Second Pass | ||
1871 | // ResultArr2: | ||
1872 | // 1,,1,,1,,1,,1,,1, | ||
1873 | // ,,,,,,,,,, | ||
1874 | // 1,,1,,1,,1,,1,,1, | ||
1875 | // ,,,,,,,,,, | ||
1876 | // 1,,1,,1,,1,,1,,1, | ||
1877 | // ,,,,,,,,,, | ||
1878 | // 1,,1,,1,,1,,1,,1, | ||
1879 | // ,,,,,,,,,, | ||
1880 | // 1,,1,,1,,1,,1,,1, | ||
1881 | // ,,,,,,,,,, | ||
1882 | // 1,,1,,1,,1,,1,,1, | ||
1883 | |||
1884 | // Third pass fills in the blanks | ||
1885 | // ResultArr2: | ||
1886 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1887 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1888 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1889 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1890 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1891 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1892 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1893 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1894 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1895 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1896 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
1897 | |||
1898 | // X,Y = . | ||
1899 | // X+1,y = ^ | ||
1900 | // X,Y+1 = * | ||
1901 | // X+1,Y+1 = # | ||
1902 | |||
1903 | // Filling in like this; | ||
1904 | // .* | ||
1905 | // ^# | ||
1906 | // 1st . | ||
1907 | // 2nd * | ||
1908 | // 3rd ^ | ||
1909 | // 4th # | ||
1910 | // on single loop. | ||
1911 | |||
1912 | float[,] resultarr2 = new float[512, 512]; | ||
1913 | for (int y = 0; y < WorldExtents.Y; y++) | ||
1914 | { | ||
1915 | for (int x = 0; x < WorldExtents.X; x++) | ||
1916 | { | ||
1917 | resultarr2[y * 2, x * 2] = resultarr[y, x]; | ||
1918 | 1766 | ||
1919 | if (y < WorldExtents.Y) | 1767 | // get region map |
1920 | { | 1768 | if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom)) |
1921 | resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x]; | 1769 | return 0f; |
1922 | } | ||
1923 | if (x < WorldExtents.X) | ||
1924 | { | ||
1925 | resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x]; | ||
1926 | } | ||
1927 | if (x < WorldExtents.X && y < WorldExtents.Y) | ||
1928 | { | ||
1929 | resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x]; | ||
1930 | } | ||
1931 | } | ||
1932 | } | ||
1933 | 1770 | ||
1934 | //Flatten out the array | 1771 | if (heightFieldGeom == IntPtr.Zero) |
1935 | int i = 0; | 1772 | return 0f; |
1936 | for (int y = 0; y < 512; y++) | ||
1937 | { | ||
1938 | for (int x = 0; x < 512; x++) | ||
1939 | { | ||
1940 | if (resultarr2[y, x] <= 0) | ||
1941 | returnarr[i] = 0.0000001f; | ||
1942 | else | ||
1943 | returnarr[i] = resultarr2[y, x]; | ||
1944 | 1773 | ||
1945 | i++; | 1774 | if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) |
1946 | } | 1775 | return 0f; |
1947 | } | ||
1948 | 1776 | ||
1949 | return returnarr; | 1777 | // TerrainHeightField for ODE as offset 1m |
1950 | } | 1778 | x += 1f - offsetX; |
1779 | y += 1f - offsetY; | ||
1951 | 1780 | ||
1952 | public float[] ResizeTerrain512Interpolation(float[] heightMap) | 1781 | // make position fit into array |
1953 | { | 1782 | if (x < 0) |
1954 | float[] returnarr = new float[262144]; | 1783 | x = 0; |
1955 | float[,] resultarr = new float[512,512]; | 1784 | if (y < 0) |
1785 | y = 0; | ||
1786 | |||
1787 | // integer indexs | ||
1788 | int ix; | ||
1789 | int iy; | ||
1790 | // interpolators offset | ||
1791 | float dx; | ||
1792 | float dy; | ||
1793 | |||
1794 | int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples | ||
1956 | 1795 | ||
1957 | // Filling out the array into its multi-dimensional components | 1796 | // we still have square fixed size regions |
1958 | for (int y = 0; y < 256; y++) | 1797 | // also flip x and y because of how map is done for ODE fliped axis |
1798 | // so ix,iy,dx and dy are inter exchanged | ||
1799 | if (x < regsize - 1) | ||
1959 | { | 1800 | { |
1960 | for (int x = 0; x < 256; x++) | 1801 | iy = (int)x; |
1961 | { | 1802 | dy = x - (float)iy; |
1962 | resultarr[y, x] = heightMap[y * 256 + x]; | ||
1963 | } | ||
1964 | } | 1803 | } |
1965 | 1804 | else // out world use external height | |
1966 | // Resize using interpolation | ||
1967 | |||
1968 | // This particular way is quick but it only works on a multiple of the original | ||
1969 | |||
1970 | // The idea behind this method can be described with the following diagrams | ||
1971 | // second pass and third pass happen in the same loop really.. just separated | ||
1972 | // them to show what this does. | ||
1973 | |||
1974 | // First Pass | ||
1975 | // ResultArr: | ||
1976 | // 1,1,1,1,1,1 | ||
1977 | // 1,1,1,1,1,1 | ||
1978 | // 1,1,1,1,1,1 | ||
1979 | // 1,1,1,1,1,1 | ||
1980 | // 1,1,1,1,1,1 | ||
1981 | // 1,1,1,1,1,1 | ||
1982 | |||
1983 | // Second Pass | ||
1984 | // ResultArr2: | ||
1985 | // 1,,1,,1,,1,,1,,1, | ||
1986 | // ,,,,,,,,,, | ||
1987 | // 1,,1,,1,,1,,1,,1, | ||
1988 | // ,,,,,,,,,, | ||
1989 | // 1,,1,,1,,1,,1,,1, | ||
1990 | // ,,,,,,,,,, | ||
1991 | // 1,,1,,1,,1,,1,,1, | ||
1992 | // ,,,,,,,,,, | ||
1993 | // 1,,1,,1,,1,,1,,1, | ||
1994 | // ,,,,,,,,,, | ||
1995 | // 1,,1,,1,,1,,1,,1, | ||
1996 | |||
1997 | // Third pass fills in the blanks | ||
1998 | // ResultArr2: | ||
1999 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2000 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2001 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2002 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2003 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2004 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2005 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2006 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2007 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2008 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2009 | // 1,1,1,1,1,1,1,1,1,1,1,1 | ||
2010 | |||
2011 | // X,Y = . | ||
2012 | // X+1,y = ^ | ||
2013 | // X,Y+1 = * | ||
2014 | // X+1,Y+1 = # | ||
2015 | |||
2016 | // Filling in like this; | ||
2017 | // .* | ||
2018 | // ^# | ||
2019 | // 1st . | ||
2020 | // 2nd * | ||
2021 | // 3rd ^ | ||
2022 | // 4th # | ||
2023 | // on single loop. | ||
2024 | |||
2025 | float[,] resultarr2 = new float[512,512]; | ||
2026 | for (int y = 0; y < (int)Constants.RegionSize; y++) | ||
2027 | { | 1805 | { |
2028 | for (int x = 0; x < (int)Constants.RegionSize; x++) | 1806 | iy = regsize - 1; |
2029 | { | 1807 | dy = 0; |
2030 | resultarr2[y*2, x*2] = resultarr[y, x]; | ||
2031 | |||
2032 | if (y < (int)Constants.RegionSize) | ||
2033 | { | ||
2034 | if (y + 1 < (int)Constants.RegionSize) | ||
2035 | { | ||
2036 | if (x + 1 < (int)Constants.RegionSize) | ||
2037 | { | ||
2038 | resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
2039 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
2040 | } | ||
2041 | else | ||
2042 | { | ||
2043 | resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2); | ||
2044 | } | ||
2045 | } | ||
2046 | else | ||
2047 | { | ||
2048 | resultarr2[(y*2) + 1, x*2] = resultarr[y, x]; | ||
2049 | } | ||
2050 | } | ||
2051 | if (x < (int)Constants.RegionSize) | ||
2052 | { | ||
2053 | if (x + 1 < (int)Constants.RegionSize) | ||
2054 | { | ||
2055 | if (y + 1 < (int)Constants.RegionSize) | ||
2056 | { | ||
2057 | resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
2058 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
2059 | } | ||
2060 | else | ||
2061 | { | ||
2062 | resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2); | ||
2063 | } | ||
2064 | } | ||
2065 | else | ||
2066 | { | ||
2067 | resultarr2[y*2, (x*2) + 1] = resultarr[y, x]; | ||
2068 | } | ||
2069 | } | ||
2070 | if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize) | ||
2071 | { | ||
2072 | if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize)) | ||
2073 | { | ||
2074 | resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + | ||
2075 | resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); | ||
2076 | } | ||
2077 | else | ||
2078 | { | ||
2079 | resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x]; | ||
2080 | } | ||
2081 | } | ||
2082 | } | ||
2083 | } | 1808 | } |
2084 | //Flatten out the array | 1809 | if (y < regsize - 1) |
2085 | int i = 0; | ||
2086 | for (int y = 0; y < 512; y++) | ||
2087 | { | 1810 | { |
2088 | for (int x = 0; x < 512; x++) | 1811 | ix = (int)y; |
2089 | { | 1812 | dx = y - (float)ix; |
2090 | if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x])) | 1813 | } |
2091 | { | 1814 | else |
2092 | m_log.Warn("[PHYSICS]: Non finite heightfield element detected. Setting it to 0"); | 1815 | { |
2093 | resultarr2[y, x] = 0; | 1816 | ix = regsize - 1; |
2094 | } | 1817 | dx = 0; |
2095 | returnarr[i] = resultarr2[y, x]; | ||
2096 | i++; | ||
2097 | } | ||
2098 | } | 1818 | } |
2099 | 1819 | ||
2100 | return returnarr; | 1820 | float h0; |
2101 | } | 1821 | float h1; |
1822 | float h2; | ||
2102 | 1823 | ||
2103 | #endregion | 1824 | iy *= regsize; |
1825 | iy += ix; // all indexes have iy + ix | ||
2104 | 1826 | ||
1827 | float[] heights = TerrainHeightFieldHeights[heightFieldGeom]; | ||
1828 | |||
1829 | if ((dx + dy) <= 1.0f) | ||
1830 | { | ||
1831 | h0 = ((float)heights[iy]); // 0,0 vertice | ||
1832 | h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0 | ||
1833 | h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0 | ||
1834 | } | ||
1835 | else | ||
1836 | { | ||
1837 | h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice | ||
1838 | h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0 | ||
1839 | h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1 | ||
1840 | } | ||
1841 | |||
1842 | return h0 + h1 + h2; | ||
1843 | } | ||
2105 | public override void SetTerrain(float[] heightMap) | 1844 | public override void SetTerrain(float[] heightMap) |
2106 | { | 1845 | { |
2107 | if (m_worldOffset != Vector3.Zero && m_parentScene != null) | 1846 | if (m_worldOffset != Vector3.Zero && m_parentScene != null) |
@@ -2124,48 +1863,47 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2124 | 1863 | ||
2125 | public void SetTerrain(float[] heightMap, Vector3 pOffset) | 1864 | public void SetTerrain(float[] heightMap, Vector3 pOffset) |
2126 | { | 1865 | { |
1866 | // assumes 1m size grid and constante size square regions | ||
1867 | // needs to know about sims around in future | ||
2127 | 1868 | ||
2128 | float[] _heightmap; | 1869 | float[] _heightmap; |
2129 | _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))]; | ||
2130 | 1870 | ||
2131 | uint heightmapWidth = Constants.RegionSize + 2; | 1871 | uint heightmapWidth = Constants.RegionSize + 2; |
2132 | uint heightmapHeight = Constants.RegionSize + 2; | 1872 | uint heightmapHeight = Constants.RegionSize + 2; |
2133 | 1873 | ||
2134 | uint heightmapWidthSamples; | 1874 | uint heightmapWidthSamples = heightmapWidth + 1; |
1875 | uint heightmapHeightSamples = heightmapHeight + 1; | ||
2135 | 1876 | ||
2136 | uint heightmapHeightSamples; | 1877 | _heightmap = new float[heightmapWidthSamples * heightmapHeightSamples]; |
2137 | |||
2138 | heightmapWidthSamples = (uint)Constants.RegionSize + 2; | ||
2139 | heightmapHeightSamples = (uint)Constants.RegionSize + 2; | ||
2140 | 1878 | ||
2141 | const float scale = 1.0f; | 1879 | const float scale = 1.0f; |
2142 | const float offset = 0.0f; | 1880 | const float offset = 0.0f; |
2143 | const float thickness = 10f; | 1881 | const float thickness = 10f; |
2144 | const int wrap = 0; | 1882 | const int wrap = 0; |
2145 | 1883 | ||
2146 | int regionsize = (int) Constants.RegionSize + 2; | 1884 | uint regionsize = Constants.RegionSize; |
2147 | 1885 | ||
2148 | float hfmin = float.MaxValue; | 1886 | float hfmin = float.MaxValue; |
2149 | float hfmax = float.MinValue; | 1887 | float hfmax = float.MinValue; |
2150 | float val; | 1888 | float val; |
2151 | int xx; | 1889 | uint xx; |
2152 | int yy; | 1890 | uint yy; |
2153 | 1891 | ||
2154 | int maxXXYY = regionsize - 3; | 1892 | uint maxXXYY = regionsize - 1; |
2155 | // flipping map adding one margin all around so things don't fall in edges | 1893 | // flipping map adding one margin all around so things don't fall in edges |
2156 | 1894 | ||
2157 | int xt = 0; | 1895 | uint xt = 0; |
2158 | xx = 0; | 1896 | xx = 0; |
2159 | 1897 | ||
2160 | for (int x = 0; x < heightmapWidthSamples; x++) | 1898 | for (uint x = 0; x < heightmapWidthSamples; x++) |
2161 | { | 1899 | { |
2162 | if (x > 1 && xx < maxXXYY) | 1900 | if (x > 1 && xx < maxXXYY) |
2163 | xx++; | 1901 | xx++; |
2164 | yy = 0; | 1902 | yy = 0; |
2165 | for (int y = 0; y < heightmapHeightSamples; y++) | 1903 | for (uint y = 0; y < heightmapHeightSamples; y++) |
2166 | { | 1904 | { |
2167 | if (y > 1 && y < maxXXYY) | 1905 | if (y > 1 && y < maxXXYY) |
2168 | yy += (int)Constants.RegionSize; | 1906 | yy += regionsize; |
2169 | 1907 | ||
2170 | val = heightMap[yy + xx]; | 1908 | val = heightMap[yy + xx]; |
2171 | _heightmap[xt + y] = val; | 1909 | _heightmap[xt + y] = val; |
@@ -2176,8 +1914,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2176 | hfmax = val; | 1914 | hfmax = val; |
2177 | 1915 | ||
2178 | } | 1916 | } |
2179 | 1917 | xt += heightmapHeightSamples; | |
2180 | xt += regionsize; | ||
2181 | } | 1918 | } |
2182 | lock (OdeLock) | 1919 | lock (OdeLock) |
2183 | { | 1920 | { |
@@ -2230,11 +1967,6 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2230 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); | 1967 | d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); |
2231 | d.GeomSetRotation(GroundGeom, ref R); | 1968 | d.GeomSetRotation(GroundGeom, ref R); |
2232 | d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0); | 1969 | d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0); |
2233 | IntPtr testGround = IntPtr.Zero; | ||
2234 | if (RegionTerrain.TryGetValue(pOffset, out testGround)) | ||
2235 | { | ||
2236 | RegionTerrain.Remove(pOffset); | ||
2237 | } | ||
2238 | RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); | 1970 | RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); |
2239 | // TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); | 1971 | // TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); |
2240 | TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); | 1972 | TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); |