diff options
Diffstat (limited to 'OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs')
-rw-r--r-- | OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs | 159 |
1 files changed, 143 insertions, 16 deletions
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs index cc37ef5..1cebacf 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs | |||
@@ -157,6 +157,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
157 | 157 | ||
158 | float mu; | 158 | float mu; |
159 | 159 | ||
160 | // HoverHeight control | ||
161 | private float m_PIDHoverHeight; | ||
162 | private float m_PIDHoverTau; | ||
163 | private bool m_useHoverPID; | ||
164 | private PIDHoverType m_PIDHoverType; | ||
165 | private float m_targetHoverHeight; | ||
166 | |||
167 | |||
160 | public OdeCharacter(uint localID, String avName, ODEScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor) | 168 | public OdeCharacter(uint localID, String avName, ODEScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor) |
161 | { | 169 | { |
162 | m_uuid = UUID.Random(); | 170 | m_uuid = UUID.Random(); |
@@ -1042,7 +1050,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1042 | Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); | 1050 | Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); |
1043 | float velLengthSquared = vel.LengthSquared(); | 1051 | float velLengthSquared = vel.LengthSquared(); |
1044 | 1052 | ||
1045 | |||
1046 | Vector3 ctz = _target_velocity; | 1053 | Vector3 ctz = _target_velocity; |
1047 | 1054 | ||
1048 | float movementdivisor = 1f; | 1055 | float movementdivisor = 1f; |
@@ -1144,6 +1151,52 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1144 | } | 1151 | } |
1145 | } | 1152 | } |
1146 | 1153 | ||
1154 | bool hoverPIDActive = false; | ||
1155 | |||
1156 | if (m_useHoverPID && m_PIDHoverTau != 0 && m_PIDHoverHeight != 0) | ||
1157 | { | ||
1158 | hoverPIDActive = true; | ||
1159 | |||
1160 | switch (m_PIDHoverType) | ||
1161 | { | ||
1162 | case PIDHoverType.Ground: | ||
1163 | m_targetHoverHeight = terrainheight + m_PIDHoverHeight; | ||
1164 | break; | ||
1165 | |||
1166 | case PIDHoverType.GroundAndWater: | ||
1167 | float waterHeight = _parent_scene.GetWaterLevel(); | ||
1168 | if (terrainheight > waterHeight) | ||
1169 | m_targetHoverHeight = terrainheight + m_PIDHoverHeight; | ||
1170 | else | ||
1171 | m_targetHoverHeight = waterHeight + m_PIDHoverHeight; | ||
1172 | break; | ||
1173 | } // end switch (m_PIDHoverType) | ||
1174 | |||
1175 | // don't go underground | ||
1176 | if (m_targetHoverHeight > terrainheight + 0.5f * (aabb.MaxZ - aabb.MinZ)) | ||
1177 | { | ||
1178 | float fz = (m_targetHoverHeight - localpos.Z); | ||
1179 | |||
1180 | // if error is zero, use position control; otherwise, velocity control | ||
1181 | if (Math.Abs(fz) < 0.01f) | ||
1182 | { | ||
1183 | ctz.Z = 0; | ||
1184 | } | ||
1185 | else | ||
1186 | { | ||
1187 | _zeroFlag = false; | ||
1188 | fz /= m_PIDHoverTau; | ||
1189 | |||
1190 | float tmp = Math.Abs(fz); | ||
1191 | if (tmp > 50) | ||
1192 | fz = 50 * Math.Sign(fz); | ||
1193 | else if (tmp < 0.1) | ||
1194 | fz = 0.1f * Math.Sign(fz); | ||
1195 | |||
1196 | ctz.Z = fz; | ||
1197 | } | ||
1198 | } | ||
1199 | } | ||
1147 | 1200 | ||
1148 | //****************************************** | 1201 | //****************************************** |
1149 | if (!m_iscolliding) | 1202 | if (!m_iscolliding) |
@@ -1151,8 +1204,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1151 | 1204 | ||
1152 | bool tviszero = (ctz.X == 0.0f && ctz.Y == 0.0f && ctz.Z == 0.0f); | 1205 | bool tviszero = (ctz.X == 0.0f && ctz.Y == 0.0f && ctz.Z == 0.0f); |
1153 | 1206 | ||
1154 | |||
1155 | |||
1156 | if (!tviszero) | 1207 | if (!tviszero) |
1157 | { | 1208 | { |
1158 | m_freemove = false; | 1209 | m_freemove = false; |
@@ -1172,7 +1223,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1172 | 1223 | ||
1173 | } | 1224 | } |
1174 | 1225 | ||
1175 | |||
1176 | if (!m_freemove) | 1226 | if (!m_freemove) |
1177 | { | 1227 | { |
1178 | 1228 | ||
@@ -1262,7 +1312,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1262 | } | 1312 | } |
1263 | else // ie not colliding | 1313 | else // ie not colliding |
1264 | { | 1314 | { |
1265 | if (flying) //(!m_iscolliding && flying) | 1315 | if (flying || hoverPIDActive) //(!m_iscolliding && flying) |
1266 | { | 1316 | { |
1267 | // we're in mid air suspended | 1317 | // we're in mid air suspended |
1268 | vec.X += (ctz.X - vel.X) * (PID_D); | 1318 | vec.X += (ctz.X - vel.X) * (PID_D); |
@@ -1304,18 +1354,21 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1304 | vec.Z -= .16f* m_mass * vel.Z; | 1354 | vec.Z -= .16f* m_mass * vel.Z; |
1305 | } | 1355 | } |
1306 | 1356 | ||
1307 | if (flying) | 1357 | if (flying || hoverPIDActive) |
1308 | { | 1358 | { |
1309 | vec.Z -= _parent_scene.gravityz * m_mass; | 1359 | vec.Z -= _parent_scene.gravityz * m_mass; |
1310 | 1360 | ||
1311 | //Added for auto fly height. Kitto Flora | 1361 | if(!hoverPIDActive) |
1312 | float target_altitude = _parent_scene.GetTerrainHeightAtXY(localpos.X, localpos.Y) + MinimumGroundFlightOffset; | ||
1313 | |||
1314 | if (localpos.Z < target_altitude) | ||
1315 | { | 1362 | { |
1316 | vec.Z += (target_altitude - localpos.Z) * PID_P * 5.0f; | 1363 | //Added for auto fly height. Kitto Flora |
1364 | float target_altitude = terrainheight + MinimumGroundFlightOffset; | ||
1365 | |||
1366 | if (localpos.Z < target_altitude) | ||
1367 | { | ||
1368 | vec.Z += (target_altitude - localpos.Z) * PID_P * 5.0f; | ||
1369 | } | ||
1370 | // end add Kitto Flora | ||
1317 | } | 1371 | } |
1318 | // end add Kitto Flora | ||
1319 | } | 1372 | } |
1320 | 1373 | ||
1321 | if (vec.IsFinite()) | 1374 | if (vec.IsFinite()) |
@@ -1418,10 +1471,45 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1418 | public override bool PIDActive {get {return m_pidControllerActive;} set { return; } } | 1471 | public override bool PIDActive {get {return m_pidControllerActive;} set { return; } } |
1419 | public override float PIDTau { set { return; } } | 1472 | public override float PIDTau { set { return; } } |
1420 | 1473 | ||
1421 | public override float PIDHoverHeight { set { return; } } | 1474 | public override float PIDHoverHeight |
1422 | public override bool PIDHoverActive { set { return; } } | 1475 | { |
1423 | public override PIDHoverType PIDHoverType { set { return; } } | 1476 | set |
1424 | public override float PIDHoverTau { set { return; } } | 1477 | { |
1478 | AddChange(changes.PIDHoverHeight,value); | ||
1479 | } | ||
1480 | } | ||
1481 | public override bool PIDHoverActive | ||
1482 | { | ||
1483 | set | ||
1484 | { | ||
1485 | AddChange(changes.PIDHoverActive, value); | ||
1486 | } | ||
1487 | } | ||
1488 | |||
1489 | public override PIDHoverType PIDHoverType | ||
1490 | { | ||
1491 | set | ||
1492 | { | ||
1493 | AddChange(changes.PIDHoverType,value); | ||
1494 | } | ||
1495 | } | ||
1496 | |||
1497 | public override float PIDHoverTau | ||
1498 | { | ||
1499 | set | ||
1500 | { | ||
1501 | float tmp =0; | ||
1502 | if (value > 0) | ||
1503 | { | ||
1504 | float mint = (0.05f > timeStep ? 0.05f : timeStep); | ||
1505 | if (value < mint) | ||
1506 | tmp = mint; | ||
1507 | else | ||
1508 | tmp = value; | ||
1509 | } | ||
1510 | AddChange(changes.PIDHoverTau, tmp); | ||
1511 | } | ||
1512 | } | ||
1425 | 1513 | ||
1426 | public override Quaternion APIDTarget { set { return; } } | 1514 | public override Quaternion APIDTarget { set { return; } } |
1427 | 1515 | ||
@@ -1713,6 +1801,28 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1713 | d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); | 1801 | d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); |
1714 | } | 1802 | } |
1715 | 1803 | ||
1804 | private void changePIDHoverHeight(float val) | ||
1805 | { | ||
1806 | m_PIDHoverHeight = val; | ||
1807 | if (val == 0) | ||
1808 | m_useHoverPID = false; | ||
1809 | } | ||
1810 | |||
1811 | private void changePIDHoverType(PIDHoverType type) | ||
1812 | { | ||
1813 | m_PIDHoverType = type; | ||
1814 | } | ||
1815 | |||
1816 | private void changePIDHoverTau(float tau) | ||
1817 | { | ||
1818 | m_PIDHoverTau = tau; | ||
1819 | } | ||
1820 | |||
1821 | private void changePIDHoverActive(bool active) | ||
1822 | { | ||
1823 | m_useHoverPID = active; | ||
1824 | } | ||
1825 | |||
1716 | private void donullchange() | 1826 | private void donullchange() |
1717 | { | 1827 | { |
1718 | } | 1828 | } |
@@ -1792,6 +1902,23 @@ namespace OpenSim.Region.PhysicsModule.ubOde | |||
1792 | case changes.Momentum: | 1902 | case changes.Momentum: |
1793 | changeMomentum((Vector3)arg); | 1903 | changeMomentum((Vector3)arg); |
1794 | break; | 1904 | break; |
1905 | |||
1906 | case changes.PIDHoverHeight: | ||
1907 | changePIDHoverHeight((float)arg); | ||
1908 | break; | ||
1909 | |||
1910 | case changes.PIDHoverType: | ||
1911 | changePIDHoverType((PIDHoverType)arg); | ||
1912 | break; | ||
1913 | |||
1914 | case changes.PIDHoverTau: | ||
1915 | changePIDHoverTau((float)arg); | ||
1916 | break; | ||
1917 | |||
1918 | case changes.PIDHoverActive: | ||
1919 | changePIDHoverActive((bool)arg); | ||
1920 | break; | ||
1921 | |||
1795 | /* not in use for now | 1922 | /* not in use for now |
1796 | case changes.Shape: | 1923 | case changes.Shape: |
1797 | changeShape((PrimitiveBaseShape)arg); | 1924 | changeShape((PrimitiveBaseShape)arg); |