Clean up collision reporting code so they are properly passed to
the simulator in batches. More comments.0.7.4.1
parent
056c9a59b2
commit
e4a6611865
|
@ -74,7 +74,7 @@ public class BSCharacter : PhysicsActor
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
|
||||||
private int _subscribedEventsMs = 0;
|
private int _subscribedEventsMs = 0;
|
||||||
private int _lastCollisionTime = 0;
|
private int _nextCollisionOkTime = 0;
|
||||||
|
|
||||||
private Vector3 _PIDTarget;
|
private Vector3 _PIDTarget;
|
||||||
private bool _usePID;
|
private bool _usePID;
|
||||||
|
@ -360,17 +360,22 @@ public class BSCharacter : PhysicsActor
|
||||||
}
|
}
|
||||||
//m_lastUpdateSent = false;
|
//m_lastUpdateSent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddAngularForce(Vector3 force, bool pushforce) {
|
public override void AddAngularForce(Vector3 force, bool pushforce) {
|
||||||
}
|
}
|
||||||
public override void SetMomentum(Vector3 momentum) {
|
public override void SetMomentum(Vector3 momentum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Turn on collision events at a rate no faster than one every the given milliseconds
|
||||||
public override void SubscribeEvents(int ms) {
|
public override void SubscribeEvents(int ms) {
|
||||||
_subscribedEventsMs = ms;
|
_subscribedEventsMs = ms;
|
||||||
_lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
|
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
|
||||||
}
|
}
|
||||||
|
// Stop collision events
|
||||||
public override void UnSubscribeEvents() {
|
public override void UnSubscribeEvents() {
|
||||||
_subscribedEventsMs = 0;
|
_subscribedEventsMs = 0;
|
||||||
}
|
}
|
||||||
|
// Return 'true' if someone has subscribed to events
|
||||||
public override bool SubscribedEvents() {
|
public override bool SubscribedEvents() {
|
||||||
return (_subscribedEventsMs > 0);
|
return (_subscribedEventsMs > 0);
|
||||||
}
|
}
|
||||||
|
@ -386,47 +391,57 @@ public class BSCharacter : PhysicsActor
|
||||||
_mass = _density * _avatarVolume;
|
_mass = _density * _avatarVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set to 'true' if the individual changed items should be checked
|
||||||
|
// (someday RequestPhysicsTerseUpdate() will take a bitmap of changed properties)
|
||||||
|
const bool SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES = false;
|
||||||
|
|
||||||
// The physics engine says that properties have updated. Update same and inform
|
// The physics engine says that properties have updated. Update same and inform
|
||||||
// the world that things have changed.
|
// the world that things have changed.
|
||||||
public void UpdateProperties(EntityProperties entprop)
|
public void UpdateProperties(EntityProperties entprop)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
// we assign to the local variables so the normal set action does not happen
|
if (SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES) {
|
||||||
if (_position != entprop.Position)
|
// we assign to the local variables so the normal set action does not happen
|
||||||
{
|
if (_position != entprop.Position) {
|
||||||
|
_position = entprop.Position;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (_orientation != entprop.Rotation) {
|
||||||
|
_orientation = entprop.Rotation;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (_velocity != entprop.Velocity) {
|
||||||
|
_velocity = entprop.Velocity;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (_acceleration != entprop.Acceleration) {
|
||||||
|
_acceleration = entprop.Acceleration;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (_rotationalVelocity != entprop.RotationalVelocity) {
|
||||||
|
_rotationalVelocity = entprop.RotationalVelocity;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
|
||||||
|
// Avatar movement is not done by generating this event. There is code in the heartbeat
|
||||||
|
// loop that updates avatars.
|
||||||
|
// base.RequestPhysicsterseUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
_position = entprop.Position;
|
_position = entprop.Position;
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (_orientation != entprop.Rotation)
|
|
||||||
{
|
|
||||||
_orientation = entprop.Rotation;
|
_orientation = entprop.Rotation;
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (_velocity != entprop.Velocity)
|
|
||||||
{
|
|
||||||
_velocity = entprop.Velocity;
|
_velocity = entprop.Velocity;
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (_acceleration != entprop.Acceleration)
|
|
||||||
{
|
|
||||||
_acceleration = entprop.Acceleration;
|
_acceleration = entprop.Acceleration;
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (_rotationalVelocity != entprop.RotationalVelocity)
|
|
||||||
{
|
|
||||||
_rotationalVelocity = entprop.RotationalVelocity;
|
_rotationalVelocity = entprop.RotationalVelocity;
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (changed)
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
|
|
||||||
// Avatar movement is not done by generating this event. There is a system that
|
|
||||||
// checks for avatar updates each heartbeat loop.
|
|
||||||
// base.RequestPhysicsterseUpdate();
|
// base.RequestPhysicsterseUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by the scene when a collision with this object is reported
|
// Called by the scene when a collision with this object is reported
|
||||||
|
// The collision, if it should be reported to the character, is placed in a collection
|
||||||
|
// that will later be sent to the simulator when SendCollisions() is called.
|
||||||
CollisionEventUpdate collisionCollection = null;
|
CollisionEventUpdate collisionCollection = null;
|
||||||
public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||||
{
|
{
|
||||||
|
@ -440,29 +455,34 @@ public class BSCharacter : PhysicsActor
|
||||||
}
|
}
|
||||||
|
|
||||||
// throttle collisions to the rate specified in the subscription
|
// throttle collisions to the rate specified in the subscription
|
||||||
if (_subscribedEventsMs == 0) return; // don't want collisions
|
if (_subscribedEventsMs != 0) {
|
||||||
int nowTime = _scene.SimulationNowTime;
|
int nowTime = _scene.SimulationNowTime;
|
||||||
if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
|
if (nowTime >= _nextCollisionOkTime) {
|
||||||
_lastCollisionTime = nowTime;
|
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
||||||
|
|
||||||
if (collisionCollection == null)
|
if (collisionCollection == null)
|
||||||
collisionCollection = new CollisionEventUpdate();
|
collisionCollection = new CollisionEventUpdate();
|
||||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendCollisions()
|
public void SendCollisions()
|
||||||
{
|
{
|
||||||
// if (collisionCollection != null)
|
/*
|
||||||
// {
|
if (collisionCollection != null && collisionCollection.Count > 0)
|
||||||
// base.SendCollisionUpdate(collisionCollection);
|
{
|
||||||
// collisionCollection = null;
|
base.SendCollisionUpdate(collisionCollection);
|
||||||
// }
|
collisionCollection = null;
|
||||||
|
}
|
||||||
|
*/
|
||||||
// Kludge to make a collision call even if there are no collisions.
|
// Kludge to make a collision call even if there are no collisions.
|
||||||
// This causes the avatar animation to get updated.
|
// This causes the avatar animation to get updated.
|
||||||
if (collisionCollection == null)
|
if (collisionCollection == null)
|
||||||
collisionCollection = new CollisionEventUpdate();
|
collisionCollection = new CollisionEventUpdate();
|
||||||
base.SendCollisionUpdate(collisionCollection);
|
base.SendCollisionUpdate(collisionCollection);
|
||||||
collisionCollection = null;
|
collisionCollection.Clear();
|
||||||
|
// End kludge
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,14 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Entry for a port of Bullet (http://bulletphysics.org/) to OpenSim.
|
||||||
|
/// This module interfaces to an unmanaged C++ library which makes the
|
||||||
|
/// actual calls into the Bullet physics engine.
|
||||||
|
/// The unmanaged library is found in opensim-libs::trunk/unmanaged/BulletSim/.
|
||||||
|
/// The unmanaged library is compiled and linked statically with Bullet
|
||||||
|
/// to create BulletSim.dll and libBulletSim.so (for both 32 and 64 bit).
|
||||||
|
/// </summary>
|
||||||
public class BSPlugin : IPhysicsPlugin
|
public class BSPlugin : IPhysicsPlugin
|
||||||
{
|
{
|
||||||
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -53,6 +61,9 @@ public class BSPlugin : IPhysicsPlugin
|
||||||
{
|
{
|
||||||
if (Util.IsWindows())
|
if (Util.IsWindows())
|
||||||
Util.LoadArchSpecificWindowsDll("BulletSim.dll");
|
Util.LoadArchSpecificWindowsDll("BulletSim.dll");
|
||||||
|
// If not Windows, loading is performed by the
|
||||||
|
// Mono loader as specified in
|
||||||
|
// "bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config".
|
||||||
|
|
||||||
_mScene = new BSScene(sceneIdentifier);
|
_mScene = new BSScene(sceneIdentifier);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
private BSPrim _parentPrim;
|
private BSPrim _parentPrim;
|
||||||
|
|
||||||
private int _subscribedEventsMs = 0;
|
private int _subscribedEventsMs = 0;
|
||||||
private int _lastCollisionTime = 0;
|
private int _nextCollisionOkTime = 0;
|
||||||
long _collidingStep;
|
long _collidingStep;
|
||||||
long _collidingGroundStep;
|
long _collidingGroundStep;
|
||||||
|
|
||||||
|
@ -597,7 +597,8 @@ public sealed class BSPrim : PhysicsActor
|
||||||
}
|
}
|
||||||
public override void SubscribeEvents(int ms) {
|
public override void SubscribeEvents(int ms) {
|
||||||
_subscribedEventsMs = ms;
|
_subscribedEventsMs = ms;
|
||||||
_lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
|
// make sure first collision happens
|
||||||
|
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
||||||
}
|
}
|
||||||
public override void UnSubscribeEvents() {
|
public override void UnSubscribeEvents() {
|
||||||
_subscribedEventsMs = 0;
|
_subscribedEventsMs = 0;
|
||||||
|
@ -1338,23 +1339,27 @@ public sealed class BSPrim : PhysicsActor
|
||||||
_collidingGroundStep = _scene.SimulationStep;
|
_collidingGroundStep = _scene.SimulationStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events
|
// if someone is subscribed to collision events....
|
||||||
// throttle the collisions to the number of milliseconds specified in the subscription
|
if (_subscribedEventsMs != 0) {
|
||||||
int nowTime = _scene.SimulationNowTime;
|
// throttle the collisions to the number of milliseconds specified in the subscription
|
||||||
if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
|
int nowTime = _scene.SimulationNowTime;
|
||||||
_lastCollisionTime = nowTime;
|
if (nowTime >= _nextCollisionOkTime) {
|
||||||
|
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
||||||
|
|
||||||
if (collisionCollection == null)
|
if (collisionCollection == null)
|
||||||
collisionCollection = new CollisionEventUpdate();
|
collisionCollection = new CollisionEventUpdate();
|
||||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The scene is telling us it's time to pass our collected collisions into the simulator
|
||||||
public void SendCollisions()
|
public void SendCollisions()
|
||||||
{
|
{
|
||||||
if (collisionCollection != null)
|
if (collisionCollection != null && collisionCollection.Count > 0)
|
||||||
{
|
{
|
||||||
base.SendCollisionUpdate(collisionCollection);
|
base.SendCollisionUpdate(collisionCollection);
|
||||||
collisionCollection = null;
|
collisionCollection.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ using OpenSim.Region.Framework;
|
||||||
// Should prim.link() and prim.delink() membership checking happen at taint time?
|
// Should prim.link() and prim.delink() membership checking happen at taint time?
|
||||||
// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
|
// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
|
||||||
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
|
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
|
||||||
|
// Use collision masks for collision with terrain and phantom objects
|
||||||
// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
|
// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
|
||||||
// Implement LockAngularMotion
|
// Implement LockAngularMotion
|
||||||
// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
|
// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
|
||||||
|
@ -62,9 +63,6 @@ using OpenSim.Region.Framework;
|
||||||
// Multiple contact points on collision?
|
// Multiple contact points on collision?
|
||||||
// See code in ode::near... calls to collision_accounting_events()
|
// See code in ode::near... calls to collision_accounting_events()
|
||||||
// (This might not be a problem. ODE collects all the collisions with one object in one tick.)
|
// (This might not be a problem. ODE collects all the collisions with one object in one tick.)
|
||||||
// Use collision masks for collision with terrain and phantom objects
|
|
||||||
// Figure out how to not allocate a new Dictionary and List for every collision
|
|
||||||
// in BSPrim.Collide() and BSCharacter.Collide(). Can the same ones be reused?
|
|
||||||
// Raycast
|
// Raycast
|
||||||
//
|
//
|
||||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
@ -405,6 +403,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// prevent simulation until we've been initialized
|
// prevent simulation until we've been initialized
|
||||||
if (!m_initialized) return 10.0f;
|
if (!m_initialized) return 10.0f;
|
||||||
|
|
||||||
|
long simulateStartTime = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
// update the prim states while we know the physics engine is not busy
|
// update the prim states while we know the physics engine is not busy
|
||||||
ProcessTaints();
|
ProcessTaints();
|
||||||
|
|
||||||
|
@ -437,13 +437,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The SendCollision's batch up the collisions on the objects. Now push the collisions into the simulator.
|
// The above SendCollision's batch up the collisions on the objects.
|
||||||
|
// Now push the collisions into the simulator.
|
||||||
foreach (BSPrim bsp in m_primsWithCollisions)
|
foreach (BSPrim bsp in m_primsWithCollisions)
|
||||||
bsp.SendCollisions();
|
bsp.SendCollisions();
|
||||||
m_primsWithCollisions.Clear();
|
m_primsWithCollisions.Clear();
|
||||||
|
|
||||||
|
// This is a kludge to get avatar movement updated.
|
||||||
|
// Don't send collisions only if there were collisions -- send everytime.
|
||||||
|
// ODE sends collisions even if there are none and this is used to update
|
||||||
|
// avatar animations and stuff.
|
||||||
// foreach (BSCharacter bsc in m_avatarsWithCollisions)
|
// foreach (BSCharacter bsc in m_avatarsWithCollisions)
|
||||||
// bsc.SendCollisions();
|
// bsc.SendCollisions();
|
||||||
// This is a kludge to get avatar movement updated. ODE sends collisions even if there isn't any
|
|
||||||
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
|
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
|
||||||
kvp.Value.SendCollisions();
|
kvp.Value.SendCollisions();
|
||||||
m_avatarsWithCollisions.Clear();
|
m_avatarsWithCollisions.Clear();
|
||||||
|
@ -465,10 +470,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
if (m_avatars.TryGetValue(entprop.ID, out actor))
|
if (m_avatars.TryGetValue(entprop.ID, out actor))
|
||||||
{
|
{
|
||||||
actor.UpdateProperties(entprop);
|
actor.UpdateProperties(entprop);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If enabled, call into the physics engine to dump statistics
|
||||||
if (m_detailedStatsStep > 0)
|
if (m_detailedStatsStep > 0)
|
||||||
{
|
{
|
||||||
if ((m_simulationStep % m_detailedStatsStep) == 0)
|
if ((m_simulationStep % m_detailedStatsStep) == 0)
|
||||||
|
@ -477,6 +484,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is a waste since the outside routine also calcuates the physics simulation
|
||||||
|
// period. TODO: There should be a way of computing physics frames from simulator computation.
|
||||||
|
// long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
||||||
|
// return (timeStep * (float)simulateTotalTime);
|
||||||
|
|
||||||
// TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
|
// TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
|
||||||
return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
|
return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
|
||||||
}
|
}
|
||||||
|
@ -528,6 +540,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
public override void SetWaterLevel(float baseheight)
|
public override void SetWaterLevel(float baseheight)
|
||||||
{
|
{
|
||||||
m_waterLevel = baseheight;
|
m_waterLevel = baseheight;
|
||||||
|
// TODO: pass to physics engine so things will float?
|
||||||
}
|
}
|
||||||
public float GetWaterLevel()
|
public float GetWaterLevel()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue