BulletSim: move a bunch of common logic out of BSPrim and BSCharacter
and into the parent class BSPhysObject. Rework collision logic to enable extra collision after done colliding. Rename 'Scene' to 'PhysicsScene' to differentiate it from the simulator 'Scene'.connector_plugin
parent
d26fbf727a
commit
ee7cda261c
|
@ -28,7 +28,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OMV = OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
|
@ -39,25 +39,24 @@ public class BSCharacter : BSPhysObject
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static readonly string LogHeader = "[BULLETS CHAR]";
|
private static readonly string LogHeader = "[BULLETS CHAR]";
|
||||||
|
|
||||||
public BSScene Scene { get; private set; }
|
|
||||||
private String _avName;
|
private String _avName;
|
||||||
// private bool _stopped;
|
// private bool _stopped;
|
||||||
private Vector3 _size;
|
private OMV.Vector3 _size;
|
||||||
private Vector3 _scale;
|
private OMV.Vector3 _scale;
|
||||||
private PrimitiveBaseShape _pbs;
|
private PrimitiveBaseShape _pbs;
|
||||||
private uint _localID = 0;
|
private uint _localID = 0;
|
||||||
private bool _grabbed;
|
private bool _grabbed;
|
||||||
private bool _selected;
|
private bool _selected;
|
||||||
private Vector3 _position;
|
private OMV.Vector3 _position;
|
||||||
private float _mass;
|
private float _mass;
|
||||||
public float _density;
|
public float _density;
|
||||||
public float _avatarVolume;
|
public float _avatarVolume;
|
||||||
private Vector3 _force;
|
private OMV.Vector3 _force;
|
||||||
private Vector3 _velocity;
|
private OMV.Vector3 _velocity;
|
||||||
private Vector3 _torque;
|
private OMV.Vector3 _torque;
|
||||||
private float _collisionScore;
|
private float _collisionScore;
|
||||||
private Vector3 _acceleration;
|
private OMV.Vector3 _acceleration;
|
||||||
private Quaternion _orientation;
|
private OMV.Quaternion _orientation;
|
||||||
private int _physicsActorType;
|
private int _physicsActorType;
|
||||||
private bool _isPhysical;
|
private bool _isPhysical;
|
||||||
private bool _flying;
|
private bool _flying;
|
||||||
|
@ -69,18 +68,14 @@ public class BSCharacter : BSPhysObject
|
||||||
private long _collidingGroundStep;
|
private long _collidingGroundStep;
|
||||||
private bool _collidingObj;
|
private bool _collidingObj;
|
||||||
private bool _floatOnWater;
|
private bool _floatOnWater;
|
||||||
private Vector3 _rotationalVelocity;
|
private OMV.Vector3 _rotationalVelocity;
|
||||||
private bool _kinematic;
|
private bool _kinematic;
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
|
||||||
public override BulletBody BSBody { get; set; }
|
|
||||||
public override BulletShape BSShape { get; set; }
|
|
||||||
public override BSLinkset Linkset { get; set; }
|
|
||||||
|
|
||||||
private int _subscribedEventsMs = 0;
|
private int _subscribedEventsMs = 0;
|
||||||
private int _nextCollisionOkTime = 0;
|
private int _nextCollisionOkTime = 0;
|
||||||
|
|
||||||
private Vector3 _PIDTarget;
|
private OMV.Vector3 _PIDTarget;
|
||||||
private bool _usePID;
|
private bool _usePID;
|
||||||
private float _PIDTau;
|
private float _PIDTau;
|
||||||
private bool _useHoverPID;
|
private bool _useHoverPID;
|
||||||
|
@ -88,26 +83,24 @@ public class BSCharacter : BSPhysObject
|
||||||
private PIDHoverType _PIDHoverType;
|
private PIDHoverType _PIDHoverType;
|
||||||
private float _PIDHoverTao;
|
private float _PIDHoverTao;
|
||||||
|
|
||||||
public BSCharacter(uint localID, String avName, BSScene parent_scene, Vector3 pos, Vector3 size, bool isFlying)
|
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
|
||||||
{
|
{
|
||||||
|
base.BaseInitialize(parent_scene);
|
||||||
_localID = localID;
|
_localID = localID;
|
||||||
_avName = avName;
|
_avName = avName;
|
||||||
Scene = parent_scene;
|
|
||||||
_physicsActorType = (int)ActorTypes.Agent;
|
_physicsActorType = (int)ActorTypes.Agent;
|
||||||
_position = pos;
|
_position = pos;
|
||||||
_size = size;
|
_size = size;
|
||||||
_flying = isFlying;
|
_flying = isFlying;
|
||||||
_orientation = Quaternion.Identity;
|
_orientation = OMV.Quaternion.Identity;
|
||||||
_velocity = Vector3.Zero;
|
_velocity = OMV.Vector3.Zero;
|
||||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||||
// The dimensions of the avatar capsule are kept in the scale.
|
// The dimensions of the avatar capsule are kept in the scale.
|
||||||
// Physics creates a unit capsule which is scaled by the physics engine.
|
// Physics creates a unit capsule which is scaled by the physics engine.
|
||||||
_scale = new Vector3(Scene.Params.avatarCapsuleRadius, Scene.Params.avatarCapsuleRadius, size.Z);
|
_scale = new OMV.Vector3(PhysicsScene.Params.avatarCapsuleRadius, PhysicsScene.Params.avatarCapsuleRadius, size.Z);
|
||||||
_density = Scene.Params.avatarDensity;
|
_density = PhysicsScene.Params.avatarDensity;
|
||||||
ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
|
ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
|
||||||
|
|
||||||
Linkset = new BSLinkset(Scene, this);
|
|
||||||
|
|
||||||
ShapeData shapeData = new ShapeData();
|
ShapeData shapeData = new ShapeData();
|
||||||
shapeData.ID = _localID;
|
shapeData.ID = _localID;
|
||||||
shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
|
shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
|
||||||
|
@ -118,19 +111,19 @@ public class BSCharacter : BSPhysObject
|
||||||
shapeData.Mass = _mass;
|
shapeData.Mass = _mass;
|
||||||
shapeData.Buoyancy = _buoyancy;
|
shapeData.Buoyancy = _buoyancy;
|
||||||
shapeData.Static = ShapeData.numericFalse;
|
shapeData.Static = ShapeData.numericFalse;
|
||||||
shapeData.Friction = Scene.Params.avatarFriction;
|
shapeData.Friction = PhysicsScene.Params.avatarFriction;
|
||||||
shapeData.Restitution = Scene.Params.avatarRestitution;
|
shapeData.Restitution = PhysicsScene.Params.avatarRestitution;
|
||||||
|
|
||||||
// do actual create at taint time
|
// do actual create at taint time
|
||||||
Scene.TaintedObject("BSCharacter.create", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.create", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.create", _localID);
|
DetailLog("{0},BSCharacter.create", _localID);
|
||||||
BulletSimAPI.CreateObject(Scene.WorldID, shapeData);
|
BulletSimAPI.CreateObject(PhysicsScene.WorldID, shapeData);
|
||||||
|
|
||||||
// Set the buoyancy for flying. This will be refactored when all the settings happen in C#
|
// Set the buoyancy for flying. This will be refactored when all the settings happen in C#
|
||||||
BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
|
BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy);
|
||||||
|
|
||||||
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID));
|
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID));
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -140,9 +133,9 @@ public class BSCharacter : BSPhysObject
|
||||||
public override void Destroy()
|
public override void Destroy()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.Destroy", LocalID);
|
DetailLog("{0},BSCharacter.Destroy", LocalID);
|
||||||
Scene.TaintedObject("BSCharacter.destroy", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
|
||||||
{
|
{
|
||||||
BulletSimAPI.DestroyObject(Scene.WorldID, _localID);
|
BulletSimAPI.DestroyObject(PhysicsScene.WorldID, _localID);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,11 +147,11 @@ public class BSCharacter : BSPhysObject
|
||||||
public override bool Stopped {
|
public override bool Stopped {
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
public override Vector3 Size {
|
public override OMV.Vector3 Size {
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
// Avatar capsule size is kept in the scale parameter.
|
// Avatar capsule size is kept in the scale parameter.
|
||||||
return new Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z);
|
return new OMV.Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
set {
|
set {
|
||||||
|
@ -171,9 +164,9 @@ public class BSCharacter : BSPhysObject
|
||||||
|
|
||||||
ComputeAvatarVolumeAndMass();
|
ComputeAvatarVolumeAndMass();
|
||||||
|
|
||||||
Scene.TaintedObject("BSCharacter.setSize", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
|
||||||
{
|
{
|
||||||
BulletSimAPI.SetObjectScaleMass(Scene.WorldID, LocalID, _scale, _mass, true);
|
BulletSimAPI.SetObjectScaleMass(PhysicsScene.WorldID, LocalID, _scale, _mass, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -198,9 +191,27 @@ public class BSCharacter : BSPhysObject
|
||||||
public override void CrossingFailure() { return; }
|
public override void CrossingFailure() { return; }
|
||||||
public override void link(PhysicsActor obj) { return; }
|
public override void link(PhysicsActor obj) { return; }
|
||||||
public override void delink() { return; }
|
public override void delink() { return; }
|
||||||
public override void LockAngularMotion(Vector3 axis) { return; }
|
|
||||||
|
|
||||||
public override Vector3 Position {
|
// Set motion values to zero.
|
||||||
|
// Do it to the properties so the values get set in the physics engine.
|
||||||
|
// Push the setting of the values to the viewer.
|
||||||
|
// Called at taint time!
|
||||||
|
public override void ZeroMotion()
|
||||||
|
{
|
||||||
|
_velocity = OMV.Vector3.Zero;
|
||||||
|
_acceleration = OMV.Vector3.Zero;
|
||||||
|
_rotationalVelocity = OMV.Vector3.Zero;
|
||||||
|
|
||||||
|
// Zero some other properties directly into the physics engine
|
||||||
|
BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
|
||||||
|
BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
|
||||||
|
BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||||
|
BulletSimAPI.ClearForces2(BSBody.Ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LockAngularMotion(OMV.Vector3 axis) { return; }
|
||||||
|
|
||||||
|
public override OMV.Vector3 Position {
|
||||||
get {
|
get {
|
||||||
// _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
|
// _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
|
||||||
return _position;
|
return _position;
|
||||||
|
@ -209,10 +220,10 @@ public class BSCharacter : BSPhysObject
|
||||||
_position = value;
|
_position = value;
|
||||||
PositionSanityCheck();
|
PositionSanityCheck();
|
||||||
|
|
||||||
Scene.TaintedObject("BSCharacter.setPosition", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
|
BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, _localID, _position, _orientation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +236,7 @@ public class BSCharacter : BSPhysObject
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
// If below the ground, move the avatar up
|
// If below the ground, move the avatar up
|
||||||
float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position);
|
float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
|
||||||
if (Position.Z < terrainHeight)
|
if (Position.Z < terrainHeight)
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
|
DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
|
||||||
|
@ -247,10 +258,10 @@ public class BSCharacter : BSPhysObject
|
||||||
{
|
{
|
||||||
// The new position value must be pushed into the physics engine but we can't
|
// The new position value must be pushed into the physics engine but we can't
|
||||||
// just assign to "Position" because of potential call loops.
|
// just assign to "Position" because of potential call loops.
|
||||||
Scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
|
BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, _localID, _position, _orientation);
|
||||||
});
|
});
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
@ -266,15 +277,15 @@ public class BSCharacter : BSPhysObject
|
||||||
// used when we only want this prim's mass and not the linkset thing
|
// used when we only want this prim's mass and not the linkset thing
|
||||||
public override float MassRaw { get {return _mass; } }
|
public override float MassRaw { get {return _mass; } }
|
||||||
|
|
||||||
public override Vector3 Force {
|
public override OMV.Vector3 Force {
|
||||||
get { return _force; }
|
get { return _force; }
|
||||||
set {
|
set {
|
||||||
_force = value;
|
_force = value;
|
||||||
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
|
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
|
||||||
Scene.TaintedObject("BSCharacter.SetForce", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
|
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
|
||||||
BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force);
|
BulletSimAPI.SetObjectForce(PhysicsScene.WorldID, LocalID, _force);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,28 +295,28 @@ public class BSCharacter : BSPhysObject
|
||||||
set { return; }
|
set { return; }
|
||||||
}
|
}
|
||||||
public override void VehicleFloatParam(int param, float value) { }
|
public override void VehicleFloatParam(int param, float value) { }
|
||||||
public override void VehicleVectorParam(int param, Vector3 value) {}
|
public override void VehicleVectorParam(int param, OMV.Vector3 value) {}
|
||||||
public override void VehicleRotationParam(int param, Quaternion rotation) { }
|
public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { }
|
||||||
public override void VehicleFlags(int param, bool remove) { }
|
public override void VehicleFlags(int param, bool remove) { }
|
||||||
|
|
||||||
// Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
|
// Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
|
||||||
public override void SetVolumeDetect(int param) { return; }
|
public override void SetVolumeDetect(int param) { return; }
|
||||||
|
|
||||||
public override Vector3 GeometricCenter { get { return Vector3.Zero; } }
|
public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
|
||||||
public override Vector3 CenterOfMass { get { return Vector3.Zero; } }
|
public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
|
||||||
public override Vector3 Velocity {
|
public override OMV.Vector3 Velocity {
|
||||||
get { return _velocity; }
|
get { return _velocity; }
|
||||||
set {
|
set {
|
||||||
_velocity = value;
|
_velocity = value;
|
||||||
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
|
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
|
||||||
Scene.TaintedObject("BSCharacter.setVelocity", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
|
DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
|
||||||
BulletSimAPI.SetObjectVelocity(Scene.WorldID, _localID, _velocity);
|
BulletSimAPI.SetObjectVelocity(PhysicsScene.WorldID, _localID, _velocity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override Vector3 Torque {
|
public override OMV.Vector3 Torque {
|
||||||
get { return _torque; }
|
get { return _torque; }
|
||||||
set { _torque = value;
|
set { _torque = value;
|
||||||
}
|
}
|
||||||
|
@ -315,19 +326,19 @@ public class BSCharacter : BSPhysObject
|
||||||
set { _collisionScore = value;
|
set { _collisionScore = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override Vector3 Acceleration {
|
public override OMV.Vector3 Acceleration {
|
||||||
get { return _acceleration; }
|
get { return _acceleration; }
|
||||||
set { _acceleration = value; }
|
set { _acceleration = value; }
|
||||||
}
|
}
|
||||||
public override Quaternion Orientation {
|
public override OMV.Quaternion Orientation {
|
||||||
get { return _orientation; }
|
get { return _orientation; }
|
||||||
set {
|
set {
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
// m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
|
// m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
|
||||||
Scene.TaintedObject("BSCharacter.setOrientation", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate()
|
||||||
{
|
{
|
||||||
// _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
|
// _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
|
||||||
BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
|
BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, _localID, _position, _orientation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,11 +375,11 @@ public class BSCharacter : BSPhysObject
|
||||||
set { _throttleUpdates = value; }
|
set { _throttleUpdates = value; }
|
||||||
}
|
}
|
||||||
public override bool IsColliding {
|
public override bool IsColliding {
|
||||||
get { return (_collidingStep == Scene.SimulationStep); }
|
get { return (_collidingStep == PhysicsScene.SimulationStep); }
|
||||||
set { _isColliding = value; }
|
set { _isColliding = value; }
|
||||||
}
|
}
|
||||||
public override bool CollidingGround {
|
public override bool CollidingGround {
|
||||||
get { return (_collidingGroundStep == Scene.SimulationStep); }
|
get { return (_collidingGroundStep == PhysicsScene.SimulationStep); }
|
||||||
set { _collidingGround = value; }
|
set { _collidingGround = value; }
|
||||||
}
|
}
|
||||||
public override bool CollidingObj {
|
public override bool CollidingObj {
|
||||||
|
@ -378,7 +389,7 @@ public class BSCharacter : BSPhysObject
|
||||||
public override bool FloatOnWater {
|
public override bool FloatOnWater {
|
||||||
set { _floatOnWater = value; }
|
set { _floatOnWater = value; }
|
||||||
}
|
}
|
||||||
public override Vector3 RotationalVelocity {
|
public override OMV.Vector3 RotationalVelocity {
|
||||||
get { return _rotationalVelocity; }
|
get { return _rotationalVelocity; }
|
||||||
set { _rotationalVelocity = value; }
|
set { _rotationalVelocity = value; }
|
||||||
}
|
}
|
||||||
|
@ -390,16 +401,16 @@ public class BSCharacter : BSPhysObject
|
||||||
public override float Buoyancy {
|
public override float Buoyancy {
|
||||||
get { return _buoyancy; }
|
get { return _buoyancy; }
|
||||||
set { _buoyancy = value;
|
set { _buoyancy = value;
|
||||||
Scene.TaintedObject("BSCharacter.setBuoyancy", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||||
BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
|
BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for MoveTo
|
// Used for MoveTo
|
||||||
public override Vector3 PIDTarget {
|
public override OMV.Vector3 PIDTarget {
|
||||||
set { _PIDTarget = value; }
|
set { _PIDTarget = value; }
|
||||||
}
|
}
|
||||||
public override bool PIDActive {
|
public override bool PIDActive {
|
||||||
|
@ -425,19 +436,19 @@ public class BSCharacter : BSPhysObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// For RotLookAt
|
// For RotLookAt
|
||||||
public override Quaternion APIDTarget { set { return; } }
|
public override OMV.Quaternion APIDTarget { set { return; } }
|
||||||
public override bool APIDActive { set { return; } }
|
public override bool APIDActive { set { return; } }
|
||||||
public override float APIDStrength { set { return; } }
|
public override float APIDStrength { set { return; } }
|
||||||
public override float APIDDamping { set { return; } }
|
public override float APIDDamping { set { return; } }
|
||||||
|
|
||||||
public override void AddForce(Vector3 force, bool pushforce) {
|
public override void AddForce(OMV.Vector3 force, bool pushforce) {
|
||||||
if (force.IsFinite())
|
if (force.IsFinite())
|
||||||
{
|
{
|
||||||
_force.X += force.X;
|
_force.X += force.X;
|
||||||
_force.Y += force.Y;
|
_force.Y += force.Y;
|
||||||
_force.Z += force.Z;
|
_force.Z += force.Z;
|
||||||
// m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
|
// m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
|
||||||
Scene.TaintedObject("BSCharacter.AddForce", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
|
DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
|
||||||
BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
|
BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
|
||||||
|
@ -450,42 +461,9 @@ public class BSCharacter : BSPhysObject
|
||||||
//m_lastUpdateSent = false;
|
//m_lastUpdateSent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddAngularForce(Vector3 force, bool pushforce) {
|
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
||||||
}
|
}
|
||||||
public override void SetMomentum(Vector3 momentum) {
|
public override void SetMomentum(OMV.Vector3 momentum) {
|
||||||
}
|
|
||||||
|
|
||||||
// Turn on collision events at a rate no faster than one every the given milliseconds
|
|
||||||
public override void SubscribeEvents(int ms) {
|
|
||||||
_subscribedEventsMs = ms;
|
|
||||||
if (ms > 0)
|
|
||||||
{
|
|
||||||
// make sure first collision happens
|
|
||||||
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
|
||||||
|
|
||||||
Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate()
|
|
||||||
{
|
|
||||||
BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ZeroMotion()
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop collision events
|
|
||||||
public override void UnSubscribeEvents() {
|
|
||||||
_subscribedEventsMs = 0;
|
|
||||||
Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
|
|
||||||
{
|
|
||||||
BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Return 'true' if someone has subscribed to events
|
|
||||||
public override bool SubscribedEvents() {
|
|
||||||
return (_subscribedEventsMs > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set _avatarVolume and _mass based on capsule size, _density and _scale
|
// set _avatarVolume and _mass based on capsule size, _density and _scale
|
||||||
|
@ -520,67 +498,15 @@ public class BSCharacter : BSPhysObject
|
||||||
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
|
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
|
||||||
PositionSanityCheck2();
|
PositionSanityCheck2();
|
||||||
|
|
||||||
float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug
|
float heightHere = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug
|
||||||
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
|
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
|
||||||
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
|
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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;
|
|
||||||
public override bool Collide(uint collidingWith, BSPhysObject collidee, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
// The following makes IsColliding() and IsCollidingGround() work
|
|
||||||
_collidingStep = Scene.SimulationStep;
|
|
||||||
if (collidingWith <= Scene.TerrainManager.HighestTerrainID)
|
|
||||||
{
|
|
||||||
_collidingGroundStep = Scene.SimulationStep;
|
|
||||||
}
|
|
||||||
// DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
|
|
||||||
|
|
||||||
// throttle collisions to the rate specified in the subscription
|
|
||||||
if (SubscribedEvents()) {
|
|
||||||
int nowTime = Scene.SimulationNowTime;
|
|
||||||
if (nowTime >= _nextCollisionOkTime) {
|
|
||||||
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
|
||||||
|
|
||||||
if (collisionCollection == null)
|
|
||||||
collisionCollection = new CollisionEventUpdate();
|
|
||||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SendCollisions()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (collisionCollection != null && collisionCollection.Count > 0)
|
|
||||||
{
|
|
||||||
base.SendCollisionUpdate(collisionCollection);
|
|
||||||
collisionCollection = null;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// Kludge to make a collision call even if there are no collisions.
|
|
||||||
// This causes the avatar animation to get updated.
|
|
||||||
if (collisionCollection == null)
|
|
||||||
collisionCollection = new CollisionEventUpdate();
|
|
||||||
base.SendCollisionUpdate(collisionCollection);
|
|
||||||
// If there were any collisions in the collection, make sure we don't use the
|
|
||||||
// same instance next time.
|
|
||||||
if (collisionCollection.Count > 0)
|
|
||||||
collisionCollection = null;
|
|
||||||
// End kludge
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
private void DetailLog(string msg, params Object[] args)
|
private void DetailLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
Scene.PhysicsLogging.Write(msg, args);
|
PhysicsScene.PhysicsLogging.Write(msg, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -539,7 +539,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// add Gravity and Buoyancy
|
// add Gravity and Buoyancy
|
||||||
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
||||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||||
Vector3 grav = m_prim.Scene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy));
|
Vector3 grav = m_prim.PhysicsScene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RA: Not sure why one would do this
|
* RA: Not sure why one would do this
|
||||||
|
@ -552,7 +552,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
|
// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
|
||||||
|
|
||||||
// If below the terrain, move us above the ground a little.
|
// If below the terrain, move us above the ground a little.
|
||||||
float terrainHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
float terrainHeight = m_prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||||
// Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
|
// Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
|
||||||
// Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
|
// Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
|
||||||
// Vector3 rotatedSize = m_prim.Size * m_prim.Orientation;
|
// Vector3 rotatedSize = m_prim.Size * m_prim.Orientation;
|
||||||
|
@ -570,7 +570,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// We should hover, get the target height
|
// We should hover, get the target height
|
||||||
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||||
{
|
{
|
||||||
m_VhoverTargetHeight = m_prim.Scene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
|
m_VhoverTargetHeight = m_prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
|
||||||
}
|
}
|
||||||
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||||
{
|
{
|
||||||
|
@ -849,8 +849,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
private void VDetailLog(string msg, params Object[] args)
|
private void VDetailLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
if (m_prim.Scene.VehicleLoggingEnabled)
|
if (m_prim.PhysicsScene.VehicleLoggingEnabled)
|
||||||
m_prim.Scene.PhysicsLogging.Write(msg, args);
|
m_prim.PhysicsScene.PhysicsLogging.Write(msg, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,9 @@ public class BSLinkset
|
||||||
{
|
{
|
||||||
private static string LogHeader = "[BULLETSIM LINKSET]";
|
private static string LogHeader = "[BULLETSIM LINKSET]";
|
||||||
|
|
||||||
private BSPhysObject m_linksetRoot;
|
public BSPhysObject LinksetRoot { get; protected set; }
|
||||||
public BSPhysObject LinksetRoot { get { return m_linksetRoot; } }
|
|
||||||
|
|
||||||
private BSScene m_physicsScene;
|
public BSScene PhysicsScene { get; private set; }
|
||||||
public BSScene PhysicsScene { get { return m_physicsScene; } }
|
|
||||||
|
|
||||||
static int m_nextLinksetID = 1;
|
static int m_nextLinksetID = 1;
|
||||||
public int LinksetID { get; private set; }
|
public int LinksetID { get; private set; }
|
||||||
|
@ -81,8 +79,8 @@ public class BSLinkset
|
||||||
// We create LOTS of linksets.
|
// We create LOTS of linksets.
|
||||||
if (m_nextLinksetID < 0)
|
if (m_nextLinksetID < 0)
|
||||||
m_nextLinksetID = 1;
|
m_nextLinksetID = 1;
|
||||||
m_physicsScene = scene;
|
PhysicsScene = scene;
|
||||||
m_linksetRoot = parent;
|
LinksetRoot = parent;
|
||||||
m_children = new List<BSPhysObject>();
|
m_children = new List<BSPhysObject>();
|
||||||
m_mass = parent.MassRaw;
|
m_mass = parent.MassRaw;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +129,7 @@ public class BSLinkset
|
||||||
// Return 'true' if the passed object is the root object of this linkset
|
// Return 'true' if the passed object is the root object of this linkset
|
||||||
public bool IsRoot(BSPhysObject requestor)
|
public bool IsRoot(BSPhysObject requestor)
|
||||||
{
|
{
|
||||||
return (requestor.LocalID == m_linksetRoot.LocalID);
|
return (requestor.LocalID == LinksetRoot.LocalID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int NumberOfChildren { get { return m_children.Count; } }
|
public int NumberOfChildren { get { return m_children.Count; } }
|
||||||
|
@ -159,7 +157,7 @@ public class BSLinkset
|
||||||
|
|
||||||
private float ComputeLinksetMass()
|
private float ComputeLinksetMass()
|
||||||
{
|
{
|
||||||
float mass = m_linksetRoot.MassRaw;
|
float mass = LinksetRoot.MassRaw;
|
||||||
foreach (BSPhysObject bp in m_children)
|
foreach (BSPhysObject bp in m_children)
|
||||||
{
|
{
|
||||||
mass += bp.MassRaw;
|
mass += bp.MassRaw;
|
||||||
|
@ -169,8 +167,8 @@ public class BSLinkset
|
||||||
|
|
||||||
private OMV.Vector3 ComputeLinksetCenterOfMass()
|
private OMV.Vector3 ComputeLinksetCenterOfMass()
|
||||||
{
|
{
|
||||||
OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw;
|
OMV.Vector3 com = LinksetRoot.Position * LinksetRoot.MassRaw;
|
||||||
float totalMass = m_linksetRoot.MassRaw;
|
float totalMass = LinksetRoot.MassRaw;
|
||||||
|
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
|
@ -188,7 +186,7 @@ public class BSLinkset
|
||||||
|
|
||||||
private OMV.Vector3 ComputeLinksetGeometricCenter()
|
private OMV.Vector3 ComputeLinksetGeometricCenter()
|
||||||
{
|
{
|
||||||
OMV.Vector3 com = m_linksetRoot.Position;
|
OMV.Vector3 com = LinksetRoot.Position;
|
||||||
|
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
|
@ -256,7 +254,7 @@ public class BSLinkset
|
||||||
foreach (BSPhysObject child in m_children)
|
foreach (BSPhysObject child in m_children)
|
||||||
{
|
{
|
||||||
BSConstraint constrain;
|
BSConstraint constrain;
|
||||||
if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain))
|
if (PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain))
|
||||||
{
|
{
|
||||||
// DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
|
// DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
|
||||||
// LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
|
// LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
|
||||||
|
@ -306,9 +304,9 @@ public class BSLinkset
|
||||||
|
|
||||||
BSPhysObject rootx = LinksetRoot; // capture the root as of now
|
BSPhysObject rootx = LinksetRoot; // capture the root as of now
|
||||||
BSPhysObject childx = child;
|
BSPhysObject childx = child;
|
||||||
m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
|
PhysicsScene.TaintedObject("AddChildToLinkset", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
|
DetailLog("{0},AddChildToLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
|
||||||
PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
|
PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -322,7 +320,7 @@ public class BSLinkset
|
||||||
// has to be updated also (like pointer to prim's parent).
|
// has to be updated also (like pointer to prim's parent).
|
||||||
private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
|
private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
|
||||||
{
|
{
|
||||||
pchild.Linkset = new BSLinkset(m_physicsScene, pchild);
|
pchild.Linkset = new BSLinkset(PhysicsScene, pchild);
|
||||||
RemoveChildFromLinkset(pchild);
|
RemoveChildFromLinkset(pchild);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,9 +332,9 @@ public class BSLinkset
|
||||||
{
|
{
|
||||||
BSPhysObject rootx = LinksetRoot; // capture the root as of now
|
BSPhysObject rootx = LinksetRoot; // capture the root as of now
|
||||||
BSPhysObject childx = child;
|
BSPhysObject childx = child;
|
||||||
m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
|
PhysicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
|
DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", LinksetRoot.LocalID, child.LocalID);
|
||||||
|
|
||||||
PhysicallyUnlinkAChildFromRoot(rootx, childx);
|
PhysicallyUnlinkAChildFromRoot(rootx, childx);
|
||||||
RecomputeLinksetConstraintVariables();
|
RecomputeLinksetConstraintVariables();
|
||||||
|
@ -370,7 +368,7 @@ public class BSLinkset
|
||||||
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
|
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
|
||||||
rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
|
rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
|
||||||
BS6DofConstraint constrain = new BS6DofConstraint(
|
BS6DofConstraint constrain = new BS6DofConstraint(
|
||||||
m_physicsScene.World, rootPrim.BSBody, childPrim.BSBody,
|
PhysicsScene.World, rootPrim.BSBody, childPrim.BSBody,
|
||||||
midPoint,
|
midPoint,
|
||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
|
@ -408,7 +406,7 @@ public class BSLinkset
|
||||||
// ==================================================================================
|
// ==================================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
m_physicsScene.Constraints.AddConstraint(constrain);
|
PhysicsScene.Constraints.AddConstraint(constrain);
|
||||||
|
|
||||||
// zero linear and angular limits makes the objects unable to move in relation to each other
|
// zero linear and angular limits makes the objects unable to move in relation to each other
|
||||||
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||||
|
@ -435,7 +433,7 @@ public class BSLinkset
|
||||||
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
|
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
|
||||||
|
|
||||||
// Find the constraint for this link and get rid of it from the overall collection and from my list
|
// Find the constraint for this link and get rid of it from the overall collection and from my list
|
||||||
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody);
|
PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody);
|
||||||
|
|
||||||
// Make the child refresh its location
|
// Make the child refresh its location
|
||||||
BulletSimAPI.PushUpdate2(childPrim.BSBody.Ptr);
|
BulletSimAPI.PushUpdate2(childPrim.BSBody.Ptr);
|
||||||
|
@ -447,13 +445,13 @@ public class BSLinkset
|
||||||
{
|
{
|
||||||
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
|
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
|
||||||
|
|
||||||
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody);
|
PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
private void DetailLog(string msg, params Object[] args)
|
private void DetailLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
m_physicsScene.PhysicsLogging.Write(msg, args);
|
PhysicsScene.PhysicsLogging.Write(msg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,26 +39,150 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// unless the difference is significant.
|
// unless the difference is significant.
|
||||||
public abstract class BSPhysObject : PhysicsActor
|
public abstract class BSPhysObject : PhysicsActor
|
||||||
{
|
{
|
||||||
public abstract BSLinkset Linkset { get; set; }
|
protected void BaseInitialize(BSScene parentScene)
|
||||||
|
{
|
||||||
|
PhysicsScene = parentScene;
|
||||||
|
Linkset = new BSLinkset(PhysicsScene, this);
|
||||||
|
|
||||||
public abstract bool Collide(uint collidingWith, BSPhysObject collidee,
|
CollisionCollection = new CollisionEventUpdate();
|
||||||
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
|
SubscribedEventsMs = 0;
|
||||||
public abstract void SendCollisions();
|
CollidingStep = 0;
|
||||||
|
CollidingGroundStep = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Return the object mass without calculating it or side effects
|
public BSScene PhysicsScene { get; protected set; }
|
||||||
|
|
||||||
|
public BSLinkset Linkset { get; set; }
|
||||||
|
|
||||||
|
// Return the object mass without calculating it or having side effects
|
||||||
public abstract float MassRaw { get; }
|
public abstract float MassRaw { get; }
|
||||||
|
|
||||||
// Reference to the physical body (btCollisionObject) of this object
|
// Reference to the physical body (btCollisionObject) of this object
|
||||||
public abstract BulletBody BSBody { get; set; }
|
public BulletBody BSBody { get; protected set; }
|
||||||
// Reference to the physical shape (btCollisionShape) of this object
|
// Reference to the physical shape (btCollisionShape) of this object
|
||||||
public abstract BulletShape BSShape { get; set; }
|
public BulletShape BSShape { get; protected set; }
|
||||||
|
|
||||||
|
// Stop all physical motion.
|
||||||
public abstract void ZeroMotion();
|
public abstract void ZeroMotion();
|
||||||
|
|
||||||
|
// Step the vehicle simulation for this object. A NOOP if the vehicle was not configured.
|
||||||
public virtual void StepVehicle(float timeStep) { }
|
public virtual void StepVehicle(float timeStep) { }
|
||||||
|
|
||||||
|
// Update the physical location and motion of the object. Called with data from Bullet.
|
||||||
public abstract void UpdateProperties(EntityProperties entprop);
|
public abstract void UpdateProperties(EntityProperties entprop);
|
||||||
|
|
||||||
|
// Tell the object to clean up.
|
||||||
public abstract void Destroy();
|
public abstract void Destroy();
|
||||||
|
|
||||||
|
#region Collisions
|
||||||
|
|
||||||
|
// Requested number of milliseconds between collision events. Zero means disabled.
|
||||||
|
protected int SubscribedEventsMs { get; set; }
|
||||||
|
// Given subscription, the time that a collision may be passed up
|
||||||
|
protected int NextCollisionOkTime { get; set; }
|
||||||
|
// The simulation step that last had a collision
|
||||||
|
protected long CollidingStep { get; set; }
|
||||||
|
// The simulation step that last had a collision with the ground
|
||||||
|
protected long CollidingGroundStep { get; set; }
|
||||||
|
// The collision flags we think are set in Bullet
|
||||||
|
protected CollisionFlags CurrentCollisionFlags { get; set; }
|
||||||
|
|
||||||
|
// The collisions that have been collected this tick
|
||||||
|
protected CollisionEventUpdate CollisionCollection;
|
||||||
|
|
||||||
|
// The simulation step is telling this object about a collision.
|
||||||
|
// Return 'true' if a collision was processed and should be sent up.
|
||||||
|
// Called at taint time from within the Step() function
|
||||||
|
public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
|
||||||
|
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
// The following lines make IsColliding() and IsCollidingGround() work
|
||||||
|
CollidingStep = PhysicsScene.SimulationStep;
|
||||||
|
if (collidingWith <= PhysicsScene.TerrainManager.HighestTerrainID)
|
||||||
|
{
|
||||||
|
CollidingGroundStep = PhysicsScene.SimulationStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prims in the same linkset cannot collide with each other
|
||||||
|
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicsScene.PhysicsLogging.Write("{0},BSPhysObject.Collison,call,with={1}", LocalID, collidingWith);
|
||||||
|
|
||||||
|
// if someone has subscribed for collision events....
|
||||||
|
if (SubscribedEvents()) {
|
||||||
|
CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||||
|
PhysicsScene.PhysicsLogging.Write("{0},BSPhysObject.Collison.AddCollider,call,with={1},point={2},normal={3},depth={4},next={5}",
|
||||||
|
LocalID, collidingWith, contactPoint, contactNormal, pentrationDepth, NextCollisionOkTime.ToString("yyyyMMddHHmmssfff"));
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Routine to send the collected collisions into the simulator.
|
||||||
|
// Also handles removal of this from the collection of objects with collisions if
|
||||||
|
// there are no collisions from this object. Mechanism is create one last
|
||||||
|
// collision event to make collision_end work.
|
||||||
|
public virtual void SendCollisions()
|
||||||
|
{
|
||||||
|
// throttle the collisions to the number of milliseconds specified in the subscription
|
||||||
|
int nowTime = PhysicsScene.SimulationNowTime;
|
||||||
|
if (nowTime >= NextCollisionOkTime)
|
||||||
|
{
|
||||||
|
NextCollisionOkTime = nowTime + SubscribedEventsMs;
|
||||||
|
|
||||||
|
// We are called if we previously had collisions. If there are no collisions
|
||||||
|
// this time, send up one last empty event so OpenSim can sense collision end.
|
||||||
|
if (CollisionCollection.Count == 0)
|
||||||
|
PhysicsScene.ObjectsWithNoMoreCollisions.Add(this);
|
||||||
|
|
||||||
|
base.SendCollisionUpdate(CollisionCollection);
|
||||||
|
|
||||||
|
// The collisionCollection structure is passed around in the simulator.
|
||||||
|
// Make sure we don't have a handle to that one and that a new one is used next time.
|
||||||
|
CollisionCollection = new CollisionEventUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe for collision events.
|
||||||
|
// Parameter is the millisecond rate the caller wishes collision events to occur.
|
||||||
|
public override void SubscribeEvents(int ms) {
|
||||||
|
SubscribedEventsMs = ms;
|
||||||
|
if (ms > 0)
|
||||||
|
{
|
||||||
|
// make sure first collision happens
|
||||||
|
NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
|
||||||
|
PhysicsScene.PhysicsLogging.Write("{0},SubscribeEvents,call,ms={1},nextOKTime={2}",
|
||||||
|
LocalID, SubscribedEventsMs, NextCollisionOkTime.ToString("yyyyMMddHHmmssfff"));
|
||||||
|
|
||||||
|
PhysicsScene.TaintedObject("BSPhysObject.SubscribeEvents", delegate()
|
||||||
|
{
|
||||||
|
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Subscribing for zero or less is the same as unsubscribing
|
||||||
|
UnSubscribeEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override void UnSubscribeEvents() {
|
||||||
|
SubscribedEventsMs = 0;
|
||||||
|
PhysicsScene.PhysicsLogging.Write("{0},UnSubscribeEvents,call", LocalID);
|
||||||
|
PhysicsScene.TaintedObject("BSPhysObject.UnSubscribeEvents", delegate()
|
||||||
|
{
|
||||||
|
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Return 'true' if the simulator wants collision events
|
||||||
|
public override bool SubscribedEvents() {
|
||||||
|
return (SubscribedEventsMs > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion // Collisions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
private ulong _hullKey;
|
private ulong _hullKey;
|
||||||
private List<ConvexResult> _hulls;
|
private List<ConvexResult> _hulls;
|
||||||
|
|
||||||
private BSScene _scene;
|
|
||||||
public BSScene Scene { get { return _scene; } }
|
|
||||||
private String _avName;
|
private String _avName;
|
||||||
private uint _localID = 0;
|
private uint _localID = 0;
|
||||||
|
|
||||||
|
@ -87,18 +85,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
private bool _kinematic;
|
private bool _kinematic;
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
|
||||||
// Membership in a linkset is controlled by this class.
|
|
||||||
public override BSLinkset Linkset { get; set; }
|
|
||||||
|
|
||||||
private int _subscribedEventsMs = 0;
|
|
||||||
private int _nextCollisionOkTime = 0;
|
|
||||||
long _collidingStep;
|
|
||||||
long _collidingGroundStep;
|
|
||||||
CollisionFlags m_currentCollisionFlags = 0;
|
|
||||||
|
|
||||||
public override BulletBody BSBody { get; set; }
|
|
||||||
public override BulletShape BSShape { get; set; }
|
|
||||||
|
|
||||||
private BSDynamics _vehicle;
|
private BSDynamics _vehicle;
|
||||||
|
|
||||||
private OMV.Vector3 _PIDTarget;
|
private OMV.Vector3 _PIDTarget;
|
||||||
|
@ -113,10 +99,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
|
// m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
|
||||||
|
base.BaseInitialize(parent_scene);
|
||||||
_localID = localID;
|
_localID = localID;
|
||||||
_avName = primName;
|
_avName = primName;
|
||||||
_physicsActorType = (int)ActorTypes.Prim;
|
_physicsActorType = (int)ActorTypes.Prim;
|
||||||
_scene = parent_scene;
|
|
||||||
_position = pos;
|
_position = pos;
|
||||||
_size = size;
|
_size = size;
|
||||||
_scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type
|
_scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type
|
||||||
|
@ -129,25 +115,23 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_pbs = pbs;
|
_pbs = pbs;
|
||||||
_isPhysical = pisPhysical;
|
_isPhysical = pisPhysical;
|
||||||
_isVolumeDetect = false;
|
_isVolumeDetect = false;
|
||||||
_subscribedEventsMs = 0;
|
_friction = PhysicsScene.Params.defaultFriction; // TODO: compute based on object material
|
||||||
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
|
_density = PhysicsScene.Params.defaultDensity; // TODO: compute based on object material
|
||||||
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
|
_restitution = PhysicsScene.Params.defaultRestitution;
|
||||||
_restitution = _scene.Params.defaultRestitution;
|
_vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness
|
||||||
Linkset = new BSLinkset(Scene, this); // a linkset of one
|
|
||||||
_vehicle = new BSDynamics(Scene, this); // add vehicleness
|
|
||||||
_mass = CalculateMass();
|
_mass = CalculateMass();
|
||||||
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
||||||
// do the actual object creation at taint time
|
// do the actual object creation at taint time
|
||||||
_scene.TaintedObject("BSPrim.create", delegate()
|
PhysicsScene.TaintedObject("BSPrim.create", delegate()
|
||||||
{
|
{
|
||||||
CreateGeomAndObject(true);
|
CreateGeomAndObject(true);
|
||||||
|
|
||||||
// Get the pointer to the physical body for this object.
|
// Get the pointer to the physical body for this object.
|
||||||
// At the moment, we're still letting BulletSim manage the creation and destruction
|
// At the moment, we're still letting BulletSim manage the creation and destruction
|
||||||
// of the object. Someday we'll move that into the C# code.
|
// of the object. Someday we'll move that into the C# code.
|
||||||
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID));
|
||||||
BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
|
BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
|
||||||
m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
|
CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,11 +152,11 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Undo any vehicle properties
|
// Undo any vehicle properties
|
||||||
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||||
|
|
||||||
_scene.TaintedObject("BSPrim.destroy", delegate()
|
PhysicsScene.TaintedObject("BSPrim.destroy", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
||||||
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
|
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
|
||||||
BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
|
BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +167,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
get { return _size; }
|
get { return _size; }
|
||||||
set {
|
set {
|
||||||
_size = value;
|
_size = value;
|
||||||
_scene.TaintedObject("BSPrim.setSize", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setSize", delegate()
|
||||||
{
|
{
|
||||||
_mass = CalculateMass(); // changing size changes the mass
|
_mass = CalculateMass(); // changing size changes the mass
|
||||||
// Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct
|
// Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct
|
||||||
|
@ -196,7 +180,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
public override PrimitiveBaseShape Shape {
|
public override PrimitiveBaseShape Shape {
|
||||||
set {
|
set {
|
||||||
_pbs = value;
|
_pbs = value;
|
||||||
_scene.TaintedObject("BSPrim.setShape", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setShape", delegate()
|
||||||
{
|
{
|
||||||
_mass = CalculateMass(); // changing the shape changes the mass
|
_mass = CalculateMass(); // changing the shape changes the mass
|
||||||
CreateGeomAndObject(false);
|
CreateGeomAndObject(false);
|
||||||
|
@ -214,7 +198,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
public override bool Selected {
|
public override bool Selected {
|
||||||
set {
|
set {
|
||||||
_isSelected = value;
|
_isSelected = value;
|
||||||
_scene.TaintedObject("BSPrim.setSelected", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setSelected", delegate()
|
||||||
{
|
{
|
||||||
SetObjectDynamic();
|
SetObjectDynamic();
|
||||||
});
|
});
|
||||||
|
@ -283,13 +267,13 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_position = BulletSimAPI.GetPosition2(BSBody.Ptr);
|
_position = BulletSimAPI.GetPosition2(BSBody.Ptr);
|
||||||
|
|
||||||
// don't do the GetObjectPosition for root elements because this function is called a zillion times
|
// don't do the GetObjectPosition for root elements because this function is called a zillion times
|
||||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
// _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
|
||||||
return _position;
|
return _position;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
_position = value;
|
_position = value;
|
||||||
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
|
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
|
||||||
_scene.TaintedObject("BSPrim.setPosition", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
|
BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
|
||||||
|
@ -327,7 +311,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
get { return _force; }
|
get { return _force; }
|
||||||
set {
|
set {
|
||||||
_force = value;
|
_force = value;
|
||||||
_scene.TaintedObject("BSPrim.setForce", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setForce", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
|
DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
|
||||||
BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
|
BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
|
||||||
|
@ -342,40 +326,40 @@ public sealed class BSPrim : BSPhysObject
|
||||||
set {
|
set {
|
||||||
Vehicle type = (Vehicle)value;
|
Vehicle type = (Vehicle)value;
|
||||||
BSPrim vehiclePrim = this;
|
BSPrim vehiclePrim = this;
|
||||||
_scene.TaintedObject("setVehicleType", delegate()
|
PhysicsScene.TaintedObject("setVehicleType", delegate()
|
||||||
{
|
{
|
||||||
// Done at taint time so we're sure the physics engine is not using the variables
|
// Done at taint time so we're sure the physics engine is not using the variables
|
||||||
// Vehicle code changes the parameters for this vehicle type.
|
// Vehicle code changes the parameters for this vehicle type.
|
||||||
_vehicle.ProcessTypeChange(type);
|
_vehicle.ProcessTypeChange(type);
|
||||||
// Tell the scene about the vehicle so it will get processing each frame.
|
// Tell the scene about the vehicle so it will get processing each frame.
|
||||||
_scene.VehicleInSceneTypeChanged(this, type);
|
PhysicsScene.VehicleInSceneTypeChanged(this, type);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override void VehicleFloatParam(int param, float value)
|
public override void VehicleFloatParam(int param, float value)
|
||||||
{
|
{
|
||||||
_scene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
|
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public override void VehicleVectorParam(int param, OMV.Vector3 value)
|
public override void VehicleVectorParam(int param, OMV.Vector3 value)
|
||||||
{
|
{
|
||||||
_scene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
|
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
|
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
|
||||||
{
|
{
|
||||||
_scene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public override void VehicleFlags(int param, bool remove)
|
public override void VehicleFlags(int param, bool remove)
|
||||||
{
|
{
|
||||||
_scene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessVehicleFlags(param, remove);
|
_vehicle.ProcessVehicleFlags(param, remove);
|
||||||
});
|
});
|
||||||
|
@ -393,8 +377,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
public override void SetVolumeDetect(int param) {
|
public override void SetVolumeDetect(int param) {
|
||||||
bool newValue = (param != 0);
|
bool newValue = (param != 0);
|
||||||
_isVolumeDetect = newValue;
|
_isVolumeDetect = newValue;
|
||||||
_scene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
|
PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
|
||||||
{
|
{
|
||||||
|
DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect);
|
||||||
SetObjectDynamic();
|
SetObjectDynamic();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
@ -404,7 +389,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
get { return _velocity; }
|
get { return _velocity; }
|
||||||
set {
|
set {
|
||||||
_velocity = value;
|
_velocity = value;
|
||||||
_scene.TaintedObject("BSPrim.setVelocity", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
|
DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
|
||||||
BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity);
|
BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity);
|
||||||
|
@ -438,9 +423,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
set {
|
set {
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
// TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
|
// TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
|
||||||
_scene.TaintedObject("BSPrim.setOrientation", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||||
{
|
{
|
||||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
// _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
|
||||||
DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
|
BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
|
||||||
});
|
});
|
||||||
|
@ -454,8 +439,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
get { return _isPhysical; }
|
get { return _isPhysical; }
|
||||||
set {
|
set {
|
||||||
_isPhysical = value;
|
_isPhysical = value;
|
||||||
_scene.TaintedObject("BSPrim.setIsPhysical", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate()
|
||||||
{
|
{
|
||||||
|
DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
|
||||||
SetObjectDynamic();
|
SetObjectDynamic();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -493,9 +479,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Bullet wants static objects to have a mass of zero
|
// Bullet wants static objects to have a mass of zero
|
||||||
float mass = IsStatic ? 0f : _mass;
|
float mass = IsStatic ? 0f : _mass;
|
||||||
|
|
||||||
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
|
BulletSimAPI.SetObjectProperties(Scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
|
||||||
*/
|
*/
|
||||||
BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr);
|
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
|
||||||
|
|
||||||
// Set up the object physicalness (does gravity and collisions move this object)
|
// Set up the object physicalness (does gravity and collisions move this object)
|
||||||
MakeDynamic(IsStatic);
|
MakeDynamic(IsStatic);
|
||||||
|
@ -506,15 +492,15 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Arrange for collisions events if the simulator wants them
|
// Arrange for collisions events if the simulator wants them
|
||||||
EnableCollisions(SubscribedEvents());
|
EnableCollisions(SubscribedEvents());
|
||||||
|
|
||||||
BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr);
|
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, BSBody.Ptr);
|
||||||
|
|
||||||
// Recompute any linkset parameters.
|
// Recompute any linkset parameters.
|
||||||
// When going from non-physical to physical, this re-enables the constraints that
|
// When going from non-physical to physical, this re-enables the constraints that
|
||||||
// had been automatically disabled when the mass was set to zero.
|
// had been automatically disabled when the mass was set to zero.
|
||||||
Linkset.Refresh(this);
|
Linkset.Refresh(this);
|
||||||
|
|
||||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3}, cf={4}",
|
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3},collide={4},cf={5}",
|
||||||
LocalID, IsStatic, IsSolid, _mass, m_currentCollisionFlags);
|
LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Making dynamic" means changing to and from static.
|
// "Making dynamic" means changing to and from static.
|
||||||
|
@ -527,7 +513,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
if (makeStatic)
|
if (makeStatic)
|
||||||
{
|
{
|
||||||
// Become a Bullet 'static' object type
|
// Become a Bullet 'static' object type
|
||||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||||
// Stop all movement
|
// Stop all movement
|
||||||
BulletSimAPI.ClearAllForces2(BSBody.Ptr);
|
BulletSimAPI.ClearAllForces2(BSBody.Ptr);
|
||||||
// Center of mass is at the center of the object
|
// Center of mass is at the center of the object
|
||||||
|
@ -539,16 +525,17 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// There can be special things needed for implementing linksets
|
// There can be special things needed for implementing linksets
|
||||||
Linkset.MakeStatic(this);
|
Linkset.MakeStatic(this);
|
||||||
// The activation state is 'sleeping' so Bullet will not try to act on it
|
// The activation state is 'sleeping' so Bullet will not try to act on it
|
||||||
BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING);
|
// BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING);
|
||||||
|
BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.DISABLE_SIMULATION);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Not a Bullet static object
|
// Not a Bullet static object
|
||||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||||
|
|
||||||
// Set various physical properties so internal things will get computed correctly as they are set
|
// Set various physical properties so internal dynamic properties will get computed correctly as they are set
|
||||||
BulletSimAPI.SetFriction2(BSBody.Ptr, Scene.Params.defaultFriction);
|
BulletSimAPI.SetFriction2(BSBody.Ptr, PhysicsScene.Params.defaultFriction);
|
||||||
BulletSimAPI.SetRestitution2(BSBody.Ptr, Scene.Params.defaultRestitution);
|
BulletSimAPI.SetRestitution2(BSBody.Ptr, PhysicsScene.Params.defaultRestitution);
|
||||||
// per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
|
// per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
|
||||||
BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
|
BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
|
||||||
BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
|
BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
|
||||||
|
@ -562,10 +549,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
|
BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
|
||||||
|
|
||||||
// Various values for simulation limits
|
// Various values for simulation limits
|
||||||
BulletSimAPI.SetDamping2(BSBody.Ptr, Scene.Params.linearDamping, Scene.Params.angularDamping);
|
BulletSimAPI.SetDamping2(BSBody.Ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping);
|
||||||
BulletSimAPI.SetDeactivationTime2(BSBody.Ptr, Scene.Params.deactivationTime);
|
BulletSimAPI.SetDeactivationTime2(BSBody.Ptr, PhysicsScene.Params.deactivationTime);
|
||||||
BulletSimAPI.SetSleepingThresholds2(BSBody.Ptr, Scene.Params.linearSleepingThreshold, Scene.Params.angularSleepingThreshold);
|
BulletSimAPI.SetSleepingThresholds2(BSBody.Ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold);
|
||||||
BulletSimAPI.SetContactProcessingThreshold2(BSBody.Ptr, Scene.Params.contactProcessingThreshold);
|
BulletSimAPI.SetContactProcessingThreshold2(BSBody.Ptr, PhysicsScene.Params.contactProcessingThreshold);
|
||||||
|
|
||||||
// There can be special things needed for implementing linksets
|
// There can be special things needed for implementing linksets
|
||||||
Linkset.MakeDynamic(this);
|
Linkset.MakeDynamic(this);
|
||||||
|
@ -581,11 +568,11 @@ public sealed class BSPrim : BSPhysObject
|
||||||
if (makeSolid)
|
if (makeSolid)
|
||||||
{
|
{
|
||||||
// Easy in Bullet -- just remove the object flag that controls collision response
|
// Easy in Bullet -- just remove the object flag that controls collision response
|
||||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,11 +581,11 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
if (wantsCollisionEvents)
|
if (wantsCollisionEvents)
|
||||||
{
|
{
|
||||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,11 +605,11 @@ public sealed class BSPrim : BSPhysObject
|
||||||
set { _throttleUpdates = value; }
|
set { _throttleUpdates = value; }
|
||||||
}
|
}
|
||||||
public override bool IsColliding {
|
public override bool IsColliding {
|
||||||
get { return (_collidingStep == _scene.SimulationStep); }
|
get { return (CollidingStep == PhysicsScene.SimulationStep); }
|
||||||
set { _isColliding = value; }
|
set { _isColliding = value; }
|
||||||
}
|
}
|
||||||
public override bool CollidingGround {
|
public override bool CollidingGround {
|
||||||
get { return (_collidingGroundStep == _scene.SimulationStep); }
|
get { return (CollidingGroundStep == PhysicsScene.SimulationStep); }
|
||||||
set { _collidingGround = value; }
|
set { _collidingGround = value; }
|
||||||
}
|
}
|
||||||
public override bool CollidingObj {
|
public override bool CollidingObj {
|
||||||
|
@ -656,7 +643,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
set {
|
set {
|
||||||
_rotationalVelocity = value;
|
_rotationalVelocity = value;
|
||||||
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
|
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
|
||||||
_scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
||||||
BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity);
|
BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity);
|
||||||
|
@ -673,13 +660,13 @@ public sealed class BSPrim : BSPhysObject
|
||||||
get { return _buoyancy; }
|
get { return _buoyancy; }
|
||||||
set {
|
set {
|
||||||
_buoyancy = value;
|
_buoyancy = value;
|
||||||
_scene.TaintedObject("BSPrim.setBuoyancy", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setBuoyancy", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||||
// Buoyancy is faked by changing the gravity applied to the object
|
// Buoyancy is faked by changing the gravity applied to the object
|
||||||
float grav = Scene.Params.gravity * (1f - _buoyancy);
|
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
|
||||||
BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav));
|
BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav));
|
||||||
// BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
|
// BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, _localID, _buoyancy);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -730,7 +717,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
|
m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_scene.TaintedObject("BSPrim.AddForce", delegate()
|
PhysicsScene.TaintedObject("BSPrim.AddForce", delegate()
|
||||||
{
|
{
|
||||||
OMV.Vector3 fSum = OMV.Vector3.Zero;
|
OMV.Vector3 fSum = OMV.Vector3.Zero;
|
||||||
lock (m_accumulatedForces)
|
lock (m_accumulatedForces)
|
||||||
|
@ -754,30 +741,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
public override void SetMomentum(OMV.Vector3 momentum) {
|
public override void SetMomentum(OMV.Vector3 momentum) {
|
||||||
DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
|
DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
|
||||||
}
|
}
|
||||||
public override void SubscribeEvents(int ms) {
|
|
||||||
_subscribedEventsMs = ms;
|
|
||||||
if (ms > 0)
|
|
||||||
{
|
|
||||||
// make sure first collision happens
|
|
||||||
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
|
||||||
|
|
||||||
Scene.TaintedObject("BSPrim.SubscribeEvents", delegate()
|
|
||||||
{
|
|
||||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override void UnSubscribeEvents() {
|
|
||||||
_subscribedEventsMs = 0;
|
|
||||||
Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate()
|
|
||||||
{
|
|
||||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public override bool SubscribedEvents() {
|
|
||||||
return (_subscribedEventsMs > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Mass Calculation
|
#region Mass Calculation
|
||||||
|
|
||||||
private float CalculateMass()
|
private float CalculateMass()
|
||||||
|
@ -1071,8 +1034,8 @@ public sealed class BSPrim : BSPhysObject
|
||||||
if (returnMass <= 0)
|
if (returnMass <= 0)
|
||||||
returnMass = 0.0001f;
|
returnMass = 0.0001f;
|
||||||
|
|
||||||
if (returnMass > _scene.MaximumObjectMass)
|
if (returnMass > PhysicsScene.MaximumObjectMass)
|
||||||
returnMass = _scene.MaximumObjectMass;
|
returnMass = PhysicsScene.MaximumObjectMass;
|
||||||
|
|
||||||
return returnMass;
|
return returnMass;
|
||||||
}// end CalculateMass
|
}// end CalculateMass
|
||||||
|
@ -1090,7 +1053,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
bool haveShape = false;
|
bool haveShape = false;
|
||||||
|
|
||||||
// If the prim attributes are simple, this could be a simple Bullet native shape
|
// If the prim attributes are simple, this could be a simple Bullet native shape
|
||||||
if ((_pbs.SculptEntry && !Scene.ShouldMeshSculptedPrim)
|
if ((_pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim)
|
||||||
|| (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0
|
|| (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0
|
||||||
&& _pbs.ProfileHollow == 0
|
&& _pbs.ProfileHollow == 0
|
||||||
&& _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0
|
&& _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0
|
||||||
|
@ -1156,12 +1119,12 @@ public sealed class BSPrim : BSPhysObject
|
||||||
private bool CreateGeomMesh()
|
private bool CreateGeomMesh()
|
||||||
{
|
{
|
||||||
// level of detail based on size and type of the object
|
// level of detail based on size and type of the object
|
||||||
float lod = _scene.MeshLOD;
|
float lod = PhysicsScene.MeshLOD;
|
||||||
if (_pbs.SculptEntry)
|
if (_pbs.SculptEntry)
|
||||||
lod = _scene.SculptLOD;
|
lod = PhysicsScene.SculptLOD;
|
||||||
float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
|
float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
|
||||||
if (maxAxis > _scene.MeshMegaPrimThreshold)
|
if (maxAxis > PhysicsScene.MeshMegaPrimThreshold)
|
||||||
lod = _scene.MeshMegaPrimLOD;
|
lod = PhysicsScene.MeshMegaPrimLOD;
|
||||||
|
|
||||||
ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
|
ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
|
||||||
// m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
|
// m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
|
||||||
|
@ -1175,14 +1138,14 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
|
// m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
|
||||||
DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
|
DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
|
||||||
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
|
BulletSimAPI.DestroyMesh(PhysicsScene.WorldID, _meshKey);
|
||||||
_mesh = null;
|
_mesh = null;
|
||||||
_meshKey = 0;
|
_meshKey = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_meshKey = newMeshKey;
|
_meshKey = newMeshKey;
|
||||||
// always pass false for physicalness as this creates some sort of bounding box which we don't need
|
// always pass false for physicalness as this creates some sort of bounding box which we don't need
|
||||||
_mesh = _scene.mesher.CreateMesh(_avName, _pbs, _size, lod, false);
|
_mesh = PhysicsScene.mesher.CreateMesh(_avName, _pbs, _size, lod, false);
|
||||||
|
|
||||||
int[] indices = _mesh.getIndexListAsInt();
|
int[] indices = _mesh.getIndexListAsInt();
|
||||||
List<OMV.Vector3> vertices = _mesh.getVertexList();
|
List<OMV.Vector3> vertices = _mesh.getVertexList();
|
||||||
|
@ -1198,7 +1161,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
// m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
|
// m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
|
||||||
// LogHeader, _localID, _meshKey, indices.Length, vertices.Count);
|
// LogHeader, _localID, _meshKey, indices.Length, vertices.Count);
|
||||||
BulletSimAPI.CreateMesh(_scene.WorldID, _meshKey, indices.GetLength(0), indices,
|
BulletSimAPI.CreateMesh(PhysicsScene.WorldID, _meshKey, indices.GetLength(0), indices,
|
||||||
vertices.Count, verticesAsFloats);
|
vertices.Count, verticesAsFloats);
|
||||||
|
|
||||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
|
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
|
||||||
|
@ -1211,7 +1174,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
|
// Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
|
||||||
private bool CreateGeomHull()
|
private bool CreateGeomHull()
|
||||||
{
|
{
|
||||||
float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
|
float lod = _pbs.SculptEntry ? PhysicsScene.SculptLOD : PhysicsScene.MeshLOD;
|
||||||
ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
|
ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
|
||||||
// m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey);
|
// m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey);
|
||||||
|
|
||||||
|
@ -1225,7 +1188,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
|
// m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
|
||||||
DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
|
DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
|
||||||
BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
|
BulletSimAPI.DestroyHull(PhysicsScene.WorldID, _hullKey);
|
||||||
_hullKey = 0;
|
_hullKey = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1314,7 +1277,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
// create the hull definition in Bullet
|
// create the hull definition in Bullet
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount);
|
// m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, _localID, _hullKey, hullCount);
|
||||||
BulletSimAPI.CreateHull(_scene.WorldID, _hullKey, hullCount, convHulls);
|
BulletSimAPI.CreateHull(PhysicsScene.WorldID, _hullKey, hullCount, convHulls);
|
||||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
|
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
|
||||||
// meshes are already scaled by the meshmerizer
|
// meshes are already scaled by the meshmerizer
|
||||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||||
|
@ -1354,10 +1317,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
ShapeData shape;
|
ShapeData shape;
|
||||||
FillShapeInfo(out shape);
|
FillShapeInfo(out shape);
|
||||||
// m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
|
// m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
|
||||||
bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
|
bool ret = BulletSimAPI.CreateObject(PhysicsScene.WorldID, shape);
|
||||||
|
|
||||||
// the CreateObject() may have recreated the rigid body. Make sure we have the latest address.
|
// the CreateObject() may have recreated the rigid body. Make sure we have the latest address.
|
||||||
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID));
|
||||||
BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
|
BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1490,61 +1453,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// I've collided with something
|
|
||||||
// Called at taint time from within the Step() function
|
|
||||||
CollisionEventUpdate collisionCollection;
|
|
||||||
public override bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
// The following lines make IsColliding() and IsCollidingGround() work
|
|
||||||
_collidingStep = Scene.SimulationStep;
|
|
||||||
if (collidingWith <= Scene.TerrainManager.HighestTerrainID)
|
|
||||||
{
|
|
||||||
_collidingGroundStep = Scene.SimulationStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
|
|
||||||
|
|
||||||
// prims in the same linkset cannot collide with each other
|
|
||||||
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if someone has subscribed for collision events....
|
|
||||||
if (SubscribedEvents()) {
|
|
||||||
// throttle the collisions to the number of milliseconds specified in the subscription
|
|
||||||
int nowTime = Scene.SimulationNowTime;
|
|
||||||
if (nowTime >= _nextCollisionOkTime) {
|
|
||||||
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
|
||||||
|
|
||||||
if (collisionCollection == null)
|
|
||||||
collisionCollection = new CollisionEventUpdate();
|
|
||||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The scene is telling us it's time to pass our collected collisions into the simulator
|
|
||||||
public override void SendCollisions()
|
|
||||||
{
|
|
||||||
if (collisionCollection != null && collisionCollection.Count > 0)
|
|
||||||
{
|
|
||||||
base.SendCollisionUpdate(collisionCollection);
|
|
||||||
// The collisionCollection structure is passed around in the simulator.
|
|
||||||
// Make sure we don't have a handle to that one and that a new one is used next time.
|
|
||||||
collisionCollection = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
private void DetailLog(string msg, params Object[] args)
|
private void DetailLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
Scene.PhysicsLogging.Write(msg, args);
|
PhysicsScene.PhysicsLogging.Write(msg, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
public Dictionary<uint, BSPhysObject> PhysObjects = new Dictionary<uint, BSPhysObject>();
|
public Dictionary<uint, BSPhysObject> PhysObjects = new Dictionary<uint, BSPhysObject>();
|
||||||
|
|
||||||
private HashSet<BSPhysObject> m_objectsWithCollisions = new HashSet<BSPhysObject>();
|
public HashSet<BSPhysObject> ObjectsWithCollisions = new HashSet<BSPhysObject>();
|
||||||
// Following is a kludge and can be removed when avatar animation updating is
|
public HashSet<BSPhysObject> ObjectsWithNoMoreCollisions = new HashSet<BSPhysObject>();
|
||||||
// moved to a better place.
|
// Keep track of all the avatars so we can send them a collision event
|
||||||
private HashSet<BSPhysObject> m_avatarsWithCollisions = new HashSet<BSPhysObject>();
|
// every tick so OpenSim will update its animation.
|
||||||
|
private HashSet<BSPhysObject> m_avatars = new HashSet<BSPhysObject>();
|
||||||
|
|
||||||
// List of all the objects that have vehicle properties and should be called
|
// List of all the objects that have vehicle properties and should be called
|
||||||
// to update each physics step.
|
// to update each physics step.
|
||||||
|
@ -379,7 +380,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// TODO: Remove kludge someday.
|
// TODO: Remove kludge someday.
|
||||||
// We must generate a collision for avatars whether they collide or not.
|
// We must generate a collision for avatars whether they collide or not.
|
||||||
// This is required by OpenSim to update avatar animations, etc.
|
// This is required by OpenSim to update avatar animations, etc.
|
||||||
lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor);
|
lock (m_avatars) m_avatars.Add(actor);
|
||||||
|
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
|
@ -397,7 +398,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
{
|
{
|
||||||
lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
|
lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
|
||||||
// Remove kludge someday
|
// Remove kludge someday
|
||||||
lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Remove(bsactor);
|
lock (m_avatars) m_avatars.Remove(bsactor);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -464,6 +465,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
int collidersCount = 0;
|
int collidersCount = 0;
|
||||||
IntPtr collidersPtr;
|
IntPtr collidersPtr;
|
||||||
|
|
||||||
|
int beforeTime = 0;
|
||||||
|
int simTime = 0;
|
||||||
|
|
||||||
// prevent simulation until we've been initialized
|
// prevent simulation until we've been initialized
|
||||||
if (!m_initialized) return 5.0f;
|
if (!m_initialized) return 5.0f;
|
||||||
|
|
||||||
|
@ -481,10 +485,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
int numSubSteps = 0;
|
int numSubSteps = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
numSubSteps = BulletSimAPI.PhysicsStep(WorldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
numSubSteps = BulletSimAPI.PhysicsStep(WorldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
||||||
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
|
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
|
||||||
DetailLog("{0},Simulate,call, nTaints= {1}, substeps={2}, updates={3}, colliders={4}",
|
|
||||||
DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
|
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
|
||||||
|
DetailLog("{0},Simulate,call, nTaints={1}, simTime={2}, substeps={3}, updates={4}, colliders={5}",
|
||||||
|
DetailLogZero, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -502,12 +510,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// Get a value for 'now' so all the collision and update routines don't have to get their own
|
// Get a value for 'now' so all the collision and update routines don't have to get their own
|
||||||
SimulationNowTime = Util.EnvironmentTickCount();
|
SimulationNowTime = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
// This is a kludge to get avatar movement updates.
|
|
||||||
// ODE sends collisions for avatars even if there are have been no collisions. This updates
|
|
||||||
// avatar animations and stuff.
|
|
||||||
// If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
|
|
||||||
m_objectsWithCollisions = new HashSet<BSPhysObject>(m_avatarsWithCollisions);
|
|
||||||
|
|
||||||
// If there were collisions, process them by sending the event to the prim.
|
// If there were collisions, process them by sending the event to the prim.
|
||||||
// Collisions must be processed before updates.
|
// Collisions must be processed before updates.
|
||||||
if (collidersCount > 0)
|
if (collidersCount > 0)
|
||||||
|
@ -523,11 +525,31 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a kludge to get avatar movement updates.
|
||||||
|
// ODE sends collisions for avatars even if there are have been no collisions. This updates
|
||||||
|
// avatar animations and stuff.
|
||||||
|
// If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
|
||||||
|
foreach (BSPhysObject bsp in m_avatars)
|
||||||
|
bsp.SendCollisions();
|
||||||
|
|
||||||
// The above SendCollision's batch up the collisions on the objects.
|
// The above SendCollision's batch up the collisions on the objects.
|
||||||
// Now push the collisions into the simulator.
|
// Now push the collisions into the simulator.
|
||||||
foreach (BSPhysObject bsp in m_objectsWithCollisions)
|
// If the object is done colliding, it will add itself to the ObjectsWithNoMoreCollisions list.
|
||||||
bsp.SendCollisions();
|
if (ObjectsWithCollisions.Count > 0)
|
||||||
m_objectsWithCollisions.Clear();
|
{
|
||||||
|
foreach (BSPhysObject bsp in ObjectsWithCollisions)
|
||||||
|
if (!m_avatars.Contains(bsp)) // don't call avatars twice
|
||||||
|
bsp.SendCollisions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Objects that are done colliding are removed from the ObjectsWithCollisions list.
|
||||||
|
// This can't be done by SendCollisions because it is inside an iteration of ObjectWithCollisions.
|
||||||
|
if (ObjectsWithNoMoreCollisions.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (BSPhysObject po in ObjectsWithNoMoreCollisions)
|
||||||
|
ObjectsWithCollisions.Remove(po);
|
||||||
|
ObjectsWithNoMoreCollisions.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
// If any of the objects had updated properties, tell the object it has been changed by the physics engine
|
// If any of the objects had updated properties, tell the object it has been changed by the physics engine
|
||||||
if (updatedEntityCount > 0)
|
if (updatedEntityCount > 0)
|
||||||
|
@ -555,7 +577,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// The physics engine returns the number of milliseconds it simulated this call.
|
// The physics engine returns the number of milliseconds it simulated this call.
|
||||||
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
|
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
|
||||||
// Since Bullet normally does 5 or 6 substeps, this will normally sum to about 60 FPS.
|
// Since Bullet normally does 5 or 6 substeps, this will normally sum to about 60 FPS.
|
||||||
return numSubSteps * m_fixedTimeStep;
|
return numSubSteps * m_fixedTimeStep * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Something has collided
|
// Something has collided
|
||||||
|
@ -583,7 +605,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration))
|
if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration))
|
||||||
{
|
{
|
||||||
// If a collision was posted, remember to send it to the simulator
|
// If a collision was posted, remember to send it to the simulator
|
||||||
m_objectsWithCollisions.Add(collider);
|
ObjectsWithCollisions.Add(collider);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -249,7 +249,16 @@ public enum CollisionFlags : uint
|
||||||
BS_PHYSICAL_OBJECT = 1 << 13,
|
BS_PHYSICAL_OBJECT = 1 << 13,
|
||||||
BS_TERRAIN_OBJECT = 1 << 14,
|
BS_TERRAIN_OBJECT = 1 << 14,
|
||||||
BS_NONE = 0,
|
BS_NONE = 0,
|
||||||
BS_ALL = 0xFFFFFFFF
|
BS_ALL = 0xFFFFFFFF,
|
||||||
|
|
||||||
|
// These are the collision flags switched depending on physical state.
|
||||||
|
// The other flags are used for other things and should not be fooled with.
|
||||||
|
BS_ACTIVE = CF_STATIC_OBJECT
|
||||||
|
| CF_KINEMATIC_OBJECT
|
||||||
|
| CF_NO_CONTACT_RESPONSE
|
||||||
|
| BS_VOLUME_DETECT_OBJECT
|
||||||
|
| BS_PHANTOM_OBJECT
|
||||||
|
| BS_PHYSICAL_OBJECT,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Values for collisions groups and masks
|
// Values for collisions groups and masks
|
||||||
|
@ -270,52 +279,6 @@ public enum CollisionFilterGroups : uint
|
||||||
SolidFilter = 1 << 13,
|
SolidFilter = 1 << 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
// For each type, we first clear and then set the collision flags
|
|
||||||
public enum ClearCollisionFlag : uint
|
|
||||||
{
|
|
||||||
Terrain = CollisionFlags.BS_ALL,
|
|
||||||
Phantom = CollisionFlags.BS_ALL,
|
|
||||||
VolumeDetect = CollisionFlags.BS_ALL,
|
|
||||||
PhysicalObject = CollisionFlags.BS_ALL,
|
|
||||||
StaticObject = CollisionFlags.BS_ALL
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SetCollisionFlag : uint
|
|
||||||
{
|
|
||||||
Terrain = CollisionFlags.CF_STATIC_OBJECT
|
|
||||||
| CollisionFlags.BS_TERRAIN_OBJECT,
|
|
||||||
Phantom = CollisionFlags.CF_STATIC_OBJECT
|
|
||||||
| CollisionFlags.BS_PHANTOM_OBJECT
|
|
||||||
| CollisionFlags.CF_NO_CONTACT_RESPONSE,
|
|
||||||
VolumeDetect = CollisionFlags.CF_STATIC_OBJECT
|
|
||||||
| CollisionFlags.BS_VOLUME_DETECT_OBJECT
|
|
||||||
| CollisionFlags.CF_NO_CONTACT_RESPONSE,
|
|
||||||
PhysicalObject = CollisionFlags.BS_PHYSICAL_OBJECT,
|
|
||||||
StaticObject = CollisionFlags.CF_STATIC_OBJECT,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collision filters used for different types of objects
|
|
||||||
public enum SetCollisionFilter : uint
|
|
||||||
{
|
|
||||||
Terrain = CollisionFilterGroups.AllFilter,
|
|
||||||
Phantom = CollisionFilterGroups.GroundPlaneFilter
|
|
||||||
| CollisionFilterGroups.TerrainFilter,
|
|
||||||
VolumeDetect = CollisionFilterGroups.AllFilter,
|
|
||||||
PhysicalObject = CollisionFilterGroups.AllFilter,
|
|
||||||
StaticObject = CollisionFilterGroups.AllFilter,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collision masks used for different types of objects
|
|
||||||
public enum SetCollisionMask : uint
|
|
||||||
{
|
|
||||||
Terrain = CollisionFilterGroups.AllFilter,
|
|
||||||
Phantom = CollisionFilterGroups.GroundPlaneFilter
|
|
||||||
| CollisionFilterGroups.TerrainFilter,
|
|
||||||
VolumeDetect = CollisionFilterGroups.AllFilter,
|
|
||||||
PhysicalObject = CollisionFilterGroups.AllFilter,
|
|
||||||
StaticObject = CollisionFilterGroups.AllFilter
|
|
||||||
}
|
|
||||||
|
|
||||||
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
|
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
|
||||||
// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2.
|
// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2.
|
||||||
public enum ConstraintParams : int
|
public enum ConstraintParams : int
|
||||||
|
|
Loading…
Reference in New Issue