aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/OdePlugin.cs')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs1142
1 files changed, 3 insertions, 1139 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index e8ee33c..1e05274 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -1087,1143 +1087,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1087 { 1087 {
1088 } 1088 }
1089 } 1089 }
1090 # region ODE Actors 1090
1091 1091
1092 public class OdeCharacter : PhysicsActor 1092
1093 { 1093} \ No newline at end of file
1094 private PhysicsVector _position;
1095 private d.Vector3 _zeroPosition;
1096 private bool _zeroFlag = false;
1097 private bool m_lastUpdateSent = false;
1098 private PhysicsVector _velocity;
1099 private PhysicsVector _target_velocity;
1100 private PhysicsVector _acceleration;
1101 private PhysicsVector m_rotationalVelocity;
1102 private static float PID_D = 3020.0f;
1103 private static float PID_P = 7000.0f;
1104 private static float POSTURE_SERVO = 10000.0f;
1105 public static float CAPSULE_RADIUS = 0.5f;
1106 public float CAPSULE_LENGTH = 0.79f;
1107 private bool flying = false;
1108 private bool m_iscolliding = false;
1109 private bool m_iscollidingGround = false;
1110 private bool m_wascolliding = false;
1111 private bool m_wascollidingGround = false;
1112 private bool m_alwaysRun = false;
1113 private bool m_hackSentFall = false;
1114 private bool m_hackSentFly = false;
1115 private string m_name = "";
1116
1117 private bool[] m_colliderarr = new bool[11];
1118 private bool[] m_colliderGroundarr = new bool[11];
1119
1120
1121 private bool jumping = false;
1122 //private float gravityAccel;
1123 public IntPtr Body;
1124 private OdeScene _parent_scene;
1125 public IntPtr Shell;
1126 public d.Mass ShellMass;
1127 public bool collidelock = false;
1128
1129 public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos)
1130 {
1131 _velocity = new PhysicsVector();
1132 _target_velocity = new PhysicsVector();
1133 _position = pos;
1134 _acceleration = new PhysicsVector();
1135 _parent_scene = parent_scene;
1136
1137 for (int i = 0; i < 11; i++)
1138 {
1139 m_colliderarr[i] = false;
1140 }
1141
1142 lock (OdeScene.OdeLock)
1143 {
1144
1145 Shell = d.CreateCapsule(parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
1146 d.MassSetCapsule(out ShellMass, 50.0f, 3, 0.4f, 1.0f);
1147 Body = d.BodyCreate(parent_scene.world);
1148 d.BodySetMass(Body, ref ShellMass);
1149 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
1150 d.GeomSetBody(Shell, Body);
1151 }
1152 m_name = avName;
1153 parent_scene.geom_name_map[Shell] = avName;
1154 parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
1155 }
1156 public override int PhysicsActorType
1157 {
1158 get { return (int)ActorTypes.Agent; }
1159 set { return; }
1160 }
1161 public override bool SetAlwaysRun
1162 {
1163 get { return m_alwaysRun; }
1164 set { m_alwaysRun = value;}
1165 }
1166 public override bool IsPhysical
1167 {
1168 get { return false; }
1169 set { return; }
1170 }
1171 public override bool ThrottleUpdates
1172 {
1173 get { return false; }
1174 set { return; }
1175 }
1176 public override bool Flying
1177 {
1178 get { return flying; }
1179 set { flying = value; }
1180 }
1181 public override bool IsColliding
1182 {
1183
1184 get { return m_iscolliding; }
1185 set
1186 {
1187 int i;
1188 int truecount=0;
1189 int falsecount=0;
1190
1191 if (m_colliderarr.Length >= 10)
1192 {
1193 for (i = 0; i < 10; i++)
1194 {
1195 m_colliderarr[i] = m_colliderarr[i + 1];
1196 }
1197 }
1198 m_colliderarr[10] = value;
1199
1200 for (i = 0; i < 11; i++)
1201 {
1202 if (m_colliderarr[i])
1203 {
1204 truecount++;
1205 }
1206 else
1207 {
1208 falsecount++;
1209 }
1210 }
1211
1212 // Equal truecounts and false counts means we're colliding with something.
1213
1214 if (falsecount > 1.2 * truecount)
1215 {
1216 m_iscolliding = false;
1217 }
1218 else
1219 {
1220 m_iscolliding = true;
1221 }
1222 if (m_wascolliding != m_iscolliding)
1223 {
1224 base.SendCollisionUpdate(new CollisionEventUpdate());
1225 }
1226 m_wascolliding = m_iscolliding;
1227 }
1228 }
1229 public override bool CollidingGround
1230 {
1231 get { return m_iscollidingGround; }
1232 set
1233 {
1234 int i;
1235 int truecount = 0;
1236 int falsecount = 0;
1237
1238 if (m_colliderGroundarr.Length >= 10)
1239 {
1240 for (i = 0; i < 10; i++)
1241 {
1242 m_colliderGroundarr[i] = m_colliderGroundarr[i + 1];
1243 }
1244 }
1245 m_colliderGroundarr[10] = value;
1246
1247 for (i = 0; i < 11; i++)
1248 {
1249 if (m_colliderGroundarr[i])
1250 {
1251 truecount++;
1252 }
1253 else
1254 {
1255 falsecount++;
1256 }
1257 }
1258
1259 // Equal truecounts and false counts means we're colliding with something.
1260
1261 if (falsecount > 1.2 * truecount)
1262 {
1263 m_iscollidingGround = false;
1264 }
1265 else
1266 {
1267 m_iscollidingGround = true;
1268 }
1269 if (m_wascollidingGround != m_iscollidingGround)
1270 {
1271 //base.SendCollisionUpdate(new CollisionEventUpdate());
1272 }
1273 m_wascollidingGround = m_iscollidingGround;
1274 }
1275 }
1276 public override bool CollidingObj
1277 {
1278 get { return false; }
1279 set { return; }
1280 }
1281
1282 public override PhysicsVector Position
1283 {
1284 get { return _position; }
1285 set
1286 {
1287 lock (OdeScene.OdeLock)
1288 {
1289 d.BodySetPosition(Body, value.X, value.Y, value.Z);
1290 _position = value;
1291 }
1292 }
1293 }
1294 public override PhysicsVector RotationalVelocity
1295 {
1296 get { return m_rotationalVelocity; }
1297 set { m_rotationalVelocity = value; }
1298 }
1299 public override PhysicsVector Size
1300 {
1301 get { return new PhysicsVector(CAPSULE_RADIUS*2, CAPSULE_RADIUS*2, CAPSULE_LENGTH); }
1302 set {
1303 lock (OdeScene.OdeLock)
1304 {
1305 PhysicsVector SetSize = value;
1306 float prevCapsule = CAPSULE_LENGTH;
1307 float capsuleradius = CAPSULE_RADIUS;
1308 capsuleradius = 0.2f;
1309
1310 CAPSULE_LENGTH = (SetSize.Z - ((SetSize.Z * 0.43f))); // subtract 43% of the size
1311 d.BodyDestroy(Body);
1312 d.GeomDestroy(Shell);
1313 //OpenSim.Framework.Console.MainLog.Instance.Verbose("PHYSICS", "Set Avatar Height To: " + (CAPSULE_RADIUS + CAPSULE_LENGTH));
1314 Shell = d.CreateCapsule(_parent_scene.space, capsuleradius, CAPSULE_LENGTH);
1315 d.MassSetCapsule(out ShellMass, 50.0f, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
1316 Body = d.BodyCreate(_parent_scene.world);
1317 d.BodySetMass(Body, ref ShellMass);
1318 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z + Math.Abs(CAPSULE_LENGTH-prevCapsule));
1319 d.GeomSetBody(Shell, Body);
1320 }
1321 _parent_scene.geom_name_map[Shell] = m_name;
1322 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
1323 }
1324 }
1325
1326 public override PrimitiveBaseShape Shape
1327 {
1328 set
1329 {
1330 return;
1331 }
1332 }
1333
1334 public override PhysicsVector Velocity
1335 {
1336 get { return _velocity; }
1337 set { _target_velocity = value; }
1338 }
1339
1340 public override bool Kinematic
1341 {
1342 get { return false; }
1343 set { }
1344 }
1345
1346 public override Quaternion Orientation
1347 {
1348 get { return Quaternion.Identity; }
1349 set { }
1350 }
1351
1352 public override PhysicsVector Acceleration
1353 {
1354 get { return _acceleration; }
1355 }
1356
1357 public void SetAcceleration(PhysicsVector accel)
1358 {
1359 _acceleration = accel;
1360 }
1361
1362 public override void AddForce(PhysicsVector force)
1363 {
1364
1365 _target_velocity.X += force.X;
1366 _target_velocity.Y += force.Y;
1367 _target_velocity.Z += force.Z;
1368
1369 //m_lastUpdateSent = false;
1370 }
1371 public void doForce(PhysicsVector force)
1372 {
1373 if (!collidelock)
1374 {
1375 d.BodyAddForce(Body, force.X, force.Y, force.Z);
1376
1377 // ok -- let's stand up straight!
1378 d.Vector3 feet;
1379 d.Vector3 head;
1380 d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet);
1381 d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head);
1382 float posture = head.Z - feet.Z;
1383
1384 // restoring force proportional to lack of posture:
1385 float servo = (2.5f - posture) * POSTURE_SERVO;
1386 d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f);
1387 d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f);
1388 //m_lastUpdateSent = false;
1389
1390 }
1391
1392 }
1393 public override void SetMomentum(PhysicsVector momentum)
1394 {
1395
1396 }
1397
1398 public void Move(float timeStep)
1399 {
1400 // no lock; for now it's only called from within Simulate()
1401 PhysicsVector vec = new PhysicsVector();
1402 d.Vector3 vel = d.BodyGetLinearVel(Body);
1403 float movementdivisor = 1f;
1404
1405 if (!m_alwaysRun)
1406 {
1407 movementdivisor = 1.3f;
1408 }
1409 else
1410 {
1411 movementdivisor = 0.8f;
1412
1413 }
1414
1415 // if velocity is zero, use position control; otherwise, velocity control
1416 if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding)
1417 {
1418 // keep track of where we stopped. No more slippin' & slidin'
1419 if (!_zeroFlag)
1420 {
1421 _zeroFlag = true;
1422 _zeroPosition = d.BodyGetPosition(Body);
1423 }
1424 d.Vector3 pos = d.BodyGetPosition(Body);
1425 vec.X = (_target_velocity.X - vel.X)*PID_D + (_zeroPosition.X - pos.X)*PID_P;
1426 vec.Y = (_target_velocity.Y - vel.Y)*PID_D + (_zeroPosition.Y - pos.Y)*PID_P;
1427 if (flying)
1428 {
1429 vec.Z = (_target_velocity.Z - vel.Z)*PID_D + (_zeroPosition.Z - pos.Z)*PID_P;
1430 }
1431 }
1432 else
1433 {
1434
1435 _zeroFlag = false;
1436 if (m_iscolliding || flying)
1437 {
1438
1439 vec.X = ((_target_velocity.X/movementdivisor) - vel.X) * PID_D;
1440 vec.Y = ((_target_velocity.Y/movementdivisor) - vel.Y) * PID_D;
1441 }
1442 if (m_iscolliding && !flying && _target_velocity.Z > 0.0f)
1443 {
1444 d.Vector3 pos = d.BodyGetPosition(Body);
1445 vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P;
1446 if (_target_velocity.X > 0)
1447 {
1448 vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D;
1449 }
1450 if (_target_velocity.Y > 0)
1451 {
1452 vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D;
1453 }
1454 }
1455 else if (!m_iscolliding && !flying)
1456 {
1457 d.Vector3 pos = d.BodyGetPosition(Body);
1458 if (_target_velocity.X > 0)
1459 {
1460 vec.X = ((_target_velocity.X - vel.X)/1.2f) * PID_D;
1461 }
1462 if (_target_velocity.Y > 0)
1463 {
1464 vec.Y = ((_target_velocity.Y - vel.Y)/1.2f) * PID_D;
1465 }
1466
1467 }
1468
1469
1470 if (flying)
1471 {
1472 vec.Z = (_target_velocity.Z - vel.Z)*PID_D;
1473 }
1474 }
1475 if (flying)
1476 {
1477 vec.Z += 10.0f;
1478 }
1479
1480
1481 doForce(vec);
1482 }
1483
1484 public void UpdatePositionAndVelocity()
1485 {
1486 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
1487 d.Vector3 vec = d.BodyGetPosition(Body);
1488
1489 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
1490 if (vec.X < 0.0f) vec.X = 0.0f;
1491 if (vec.Y < 0.0f) vec.Y = 0.0f;
1492 if (vec.X > 255.95f) vec.X = 255.95f;
1493 if (vec.Y > 255.95f) vec.Y = 255.95f;
1494
1495 _position.X = vec.X;
1496 _position.Y = vec.Y;
1497 _position.Z = vec.Z;
1498
1499 if (_zeroFlag)
1500 {
1501 _velocity.X = 0.0f;
1502 _velocity.Y = 0.0f;
1503 _velocity.Z = 0.0f;
1504 if (!m_lastUpdateSent)
1505 {
1506 m_lastUpdateSent = true;
1507 base.RequestPhysicsterseUpdate();
1508 string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
1509 int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
1510 if (primScenAvatarIn == "0")
1511 {
1512 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in space with no prim. Arr:':" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
1513 }
1514 else
1515 {
1516 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in Prim space':" + primScenAvatarIn + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
1517 }
1518
1519 }
1520 }
1521 else
1522 {
1523 m_lastUpdateSent = false;
1524 vec = d.BodyGetLinearVel(Body);
1525 _velocity.X = (vec.X);
1526 _velocity.Y = (vec.Y);
1527
1528 _velocity.Z = (vec.Z);
1529 if (_velocity.Z < -6 && !m_hackSentFall)
1530 {
1531 m_hackSentFall = true;
1532 base.SendCollisionUpdate(new CollisionEventUpdate());
1533 }
1534 else if (flying && !m_hackSentFly)
1535 {
1536 //m_hackSentFly = true;
1537 //base.SendCollisionUpdate(new CollisionEventUpdate());
1538 }
1539 else
1540 {
1541 m_hackSentFly = false;
1542 m_hackSentFall = false;
1543 }
1544 }
1545 }
1546
1547 public void Destroy()
1548 {
1549 lock (OdeScene.OdeLock)
1550 {
1551 d.GeomDestroy(Shell);
1552 _parent_scene.geom_name_map.Remove(Shell);
1553 d.BodyDestroy(Body);
1554 }
1555 }
1556 }
1557
1558 public class OdePrim : PhysicsActor
1559 {
1560 public PhysicsVector _position;
1561 private PhysicsVector _velocity;
1562 private PhysicsVector m_lastVelocity = new PhysicsVector(0.0f,0.0f,0.0f);
1563 private PhysicsVector m_lastposition = new PhysicsVector(0.0f, 0.0f, 0.0f);
1564 private PhysicsVector m_rotationalVelocity;
1565 private PhysicsVector _size;
1566 private PhysicsVector _acceleration;
1567 private Quaternion _orientation;
1568 private PhysicsVector m_taintposition;
1569 private PhysicsVector m_taintsize;
1570 private Quaternion m_taintrot;
1571 private bool m_taintshape = false;
1572 private bool m_taintPhysics = false;
1573 public bool m_taintremove = false;
1574
1575 private IMesh _mesh;
1576 private PrimitiveBaseShape _pbs;
1577 private OdeScene _parent_scene;
1578 public IntPtr m_targetSpace = (IntPtr)0;
1579 public IntPtr prim_geom;
1580 public IntPtr _triMeshData;
1581 private bool iscolliding = false;
1582 private bool m_isphysical = false;
1583 private bool m_throttleUpdates = false;
1584 private int throttleCounter = 0;
1585 public bool outofBounds = false;
1586
1587 public bool _zeroFlag = false;
1588 private bool m_lastUpdateSent = false;
1589
1590 public IntPtr Body = (IntPtr) 0;
1591 private String m_primName;
1592 private PhysicsVector _target_velocity;
1593 public d.Mass pMass;
1594 private const float MassMultiplier = 150f; // Ref: Water: 1000kg.. this iset to 500
1595 private int debugcounter = 0;
1596
1597
1598 public OdePrim(String primName, OdeScene parent_scene, IntPtr targetSpace, PhysicsVector pos, PhysicsVector size,
1599 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical)
1600 {
1601
1602
1603 _velocity = new PhysicsVector();
1604 _position = pos;
1605 m_taintposition = pos;
1606 if (_position.X > 257)
1607 {
1608 _position.X = 257;
1609 }
1610 if (_position.X < 0)
1611 {
1612 _position.X = 0;
1613 }
1614 if (_position.Y > 257)
1615 {
1616 _position.Y = 257;
1617 }
1618 if (_position.Y < 0)
1619 {
1620 _position.Y = 0;
1621 }
1622
1623 _size = size;
1624 m_taintsize = _size;
1625 _acceleration = new PhysicsVector();
1626 m_rotationalVelocity = PhysicsVector.Zero;
1627 _orientation = rotation;
1628 m_taintrot = _orientation;
1629 _mesh = mesh;
1630 _pbs = pbs;
1631
1632 _parent_scene = parent_scene;
1633 m_targetSpace = targetSpace;
1634
1635 if (pos.Z < 0)
1636 m_isphysical = false;
1637 else
1638 {
1639 m_isphysical = pisPhysical;
1640 // If we're physical, we need to be in the master space for now.
1641 // linksets *should* be in a space together.. but are not currently
1642 if (m_isphysical)
1643 m_targetSpace = _parent_scene.space;
1644
1645 }
1646 m_primName = primName;
1647
1648
1649
1650 lock (OdeScene.OdeLock)
1651 {
1652 if (mesh != null)
1653 {
1654 setMesh(parent_scene, mesh);
1655 }
1656 else
1657 {
1658 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1659 }
1660
1661 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1662 d.Quaternion myrot = new d.Quaternion();
1663 myrot.W = rotation.w;
1664 myrot.X = rotation.x;
1665 myrot.Y = rotation.y;
1666 myrot.Z = rotation.z;
1667 d.GeomSetQuaternion(prim_geom, ref myrot);
1668
1669
1670 if (m_isphysical && Body == (IntPtr)0) {
1671 enableBody();
1672 }
1673 parent_scene.geom_name_map[prim_geom] = primName;
1674 parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
1675 // don't do .add() here; old geoms get recycled with the same hash
1676 }
1677 }
1678 public override int PhysicsActorType
1679 {
1680 get { return (int)ActorTypes.Prim; }
1681 set { return; }
1682 }
1683 public override bool SetAlwaysRun
1684 {
1685 get { return false; }
1686 set { return; }
1687 }
1688 public void enableBody()
1689 {
1690 // Sets the geom to a body
1691 Body = d.BodyCreate(_parent_scene.world);
1692
1693 setMass();
1694 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
1695 d.Quaternion myrot = new d.Quaternion();
1696 myrot.W = _orientation.w;
1697 myrot.X = _orientation.x;
1698 myrot.Y = _orientation.y;
1699 myrot.Z = _orientation.z;
1700 d.BodySetQuaternion(Body, ref myrot);
1701 d.GeomSetBody(prim_geom, Body);
1702 d.BodySetAutoDisableFlag(Body, true);
1703 d.BodySetAutoDisableSteps(Body,20);
1704
1705 _parent_scene.addActivePrim(this);
1706 }
1707 public void setMass()
1708 {
1709 //Sets Mass based on member MassMultiplier.
1710 if (Body != (IntPtr)0)
1711 {
1712 d.MassSetBox(out pMass, (_size.X * _size.Y * _size.Z * MassMultiplier), _size.X, _size.Y, _size.Z);
1713 d.BodySetMass(Body, ref pMass);
1714 }
1715 }
1716 public void disableBody()
1717 {
1718 //this kills the body so things like 'mesh' can re-create it.
1719 if (Body != (IntPtr)0)
1720 {
1721 _parent_scene.remActivePrim(this);
1722 d.BodyDestroy(Body);
1723 Body = (IntPtr)0;
1724 }
1725 }
1726 public void setMesh(OdeScene parent_scene, IMesh mesh)
1727 {
1728 //Kill Body so that mesh can re-make the geom
1729 if (IsPhysical && Body != (IntPtr)0)
1730 {
1731 disableBody();
1732 }
1733 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
1734 int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
1735 int VertexCount = vertexList.GetLength(0)/3;
1736 int IndexCount = indexList.GetLength(0);
1737
1738 _triMeshData = d.GeomTriMeshDataCreate();
1739
1740 d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount,
1741 3*sizeof (int));
1742 d.GeomTriMeshDataPreprocess(_triMeshData);
1743
1744 prim_geom = d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null);
1745
1746 if (IsPhysical && Body == (IntPtr)0)
1747 {
1748 // Recreate the body
1749 enableBody();
1750 }
1751 }
1752 public void ProcessTaints(float timestep)
1753 {
1754 if (m_taintposition != _position)
1755 Move(timestep);
1756
1757 if (m_taintrot != _orientation)
1758 rotate(timestep);
1759 //
1760
1761 if (m_taintPhysics != m_isphysical)
1762 changePhysicsStatus(timestep);
1763 //
1764
1765 if (m_taintsize != _size)
1766 changesize(timestep);
1767 //
1768
1769 if (m_taintshape)
1770 changeshape(timestep);
1771 //
1772
1773 }
1774 public void Move(float timestep)
1775 {
1776 if (m_isphysical)
1777 {
1778 // This is a fallback.. May no longer be necessary.
1779 if (Body == (IntPtr)0)
1780 enableBody();
1781 //Prim auto disable after 20 frames,
1782 ///if you move it, re-enable the prim manually.
1783 d.BodyEnable(Body);
1784 d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
1785 }
1786 else
1787 {
1788 string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
1789 int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
1790 if (primScenAvatarIn == "0")
1791 {
1792 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in space with no prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + " . Arr:': " + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
1793 }
1794 else
1795 {
1796 OpenSim.Framework.Console.MainLog.Instance.Verbose("Physics", "Prim " + m_primName + " in Prim space with prim: " + primScenAvatarIn + ". Expected to be at: " + m_targetSpace.ToString() + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
1797 }
1798 m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
1799 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1800 d.SpaceAdd(m_targetSpace, prim_geom);
1801 }
1802
1803 m_taintposition = _position;
1804 }
1805 public void rotate(float timestep)
1806 {
1807
1808 d.Quaternion myrot = new d.Quaternion();
1809 myrot.W = _orientation.w;
1810 myrot.X = _orientation.x;
1811 myrot.Y = _orientation.y;
1812 myrot.Z = _orientation.z;
1813 d.GeomSetQuaternion(prim_geom, ref myrot);
1814 if (m_isphysical && Body != (IntPtr)0)
1815 {
1816 d.BodySetQuaternion(Body, ref myrot);
1817 }
1818
1819 m_taintrot = _orientation;
1820 }
1821 public void changePhysicsStatus(float timestap)
1822 {
1823 if (m_isphysical == true)
1824 {
1825 if (Body == (IntPtr)0)
1826 {
1827 enableBody();
1828 }
1829
1830 }
1831 else
1832 {
1833 if (Body != (IntPtr)0)
1834 {
1835 disableBody();
1836 }
1837 }
1838
1839
1840 m_taintPhysics = m_isphysical;
1841 }
1842 public void changesize(float timestamp)
1843 {
1844 string oldname = _parent_scene.geom_name_map[prim_geom];
1845
1846 // Cleanup of old prim geometry
1847 if (_mesh != null)
1848 {
1849 // Cleanup meshing here
1850 }
1851 //kill body to rebuild
1852 if (IsPhysical && Body != (IntPtr)0)
1853 {
1854 disableBody();
1855 }
1856 if (d.SpaceQuery(m_targetSpace, prim_geom))
1857 {
1858 d.SpaceRemove(m_targetSpace, prim_geom);
1859 }
1860 d.GeomDestroy(prim_geom);
1861
1862 // we don't need to do space calculation because the client sends a position update also.
1863
1864 // Construction of new prim
1865 if (this._parent_scene.needsMeshing(_pbs))
1866 {
1867
1868
1869 // Don't need to re-enable body.. it's done in SetMesh
1870 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
1871 // createmesh returns null when it's a shape that isn't a cube.
1872 if (mesh != null)
1873 {
1874 setMesh(_parent_scene, mesh);
1875 }
1876 else
1877 {
1878 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1879 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1880 d.Quaternion myrot = new d.Quaternion();
1881 myrot.W = _orientation.w;
1882 myrot.X = _orientation.x;
1883 myrot.Y = _orientation.y;
1884 myrot.Z = _orientation.z;
1885 d.GeomSetQuaternion(prim_geom, ref myrot);
1886
1887
1888 }
1889 }
1890 else
1891 {
1892 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1893 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1894 d.Quaternion myrot = new d.Quaternion();
1895 myrot.W = _orientation.w;
1896 myrot.X = _orientation.x;
1897 myrot.Y = _orientation.y;
1898 myrot.Z = _orientation.z;
1899 d.GeomSetQuaternion(prim_geom, ref myrot);
1900
1901
1902 //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
1903 if (IsPhysical && Body == (IntPtr)0)
1904 {
1905 // Re creates body on size.
1906 // EnableBody also does setMass()
1907 enableBody();
1908 d.BodyEnable(Body);
1909 }
1910
1911 }
1912
1913
1914 _parent_scene.geom_name_map[prim_geom] = oldname;
1915
1916
1917 m_taintsize = _size;
1918 }
1919 public void changeshape(float timestamp)
1920 {
1921 string oldname = _parent_scene.geom_name_map[prim_geom];
1922
1923 // Cleanup of old prim geometry and Bodies
1924 if (IsPhysical && Body != (IntPtr)0)
1925 {
1926 disableBody();
1927 }
1928 d.GeomDestroy(prim_geom);
1929 if (_mesh != null)
1930 {
1931
1932 d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
1933
1934 }
1935
1936 // Construction of new prim
1937 if (this._parent_scene.needsMeshing(_pbs))
1938 {
1939 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
1940 if (mesh != null)
1941 {
1942 setMesh(_parent_scene, mesh);
1943 }
1944 else
1945 {
1946 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1947 }
1948 }
1949 else
1950 {
1951 prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
1952 }
1953 if (IsPhysical && Body == (IntPtr)0)
1954 {
1955 //re-create new body
1956 enableBody();
1957 }
1958 else
1959 {
1960 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
1961 d.Quaternion myrot = new d.Quaternion();
1962 myrot.W = _orientation.w;
1963 myrot.X = _orientation.x;
1964 myrot.Y = _orientation.y;
1965 myrot.Z = _orientation.z;
1966 d.GeomSetQuaternion(prim_geom, ref myrot);
1967 }
1968 _parent_scene.geom_name_map[prim_geom] = oldname;
1969
1970
1971
1972
1973 m_taintshape = false;
1974 }
1975 public override bool IsPhysical
1976 {
1977 get { return m_isphysical; }
1978 set{ m_isphysical = value;}
1979 }
1980 public void setPrimForRemoval()
1981 {
1982 m_taintremove = true;
1983 }
1984
1985 public override bool Flying
1986 {
1987 get { return false; //no flying prims for you
1988 }
1989 set { }
1990 }
1991
1992 public override bool IsColliding
1993 {
1994 get { return iscolliding; }
1995 set { iscolliding = value; }
1996 }
1997 public override bool CollidingGround
1998 {
1999 get { return false; }
2000 set { return; }
2001 }
2002 public override bool CollidingObj
2003 {
2004 get { return false; }
2005 set { return; }
2006 }
2007 public override bool ThrottleUpdates
2008 {
2009 get { return m_throttleUpdates; }
2010 set { m_throttleUpdates=value; }
2011 }
2012
2013 public override PhysicsVector Position
2014 {
2015 get {return _position; }
2016
2017
2018 set
2019 {
2020 _position = value;
2021
2022 }
2023 }
2024
2025 public override PhysicsVector Size
2026 {
2027 get { return _size; }
2028 set
2029 {
2030 _size = value;
2031
2032 }
2033 }
2034
2035 public override PrimitiveBaseShape Shape
2036 {
2037 set
2038 {
2039 _pbs = value;
2040
2041 }
2042 }
2043
2044 public override PhysicsVector Velocity
2045 {
2046 get {
2047 // Averate previous velocity with the new one so
2048 // client object interpolation works a 'little' better
2049 PhysicsVector returnVelocity = new PhysicsVector();
2050 returnVelocity.X = (m_lastVelocity.X + _velocity.X) / 2;
2051 returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) / 2;
2052 returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) / 2;
2053 return returnVelocity;
2054 }
2055 set { _velocity = value; }
2056 }
2057
2058 public override bool Kinematic
2059 {
2060 get { return false; }
2061 set { }
2062 }
2063
2064 public override Quaternion Orientation
2065 {
2066 get { return _orientation; }
2067 set
2068 {
2069 _orientation = value;
2070
2071 }
2072 }
2073
2074 public override PhysicsVector Acceleration
2075 {
2076 get { return _acceleration; }
2077 }
2078
2079
2080 public void SetAcceleration(PhysicsVector accel)
2081 {
2082 _acceleration = accel;
2083 }
2084
2085 public override void AddForce(PhysicsVector force)
2086 {
2087 }
2088
2089 public override PhysicsVector RotationalVelocity
2090 {
2091 get{ return m_rotationalVelocity;}
2092 set { m_rotationalVelocity = value; }
2093 }
2094
2095 public void UpdatePositionAndVelocity() {
2096 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
2097
2098 if (Body != (IntPtr)0)
2099 {
2100 d.Vector3 vec = d.BodyGetPosition(Body);
2101 d.Quaternion ori = d.BodyGetQuaternion(Body);
2102 d.Vector3 vel = d.BodyGetLinearVel(Body);
2103 d.Vector3 rotvel = d.BodyGetAngularVel(Body);
2104
2105 PhysicsVector l_position = new PhysicsVector();
2106 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
2107 if (vec.X < 0.0f) vec.X = 0.0f;
2108 if (vec.Y < 0.0f) vec.Y = 0.0f;
2109 if (vec.X > 255.95f) vec.X = 255.95f;
2110 if (vec.Y > 255.95f) vec.Y = 255.95f;
2111 m_lastposition = _position;
2112
2113 l_position.X = vec.X;
2114 l_position.Y = vec.Y;
2115 l_position.Z = vec.Z;
2116 if (l_position.Z < 0)
2117 {
2118 // This is so prim that get lost underground don't fall forever and suck up
2119 //
2120 // Sim resources and memory.
2121 // Disables the prim's movement physics....
2122 // It's a hack and will generate a console message if it fails.
2123
2124
2125
2126
2127 //IsPhysical = false;
2128 base.RaiseOutOfBounds(_position);
2129 _velocity.X = 0;
2130 _velocity.Y = 0;
2131 _velocity.Z = 0;
2132 m_rotationalVelocity.X = 0;
2133 m_rotationalVelocity.Y = 0;
2134 m_rotationalVelocity.Z = 0;
2135 base.RequestPhysicsterseUpdate();
2136 m_throttleUpdates = false;
2137 throttleCounter = 0;
2138 _zeroFlag = true;
2139 //outofBounds = true;
2140 }
2141
2142 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
2143 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
2144 && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02 ))
2145 {
2146
2147 _zeroFlag = true;
2148 }
2149 else
2150 {
2151 //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString());
2152 _zeroFlag = false;
2153 }
2154
2155
2156
2157 if (_zeroFlag)
2158 {
2159 // Supposedly this is supposed to tell SceneObjectGroup that
2160 // no more updates need to be sent..
2161 // but it seems broken.
2162 _velocity.X = 0.0f;
2163 _velocity.Y = 0.0f;
2164 _velocity.Z = 0.0f;
2165 //_orientation.w = 0f;
2166 //_orientation.x = 0f;
2167 //_orientation.y = 0f;
2168 //_orientation.z = 0f;
2169 m_rotationalVelocity.X = 0;
2170 m_rotationalVelocity.Y = 0;
2171 m_rotationalVelocity.Z = 0;
2172 if (!m_lastUpdateSent)
2173 {
2174 m_throttleUpdates = false;
2175 throttleCounter = 0;
2176 base.RequestPhysicsterseUpdate();
2177 m_lastUpdateSent = true;
2178 }
2179
2180 }
2181 else
2182 {
2183 m_lastVelocity = _velocity;
2184
2185 _position = l_position;
2186
2187 _velocity.X = vel.X;
2188 _velocity.Y = vel.Y;
2189 _velocity.Z = vel.Z;
2190
2191 m_rotationalVelocity.X = rotvel.X;
2192 m_rotationalVelocity.Y = rotvel.Y;
2193 m_rotationalVelocity.Z = rotvel.Z;
2194 //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString());
2195 _orientation.w = ori.W;
2196 _orientation.x = ori.X;
2197 _orientation.y = ori.Y;
2198 _orientation.z = ori.Z;
2199 m_lastUpdateSent = false;
2200 if (!m_throttleUpdates || throttleCounter > 15)
2201 {
2202 base.RequestPhysicsterseUpdate();
2203 }
2204 else
2205 {
2206 throttleCounter++;
2207 }
2208 }
2209 m_lastposition = l_position;
2210 }
2211 else
2212 {
2213 // Not a body.. so Make sure the client isn't interpolating
2214 _velocity.X = 0;
2215 _velocity.Y = 0;
2216 _velocity.Z = 0;
2217 m_rotationalVelocity.X = 0;
2218 m_rotationalVelocity.Y = 0;
2219 m_rotationalVelocity.Z = 0;
2220 _zeroFlag = true;
2221 }
2222
2223 }
2224 public override void SetMomentum(PhysicsVector momentum)
2225 {
2226 }
2227 }
2228}
2229 #endregion \ No newline at end of file