update ubitODE to my current working state
parent
f451f67213
commit
0d51c42f59
|
@ -83,7 +83,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
private float m_linearMotorDecayTimescale = 120;
|
||||
private float m_linearMotorTimescale = 1000;
|
||||
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
|
||||
private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||
|
||||
//Angular properties
|
||||
|
@ -91,7 +90,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate
|
||||
private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate
|
||||
private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate
|
||||
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||
|
||||
//Deflection properties
|
||||
private float m_angularDeflectionEfficiency = 0;
|
||||
|
@ -102,7 +100,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
//Banking properties
|
||||
private float m_bankingEfficiency = 0;
|
||||
private float m_bankingMix = 0;
|
||||
private float m_bankingTimescale = 0;
|
||||
private float m_bankingTimescale = 1000;
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
private float m_VhoverHeight = 0f;
|
||||
|
@ -117,9 +115,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||
private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor.
|
||||
|
||||
// auxiliar
|
||||
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||
|
||||
// auxiliar
|
||||
private float m_lmEfect = 0; // current linear motor eficiency
|
||||
private float m_amEfect = 0; // current angular motor eficiency
|
||||
|
||||
|
@ -130,6 +127,82 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
_pParentScene = rootPrim._parent_scene;
|
||||
}
|
||||
|
||||
|
||||
public void DoSetVehicle(VehicleData vd)
|
||||
{
|
||||
|
||||
float timestep = _pParentScene.ODE_STEPSIZE;
|
||||
float invtimestep = 1.0f / timestep;
|
||||
|
||||
m_type = vd.m_type;
|
||||
m_flags = vd.m_flags;
|
||||
|
||||
// Linear properties
|
||||
m_linearMotorDirection = vd.m_linearMotorDirection;
|
||||
|
||||
m_linearFrictionTimescale = vd.m_linearFrictionTimescale;
|
||||
if (m_linearFrictionTimescale.X < timestep) m_linearFrictionTimescale.X = timestep;
|
||||
if (m_linearFrictionTimescale.Y < timestep) m_linearFrictionTimescale.Y = timestep;
|
||||
if (m_linearFrictionTimescale.Z < timestep) m_linearFrictionTimescale.Z = timestep;
|
||||
|
||||
m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale;
|
||||
if (m_linearMotorDecayTimescale < 0.5f) m_linearMotorDecayTimescale = 0.5f;
|
||||
m_linearMotorDecayTimescale *= invtimestep;
|
||||
|
||||
m_linearMotorTimescale = vd.m_linearMotorTimescale;
|
||||
if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep;
|
||||
|
||||
m_linearMotorOffset = vd.m_linearMotorOffset;
|
||||
|
||||
//Angular properties
|
||||
m_angularMotorDirection = vd.m_angularMotorDirection;
|
||||
m_angularMotorTimescale = vd.m_angularMotorTimescale;
|
||||
if (m_angularMotorTimescale < timestep) m_angularMotorTimescale = timestep;
|
||||
|
||||
m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale;
|
||||
if (m_angularMotorDecayTimescale < 0.5f) m_angularMotorDecayTimescale = 0.5f;
|
||||
m_angularMotorDecayTimescale *= invtimestep;
|
||||
|
||||
m_angularFrictionTimescale = vd.m_angularFrictionTimescale;
|
||||
if (m_angularFrictionTimescale.X < timestep) m_angularFrictionTimescale.X = timestep;
|
||||
if (m_angularFrictionTimescale.Y < timestep) m_angularFrictionTimescale.Y = timestep;
|
||||
if (m_angularFrictionTimescale.Z < timestep) m_angularFrictionTimescale.Z = timestep;
|
||||
|
||||
//Deflection properties
|
||||
m_angularDeflectionEfficiency = vd.m_angularDeflectionEfficiency;
|
||||
m_angularDeflectionTimescale = vd.m_angularDeflectionTimescale;
|
||||
if (m_angularDeflectionTimescale < timestep) m_angularDeflectionTimescale = timestep;
|
||||
|
||||
m_linearDeflectionEfficiency = vd.m_linearDeflectionEfficiency;
|
||||
m_linearDeflectionTimescale = vd.m_linearDeflectionTimescale;
|
||||
if (m_linearDeflectionTimescale < timestep) m_linearDeflectionTimescale = timestep;
|
||||
|
||||
//Banking properties
|
||||
m_bankingEfficiency = vd.m_bankingEfficiency;
|
||||
m_bankingMix = vd.m_bankingMix;
|
||||
m_bankingTimescale = vd.m_bankingTimescale;
|
||||
if (m_bankingTimescale < timestep) m_bankingTimescale = timestep;
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
m_VhoverHeight = vd.m_VhoverHeight;
|
||||
m_VhoverEfficiency = vd.m_VhoverEfficiency;
|
||||
m_VhoverTimescale = vd.m_VhoverTimescale;
|
||||
if (m_VhoverTimescale < timestep) m_VhoverTimescale = timestep;
|
||||
|
||||
m_VehicleBuoyancy = vd.m_VehicleBuoyancy;
|
||||
|
||||
//Attractor properties
|
||||
m_verticalAttractionEfficiency = vd.m_verticalAttractionEfficiency;
|
||||
m_verticalAttractionTimescale = vd.m_verticalAttractionTimescale;
|
||||
if (m_verticalAttractionTimescale < timestep) m_verticalAttractionTimescale = timestep;
|
||||
|
||||
// Axis
|
||||
m_referenceFrame = vd.m_referenceFrame;
|
||||
|
||||
m_lmEfect = 0;
|
||||
m_amEfect = 0;
|
||||
}
|
||||
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
float len;
|
||||
|
@ -231,6 +304,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if (len > 12.566f)
|
||||
m_angularMotorDirection *= (12.566f / len);
|
||||
m_amEfect = 1.0f; // turn it on
|
||||
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
|
||||
&& !rootPrim.m_isSelected && !rootPrim.m_disabled)
|
||||
d.BodyEnable(rootPrim.Body);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
|
@ -242,6 +318,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if (len > 30.0f)
|
||||
m_linearMotorDirection *= (30.0f / len);
|
||||
m_lmEfect = 1.0f; // turn it on
|
||||
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
|
||||
&& !rootPrim.m_isSelected && !rootPrim.m_disabled)
|
||||
d.BodyEnable(rootPrim.Body);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||
|
@ -273,6 +352,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if (len > 12.566f)
|
||||
m_angularMotorDirection *= (12.566f / len);
|
||||
m_amEfect = 1.0f; // turn it on
|
||||
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
|
||||
&& !rootPrim.m_isSelected && !rootPrim.m_disabled)
|
||||
d.BodyEnable(rootPrim.Body);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue.X < timestep) pValue.X = timestep;
|
||||
|
@ -286,6 +368,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if (len > 30.0f)
|
||||
m_linearMotorDirection *= (30.0f / len);
|
||||
m_lmEfect = 1.0f; // turn it on
|
||||
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
|
||||
&& !rootPrim.m_isSelected && !rootPrim.m_disabled)
|
||||
d.BodyEnable(rootPrim.Body);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
|
@ -347,12 +432,23 @@ 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 * invtimestep;
|
||||
m_linearMotorDecayTimescale = 120;
|
||||
m_angularMotorTimescale = 1000;
|
||||
m_angularMotorDecayTimescale = 1000 * invtimestep;
|
||||
m_angularMotorDecayTimescale = 1000;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 1;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
m_linearDeflectionEfficiency = 0;
|
||||
m_linearDeflectionTimescale = 1000;
|
||||
m_angularDeflectionEfficiency = 0;
|
||||
m_angularDeflectionTimescale = 1000;
|
||||
m_bankingEfficiency = 0;
|
||||
m_bankingMix = 1;
|
||||
m_bankingTimescale = 1000;
|
||||
m_verticalAttractionEfficiency = 0;
|
||||
m_verticalAttractionTimescale = 1000;
|
||||
|
||||
m_flags = (VehicleFlag)0;
|
||||
break;
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
| CollisionCategories.Body
|
||||
| CollisionCategories.Character
|
||||
);
|
||||
private bool m_collidesLand = true;
|
||||
// private bool m_collidesLand = true;
|
||||
private bool m_collidesWater;
|
||||
public bool m_returnCollisions;
|
||||
|
||||
|
@ -122,7 +122,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private CollisionCategories m_collisionFlags = m_default_collisionFlags;
|
||||
|
||||
public bool m_disabled;
|
||||
public bool m_taintselected;
|
||||
|
||||
|
||||
public uint m_localID;
|
||||
|
||||
|
@ -142,20 +142,19 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private List<OdePrim> childrenPrim = new List<OdePrim>();
|
||||
|
||||
private bool m_iscolliding;
|
||||
private bool m_wascolliding;
|
||||
private bool m_isSelected;
|
||||
|
||||
public bool m_isSelected;
|
||||
private bool m_delaySelect;
|
||||
private bool m_lastdoneSelected;
|
||||
public bool m_outbounds;
|
||||
|
||||
internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
|
||||
|
||||
private bool m_throttleUpdates;
|
||||
private int throttleCounter;
|
||||
public int m_interpenetrationcount;
|
||||
public float m_collisionscore;
|
||||
int m_colliderfilter = 0;
|
||||
public int m_roundsUnderMotionThreshold;
|
||||
private int m_crossingfailures;
|
||||
|
||||
public bool outofBounds;
|
||||
private float m_density = 10.000006836f; // Aluminum g/cm3;
|
||||
|
||||
public bool _zeroFlag;
|
||||
|
@ -166,12 +165,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private Vector3 _target_velocity;
|
||||
|
||||
public Vector3 primOOBsize; // prim real dimensions from mesh
|
||||
public Vector3 primOOBoffset; // is centroid out of mesh or rest aabb
|
||||
public Vector3 primOOBoffset; // its centroid out of mesh or rest aabb
|
||||
public float primOOBradiusSQ;
|
||||
public d.Mass primdMass; // prim inertia information on it's own referencial
|
||||
float primMass; // prim own mass
|
||||
float _mass; // object mass acording to case
|
||||
public d.Mass objectpMass; // object last computed inertia
|
||||
private bool hasOOBoffsetFromMesh = false; // if true we did compute it form mesh centroid, else from aabb
|
||||
|
||||
public int givefakepos = 0;
|
||||
|
@ -182,9 +180,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
public int m_eventsubscription;
|
||||
private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate();
|
||||
|
||||
private IntPtr m_linkJoint = IntPtr.Zero;
|
||||
private IntPtr _linkJointGroup = IntPtr.Zero;
|
||||
|
||||
public volatile bool childPrim;
|
||||
|
||||
public ODEDynamics m_vehicle;
|
||||
|
@ -264,7 +259,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
set
|
||||
{
|
||||
if (value)
|
||||
m_isSelected = value;
|
||||
m_isSelected = value; // if true set imediatly to stop moves etc
|
||||
AddChange(changes.Selected, value);
|
||||
}
|
||||
}
|
||||
|
@ -298,13 +293,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
m_iscolliding = false;
|
||||
else
|
||||
m_iscolliding = true;
|
||||
|
||||
if (m_wascolliding != m_iscolliding)
|
||||
{
|
||||
if (m_wascolliding && !m_isSelected && Body != IntPtr.Zero)
|
||||
d.BodyEnable(Body);
|
||||
m_wascolliding = m_iscolliding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -665,19 +653,21 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
strVehicleQuatParam fp = new strVehicleQuatParam();
|
||||
fp.param = param;
|
||||
fp.value = value;
|
||||
AddChange(changes.VehicleVectorParam, fp);
|
||||
AddChange(changes.VehicleRotationParam, fp);
|
||||
}
|
||||
|
||||
public override void VehicleFlags(int param, bool value)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
strVehicleBoolParam bp = new strVehicleBoolParam();
|
||||
bp.param = param;
|
||||
bp.value = value;
|
||||
AddChange(changes.VehicleFlags, bp);
|
||||
}
|
||||
|
||||
public override void SetVehicle(object vdata)
|
||||
{
|
||||
AddChange(changes.SetVehicle, vdata);
|
||||
}
|
||||
public void SetAcceleration(Vector3 accel)
|
||||
{
|
||||
_acceleration = accel;
|
||||
|
@ -710,8 +700,30 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
public override void CrossingFailure()
|
||||
{
|
||||
m_crossingfailures++;
|
||||
changeDisable(false);
|
||||
if (m_outbounds)
|
||||
{
|
||||
_position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f);
|
||||
_position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f);
|
||||
_position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f);
|
||||
|
||||
m_lastposition = _position;
|
||||
_velocity.X = 0;
|
||||
_velocity.Y = 0;
|
||||
_velocity.Z = 0;
|
||||
|
||||
m_lastVelocity = _velocity;
|
||||
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||
m_vehicle.Stop();
|
||||
|
||||
if(Body != IntPtr.Zero)
|
||||
d.BodySetLinearVel(Body, 0, 0, 0); // stop it
|
||||
if (prim_geom != IntPtr.Zero)
|
||||
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
|
||||
|
||||
m_outbounds = false;
|
||||
changeDisable(false);
|
||||
base.RequestPhysicsterseUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetMomentum(Vector3 momentum)
|
||||
|
@ -865,12 +877,14 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
m_force = Vector3.Zero;
|
||||
|
||||
m_iscolliding = false;
|
||||
m_wascolliding = false;
|
||||
m_colliderfilter = 0;
|
||||
|
||||
hasOOBoffsetFromMesh = false;
|
||||
_triMeshData = IntPtr.Zero;
|
||||
|
||||
m_lastdoneSelected = false;
|
||||
m_isSelected = false;
|
||||
m_delaySelect = false;
|
||||
|
||||
primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
|
||||
primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
|
||||
|
@ -885,8 +899,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private void resetCollisionAccounting()
|
||||
{
|
||||
m_collisionscore = 0;
|
||||
m_interpenetrationcount = 0;
|
||||
m_disabled = false;
|
||||
}
|
||||
|
||||
private void createAMotor(Vector3 axis)
|
||||
|
@ -926,9 +938,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
curr.W = dcur.W;
|
||||
Vector3 ax;
|
||||
|
||||
const int StopERP = 7;
|
||||
const int StopCFM = 8;
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
if (axis.X == 0)
|
||||
|
@ -943,10 +952,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f);
|
||||
d.JointSetAMotorParam(Amotor, (int)StopCFM, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)StopERP, 0.8f);
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f);
|
||||
i++;
|
||||
j = 256; // odeplugin.cs doesn't have all parameters so this moves to next axis set
|
||||
j = 256; // move to next axis set
|
||||
}
|
||||
|
||||
if (axis.Y == 0)
|
||||
|
@ -960,8 +969,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)StopCFM, 0f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)StopERP, 0.8f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
|
||||
i++;
|
||||
j += 256;
|
||||
}
|
||||
|
@ -977,8 +986,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)StopCFM, 0f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)StopERP, 0.8f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f);
|
||||
d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1186,24 +1195,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
public void enableBodySoft()
|
||||
{
|
||||
if (!childPrim)
|
||||
if (!childPrim && !m_isSelected)
|
||||
{
|
||||
if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
|
||||
{
|
||||
if (m_targetSpace != _parent_scene.ActiveSpace)
|
||||
{
|
||||
m_targetSpace = _parent_scene.ActiveSpace;
|
||||
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
{
|
||||
if (prm.prim_geom != IntPtr.Zero)
|
||||
{
|
||||
d.SpaceAdd(m_targetSpace, prm.prim_geom);
|
||||
prm.m_targetSpace = m_targetSpace;
|
||||
}
|
||||
}
|
||||
d.SpaceAdd(m_targetSpace, prim_geom);
|
||||
}
|
||||
d.GeomEnable(prim_geom);
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
d.GeomEnable(prm.prim_geom);
|
||||
|
@ -1211,6 +1206,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.BodyEnable(Body);
|
||||
}
|
||||
}
|
||||
m_disabled = false;
|
||||
resetCollisionAccounting(); // this sets m_disable to false
|
||||
}
|
||||
|
||||
|
@ -1221,19 +1217,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
{
|
||||
if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
|
||||
{
|
||||
if (m_targetSpace == _parent_scene.ActiveSpace)
|
||||
{
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
{
|
||||
if (prm.m_targetSpace != IntPtr.Zero && prm.prim_geom != IntPtr.Zero)
|
||||
{
|
||||
d.SpaceRemove(prm.m_targetSpace, prm.prim_geom);
|
||||
prm.m_targetSpace = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
d.SpaceRemove(m_targetSpace, prim_geom);
|
||||
m_targetSpace = IntPtr.Zero;
|
||||
}
|
||||
d.GeomDisable(prim_geom);
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
d.GeomDisable(prm.prim_geom);
|
||||
|
@ -1369,9 +1352,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.BodySetMass(Body, ref objdmass);
|
||||
_mass = objdmass.mass;
|
||||
|
||||
m_collisionCategories |= CollisionCategories.Body;
|
||||
m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
|
||||
|
||||
// disconnect from world gravity so we can apply buoyancy
|
||||
d.BodySetGravityMode(Body, false);
|
||||
|
||||
|
@ -1379,16 +1359,14 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
|
||||
// d.BodySetLinearDampingThreshold(Body, 0.01f);
|
||||
// d.BodySetAngularDampingThreshold(Body, 0.001f);
|
||||
d.BodySetDamping(Body, .001f, .0002f);
|
||||
d.BodySetDamping(Body, .002f, .002f);
|
||||
|
||||
m_collisionCategories |= CollisionCategories.Body;
|
||||
m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
|
||||
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
|
||||
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
|
||||
|
||||
m_interpenetrationcount = 0;
|
||||
m_collisionscore = 0;
|
||||
|
||||
m_disabled = false;
|
||||
|
||||
if (m_targetSpace != _parent_scene.ActiveSpace)
|
||||
{
|
||||
if (m_targetSpace != IntPtr.Zero)
|
||||
|
@ -1416,6 +1394,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
|
||||
d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
|
||||
d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
|
||||
prm.m_collisionscore = 0;
|
||||
|
||||
if (prm.m_targetSpace != _parent_scene.ActiveSpace)
|
||||
{
|
||||
|
@ -1428,10 +1407,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
prm.m_targetSpace = _parent_scene.ActiveSpace;
|
||||
d.SpaceAdd(m_targetSpace, prm.prim_geom);
|
||||
}
|
||||
d.GeomEnable(prm.prim_geom);
|
||||
|
||||
if (m_isSelected || m_disabled)
|
||||
d.GeomDisable(prm.prim_geom);
|
||||
|
||||
prm.m_disabled = false;
|
||||
prm.m_interpenetrationcount = 0;
|
||||
prm.m_collisionscore = 0;
|
||||
_parent_scene.addActivePrim(prm);
|
||||
}
|
||||
}
|
||||
|
@ -1442,8 +1422,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
createAMotor(m_angularlock);
|
||||
}
|
||||
|
||||
d.GeomEnable(prim_geom);
|
||||
m_disabled = false;
|
||||
if (m_isSelected || m_disabled)
|
||||
{
|
||||
d.GeomDisable(prim_geom);
|
||||
d.BodyDisable(Body);
|
||||
}
|
||||
|
||||
_parent_scene.addActivePrim(this);
|
||||
}
|
||||
|
||||
|
@ -1484,12 +1468,16 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
prm.m_collisionscore = 0;
|
||||
}
|
||||
}
|
||||
if (Amotor != IntPtr.Zero)
|
||||
{
|
||||
d.JointDestroy(Amotor);
|
||||
Amotor = IntPtr.Zero;
|
||||
}
|
||||
d.BodyDestroy(Body);
|
||||
}
|
||||
Body = IntPtr.Zero;
|
||||
}
|
||||
_mass = primMass;
|
||||
m_disabled = true;
|
||||
m_collisionscore = 0;
|
||||
}
|
||||
|
||||
|
@ -2115,49 +2103,72 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.BodySetTorque(Body, 0f, 0f, 0f);
|
||||
d.BodySetLinearVel(Body, 0f, 0f, 0f);
|
||||
d.BodySetAngularVel(Body, 0f, 0f, 0f);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void changeSelectedStatus(bool newval)
|
||||
{
|
||||
if (m_lastdoneSelected == newval)
|
||||
return;
|
||||
|
||||
m_lastdoneSelected = newval;
|
||||
DoSelectedStatus(newval);
|
||||
}
|
||||
|
||||
private void CheckDelaySelect()
|
||||
{
|
||||
if (m_delaySelect)
|
||||
{
|
||||
DoSelectedStatus(m_isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoSelectedStatus(bool newval)
|
||||
{
|
||||
m_isSelected = newval;
|
||||
Stop();
|
||||
|
||||
if (newval)
|
||||
{
|
||||
m_collisionCategories = CollisionCategories.Selected;
|
||||
m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
|
||||
if (!childPrim && Body != IntPtr.Zero)
|
||||
d.BodyDisable(Body);
|
||||
|
||||
if (prim_geom != IntPtr.Zero)
|
||||
if (m_delaySelect)
|
||||
{
|
||||
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
|
||||
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
|
||||
if (!childPrim)
|
||||
{
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
{
|
||||
d.GeomDisable(prm.prim_geom);
|
||||
prm.m_delaySelect = false;
|
||||
}
|
||||
}
|
||||
d.GeomDisable(prim_geom);
|
||||
m_delaySelect = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_delaySelect = true;
|
||||
}
|
||||
|
||||
disableBodySoft();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_collisionCategories = CollisionCategories.Geom;
|
||||
if (!childPrim && Body != IntPtr.Zero && !m_disabled)
|
||||
d.BodyEnable(Body);
|
||||
|
||||
if (m_isphysical)
|
||||
m_collisionCategories |= CollisionCategories.Body;
|
||||
|
||||
m_collisionFlags = m_default_collisionFlags;
|
||||
|
||||
if (m_collidesLand)
|
||||
m_collisionFlags |= CollisionCategories.Land;
|
||||
if (m_collidesWater)
|
||||
m_collisionFlags |= CollisionCategories.Water;
|
||||
|
||||
if (prim_geom != IntPtr.Zero)
|
||||
if (!childPrim)
|
||||
{
|
||||
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
|
||||
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
{
|
||||
if(!prm.m_disabled)
|
||||
d.GeomEnable(prm.prim_geom);
|
||||
prm.m_delaySelect = false;
|
||||
}
|
||||
}
|
||||
if(!m_disabled)
|
||||
d.GeomEnable(prim_geom);
|
||||
|
||||
enableBodySoft();
|
||||
m_delaySelect = false;
|
||||
}
|
||||
|
||||
resetCollisionAccounting();
|
||||
|
@ -2165,6 +2176,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
private void changePosition(Vector3 newPos)
|
||||
{
|
||||
CheckDelaySelect();
|
||||
if (m_isphysical)
|
||||
{
|
||||
if (childPrim) // inertia is messed, must rebuild
|
||||
|
@ -2207,6 +2219,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
private void changeOrientation(Quaternion newOri)
|
||||
{
|
||||
CheckDelaySelect();
|
||||
if (m_isphysical)
|
||||
{
|
||||
if (childPrim) // inertia is messed, must rebuild
|
||||
|
@ -2258,6 +2271,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
private void changePositionAndOrientation(Vector3 newPos, Quaternion newOri)
|
||||
{
|
||||
CheckDelaySelect();
|
||||
if (m_isphysical)
|
||||
{
|
||||
if (childPrim && m_building) // inertia is messed, must rebuild
|
||||
|
@ -2342,6 +2356,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
private void changePhysicsStatus(bool NewStatus)
|
||||
{
|
||||
CheckDelaySelect();
|
||||
|
||||
m_isphysical = NewStatus;
|
||||
|
||||
if (!childPrim)
|
||||
|
@ -2384,6 +2400,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
private void changeprimsizeshape()
|
||||
{
|
||||
CheckDelaySelect();
|
||||
|
||||
OdePrim parent = (OdePrim)_parent;
|
||||
|
||||
bool chp = childPrim;
|
||||
|
@ -2508,7 +2526,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
|
||||
m_collisionscore = 0;
|
||||
m_interpenetrationcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2528,7 +2545,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
}
|
||||
m_collisionscore = 0;
|
||||
m_interpenetrationcount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2565,6 +2581,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
else
|
||||
{
|
||||
m_building = false;
|
||||
CheckDelaySelect();
|
||||
if (!childPrim)
|
||||
MakeBody();
|
||||
}
|
||||
|
@ -2575,18 +2592,26 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
}
|
||||
|
||||
private void changeVehicleType(int value)
|
||||
public void changeSetVehicle(VehicleData vdata)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
m_vehicle = new ODEDynamics(this);
|
||||
m_vehicle.DoSetVehicle(vdata);
|
||||
}
|
||||
private void changeVehicleType(int value)
|
||||
{
|
||||
if (value == (int)Vehicle.TYPE_NONE)
|
||||
{
|
||||
if (value != (int)Vehicle.TYPE_NONE)
|
||||
{
|
||||
m_vehicle = new ODEDynamics(this);
|
||||
m_vehicle.ProcessTypeChange((Vehicle)value);
|
||||
}
|
||||
if (m_vehicle != null)
|
||||
m_vehicle = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
m_vehicle = new ODEDynamics(this);
|
||||
|
||||
m_vehicle.ProcessTypeChange((Vehicle)value);
|
||||
}
|
||||
}
|
||||
|
||||
private void changeVehicleFloatParam(strVehicleFloatParam fp)
|
||||
|
@ -2595,8 +2620,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
return;
|
||||
|
||||
m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
private void changeVehicleVectorParam(strVehicleVectorParam vp)
|
||||
|
@ -2604,8 +2627,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
private void changeVehicleRotationParam(strVehicleQuatParam qp)
|
||||
|
@ -2613,8 +2634,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
private void changeVehicleFlags(strVehicleBoolParam bp)
|
||||
|
@ -2622,8 +2641,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessVehicleFlags(bp.param, bp.value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -2849,41 +2866,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
{
|
||||
if (Body != IntPtr.Zero)
|
||||
{
|
||||
if (m_crossingfailures != 0 && m_crossingfailures < 5)
|
||||
{
|
||||
_position.X = Util.Clip(_position.X, 0.4f, _parent_scene.WorldExtents.X - 0.4f);
|
||||
_position.Y = Util.Clip(_position.Y, 0.4f, _parent_scene.WorldExtents.Y - 0.4f);
|
||||
_position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f);
|
||||
|
||||
float tmp = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y);
|
||||
if (_position.Z < tmp)
|
||||
_position.Z = tmp + 0.2f;
|
||||
|
||||
m_lastposition = _position;
|
||||
m_lastorientation = _orientation;
|
||||
_velocity.X = 0;
|
||||
_velocity.Y = 0;
|
||||
_velocity.Z = 0;
|
||||
|
||||
m_lastVelocity = _velocity;
|
||||
m_rotationalVelocity = _velocity;
|
||||
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||
m_vehicle.Stop();
|
||||
|
||||
m_crossingfailures = 0; // do this only once
|
||||
d.BodySetLinearVel(Body, 0, 0, 0); // stop it
|
||||
d.BodySetAngularVel(Body, 0, 0, 0);
|
||||
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
|
||||
enableBodySoft();
|
||||
base.RequestPhysicsterseUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
else if (m_crossingfailures != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 pv = Vector3.Zero;
|
||||
bool lastZeroFlag = _zeroFlag;
|
||||
|
||||
|
@ -2899,24 +2881,21 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
// we can't let it keeping moving and having colisions
|
||||
// since it can be stucked between something like terrain and edge
|
||||
// so lets stop and disable it until something else kicks it
|
||||
if (m_crossingfailures == 0)
|
||||
{
|
||||
|
||||
_position.X = Util.Clip(lpos.X, -0.5f, _parent_scene.WorldExtents.X + 0.5f);
|
||||
_position.Y = Util.Clip(lpos.Y, -0.5f, _parent_scene.WorldExtents.Y + 0.5f);
|
||||
_position.Z = Util.Clip(lpos.Z, -100f, 50000f);
|
||||
_position.X = Util.Clip(lpos.X, -0.2f, _parent_scene.WorldExtents.X + 0.2f);
|
||||
_position.Y = Util.Clip(lpos.Y, -0.2f, _parent_scene.WorldExtents.Y + 0.2f);
|
||||
_position.Z = Util.Clip(lpos.Z, -100f, 50000f);
|
||||
|
||||
m_lastposition = _position;
|
||||
m_lastorientation = _orientation;
|
||||
m_lastposition = _position;
|
||||
// m_lastorientation = _orientation;
|
||||
|
||||
d.BodySetLinearVel(Body, 0, 0, 0); // stop it
|
||||
d.BodySetAngularVel(Body, 0, 0, 0);
|
||||
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
|
||||
disableBodySoft(); // stop collisions
|
||||
m_crossingfailures++; // do this only once
|
||||
base.RequestPhysicsterseUpdate();
|
||||
d.BodySetLinearVel(Body, 0, 0, 0); // stop it
|
||||
// d.BodySetAngularVel(Body, 0, 0, 0);
|
||||
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
|
||||
disableBodySoft(); // stop collisions
|
||||
m_outbounds = true;
|
||||
base.RequestPhysicsterseUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpos.Z < -100 || lpos.Z > 100000f)
|
||||
|
@ -3159,6 +3138,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
else
|
||||
ChildRemove(this, false);
|
||||
|
||||
m_vehicle = null;
|
||||
RemoveGeom();
|
||||
m_targetSpace = IntPtr.Zero;
|
||||
if (m_eventsubscription > 0)
|
||||
|
@ -3273,6 +3253,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
changeVehicleRotationParam((strVehicleQuatParam) arg);
|
||||
break;
|
||||
|
||||
case changes.SetVehicle:
|
||||
changeSetVehicle((VehicleData) arg);
|
||||
break;
|
||||
case changes.Null:
|
||||
donullchange();
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* based on:
|
||||
* Ode.NET - .NET bindings for ODE
|
||||
|
|
|
@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
VehicleVectorParam,
|
||||
VehicleRotationParam,
|
||||
VehicleFlags,
|
||||
SetVehicle,
|
||||
|
||||
Null //keep this last used do dim the methods array. does nothing but pulsing the prim
|
||||
}
|
||||
|
@ -166,8 +167,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
float frictionMovementMult = 0.3f;
|
||||
|
||||
float TerrainBounce = 0.3f;
|
||||
float TerrainFriction = 0.3f;
|
||||
float TerrainBounce = 0.1f;
|
||||
float TerrainFriction = 0.1f;
|
||||
|
||||
public float AvatarBounce = 0.3f;
|
||||
public float AvatarFriction = 0;// 0.9f * 0.5f;
|
||||
|
@ -989,145 +990,62 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
/// <param name="timeStep"></param>
|
||||
private void collision_optimized()
|
||||
{
|
||||
// _perloopContact.Clear();
|
||||
// clear characts IsColliding until we do it some other way
|
||||
|
||||
lock (_characters)
|
||||
{
|
||||
foreach (OdeCharacter chr in _characters)
|
||||
try
|
||||
{
|
||||
foreach (OdeCharacter chr in _characters)
|
||||
{
|
||||
// this are odd checks if they are needed something is wrong elsewhere
|
||||
// keep for now
|
||||
if (chr == null)
|
||||
continue;
|
||||
if (chr == null || chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
|
||||
continue;
|
||||
|
||||
if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
|
||||
continue;
|
||||
|
||||
chr.IsColliding = false;
|
||||
// chr.CollidingGround = false; not done here
|
||||
chr.CollidingObj = false;
|
||||
chr.IsColliding = false;
|
||||
// chr.CollidingGround = false; not done here
|
||||
chr.CollidingObj = false;
|
||||
// do colisions with static space
|
||||
d.SpaceCollide2(StaticSpace, chr.Shell, IntPtr.Zero, nearCallback);
|
||||
}
|
||||
}
|
||||
|
||||
// now let ode do its job
|
||||
// colide active things amoung them
|
||||
|
||||
int st = Util.EnvironmentTickCount();
|
||||
int ta;
|
||||
int ts;
|
||||
try
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Unable to collide Character to static space");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// collide active prims with static enviroment
|
||||
lock (_activeprims)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (OdePrim prm in _activeprims)
|
||||
{
|
||||
if (d.BodyIsEnabled(prm.Body))
|
||||
d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback);
|
||||
}
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space");
|
||||
}
|
||||
}
|
||||
|
||||
// finally colide active things amoung them
|
||||
try
|
||||
{
|
||||
d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
|
||||
}
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Unable to Active space collide");
|
||||
}
|
||||
ta = Util.EnvironmentTickCountSubtract(st);
|
||||
// then active things with static enviroment
|
||||
try
|
||||
{
|
||||
d.SpaceCollide2(ActiveSpace,StaticSpace, IntPtr.Zero, nearCallback);
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Unable to Active to static space collide");
|
||||
}
|
||||
ts = Util.EnvironmentTickCountSubtract(st);
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Unable to collide in Active space");
|
||||
}
|
||||
|
||||
// _perloopContact.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public float GetTerrainHeightAtXY(float x, float y)
|
||||
{
|
||||
// assumes 1m size grid and constante size square regions
|
||||
// region offset in mega position
|
||||
|
||||
int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
|
||||
int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
|
||||
|
||||
IntPtr heightFieldGeom = IntPtr.Zero;
|
||||
|
||||
// get region map
|
||||
if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom))
|
||||
return 0f;
|
||||
|
||||
if (heightFieldGeom == IntPtr.Zero)
|
||||
return 0f;
|
||||
|
||||
if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
|
||||
return 0f;
|
||||
|
||||
// TerrainHeightField for ODE as offset 1m
|
||||
x += 1f - offsetX;
|
||||
y += 1f - offsetY;
|
||||
|
||||
// make position fit into array
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
|
||||
// integer indexs
|
||||
int ix;
|
||||
int iy;
|
||||
// interpolators offset
|
||||
float dx;
|
||||
float dy;
|
||||
|
||||
int regsize = (int)Constants.RegionSize + 2; // map size see setterrain
|
||||
|
||||
// we still have square fixed size regions
|
||||
// also flip x and y because of how map is done for ODE fliped axis
|
||||
// so ix,iy,dx and dy are inter exchanged
|
||||
if (x < regsize - 1)
|
||||
{
|
||||
iy = (int)x;
|
||||
dy = x - (float)iy;
|
||||
}
|
||||
else // out world use external height
|
||||
{
|
||||
iy = regsize - 1;
|
||||
dy = 0;
|
||||
}
|
||||
if (y < regsize - 1)
|
||||
{
|
||||
ix = (int)y;
|
||||
dx = y - (float)ix;
|
||||
}
|
||||
else
|
||||
{
|
||||
ix = regsize - 1;
|
||||
dx = 0;
|
||||
}
|
||||
|
||||
float h0;
|
||||
float h1;
|
||||
float h2;
|
||||
|
||||
iy *= regsize;
|
||||
iy += ix; // all indexes have iy + ix
|
||||
|
||||
float[] heights = TerrainHeightFieldHeights[heightFieldGeom];
|
||||
|
||||
if ((dx + dy) <= 1.0f)
|
||||
{
|
||||
h0 = ((float)heights[iy]); // 0,0 vertice
|
||||
h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
|
||||
h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
|
||||
}
|
||||
else
|
||||
{
|
||||
h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
|
||||
h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
|
||||
h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
|
||||
}
|
||||
|
||||
return h0 + h1 + h2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add actor to the list that should receive collision events in the simulate loop.
|
||||
|
@ -1835,273 +1753,94 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
get { return (false); }
|
||||
}
|
||||
|
||||
#region ODE Specific Terrain Fixes
|
||||
public float[] ResizeTerrain512NearestNeighbour(float[] heightMap)
|
||||
public float GetTerrainHeightAtXY(float x, float y)
|
||||
{
|
||||
float[] returnarr = new float[262144];
|
||||
float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y];
|
||||
// assumes 1m size grid and constante size square regions
|
||||
// needs to know about sims around in future
|
||||
// region offset in mega position
|
||||
|
||||
// Filling out the array into its multi-dimensional components
|
||||
for (int y = 0; y < WorldExtents.Y; y++)
|
||||
int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
|
||||
int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize;
|
||||
|
||||
IntPtr heightFieldGeom = IntPtr.Zero;
|
||||
|
||||
// get region map
|
||||
if (!RegionTerrain.TryGetValue(new Vector3(offsetX, offsetY, 0), out heightFieldGeom))
|
||||
return 0f;
|
||||
|
||||
if (heightFieldGeom == IntPtr.Zero)
|
||||
return 0f;
|
||||
|
||||
if (!TerrainHeightFieldHeights.ContainsKey(heightFieldGeom))
|
||||
return 0f;
|
||||
|
||||
// TerrainHeightField for ODE as offset 1m
|
||||
x += 1f - offsetX;
|
||||
y += 1f - offsetY;
|
||||
|
||||
// make position fit into array
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
|
||||
// integer indexs
|
||||
int ix;
|
||||
int iy;
|
||||
// interpolators offset
|
||||
float dx;
|
||||
float dy;
|
||||
|
||||
int regsize = (int)Constants.RegionSize + 3; // map size see setterrain number of samples
|
||||
|
||||
// we still have square fixed size regions
|
||||
// also flip x and y because of how map is done for ODE fliped axis
|
||||
// so ix,iy,dx and dy are inter exchanged
|
||||
if (x < regsize - 1)
|
||||
{
|
||||
for (int x = 0; x < WorldExtents.X; x++)
|
||||
{
|
||||
resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x];
|
||||
}
|
||||
iy = (int)x;
|
||||
dy = x - (float)iy;
|
||||
}
|
||||
else // out world use external height
|
||||
{
|
||||
iy = regsize - 1;
|
||||
dy = 0;
|
||||
}
|
||||
if (y < regsize - 1)
|
||||
{
|
||||
ix = (int)y;
|
||||
dx = y - (float)ix;
|
||||
}
|
||||
else
|
||||
{
|
||||
ix = regsize - 1;
|
||||
dx = 0;
|
||||
}
|
||||
|
||||
// Resize using Nearest Neighbour
|
||||
float h0;
|
||||
float h1;
|
||||
float h2;
|
||||
|
||||
// This particular way is quick but it only works on a multiple of the original
|
||||
iy *= regsize;
|
||||
iy += ix; // all indexes have iy + ix
|
||||
|
||||
// The idea behind this method can be described with the following diagrams
|
||||
// second pass and third pass happen in the same loop really.. just separated
|
||||
// them to show what this does.
|
||||
float[] heights = TerrainHeightFieldHeights[heightFieldGeom];
|
||||
|
||||
// First Pass
|
||||
// ResultArr:
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
|
||||
// Second Pass
|
||||
// ResultArr2:
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
|
||||
// Third pass fills in the blanks
|
||||
// ResultArr2:
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
|
||||
// X,Y = .
|
||||
// X+1,y = ^
|
||||
// X,Y+1 = *
|
||||
// X+1,Y+1 = #
|
||||
|
||||
// Filling in like this;
|
||||
// .*
|
||||
// ^#
|
||||
// 1st .
|
||||
// 2nd *
|
||||
// 3rd ^
|
||||
// 4th #
|
||||
// on single loop.
|
||||
|
||||
float[,] resultarr2 = new float[512, 512];
|
||||
for (int y = 0; y < WorldExtents.Y; y++)
|
||||
if ((dx + dy) <= 1.0f)
|
||||
{
|
||||
for (int x = 0; x < WorldExtents.X; x++)
|
||||
{
|
||||
resultarr2[y * 2, x * 2] = resultarr[y, x];
|
||||
|
||||
if (y < WorldExtents.Y)
|
||||
{
|
||||
resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x];
|
||||
}
|
||||
if (x < WorldExtents.X)
|
||||
{
|
||||
resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x];
|
||||
}
|
||||
if (x < WorldExtents.X && y < WorldExtents.Y)
|
||||
{
|
||||
resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x];
|
||||
}
|
||||
}
|
||||
h0 = ((float)heights[iy]); // 0,0 vertice
|
||||
h1 = (((float)heights[iy + 1]) - h0) * dx; // 1,0 vertice minus 0,0
|
||||
h2 = (((float)heights[iy + regsize]) - h0) * dy; // 0,1 vertice minus 0,0
|
||||
}
|
||||
else
|
||||
{
|
||||
h0 = ((float)heights[iy + regsize + 1]); // 1,1 vertice
|
||||
h1 = (((float)heights[iy + 1]) - h0) * (1 - dy); // 1,1 vertice minus 1,0
|
||||
h2 = (((float)heights[iy + regsize]) - h0) * (1 - dx); // 1,1 vertice minus 0,1
|
||||
}
|
||||
|
||||
//Flatten out the array
|
||||
int i = 0;
|
||||
for (int y = 0; y < 512; y++)
|
||||
{
|
||||
for (int x = 0; x < 512; x++)
|
||||
{
|
||||
if (resultarr2[y, x] <= 0)
|
||||
returnarr[i] = 0.0000001f;
|
||||
else
|
||||
returnarr[i] = resultarr2[y, x];
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return returnarr;
|
||||
return h0 + h1 + h2;
|
||||
}
|
||||
|
||||
public float[] ResizeTerrain512Interpolation(float[] heightMap)
|
||||
{
|
||||
float[] returnarr = new float[262144];
|
||||
float[,] resultarr = new float[512,512];
|
||||
|
||||
// Filling out the array into its multi-dimensional components
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
for (int x = 0; x < 256; x++)
|
||||
{
|
||||
resultarr[y, x] = heightMap[y * 256 + x];
|
||||
}
|
||||
}
|
||||
|
||||
// Resize using interpolation
|
||||
|
||||
// This particular way is quick but it only works on a multiple of the original
|
||||
|
||||
// The idea behind this method can be described with the following diagrams
|
||||
// second pass and third pass happen in the same loop really.. just separated
|
||||
// them to show what this does.
|
||||
|
||||
// First Pass
|
||||
// ResultArr:
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1
|
||||
|
||||
// Second Pass
|
||||
// ResultArr2:
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
// ,,,,,,,,,,
|
||||
// 1,,1,,1,,1,,1,,1,
|
||||
|
||||
// Third pass fills in the blanks
|
||||
// ResultArr2:
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
// 1,1,1,1,1,1,1,1,1,1,1,1
|
||||
|
||||
// X,Y = .
|
||||
// X+1,y = ^
|
||||
// X,Y+1 = *
|
||||
// X+1,Y+1 = #
|
||||
|
||||
// Filling in like this;
|
||||
// .*
|
||||
// ^#
|
||||
// 1st .
|
||||
// 2nd *
|
||||
// 3rd ^
|
||||
// 4th #
|
||||
// on single loop.
|
||||
|
||||
float[,] resultarr2 = new float[512,512];
|
||||
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||
{
|
||||
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||
{
|
||||
resultarr2[y*2, x*2] = resultarr[y, x];
|
||||
|
||||
if (y < (int)Constants.RegionSize)
|
||||
{
|
||||
if (y + 1 < (int)Constants.RegionSize)
|
||||
{
|
||||
if (x + 1 < (int)Constants.RegionSize)
|
||||
{
|
||||
resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
|
||||
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
||||
}
|
||||
else
|
||||
{
|
||||
resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
|
||||
}
|
||||
}
|
||||
if (x < (int)Constants.RegionSize)
|
||||
{
|
||||
if (x + 1 < (int)Constants.RegionSize)
|
||||
{
|
||||
if (y + 1 < (int)Constants.RegionSize)
|
||||
{
|
||||
resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
|
||||
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
||||
}
|
||||
else
|
||||
{
|
||||
resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
|
||||
}
|
||||
}
|
||||
if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize)
|
||||
{
|
||||
if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize))
|
||||
{
|
||||
resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
|
||||
resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
|
||||
}
|
||||
else
|
||||
{
|
||||
resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Flatten out the array
|
||||
int i = 0;
|
||||
for (int y = 0; y < 512; y++)
|
||||
{
|
||||
for (int x = 0; x < 512; x++)
|
||||
{
|
||||
if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x]))
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Non finite heightfield element detected. Setting it to 0");
|
||||
resultarr2[y, x] = 0;
|
||||
}
|
||||
returnarr[i] = resultarr2[y, x];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return returnarr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override void SetTerrain(float[] heightMap)
|
||||
{
|
||||
if (m_worldOffset != Vector3.Zero && m_parentScene != null)
|
||||
|
@ -2124,48 +1863,47 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
public void SetTerrain(float[] heightMap, Vector3 pOffset)
|
||||
{
|
||||
// assumes 1m size grid and constante size square regions
|
||||
// needs to know about sims around in future
|
||||
|
||||
float[] _heightmap;
|
||||
_heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))];
|
||||
|
||||
uint heightmapWidth = Constants.RegionSize + 2;
|
||||
uint heightmapHeight = Constants.RegionSize + 2;
|
||||
|
||||
uint heightmapWidthSamples;
|
||||
uint heightmapWidthSamples = heightmapWidth + 1;
|
||||
uint heightmapHeightSamples = heightmapHeight + 1;
|
||||
|
||||
uint heightmapHeightSamples;
|
||||
|
||||
heightmapWidthSamples = (uint)Constants.RegionSize + 2;
|
||||
heightmapHeightSamples = (uint)Constants.RegionSize + 2;
|
||||
_heightmap = new float[heightmapWidthSamples * heightmapHeightSamples];
|
||||
|
||||
const float scale = 1.0f;
|
||||
const float offset = 0.0f;
|
||||
const float thickness = 10f;
|
||||
const int wrap = 0;
|
||||
|
||||
int regionsize = (int) Constants.RegionSize + 2;
|
||||
uint regionsize = Constants.RegionSize;
|
||||
|
||||
float hfmin = float.MaxValue;
|
||||
float hfmax = float.MinValue;
|
||||
float val;
|
||||
int xx;
|
||||
int yy;
|
||||
uint xx;
|
||||
uint yy;
|
||||
|
||||
int maxXXYY = regionsize - 3;
|
||||
uint maxXXYY = regionsize - 1;
|
||||
// flipping map adding one margin all around so things don't fall in edges
|
||||
|
||||
int xt = 0;
|
||||
uint xt = 0;
|
||||
xx = 0;
|
||||
|
||||
for (int x = 0; x < heightmapWidthSamples; x++)
|
||||
for (uint x = 0; x < heightmapWidthSamples; x++)
|
||||
{
|
||||
if (x > 1 && xx < maxXXYY)
|
||||
xx++;
|
||||
yy = 0;
|
||||
for (int y = 0; y < heightmapHeightSamples; y++)
|
||||
for (uint y = 0; y < heightmapHeightSamples; y++)
|
||||
{
|
||||
if (y > 1 && y < maxXXYY)
|
||||
yy += (int)Constants.RegionSize;
|
||||
yy += regionsize;
|
||||
|
||||
val = heightMap[yy + xx];
|
||||
_heightmap[xt + y] = val;
|
||||
|
@ -2176,8 +1914,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
hfmax = val;
|
||||
|
||||
}
|
||||
|
||||
xt += regionsize;
|
||||
xt += heightmapHeightSamples;
|
||||
}
|
||||
lock (OdeLock)
|
||||
{
|
||||
|
@ -2230,11 +1967,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
|
||||
d.GeomSetRotation(GroundGeom, ref R);
|
||||
d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0);
|
||||
IntPtr testGround = IntPtr.Zero;
|
||||
if (RegionTerrain.TryGetValue(pOffset, out testGround))
|
||||
{
|
||||
RegionTerrain.Remove(pOffset);
|
||||
}
|
||||
RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
|
||||
// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
|
||||
TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);
|
||||
|
|
Loading…
Reference in New Issue