Merge branch 'ubitwork'

avinationmerge
Melanie 2012-04-04 23:57:09 +02:00
commit 6378abb966
6 changed files with 462 additions and 145 deletions

View File

@ -2181,7 +2181,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public void setAngularImpulse(Vector3 impulse)
public void ApplyAngularImpulse(Vector3 impulse)
{
PhysicsActor pa = RootPart.PhysActor;
@ -2189,7 +2189,7 @@ namespace OpenSim.Region.Framework.Scenes
{
if (!IsAttachment)
{
pa.Torque = impulse;
pa.AddAngularForce(impulse, true);
m_scene.PhysicsScene.AddPhysicsActorTaint(pa);
}
}

View File

@ -1789,7 +1789,7 @@ namespace OpenSim.Region.Framework.Scenes
impulse = newimpulse;
}
ParentGroup.setAngularImpulse(impulse);
ParentGroup.ApplyAngularImpulse(impulse);
}
/// <summary>
@ -2153,26 +2153,26 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentGroup.RootPart == this)
AngularVelocity = new Vector3(0, 0, 0);
if (PhysActor.Phantom)
if (pa.Phantom)
{
RemoveFromPhysics();
return;
}
PhysActor.IsPhysical = UsePhysics;
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
PhysActor.delink();
pa.IsPhysical = UsePhysics;
pa.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
pa.OnOutOfBounds -= PhysicsOutOfBounds;
pa.delink();
if (ParentGroup.Scene.PhysicsScene.SupportsNINJAJoints)
{
// destroy all joints connected to this now deactivated body
ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(PhysActor);
ParentGroup.Scene.PhysicsScene.RemoveAllJointsConnectedToActorThreadLocked(pa);
}
}
}
if (PhysActor.IsPhysical != UsePhysics)
PhysActor.IsPhysical = UsePhysics;
if (pa.IsPhysical != UsePhysics)
pa.IsPhysical = UsePhysics;
if (UsePhysics)
{
@ -2186,26 +2186,19 @@ namespace OpenSim.Region.Framework.Scenes
if (ParentID != 0 && ParentID != LocalId)
{
ParentGroup.Scene.AddPhysicalPrim(1);
PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
pa.OnOutOfBounds += PhysicsOutOfBounds;
if (ParentID != 0 && ParentID != LocalId)
if (parentPa != null)
{
PhysicsActor parentPa = ParentGroup.RootPart.PhysActor;
if (parentPa != null)
{
pa.link(parentPa);
}
pa.link(parentPa);
}
}
}
}
bool phan = ((Flags & PrimFlags.Phantom) != 0);
if (PhysActor.Phantom != phan)
PhysActor.Phantom = phan;
if (pa.Phantom != phan)
pa.Phantom = phan;
// If this part is a sculpt then delay the physics update until we've asynchronously loaded the
@ -2327,7 +2320,10 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor pa = PhysActor;
if (pa != null)
return new Vector3(pa.CenterOfMass.X, pa.CenterOfMass.Y, pa.CenterOfMass.Z);
{
Vector3 vtmp = pa.CenterOfMass;
return vtmp;
}
else
return new Vector3(0, 0, 0);
}
@ -3531,18 +3527,12 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor pa = PhysActor;
if (pa != null)
pa.FloatOnWater = floatYN == 1;
pa.FloatOnWater = (floatYN == 1);
}
public void SetForce(Vector3 force)
{
Force = force;
/*
if (PhysActor != null)
{
PhysActor.Force = force;
}
*/
}
public SOPVehicle sopVehicle
@ -5073,33 +5063,32 @@ namespace OpenSim.Region.Framework.Scenes
}
PhysicsActor pa = PhysActor;
if (
((AggregateScriptEvents & scriptEvents.collision) != 0) ||
((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
(CollisionSound != UUID.Zero)
)
if (pa != null)
{
// subscribe to physics updates.
if (pa != null)
const scriptEvents NeededSubsEvents = (
scriptEvents.collision | scriptEvents.collision_start| scriptEvents.collision_end |
scriptEvents.land_collision | scriptEvents.land_collision_start | scriptEvents.land_collision_end
);
if (
// ((AggregateScriptEvents & scriptEvents.collision) != 0) ||
// ((AggregateScriptEvents & scriptEvents.collision_end) != 0) ||
// ((AggregateScriptEvents & scriptEvents.collision_start) != 0) ||
// ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
// ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
// ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
((AggregateScriptEvents & NeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
)
{
// subscribe to physics updates.
pa.OnCollisionUpdate += PhysicsCollision;
pa.SubscribeEvents(1000);
}
}
else
{
if (pa != null)
else
{
pa.UnSubscribeEvents();
pa.OnCollisionUpdate -= PhysicsCollision;
}
}
//if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
//{
// ParentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;

View File

@ -137,7 +137,6 @@ namespace OpenSim.Region.Physics.OdePlugin
public bool bad = false;
float mu;
float bounce;
public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float density, float walk_divisor, float rundivisor)
{
@ -170,7 +169,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_mass = 80f; // sure we have a default
mu = parent_scene.AvatarFriction;
bounce = parent_scene.AvatarBounce;
walkDivisor = walk_divisor;
runDivisor = rundivisor;
@ -194,7 +192,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void getContactData(ref ContactData cdata)
{
cdata.mu = mu;
cdata.bounce = bounce;
cdata.bounce = 0;
cdata.softcolide = false;
}

View File

@ -153,7 +153,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_linearFrictionTimescale.Z < timestep) m_linearFrictionTimescale.Z = timestep;
m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale;
if (m_linearMotorDecayTimescale < 0.5f) m_linearMotorDecayTimescale = 0.5f;
if (m_linearMotorDecayTimescale < timestep) m_linearMotorDecayTimescale = timestep;
m_linearMotorDecayTimescale *= invtimestep;
m_linearMotorTimescale = vd.m_linearMotorTimescale;
@ -168,7 +168,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_angularMotorTimescale < timestep) m_angularMotorTimescale = timestep;
m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale;
if (m_angularMotorDecayTimescale < 0.5f) m_angularMotorDecayTimescale = 0.5f;
if (m_angularMotorDecayTimescale < timestep) m_angularMotorDecayTimescale = timestep;
m_angularMotorDecayTimescale *= invtimestep;
m_angularFrictionTimescale = vd.m_angularFrictionTimescale;
@ -230,9 +230,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_angularDeflectionTimescale = pValue;
break;
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
// if (pValue < timestep) pValue = timestep;
if (pValue < timestep) pValue = timestep;
// try to make impulses to work a bit better
if (pValue < 0.5f) pValue = 0.5f;
// if (pValue < 0.5f) pValue = 0.5f;
else if (pValue > 120) pValue = 120;
m_angularMotorDecayTimescale = pValue * invtimestep;
break;
@ -281,9 +281,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_linearDeflectionTimescale = pValue;
break;
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
// if (pValue < timestep) pValue = timestep;
if (pValue < timestep) pValue = timestep;
// try to make impulses to work a bit better
if (pValue < 0.5f) pValue = 0.5f;
//if (pValue < 0.5f) pValue = 0.5f;
else if (pValue > 120) pValue = 120;
m_linearMotorDecayTimescale = pValue * invtimestep;
break;
@ -444,9 +444,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
m_linearMotorTimescale = 1000;
m_linearMotorDecayTimescale = 120;
m_linearMotorDecayTimescale = 120 * invtimestep;
m_angularMotorTimescale = 1000;
m_angularMotorDecayTimescale = 1000;
m_angularMotorDecayTimescale = 1000 * invtimestep;
m_VhoverHeight = 0;
m_VhoverEfficiency = 1;
m_VhoverTimescale = 1000;
@ -901,7 +901,11 @@ namespace OpenSim.Region.Physics.OdePlugin
GetRollPitch(irotq, out roll, out pitch);
float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE;
float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE;
float ftmp2;
if (m_bankingEfficiency == 0)
ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE;
else
ftmp2 = 0;
if (roll > halfpi)
roll = pi - roll;

View File

@ -70,6 +70,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_fakeisphantom;
protected bool m_building;
protected bool m_forcePosOrRotation;
private Quaternion m_lastorientation = new Quaternion();
private Quaternion _orientation;
@ -128,9 +130,10 @@ namespace OpenSim.Region.Physics.OdePlugin
public bool m_disabled;
public uint m_localID;
private IMesh m_mesh;
private object m_meshlock = new object();
private PrimitiveBaseShape _pbs;
public OdeScene _parent_scene;
@ -482,6 +485,24 @@ namespace OpenSim.Region.Physics.OdePlugin
{
set
{
/*
IMesh mesh = null;
if (_parent_scene.needsMeshing(value))
{
bool convex;
if (m_shapetype == 0)
convex = false;
else
convex = true;
mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex);
}
if (mesh != null)
{
lock (m_meshlock)
m_mesh = mesh;
}
*/
AddChange(changes.Shape, value);
}
}
@ -497,7 +518,8 @@ namespace OpenSim.Region.Physics.OdePlugin
m_shapetype = value;
AddChange(changes.Shape, null);
}
}
}
public override Vector3 Velocity
{
@ -947,6 +969,19 @@ namespace OpenSim.Region.Physics.OdePlugin
CalcPrimBodyData();
m_mesh = null;
if (_parent_scene.needsMeshing(pbs))
{
bool convex;
if (m_shapetype == 0)
convex = false;
else
convex = true;
m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex);
}
m_building = true; // control must set this to false when done
AddChange(changes.Add, null);
@ -1049,6 +1084,10 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool setMesh(OdeScene parent_scene)
{
IntPtr vertices, indices;
int vertexCount, indexCount;
int vertexStride, triStride;
if (Body != IntPtr.Zero)
{
if (childPrim)
@ -1065,39 +1104,51 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
bool convex;
if (m_shapetype == 0)
convex = false;
else
convex = true;
IMesh mesh = null;
IMesh mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true,convex);
if (mesh == null)
lock (m_meshlock)
{
m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z);
return false;
}
if (m_mesh == null)
{
bool convex;
if (m_shapetype == 0)
convex = false;
else
convex = true;
IntPtr vertices, indices;
int vertexCount, indexCount;
int vertexStride, triStride;
mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex);
}
else
{
mesh = m_mesh;
}
mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
if (mesh == null)
{
m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z);
return false;
}
mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
if (vertexCount == 0 || indexCount == 0)
{
m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}",
Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
mesh.releaseSourceMeshData();
return false;
}
primOOBoffset = mesh.GetCentroid();
hasOOBoffsetFromMesh = true;
if (vertexCount == 0 || indexCount == 0)
{
m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}",
Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
mesh.releaseSourceMeshData();
return false;
m_mesh = null;
}
primOOBoffset = mesh.GetCentroid();
hasOOBoffsetFromMesh = true;
mesh.releaseSourceMeshData();
IntPtr geo = IntPtr.Zero;
try
@ -1429,7 +1480,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.RfromQ(out mymat, ref myrot);
d.MassRotate(ref objdmass, ref mymat);
// set the body rotation and position
// set the body rotation
d.BodySetRotation(Body, ref mymat);
// recompute full object inertia if needed
@ -1725,6 +1776,215 @@ namespace OpenSim.Region.Physics.OdePlugin
m_collisionscore = 0;
}
private void FixInertia(Vector3 NewPos,Quaternion newrot)
{
d.Matrix3 mat = new d.Matrix3();
d.Quaternion quat = new d.Quaternion();
d.Mass tmpdmass = new d.Mass { };
d.Mass objdmass = new d.Mass { };
d.BodyGetMass(Body, out tmpdmass);
objdmass = tmpdmass;
d.Vector3 dobjpos;
d.Vector3 thispos;
// get current object position and rotation
dobjpos = d.BodyGetPosition(Body);
// get prim own inertia in its local frame
tmpdmass = primdMass;
// transform to object frame
mat = d.GeomGetOffsetRotation(prim_geom);
d.MassRotate(ref tmpdmass, ref mat);
thispos = d.GeomGetOffsetPosition(prim_geom);
d.MassTranslate(ref tmpdmass,
thispos.X,
thispos.Y,
thispos.Z);
// subtract current prim inertia from object
DMassSubPartFromObj(ref tmpdmass, ref objdmass);
// back prim own inertia
tmpdmass = primdMass;
// update to new position and orientation
_position = NewPos;
d.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z);
_orientation = newrot;
quat.X = newrot.X;
quat.Y = newrot.Y;
quat.Z = newrot.Z;
quat.W = newrot.W;
d.GeomSetOffsetWorldQuaternion(prim_geom, ref quat);
mat = d.GeomGetOffsetRotation(prim_geom);
d.MassRotate(ref tmpdmass, ref mat);
thispos = d.GeomGetOffsetPosition(prim_geom);
d.MassTranslate(ref tmpdmass,
thispos.X,
thispos.Y,
thispos.Z);
d.MassAdd(ref objdmass, ref tmpdmass);
// fix all positions
IntPtr g = d.BodyGetFirstGeom(Body);
while (g != IntPtr.Zero)
{
thispos = d.GeomGetOffsetPosition(g);
thispos.X -= objdmass.c.X;
thispos.Y -= objdmass.c.Y;
thispos.Z -= objdmass.c.Z;
d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z);
g = d.dBodyGetNextGeom(g);
}
d.BodyVectorToWorld(Body,objdmass.c.X, objdmass.c.Y, objdmass.c.Z,out thispos);
d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z);
d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body
d.BodySetMass(Body, ref objdmass);
_mass = objdmass.mass;
}
private void FixInertia(Vector3 NewPos)
{
d.Matrix3 primmat = new d.Matrix3();
d.Mass tmpdmass = new d.Mass { };
d.Mass objdmass = new d.Mass { };
d.Mass primmass = new d.Mass { };
d.Vector3 dobjpos;
d.Vector3 thispos;
d.BodyGetMass(Body, out objdmass);
// get prim own inertia in its local frame
primmass = primdMass;
// transform to object frame
primmat = d.GeomGetOffsetRotation(prim_geom);
d.MassRotate(ref primmass, ref primmat);
tmpdmass = primmass;
thispos = d.GeomGetOffsetPosition(prim_geom);
d.MassTranslate(ref tmpdmass,
thispos.X,
thispos.Y,
thispos.Z);
// subtract current prim inertia from object
DMassSubPartFromObj(ref tmpdmass, ref objdmass);
// update to new position
_position = NewPos;
d.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z);
thispos = d.GeomGetOffsetPosition(prim_geom);
d.MassTranslate(ref primmass,
thispos.X,
thispos.Y,
thispos.Z);
d.MassAdd(ref objdmass, ref primmass);
// fix all positions
IntPtr g = d.BodyGetFirstGeom(Body);
while (g != IntPtr.Zero)
{
thispos = d.GeomGetOffsetPosition(g);
thispos.X -= objdmass.c.X;
thispos.Y -= objdmass.c.Y;
thispos.Z -= objdmass.c.Z;
d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z);
g = d.dBodyGetNextGeom(g);
}
d.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos);
// get current object position and rotation
dobjpos = d.BodyGetPosition(Body);
d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z);
d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body
d.BodySetMass(Body, ref objdmass);
_mass = objdmass.mass;
}
private void FixInertia(Quaternion newrot)
{
d.Matrix3 mat = new d.Matrix3();
d.Quaternion quat = new d.Quaternion();
d.Mass tmpdmass = new d.Mass { };
d.Mass objdmass = new d.Mass { };
d.Vector3 dobjpos;
d.Vector3 thispos;
d.BodyGetMass(Body, out objdmass);
// get prim own inertia in its local frame
tmpdmass = primdMass;
mat = d.GeomGetOffsetRotation(prim_geom);
d.MassRotate(ref tmpdmass, ref mat);
// transform to object frame
thispos = d.GeomGetOffsetPosition(prim_geom);
d.MassTranslate(ref tmpdmass,
thispos.X,
thispos.Y,
thispos.Z);
// subtract current prim inertia from object
DMassSubPartFromObj(ref tmpdmass, ref objdmass);
// update to new orientation
_orientation = newrot;
quat.X = newrot.X;
quat.Y = newrot.Y;
quat.Z = newrot.Z;
quat.W = newrot.W;
d.GeomSetOffsetWorldQuaternion(prim_geom, ref quat);
tmpdmass = primdMass;
mat = d.GeomGetOffsetRotation(prim_geom);
d.MassRotate(ref tmpdmass, ref mat);
d.MassTranslate(ref tmpdmass,
thispos.X,
thispos.Y,
thispos.Z);
d.MassAdd(ref objdmass, ref tmpdmass);
// fix all positions
IntPtr g = d.BodyGetFirstGeom(Body);
while (g != IntPtr.Zero)
{
thispos = d.GeomGetOffsetPosition(g);
thispos.X -= objdmass.c.X;
thispos.Y -= objdmass.c.Y;
thispos.Z -= objdmass.c.Z;
d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z);
g = d.dBodyGetNextGeom(g);
}
d.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos);
// get current object position and rotation
dobjpos = d.BodyGetPosition(Body);
d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z);
d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body
d.BodySetMass(Body, ref objdmass);
_mass = objdmass.mass;
}
#region Mass Calculation
private float CalculatePrimVolume()
@ -2126,17 +2386,18 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (prim_geom != IntPtr.Zero)
{
d.Vector3 lpos;
d.GeomCopyPosition(prim_geom, out lpos);
_position.X = lpos.X;
_position.Y = lpos.Y;
_position.Z = lpos.Z;
d.Quaternion qtmp = new d.Quaternion { };
d.GeomCopyQuaternion(prim_geom, out qtmp);
_orientation.W = qtmp.W;
_orientation.X = qtmp.X;
_orientation.Y = qtmp.Y;
_orientation.Z = qtmp.Z;
d.Vector3 lpos;
d.GeomCopyPosition(prim_geom, out lpos);
_position.X = lpos.X;
_position.Y = lpos.Y;
_position.Z = lpos.Z;
}
}
@ -2593,6 +2854,13 @@ namespace OpenSim.Region.Physics.OdePlugin
{
_position = newPos;
}
else if (m_forcePosOrRotation && _position != newPos && Body != IntPtr.Zero)
{
FixInertia(newPos);
if (!d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
}
else
{
@ -2637,6 +2905,14 @@ namespace OpenSim.Region.Physics.OdePlugin
{
_orientation = newOri;
}
/*
else if (m_forcePosOrRotation && _orientation != newOri && Body != IntPtr.Zero)
{
FixInertia(_position, newOri);
if (!d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
*/
}
else
{
@ -3512,6 +3788,29 @@ namespace OpenSim.Region.Physics.OdePlugin
dst.I.M22 = src.I.M22;
}
internal static void DMassSubPartFromObj(ref d.Mass part, ref d.Mass theobj)
{
// assumes object center of mass is zero
float smass = part.mass;
theobj.mass -= smass;
smass *= 1.0f / (theobj.mass); ;
theobj.c.X -= part.c.X * smass;
theobj.c.Y -= part.c.Y * smass;
theobj.c.Z -= part.c.Z * smass;
theobj.I.M00 -= part.I.M00;
theobj.I.M01 -= part.I.M01;
theobj.I.M02 -= part.I.M02;
theobj.I.M10 -= part.I.M10;
theobj.I.M11 -= part.I.M11;
theobj.I.M12 -= part.I.M12;
theobj.I.M20 -= part.I.M20;
theobj.I.M21 -= part.I.M21;
theobj.I.M22 -= part.I.M22;
}
private static void DMassDup(ref d.Mass src, out d.Mass dst)
{
dst = new d.Mass { };

View File

@ -160,8 +160,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private Random fluidRandomizer = new Random(Environment.TickCount);
const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce;
const float comumContactERP = 0.6f;
const float comumSoftContactERP = 0.1f;
const float MaxERP = 0.8f;
const float minERP = 0.1f;
const float comumContactCFM = 0.0001f;
float frictionMovementMult = 0.3f;
@ -169,7 +169,6 @@ namespace OpenSim.Region.Physics.OdePlugin
float TerrainBounce = 0.1f;
float TerrainFriction = 0.3f;
public float AvatarBounce = 0.3f;
public float AvatarFriction = 0;// 0.9f * 0.5f;
private const uint m_regionWidth = Constants.RegionSize;
@ -528,7 +527,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// sets a global contact for a joint for contactgeom , and base contact description)
private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce, bool softerp)
private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce,float cfm,float erp)
{
if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath)
return IntPtr.Zero;
@ -546,11 +545,8 @@ namespace OpenSim.Region.Physics.OdePlugin
newcontact.surface.mode = comumContactFlags;
newcontact.surface.mu = mu;
newcontact.surface.bounce = bounce;
newcontact.surface.soft_cfm = comumContactCFM;
if (softerp)
newcontact.surface.soft_erp = comumSoftContactERP;
else
newcontact.surface.soft_erp = comumContactERP;
newcontact.surface.soft_cfm = cfm;
newcontact.surface.soft_erp = erp;
IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf));
Marshal.StructureToPtr(newcontact, contact, true);
@ -694,9 +690,11 @@ namespace OpenSim.Region.Physics.OdePlugin
// big messy collision analises
float mu = 0;
float bounce = 0;
float cfm = 0.0001f;
float erp = 0.1f;
ContactData contactdata1 = new ContactData(0, 0, false);
ContactData contactdata2 = new ContactData(0, 0, false);
bool erpSoft = false;
String name = null;
bool dop1foot = false;
@ -706,59 +704,65 @@ namespace OpenSim.Region.Physics.OdePlugin
switch (p1.PhysicsActorType)
{
case (int)ActorTypes.Agent:
switch (p2.PhysicsActorType)
{
case (int)ActorTypes.Agent:
p1.getContactData(ref contactdata1);
p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
bounce = 0;
mu = 0;
cfm = 0.0001f;
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult;
switch (p2.PhysicsActorType)
{
case (int)ActorTypes.Agent:
/*
p1.getContactData(ref contactdata1);
p2.getContactData(ref contactdata2);
erpSoft = contactdata1.softcolide | contactdata2.softcolide;
p1.CollidingObj = true;
p2.CollidingObj = true;
break;
case (int)ActorTypes.Prim:
p1.getContactData(ref contactdata1);
p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult;
if (p2.Velocity.LengthSquared() > 0.0f)
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult;
*/
p1.CollidingObj = true;
p2.CollidingObj = true;
break;
case (int)ActorTypes.Prim:
/*
p1.getContactData(ref contactdata1);
p2.getContactData(ref contactdata2);
erpSoft = contactdata1.softcolide | contactdata2.softcolide;
dop1foot = true;
break;
default:
ignore=true; // avatar to terrain and water ignored
break;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult;
*/
if (p2.Velocity.LengthSquared() > 0.0f)
p2.CollidingObj = true;
dop1foot = true;
break;
default:
ignore = true; // avatar to terrain and water ignored
break;
}
break;
}
break;
case (int)ActorTypes.Prim:
switch (p2.PhysicsActorType)
{
case (int)ActorTypes.Agent:
p1.getContactData(ref contactdata1);
p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce;
// p1.getContactData(ref contactdata1);
// p2.getContactData(ref contactdata2);
bounce = 0;
mu = 0;
cfm = 0.0001f;
/*
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult;
erpSoft = contactdata1.softcolide | contactdata2.softcolide;
*/
dop2foot = true;
if (p1.Velocity.LengthSquared() > 0.0f)
p1.CollidingObj = true;
@ -772,9 +776,16 @@ namespace OpenSim.Region.Physics.OdePlugin
p1.getContactData(ref contactdata1);
p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce;
erpSoft = contactdata1.softcolide | contactdata2.softcolide;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
cfm = p1.Mass;
if (cfm > p2.Mass)
cfm = p2.Mass;
cfm = (float)Math.Sqrt(cfm);
cfm *= 0.0001f;
if (cfm > 0.8f)
cfm = 0.8f;
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult;
@ -789,12 +800,17 @@ namespace OpenSim.Region.Physics.OdePlugin
mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction);
if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f)
mu *= frictionMovementMult;
erpSoft = contactdata1.softcolide;
p1.CollidingGround = true;
cfm = p1.Mass;
cfm = (float)Math.Sqrt(cfm);
cfm *= 0.0001f;
if (cfm > 0.8f)
cfm = 0.8f;
}
else if (name == "Water")
{
erpSoft = true;
ignore = true;
}
}
else
@ -814,7 +830,11 @@ namespace OpenSim.Region.Physics.OdePlugin
p2.getContactData(ref contactdata2);
bounce = contactdata2.bounce * TerrainBounce;
mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction);
erpSoft = contactdata2.softcolide;
cfm = p2.Mass;
cfm = (float)Math.Sqrt(cfm);
cfm *= 0.0001f;
if (cfm > 0.8f)
cfm = 0.8f;
if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f)
mu *= frictionMovementMult;
@ -826,7 +846,7 @@ namespace OpenSim.Region.Physics.OdePlugin
else if (name == "Water" &&
(p2.PhysicsActorType == (int)ActorTypes.Prim || p2.PhysicsActorType == (int)ActorTypes.Agent))
{
erpSoft = true;
ignore = true;
}
}
else
@ -847,7 +867,14 @@ namespace OpenSim.Region.Physics.OdePlugin
if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f)
p2.IsColliding = true;
Joint = CreateContacJoint(ref curContact, mu, bounce, erpSoft);
erp = curContact.depth;
if (erp < minERP)
erp = minERP;
else if (erp > MaxERP)
erp = MaxERP;
Joint = CreateContacJoint(ref curContact, mu, bounce,cfm,erp);
d.JointAttach(Joint, b1, b2);
if (++m_global_contactcount >= maxContactsbeforedeath)