BulletSim: Way too many changes in one commit.
Many changes to BSDynamic for readability and commentary. Linkset hacking for vehicles: don't over mass the root prim. Add parameter for link constraint solver iterations. Correct uses of timestep in timescale calculations for vehicles. Reorganize code/logic for making objects static and dynamic for readability and use of API2. Changed most calls in BSPrim to use API2 calls (the new way). Avatars do not generate default Bullet collision events but do call up to the simulator for every avatar. Reduces overhead. Objects added to collision list only if they are processing collisions. Reduces overhead especially for large numbers of avatars. Generalize call for water height to GetWaterHeightAtXYZ(). Catch and correct exception getting terrain height when out of bounds. Correct race condition in Terrain Manager where creation wasn't at taint-time. Add API calls for constructing compound shapes. Move NeedsMeshing() logic into object class. Reorganize logic for object meshing to reduce rebuilding of meshs/hulls.connector_plugin
parent
1ec84ac8b1
commit
2c5ff93990
|
@ -131,8 +131,6 @@ public class BSCharacter : BSPhysObject
|
|||
BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
|
||||
|
||||
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID));
|
||||
// avatars get all collisions no matter what (makes walking on ground and such work)
|
||||
BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
|
||||
return;
|
||||
|
@ -480,11 +478,10 @@ public class BSCharacter : BSPhysObject
|
|||
// Stop collision events
|
||||
public override void UnSubscribeEvents() {
|
||||
_subscribedEventsMs = 0;
|
||||
// Avatars get all their collision events
|
||||
// Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
|
||||
// {
|
||||
// BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
// });
|
||||
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() {
|
||||
|
@ -532,10 +529,12 @@ public class BSCharacter : BSPhysObject
|
|||
// 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 void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||
public override bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
||||
|
||||
bool ret = false;
|
||||
|
||||
// The following makes IsColliding() and IsCollidingGround() work
|
||||
_collidingStep = Scene.SimulationStep;
|
||||
if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
|
||||
|
@ -553,8 +552,10 @@ public class BSCharacter : BSPhysObject
|
|||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public override void SendCollisions()
|
||||
|
|
|
@ -74,6 +74,17 @@ public abstract class BSConstraint : IDisposable
|
|||
return ret;
|
||||
}
|
||||
|
||||
public virtual bool SetSolverIterations(float cnt)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
{
|
||||
BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.Ptr, cnt);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public virtual bool CalculateTransforms()
|
||||
{
|
||||
bool ret = false;
|
||||
|
@ -96,12 +107,9 @@ public abstract class BSConstraint : IDisposable
|
|||
ret = CalculateTransforms();
|
||||
if (ret)
|
||||
{
|
||||
// m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}",
|
||||
// BSScene.DetailLogZero, Body1.ID, Body2.ID);
|
||||
|
||||
// Setting an object's mass to zero (making it static like when it's selected)
|
||||
// automatically disables the constraints.
|
||||
// If enabled, be sure to set the constraint itself to enabled.
|
||||
// If the link is enabled, be sure to set the constraint itself to enabled.
|
||||
BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true));
|
||||
}
|
||||
else
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Linear properties
|
||||
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
|
||||
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||
private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body
|
||||
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
||||
private float m_linearMotorDecayTimescale = 0;
|
||||
private float m_linearMotorTimescale = 0;
|
||||
|
@ -475,32 +475,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
frcount = 0;
|
||||
|
||||
MoveLinear(pTimestep);
|
||||
MoveAngular(pTimestep);
|
||||
// MoveAngular(pTimestep);
|
||||
LimitRotation(pTimestep);
|
||||
|
||||
// remember the position so next step we can limit absolute movement effects
|
||||
m_lastPositionVector = m_prim.Position;
|
||||
|
||||
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
||||
m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
|
||||
}// end Step
|
||||
|
||||
private void MoveLinear(float pTimestep)
|
||||
{
|
||||
// requested m_linearMotorDirection is significant
|
||||
// if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
if (m_linearMotorDirection.LengthSquared() > 0.0001f)
|
||||
// m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates
|
||||
// m_lastLinearVelocityVector is the speed we are moving in that direction
|
||||
if (m_linearMotorDirection.LengthSquared() > 0.001f)
|
||||
{
|
||||
Vector3 origDir = m_linearMotorDirection;
|
||||
Vector3 origVel = m_lastLinearVelocityVector;
|
||||
|
||||
// add drive to body
|
||||
// Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale / pTimestep);
|
||||
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale);
|
||||
// lastLinearVelocityVector is the current body velocity vector?
|
||||
Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep);
|
||||
// lastLinearVelocityVector is the current body velocity vector
|
||||
// RA: Not sure what the *10 is for. A correction for pTimestep?
|
||||
// m_lastLinearVelocityVector += (addAmount*10);
|
||||
m_lastLinearVelocityVector += addAmount;
|
||||
|
||||
// This will work temporarily, but we really need to compare speed on an axis
|
||||
// KF: Limit body velocity to applied velocity?
|
||||
// Limit the velocity vector to less than the last set linear motor direction
|
||||
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
|
||||
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
|
||||
|
@ -509,34 +510,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
|
||||
m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
|
||||
|
||||
// decay applied velocity
|
||||
Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
|
||||
m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
|
||||
|
||||
/*
|
||||
Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale;
|
||||
m_lastLinearVelocityVector += addAmount;
|
||||
|
||||
float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale);
|
||||
m_linearMotorDirection *= decayfraction;
|
||||
|
||||
// decay applied velocity
|
||||
Vector3 decayfraction = Vector3.One/(m_linearMotorDecayTimescale / pTimestep);
|
||||
// (RA: do not know where the 0.5f comes from)
|
||||
m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
|
||||
*/
|
||||
float keepfraction = 1.0f - (1.0f / (m_linearMotorDecayTimescale / pTimestep));
|
||||
m_linearMotorDirection *= keepfraction;
|
||||
|
||||
VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
|
||||
m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
|
||||
VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}",
|
||||
m_prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if what remains of applied is small, zero it.
|
||||
// if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
// m_lastLinearVelocityVector = Vector3.Zero;
|
||||
// if what remains of direction is very small, zero it.
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_lastLinearVelocityVector = Vector3.Zero;
|
||||
VDetailLog("{0},MoveLinear,zeroed", m_prim.LocalID);
|
||||
}
|
||||
|
||||
// convert requested object velocity to object relative vector
|
||||
Quaternion rotq = m_prim.Orientation;
|
||||
m_dir = m_lastLinearVelocityVector * rotq;
|
||||
m_newVelocity = m_lastLinearVelocityVector * rotq;
|
||||
|
||||
// Add the various forces into m_dir which will be our new direction vector (velocity)
|
||||
|
||||
|
@ -544,18 +540,81 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// KF: So far I have found no good method to combine a script-requested
|
||||
// .Z velocity and gravity. Therefore only 0g will used script-requested
|
||||
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
||||
Vector3 grav = Vector3.Zero;
|
||||
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||
grav.Z = m_prim.Scene.DefaultGravity.Z * m_prim.Mass * (1f - m_VehicleBuoyancy);
|
||||
Vector3 grav = m_prim.Scene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy));
|
||||
|
||||
/*
|
||||
* RA: Not sure why one would do this
|
||||
// Preserve the current Z velocity
|
||||
Vector3 vel_now = m_prim.Velocity;
|
||||
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
||||
*/
|
||||
|
||||
Vector3 pos = m_prim.Position;
|
||||
Vector3 posChange = pos;
|
||||
// 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);
|
||||
double Zchange = Math.Abs(posChange.Z);
|
||||
|
||||
// If below the terrain, move us above the ground a little.
|
||||
float terrainHeight = m_prim.Scene.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.
|
||||
// Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
|
||||
// Vector3 rotatedSize = m_prim.Size * m_prim.Orientation;
|
||||
// if (rotatedSize.Z < terrainHeight)
|
||||
if (pos.Z < terrainHeight)
|
||||
{
|
||||
pos.Z = terrainHeight + 2;
|
||||
m_prim.Position = pos;
|
||||
VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", m_prim.LocalID, terrainHeight, pos);
|
||||
}
|
||||
|
||||
// Check if hovering
|
||||
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
{
|
||||
// We should hover, get the target height
|
||||
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_prim.Scene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = terrainHeight + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_VhoverHeight;
|
||||
}
|
||||
|
||||
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
|
||||
{
|
||||
// If body is aready heigher, use its height as target height
|
||||
if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||
{
|
||||
if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
|
||||
{
|
||||
m_prim.Position = pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||
// Replace Vertical speed with correction figure if significant
|
||||
if (Math.Abs(herr0) > 0.01f)
|
||||
{
|
||||
m_newVelocity.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||
//KF: m_VhoverEfficiency is not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
m_newVelocity.Z = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight);
|
||||
}
|
||||
|
||||
Vector3 posChange = pos - m_lastPositionVector;
|
||||
if (m_BlockingEndPoint != Vector3.Zero)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -592,125 +651,43 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
}
|
||||
|
||||
// If below the terrain, move us above the ground a little.
|
||||
if (pos.Z < m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos))
|
||||
{
|
||||
pos.Z = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2;
|
||||
m_prim.Position = pos;
|
||||
VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
|
||||
}
|
||||
|
||||
// Check if hovering
|
||||
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
{
|
||||
// We should hover, get the target height
|
||||
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_VhoverHeight;
|
||||
}
|
||||
|
||||
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
|
||||
{
|
||||
// If body is aready heigher, use its height as target height
|
||||
if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||
{
|
||||
if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
|
||||
{
|
||||
m_prim.Position = pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||
// Replace Vertical speed with correction figure if significant
|
||||
if (Math.Abs(herr0) > 0.01f)
|
||||
{
|
||||
m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||
//KF: m_VhoverEfficiency is not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dir.Z = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
|
||||
|
||||
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||
// m_VhoverTimescale = 0f; // time to acheive height
|
||||
// pTimestep is time since last frame,in secs
|
||||
}
|
||||
|
||||
float Zchange = Math.Abs(posChange.Z);
|
||||
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
||||
{
|
||||
//Start Experimental Values
|
||||
if (Zchange > .3)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 3);
|
||||
}
|
||||
if (Zchange > .15)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 2);
|
||||
}
|
||||
if (Zchange > .75)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.5);
|
||||
}
|
||||
if (Zchange > .05)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.25);
|
||||
}
|
||||
if (Zchange > .025)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.125);
|
||||
}
|
||||
float terraintemp = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||
float postemp = (pos.Z - terraintemp);
|
||||
float postemp = (pos.Z - terrainHeight);
|
||||
if (postemp > 2.5f)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.037125);
|
||||
}
|
||||
VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
|
||||
//End Experimental Values
|
||||
}
|
||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||
{
|
||||
m_dir.X = 0;
|
||||
}
|
||||
m_newVelocity.X = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||
{
|
||||
m_dir.Y = 0;
|
||||
}
|
||||
m_newVelocity.Y = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||
{
|
||||
m_dir.Z = 0;
|
||||
}
|
||||
|
||||
m_lastPositionVector = m_prim.Position;
|
||||
m_newVelocity.Z = 0;
|
||||
|
||||
// Apply velocity
|
||||
m_prim.Velocity = m_dir;
|
||||
m_prim.Velocity = m_newVelocity;
|
||||
// apply gravity force
|
||||
// Why is this set here? The physics engine already does gravity.
|
||||
// m_prim.AddForce(grav, false);
|
||||
// m_prim.Force = grav;
|
||||
|
||||
// Apply friction
|
||||
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||
Vector3 keepFraction = Vector3.One - (Vector3.One / (m_linearFrictionTimescale / pTimestep));
|
||||
m_lastLinearVelocityVector *= keepFraction;
|
||||
|
||||
VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
|
||||
m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
|
||||
VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}",
|
||||
m_prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction);
|
||||
|
||||
} // end MoveLinear()
|
||||
|
||||
|
@ -741,11 +718,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
|
||||
m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
|
||||
|
||||
VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
|
||||
m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
|
||||
VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},dir={5},vel={6}",
|
||||
m_prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
|
||||
|
||||
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
|
||||
// This is done so that if script request rate is less than phys frame rate the expected
|
||||
// velocity may still be acheived.
|
||||
m_angularMotorApply--;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -760,7 +738,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
Vector3 vertattr = Vector3.Zero;
|
||||
if (m_verticalAttractionTimescale < 300)
|
||||
{
|
||||
float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep);
|
||||
float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep);
|
||||
// get present body rotation
|
||||
Quaternion rotq = m_prim.Orientation;
|
||||
// make a vector pointing up
|
||||
|
@ -863,16 +841,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_rot.Y = 0;
|
||||
changed = true;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
|
||||
{
|
||||
m_rot.X = 0;
|
||||
m_rot.Y = 0;
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
m_prim.Orientation = m_rot;
|
||||
VDetailLog("{0},LimitRotation,done,orig={1},new={2}", m_prim.LocalID, rotq, m_rot);
|
||||
}
|
||||
|
||||
VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
|
||||
}
|
||||
|
||||
// Invoke the detailed logger and output something if it's enabled.
|
||||
|
|
|
@ -206,7 +206,7 @@ public class BSLinkset
|
|||
// its internal properties.
|
||||
public void Refresh(BSPhysObject requestor)
|
||||
{
|
||||
// If there are no children, there aren't any constraints to recompute
|
||||
// If there are no children, there can't be any constraints to recompute
|
||||
if (!HasAnyChildren)
|
||||
return;
|
||||
|
||||
|
@ -225,11 +225,12 @@ public class BSLinkset
|
|||
// from a linkset to make sure the constraints know about the new mass and
|
||||
// geometry.
|
||||
// Must only be called at taint time!!
|
||||
private bool RecomputeLinksetConstraintVariables()
|
||||
private void RecomputeLinksetConstraintVariables()
|
||||
{
|
||||
float linksetMass = LinksetMass;
|
||||
lock (m_linksetActivityLock)
|
||||
{
|
||||
bool somethingMissing = false;
|
||||
foreach (BSPhysObject child in m_children)
|
||||
{
|
||||
BSConstraint constrain;
|
||||
|
@ -241,16 +242,29 @@ public class BSLinkset
|
|||
}
|
||||
else
|
||||
{
|
||||
// Non-fatal error that can happen when children are being added to the linkset but
|
||||
// Non-fatal error that happens when children are being added to the linkset but
|
||||
// their constraints have not been created yet.
|
||||
// Caused by the fact that m_children is built at run time but building constraints
|
||||
// happens at taint time.
|
||||
// m_physicsScene.Logger.ErrorFormat("{0} RecomputeLinksetConstraintVariables: constraint not found for root={1}, child={2}",
|
||||
// LogHeader, m_linksetRoot.Body.ID, child.Body.ID);
|
||||
somethingMissing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the whole linkset is not here, doesn't make sense to recompute the root prim now.
|
||||
if (!somethingMissing)
|
||||
{
|
||||
// The root prim takes on the weight of the whole linkset
|
||||
/*
|
||||
OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(LinksetRoot.BSShape.Ptr, linksetMass);
|
||||
BulletSimAPI.SetMassProps2(LinksetRoot.BSBody.Ptr, linksetMass, inertia);
|
||||
OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
|
||||
BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity);
|
||||
BulletSimAPI.UpdateInertiaTensor2(LinksetRoot.BSBody.Ptr);
|
||||
*/
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// I am the root of a linkset and a new child is being added
|
||||
|
@ -296,9 +310,9 @@ public class BSLinkset
|
|||
DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
|
||||
|
||||
PhysicallyUnlinkAChildFromRoot(rootx, childx);
|
||||
RecomputeLinksetConstraintVariables();
|
||||
});
|
||||
|
||||
RecomputeLinksetConstraintVariables();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -377,6 +391,10 @@ public class BSLinkset
|
|||
PhysicsScene.Params.linkConstraintTransMotorMaxVel,
|
||||
PhysicsScene.Params.linkConstraintTransMotorMaxForce);
|
||||
constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP);
|
||||
if (PhysicsScene.Params.linkConstraintSolverIterations != 0f)
|
||||
{
|
||||
constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations);
|
||||
}
|
||||
|
||||
RecomputeLinksetConstraintVariables();
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
{
|
||||
public abstract BSLinkset Linkset { get; set; }
|
||||
|
||||
public abstract void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type,
|
||||
public abstract bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type,
|
||||
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
|
||||
public abstract void SendCollisions();
|
||||
|
||||
|
|
|
@ -136,11 +136,11 @@ public sealed class BSPrim : BSPhysObject
|
|||
Linkset = new BSLinkset(Scene, this); // a linkset of one
|
||||
_vehicle = new BSDynamics(Scene, this); // add vehicleness
|
||||
_mass = CalculateMass();
|
||||
// do the actual object creation at taint time
|
||||
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
||||
// do the actual object creation at taint time
|
||||
_scene.TaintedObject("BSPrim.create", delegate()
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
CreateGeomAndObject(true);
|
||||
|
||||
// Get the pointer to the physical body for this object.
|
||||
// At the moment, we're still letting BulletSim manage the creation and destruction
|
||||
|
@ -186,9 +186,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setSize", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing size changes the mass
|
||||
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
|
||||
DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
|
||||
RecreateGeomAndObject();
|
||||
// Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct
|
||||
// scale and margins are set.
|
||||
CreateGeomAndObject(true);
|
||||
DetailLog("{0}: BSPrim.setSize: size={1}, scale={2}, mass={3}, physical={4}", LocalID, _size, _scale, _mass, IsPhysical);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +199,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setShape", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
RecreateGeomAndObject();
|
||||
CreateGeomAndObject(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +280,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
get {
|
||||
if (!Linkset.IsRoot(this))
|
||||
// child prims move around based on their parent. Need to get the latest location
|
||||
_position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
_position = BulletSimAPI.GetPosition2(BSBody.Ptr);
|
||||
|
||||
// don't do the GetObjectPosition for root elements because this function is called a zillion times
|
||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
|
@ -291,7 +292,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setPosition", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +303,8 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
get
|
||||
{
|
||||
return Linkset.LinksetMass;
|
||||
// return Linkset.LinksetMass;
|
||||
return _mass;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,7 +330,6 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setForce", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
|
||||
// BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
||||
BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
|
||||
});
|
||||
}
|
||||
|
@ -406,7 +407,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setVelocity", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
|
||||
BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +431,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
if (!Linkset.IsRoot(this))
|
||||
{
|
||||
// Children move around because tied to parent. Get a fresh value.
|
||||
_orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
|
||||
_orientation = BulletSimAPI.GetOrientation2(BSBody.Ptr);
|
||||
}
|
||||
return _orientation;
|
||||
}
|
||||
|
@ -441,7 +442,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -483,31 +484,37 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
// If it's becoming dynamic, it will need hullness
|
||||
VerifyCorrectPhysicalShape();
|
||||
UpdatePhysicalParameters();
|
||||
}
|
||||
|
||||
private void UpdatePhysicalParameters()
|
||||
{
|
||||
/*
|
||||
// Bullet wants static objects to have a mass of zero
|
||||
float mass = IsStatic ? 0f : _mass;
|
||||
|
||||
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
|
||||
/*
|
||||
*/
|
||||
BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr);
|
||||
|
||||
// Set up the object physicalness (static or dynamic)
|
||||
MakeDynamic();
|
||||
// Set up the object physicalness (does gravity and collisions move this object)
|
||||
MakeDynamic(IsStatic);
|
||||
|
||||
// Make solid or not and arrange for collisions, etc
|
||||
MakeSolid();
|
||||
// Make solid or not (do things bounce off or pass through this object)
|
||||
MakeSolid(IsSolid);
|
||||
|
||||
m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
|
||||
// Arrange for collisions events if the simulator wants them
|
||||
EnableCollisions(SubscribedEvents());
|
||||
|
||||
BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr);
|
||||
*/
|
||||
|
||||
// Recompute any linkset parameters.
|
||||
// When going from non-physical to physical, this re-enables the constraints that
|
||||
// had been automatically disabled when the mass was set to zero.
|
||||
Linkset.Refresh(this);
|
||||
|
||||
DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, m_currentCollisionFlags);
|
||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3}, cf={4}",
|
||||
LocalID, IsStatic, IsSolid, _mass, m_currentCollisionFlags);
|
||||
}
|
||||
|
||||
// "Making dynamic" means changing to and from static.
|
||||
|
@ -515,12 +522,12 @@ public sealed class BSPrim : BSPhysObject
|
|||
// When dynamic, the object can fall and be pushed by others.
|
||||
// This is independent of its 'solidness' which controls what passes through
|
||||
// this object and what interacts with it.
|
||||
private void MakeDynamic()
|
||||
private void MakeDynamic(bool makeStatic)
|
||||
{
|
||||
if (IsStatic)
|
||||
if (makeStatic)
|
||||
{
|
||||
// Become a Bullet 'static' object type
|
||||
BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
// Stop all movement
|
||||
BulletSimAPI.ClearAllForces2(BSBody.Ptr);
|
||||
// Mass is zero which disables a bunch of physics stuff in Bullet
|
||||
|
@ -533,12 +540,11 @@ public sealed class BSPrim : BSPhysObject
|
|||
else
|
||||
{
|
||||
// Not a Bullet static object
|
||||
BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
// A dynamic object has mass
|
||||
BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, OMV.Vector3.Zero);
|
||||
// The shape is interesting and has mass and a center of gravity
|
||||
IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr);
|
||||
BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass, OMV.Vector3.Zero);
|
||||
OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass);
|
||||
BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia);
|
||||
// Inertia is based on our new mass
|
||||
BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
|
||||
// Force activation of the object so Bullet will act on it.
|
||||
|
@ -546,8 +552,31 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
}
|
||||
|
||||
private void MakeSolid()
|
||||
// "Making solid" means that other object will not pass through this object.
|
||||
private void MakeSolid(bool makeSolid)
|
||||
{
|
||||
if (makeSolid)
|
||||
{
|
||||
// Easy in Bullet -- just remove the object flag that controls collision response
|
||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Turn on or off the flag controlling whether collision events are returned to the simulator.
|
||||
private void EnableCollisions(bool wantsCollisionEvents)
|
||||
{
|
||||
if (wantsCollisionEvents)
|
||||
{
|
||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
// prims don't fly
|
||||
|
@ -607,7 +636,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
||||
BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
|
||||
BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -624,7 +653,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setBuoyancy", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
|
||||
// Buoyancy is faked by changing the gravity applied to the object
|
||||
float grav = Scene.Params.gravity * (1f - _buoyancy);
|
||||
BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav));
|
||||
// BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -686,8 +718,8 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
m_accumulatedForces.Clear();
|
||||
}
|
||||
DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
|
||||
// For unknown reason, "ApplyCentralForce" is really additive.
|
||||
DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum);
|
||||
// For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object.
|
||||
BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum);
|
||||
});
|
||||
}
|
||||
|
@ -1030,15 +1062,22 @@ public sealed class BSPrim : BSPhysObject
|
|||
// Returns 'true' if the geometry was rebuilt
|
||||
private bool CreateGeom(bool forceRebuild)
|
||||
{
|
||||
// the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
|
||||
bool ret = false;
|
||||
if (!_scene.NeedsMeshing(_pbs))
|
||||
bool haveShape = false;
|
||||
|
||||
// If the prim attributes are simple, this could be a simple Bullet native shape
|
||||
if ((_pbs.SculptEntry && !Scene.ShouldMeshSculptedPrim)
|
||||
|| (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0
|
||||
&& _pbs.ProfileHollow == 0
|
||||
&& _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0
|
||||
&& _pbs.PathBegin == 0 && _pbs.PathEnd == 0
|
||||
&& _pbs.PathTaperX == 0 && _pbs.PathTaperY == 0
|
||||
&& _pbs.PathScaleX == 100 && _pbs.PathScaleY == 100
|
||||
&& _pbs.PathShearX == 0 && _pbs.PathShearY == 0) )
|
||||
{
|
||||
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
// if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
|
||||
// {
|
||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
|
||||
haveShape = true;
|
||||
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
|
||||
{
|
||||
DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
|
||||
|
@ -1048,11 +1087,11 @@ public sealed class BSPrim : BSPhysObject
|
|||
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
|
||||
ret = true;
|
||||
}
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
|
||||
haveShape = true;
|
||||
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
|
||||
{
|
||||
DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
|
||||
|
@ -1063,16 +1102,16 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
// If a simple shape isn't happening, create a mesh and possibly a hull
|
||||
if (!haveShape)
|
||||
{
|
||||
if (IsPhysical)
|
||||
{
|
||||
if (forceRebuild || _hullKey == 0)
|
||||
{
|
||||
// physical objects require a hull for interaction.
|
||||
// This will create the mesh if it doesn't already exist
|
||||
CreateGeomHull();
|
||||
ret = true;
|
||||
// This also creates the mesh if it doesn't already exist
|
||||
ret = CreateGeomHull();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1080,8 +1119,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
if (forceRebuild || _meshKey == 0)
|
||||
{
|
||||
// Static (non-physical) objects only need a mesh for bumping into
|
||||
CreateGeomMesh();
|
||||
ret = true;
|
||||
ret = CreateGeomMesh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1089,7 +1127,8 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
|
||||
// No locking here because this is done when we know physics is not simulating
|
||||
private void CreateGeomMesh()
|
||||
// Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
|
||||
private bool CreateGeomMesh()
|
||||
{
|
||||
// level of detail based on size and type of the object
|
||||
float lod = _scene.MeshLOD;
|
||||
|
@ -1103,7 +1142,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
|
||||
|
||||
// if this new shape is the same as last time, don't recreate the mesh
|
||||
if (_meshKey == newMeshKey) return;
|
||||
if (_meshKey == newMeshKey) return false;
|
||||
|
||||
DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
|
||||
// Since we're recreating new, get rid of any previously generated shape
|
||||
|
@ -1140,19 +1179,19 @@ public sealed class BSPrim : BSPhysObject
|
|||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
|
||||
// meshes are already scaled by the meshmerizer
|
||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||
DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// No locking here because this is done when we know physics is not simulating
|
||||
private void CreateGeomHull()
|
||||
// Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
|
||||
private bool CreateGeomHull()
|
||||
{
|
||||
float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
|
||||
ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
|
||||
// m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey);
|
||||
|
||||
// if the hull hasn't changed, don't rebuild it
|
||||
if (newHullKey == _hullKey) return;
|
||||
if (newHullKey == _hullKey) return false;
|
||||
|
||||
DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
|
||||
|
||||
|
@ -1255,7 +1294,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// meshes are already scaled by the meshmerizer
|
||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||
DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Callback from convex hull creater with a newly created hull.
|
||||
|
@ -1268,20 +1307,12 @@ public sealed class BSPrim : BSPhysObject
|
|||
|
||||
private void VerifyCorrectPhysicalShape()
|
||||
{
|
||||
if (IsStatic)
|
||||
{
|
||||
// if static, we don't need a hull so, if there is one, rebuild without it
|
||||
if (_hullKey != 0)
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!IsStatic)
|
||||
{
|
||||
// if not static, it will need a hull to efficiently collide with things
|
||||
if (_hullKey == 0)
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
CreateGeomAndObject(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1300,8 +1331,9 @@ public sealed class BSPrim : BSPhysObject
|
|||
// m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
|
||||
bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
|
||||
|
||||
// the CreateObject() may have recreated the rigid body. Make sure we have the latest.
|
||||
// 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));
|
||||
BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1325,15 +1357,20 @@ public sealed class BSPrim : BSPhysObject
|
|||
shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
|
||||
}
|
||||
|
||||
|
||||
// Rebuild the geometry and object.
|
||||
// This is called when the shape changes so we need to recreate the mesh/hull.
|
||||
// No locking here because this is done when the physics engine is not simulating
|
||||
private void RecreateGeomAndObject()
|
||||
private void CreateGeomAndObject(bool forceRebuild)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID);
|
||||
if (CreateGeom(true))
|
||||
// m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, _localID, forceRebuild);
|
||||
// Create the geometry that will make up the object
|
||||
if (CreateGeom(forceRebuild))
|
||||
{
|
||||
// Create the object and place it into the world
|
||||
CreateObject();
|
||||
// Make sure the properties are set on the new object
|
||||
UpdatePhysicalParameters();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1430,9 +1467,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
// I've collided with something
|
||||
// Called at taint time from within the Step() function
|
||||
CollisionEventUpdate collisionCollection;
|
||||
public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||
public override bool Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
||||
bool ret = false;
|
||||
|
||||
// The following lines make IsColliding() and IsCollidingGround() work
|
||||
_collidingStep = _scene.SimulationStep;
|
||||
|
@ -1446,7 +1484,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// prims in the same linkset cannot collide with each other
|
||||
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
|
||||
{
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// if someone has subscribed for collision events....
|
||||
|
@ -1459,8 +1497,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
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
|
||||
|
|
|
@ -79,7 +79,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
private HashSet<BSPhysObject> m_objectsWithCollisions = new HashSet<BSPhysObject>();
|
||||
// Following is a kludge and can be removed when avatar animation updating is
|
||||
// moved to a better place.
|
||||
private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
|
||||
private HashSet<BSPhysObject> m_avatarsWithCollisions = new HashSet<BSPhysObject>();
|
||||
|
||||
// List of all the objects that have vehicle properties and should be called
|
||||
// to update each physics step.
|
||||
|
@ -132,8 +132,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
private EntityProperties[] m_updateArray;
|
||||
private GCHandle m_updateArrayPinnedHandle;
|
||||
|
||||
private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed
|
||||
private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes
|
||||
public bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
|
||||
public bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
|
||||
|
||||
public float PID_D { get; private set; } // derivative
|
||||
public float PID_P { get; private set; } // proportional
|
||||
|
@ -153,6 +153,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
{
|
||||
get { return new Vector3(0f, 0f, Params.gravity); }
|
||||
}
|
||||
// Just the Z value of the gravity
|
||||
public float DefaultGravityZ
|
||||
{
|
||||
get { return Params.gravity; }
|
||||
}
|
||||
|
||||
public float MaximumObjectMass { get; private set; }
|
||||
|
||||
|
@ -171,8 +176,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
callback = c;
|
||||
}
|
||||
}
|
||||
private Object _taintLock = new Object(); // lock for using the next object
|
||||
private List<TaintCallbackEntry> _taintedObjects;
|
||||
private Object _taintLock = new Object();
|
||||
|
||||
// A pointer to an instance if this structure is passed to the C++ code
|
||||
// Used to pass basic configuration values to the unmanaged code.
|
||||
|
@ -478,6 +483,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
// Some of the prims operate with special vehicle properties
|
||||
ProcessVehicles(timeStep);
|
||||
numTaints += _taintedObjects.Count;
|
||||
ProcessTaints(); // the vehicles might have added taints
|
||||
|
||||
// step the physical world one interval
|
||||
|
@ -506,6 +512,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
// Get a value for 'now' so all the collision and update routines don't have to get their own
|
||||
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 collisions happen.
|
||||
m_objectsWithCollisions = new HashSet<BSPhysObject>(m_avatarsWithCollisions);
|
||||
|
||||
// If there were collisions, process them by sending the event to the prim.
|
||||
// Collisions must be processed before updates.
|
||||
if (collidersCount > 0)
|
||||
|
@ -527,13 +539,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
bsp.SendCollisions();
|
||||
m_objectsWithCollisions.Clear();
|
||||
|
||||
// This is a kludge to get avatar movement updated.
|
||||
// ODE sends collisions even if there are none and this is used to update
|
||||
// avatar animations and stuff.
|
||||
foreach (BSPhysObject bpo in m_avatarsWithCollisions)
|
||||
bpo.SendCollisions();
|
||||
// m_avatarsWithCollisions.Clear();
|
||||
|
||||
// If any of the objects had updated properties, tell the object it has been changed by the physics engine
|
||||
if (updatedEntityCount > 0)
|
||||
{
|
||||
|
@ -544,7 +549,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
if (PhysObjects.TryGetValue(entprop.ID, out pobj))
|
||||
{
|
||||
pobj.UpdateProperties(entprop);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -600,8 +604,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
// DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
|
||||
|
||||
collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration);
|
||||
if (collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration))
|
||||
{
|
||||
// If a collision was posted, remember to send it to the simulator
|
||||
m_objectsWithCollisions.Add(collider);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -619,9 +626,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
public override void SetWaterLevel(float baseheight)
|
||||
{
|
||||
m_waterLevel = baseheight;
|
||||
// TODO: pass to physics engine so things will float?
|
||||
}
|
||||
public float GetWaterLevel()
|
||||
// Someday....
|
||||
public float GetWaterLevelAtXYZ(Vector3 loc)
|
||||
{
|
||||
return m_waterLevel;
|
||||
}
|
||||
|
@ -672,7 +679,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
// int iPropertiesNotSupportedDefault = 0;
|
||||
|
||||
if (pbs.SculptEntry && !_meshSculptedPrim)
|
||||
if (pbs.SculptEntry && !ShouldMeshSculptedPrim)
|
||||
{
|
||||
// Render sculpties as boxes
|
||||
return false;
|
||||
|
@ -680,7 +687,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
// if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since Bullet
|
||||
// can use an internal representation for the prim
|
||||
if (!_forceSimplePrimMeshing)
|
||||
if (!ShouldForceSimplePrimMeshing)
|
||||
{
|
||||
if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
|| (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
|
||||
|
@ -782,7 +789,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
if (!m_initialized) return;
|
||||
|
||||
lock (_taintLock)
|
||||
{
|
||||
_taintedObjects.Add(new TaintCallbackEntry(ident, callback));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -919,14 +929,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
{
|
||||
new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
|
||||
ConfigurationParameters.numericTrue,
|
||||
(s,cf,p,v) => { s._meshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s._meshSculptedPrim); },
|
||||
(s,p,l,v) => { s._meshSculptedPrim = s.BoolNumeric(v); } ),
|
||||
(s,cf,p,v) => { s.ShouldMeshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s.ShouldMeshSculptedPrim); },
|
||||
(s,p,l,v) => { s.ShouldMeshSculptedPrim = s.BoolNumeric(v); } ),
|
||||
new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
|
||||
ConfigurationParameters.numericFalse,
|
||||
(s,cf,p,v) => { s._forceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
|
||||
(s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
|
||||
(s,cf,p,v) => { s.ShouldForceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); },
|
||||
(s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ),
|
||||
|
||||
new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
|
||||
8f,
|
||||
|
@ -1162,8 +1172,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
(s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
|
||||
(s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
|
||||
new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=none, 1=all. Default=0",
|
||||
0.0f,
|
||||
new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
|
||||
0.1f,
|
||||
(s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linkConstraintCFM; },
|
||||
(s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ),
|
||||
|
@ -1172,6 +1182,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
(s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linkConstraintERP; },
|
||||
(s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ),
|
||||
new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
|
||||
40,
|
||||
(s,cf,p,v) => { s.m_params[0].linkConstraintSolverIterations = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linkConstraintSolverIterations; },
|
||||
(s,p,l,v) => { s.m_params[0].linkConstraintSolverIterations = v; } ),
|
||||
|
||||
new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)",
|
||||
0f,
|
||||
|
|
|
@ -154,6 +154,9 @@ public class BSTerrainManager
|
|||
|
||||
// The simulator wants to set a new heightmap for the terrain.
|
||||
public void SetTerrain(float[] heightMap) {
|
||||
float[] localHeightMap = heightMap;
|
||||
m_physicsScene.TaintedObject("TerrainManager.SetTerrain", delegate()
|
||||
{
|
||||
if (m_worldOffset != Vector3.Zero && m_parentScene != null)
|
||||
{
|
||||
// If a child of a mega-region, we shouldn't have any terrain allocated for us
|
||||
|
@ -165,7 +168,7 @@ public class BSTerrainManager
|
|||
DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}",
|
||||
BSScene.DetailLogZero, m_worldOffset, m_worldMax);
|
||||
((BSScene)m_parentScene).TerrainManager.UpdateOrCreateTerrain(BSScene.CHILDTERRAIN_ID,
|
||||
heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false);
|
||||
localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -173,8 +176,9 @@ public class BSTerrainManager
|
|||
// If not doing the mega-prim thing, just change the terrain
|
||||
DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero);
|
||||
|
||||
UpdateOrCreateTerrain(BSScene.TERRAIN_ID, heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false);
|
||||
UpdateOrCreateTerrain(BSScene.TERRAIN_ID, localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If called with no mapInfo for the terrain, this will create a new mapInfo and terrain
|
||||
|
@ -319,6 +323,8 @@ public class BSTerrainManager
|
|||
|
||||
// Make sure the new shape is processed.
|
||||
BulletSimAPI.Activate2(mapInfo.terrainBody.Ptr, true);
|
||||
|
||||
m_terrainModified = true;
|
||||
};
|
||||
|
||||
// There is the option to do the changes now (we're already in 'taint time'), or
|
||||
|
@ -357,6 +363,8 @@ public class BSTerrainManager
|
|||
m_heightMaps.Add(terrainRegionBase, mapInfo);
|
||||
// Build the terrain
|
||||
UpdateOrCreateTerrain(newTerrainID, heightMap, minCoords, maxCoords, true);
|
||||
|
||||
m_terrainModified = true;
|
||||
};
|
||||
|
||||
// If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time.
|
||||
|
@ -383,7 +391,7 @@ public class BSTerrainManager
|
|||
private float lastHeightTX = 999999f;
|
||||
private float lastHeightTY = 999999f;
|
||||
private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT;
|
||||
public float GetTerrainHeightAtXY(float tX, float tY)
|
||||
private float GetTerrainHeightAtXY(float tX, float tY)
|
||||
{
|
||||
// You'd be surprized at the number of times this routine is called
|
||||
// with the same parameters as last time.
|
||||
|
@ -403,11 +411,18 @@ public class BSTerrainManager
|
|||
{
|
||||
float regionX = tX - offsetX;
|
||||
float regionY = tY - offsetY;
|
||||
if (regionX >= mapInfo.sizeX || regionX < 0f) regionX = 0;
|
||||
if (regionY >= mapInfo.sizeY || regionY < 0f) regionY = 0;
|
||||
int mapIndex = (int)regionY * (int)mapInfo.sizeY + (int)regionX;
|
||||
try
|
||||
{
|
||||
ret = mapInfo.heightMap[mapIndex];
|
||||
m_terrainModified = false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Sometimes they give us wonky values of X and Y. Give a warning and return something.
|
||||
m_physicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, x={2}, y={3}",
|
||||
LogHeader, terrainBaseXY, regionX, regionY);
|
||||
ret = HEIGHT_GETHEIGHT_RET;
|
||||
}
|
||||
// DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXY,bX={1},baseY={2},szX={3},szY={4},regX={5},regY={6},index={7},ht={8}",
|
||||
// BSScene.DetailLogZero, offsetX, offsetY, mapInfo.sizeX, mapInfo.sizeY, regionX, regionY, mapIndex, ret);
|
||||
}
|
||||
|
@ -416,6 +431,7 @@ public class BSTerrainManager
|
|||
m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||
LogHeader, m_physicsScene.RegionName, tX, tY);
|
||||
}
|
||||
m_terrainModified = false;
|
||||
lastHeight = ret;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -213,6 +213,7 @@ public struct ConfigurationParameters
|
|||
public float linkConstraintTransMotorMaxForce;
|
||||
public float linkConstraintERP;
|
||||
public float linkConstraintCFM;
|
||||
public float linkConstraintSolverIterations;
|
||||
|
||||
public const float numericTrue = 1f;
|
||||
public const float numericFalse = 0f;
|
||||
|
@ -395,23 +396,6 @@ public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey);
|
|||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool CreateObject(uint worldID, ShapeData shapeData);
|
||||
|
||||
/* Remove old functionality
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void AddConstraint(uint worldID, uint id1, uint id2,
|
||||
Vector3 frame1, Quaternion frame1rot,
|
||||
Vector3 frame2, Quaternion frame2rot,
|
||||
Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool RemoveConstraintByID(uint worldID, uint id1);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2);
|
||||
*/
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern Vector3 GetObjectPosition(uint WorldID, uint id);
|
||||
|
||||
|
@ -544,6 +528,15 @@ public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape);
|
|||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateCompoundShape2(IntPtr sim);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void AddChildToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo);
|
||||
|
||||
|
@ -1010,7 +1003,7 @@ public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale);
|
|||
public static extern Vector3 GetLocalScaling2(IntPtr shape);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void CalculateLocalInertia2(IntPtr shape, float mass, Vector3 inertia);
|
||||
public static extern Vector3 CalculateLocalInertia2(IntPtr shape, float mass);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int GetShapeType2(IntPtr shape);
|
||||
|
|
Loading…
Reference in New Issue