avatar collision plane send to viewer is only relative to feet. change
avatar collider, just rounding the boxes, etcavinationmerge
parent
b6d29aa124
commit
de3180a63e
|
@ -3465,6 +3465,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
|
ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event called by the physics plugin to tell the avatar about a collision.
|
/// Event called by the physics plugin to tell the avatar about a collision.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3494,7 +3495,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
|
CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
|
||||||
Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
|
Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
|
||||||
|
|
||||||
CollisionPlane = Vector4.UnitW;
|
|
||||||
|
|
||||||
// // No collisions at all means we may be flying. Update always
|
// // No collisions at all means we may be flying. Update always
|
||||||
// // to make falling work
|
// // to make falling work
|
||||||
|
@ -3504,6 +3504,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// m_lastColCount = coldata.Count;
|
// m_lastColCount = coldata.Count;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
CollisionPlane = Vector4.UnitW;
|
||||||
|
|
||||||
if (coldata.Count != 0)
|
if (coldata.Count != 0)
|
||||||
{
|
{
|
||||||
switch (Animator.CurrentMovementAnimation)
|
switch (Animator.CurrentMovementAnimation)
|
||||||
|
@ -3517,17 +3519,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ContactPoint lowest;
|
ContactPoint lowest;
|
||||||
lowest.SurfaceNormal = Vector3.Zero;
|
lowest.SurfaceNormal = Vector3.Zero;
|
||||||
lowest.Position = Vector3.Zero;
|
lowest.Position = Vector3.Zero;
|
||||||
lowest.Position.Z = Single.NaN;
|
lowest.Position.Z = float.MaxValue;
|
||||||
|
|
||||||
foreach (ContactPoint contact in coldata.Values)
|
foreach (ContactPoint contact in coldata.Values)
|
||||||
{
|
{
|
||||||
if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z)
|
|
||||||
|
if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
|
||||||
{
|
{
|
||||||
lowest = contact;
|
lowest = contact;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
|
if (lowest.Position.Z != float.MaxValue)
|
||||||
|
{
|
||||||
|
lowest.SurfaceNormal = -lowest.SurfaceNormal;
|
||||||
|
CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
public Vector3 SurfaceNormal;
|
public Vector3 SurfaceNormal;
|
||||||
public float PenetrationDepth;
|
public float PenetrationDepth;
|
||||||
public float RelativeSpeed;
|
public float RelativeSpeed;
|
||||||
|
public bool CharacterFeet;
|
||||||
|
|
||||||
public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
|
public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
|
||||||
{
|
{
|
||||||
|
@ -68,6 +69,7 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
SurfaceNormal = surfaceNormal;
|
SurfaceNormal = surfaceNormal;
|
||||||
PenetrationDepth = penetrationDepth;
|
PenetrationDepth = penetrationDepth;
|
||||||
RelativeSpeed = 0f; // for now let this one be set explicity
|
RelativeSpeed = 0f; // for now let this one be set explicity
|
||||||
|
CharacterFeet = true; // keep other plugins work as before
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,18 +84,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private float m_mass = 80f;
|
private float m_mass = 80f;
|
||||||
public float m_density = 60f;
|
public float m_density = 60f;
|
||||||
private bool m_pidControllerActive = true;
|
private bool m_pidControllerActive = true;
|
||||||
public float PID_D = 800.0f;
|
|
||||||
public float PID_P = 900.0f;
|
|
||||||
//private static float POSTURE_SERVO = 10000.0f;
|
|
||||||
|
|
||||||
|
const float basePID_D = 0.55f; // scaled for unit mass unit time (2200 /(50*80))
|
||||||
private float m_invElipSizeX;
|
const float basePID_P = 0.225f; // scaled for unit mass unit time (900 /(50*80))
|
||||||
private float m_invElipSizeY;
|
public float PID_D;
|
||||||
|
public float PID_P;
|
||||||
|
|
||||||
private float feetOff = 0;
|
private float feetOff = 0;
|
||||||
private float feetSZ = 0.5f;
|
private float feetSZ = 0.5f;
|
||||||
const float feetScale = 0.9f;
|
const float feetScale = 0.8f;
|
||||||
const float invFeetScale = 1.0f / 0.9f;
|
|
||||||
const float sizeZAdjust = 0.18f;
|
const float sizeZAdjust = 0.18f;
|
||||||
private float boneOff = 0;
|
private float boneOff = 0;
|
||||||
|
|
||||||
|
@ -160,7 +157,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pid_d, float pid_p, float density, float walk_divisor, float rundivisor)
|
public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float density, float walk_divisor, float rundivisor)
|
||||||
{
|
{
|
||||||
m_uuid = UUID.Random();
|
m_uuid = UUID.Random();
|
||||||
|
|
||||||
|
@ -184,8 +181,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
_parent_scene = parent_scene;
|
_parent_scene = parent_scene;
|
||||||
|
|
||||||
PID_D = pid_d;
|
|
||||||
PID_P = pid_p;
|
|
||||||
|
|
||||||
m_size.X = pSize.X;
|
m_size.X = pSize.X;
|
||||||
m_size.Y = pSize.Y;
|
m_size.Y = pSize.Y;
|
||||||
|
@ -204,6 +199,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// force lower density for testing
|
// force lower density for testing
|
||||||
m_density = 3.0f;
|
m_density = 3.0f;
|
||||||
|
|
||||||
|
m_density *= 1.4f; // scale to have mass similar to capsule
|
||||||
|
|
||||||
mu = parent_scene.AvatarFriction;
|
mu = parent_scene.AvatarFriction;
|
||||||
|
|
||||||
walkDivisor = walk_divisor;
|
walkDivisor = walk_divisor;
|
||||||
|
@ -211,6 +208,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default
|
m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default
|
||||||
|
|
||||||
|
PID_D = basePID_D * m_mass / parent_scene.ODE_STEPSIZE;
|
||||||
|
PID_P = basePID_P * m_mass / parent_scene.ODE_STEPSIZE;
|
||||||
|
|
||||||
m_isPhysical = false; // current status: no ODE information exists
|
m_isPhysical = false; // current status: no ODE information exists
|
||||||
|
|
||||||
Name = avName;
|
Name = avName;
|
||||||
|
@ -491,7 +491,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return m_density * m_size.X * m_size.Y * m_size.Z;
|
return m_mass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override void link(PhysicsActor obj)
|
public override void link(PhysicsActor obj)
|
||||||
|
@ -671,23 +671,22 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
|
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
|
||||||
{
|
{
|
||||||
// sizes one day should came from visual parameters
|
// sizes one day should came from visual parameters
|
||||||
|
float sx = m_size.X;
|
||||||
|
float sy = m_size.Y;
|
||||||
float sz = m_size.Z + sizeZAdjust;
|
float sz = m_size.Z + sizeZAdjust;
|
||||||
|
|
||||||
m_invElipSizeX = 1.0f / m_size.X;
|
float topsx = sx * 0.9f;
|
||||||
m_invElipSizeY = 1.0f / m_size.Y;
|
float midsx = sx;
|
||||||
|
float feetsx = sx * feetScale;
|
||||||
|
float bonesx = sx * 0.2f;
|
||||||
|
|
||||||
float topsx = m_size.X * 0.9f;
|
float topsy = sy * 0.4f;
|
||||||
float midsx = m_size.X;
|
float midsy = sy;
|
||||||
float feetsx = m_size.X * feetScale;
|
float feetsy = sy * feetScale * 0.8f;
|
||||||
float bonesx = feetsx * 0.2f;
|
|
||||||
|
|
||||||
float topsy = m_size.Y * 0.4f;
|
|
||||||
float midsy = m_size.Y;
|
|
||||||
float feetsy = m_size.Y * feetScale;
|
|
||||||
float bonesy = feetsy * 0.2f;
|
float bonesy = feetsy * 0.2f;
|
||||||
|
|
||||||
float topsz = sz * 0.15f;
|
float topsz = sz * 0.15f;
|
||||||
float feetsz = sz * 0.3f;
|
float feetsz = sz * 0.45f;
|
||||||
if (feetsz > 0.6f)
|
if (feetsz > 0.6f)
|
||||||
feetsz = 0.6f;
|
feetsz = 0.6f;
|
||||||
|
|
||||||
|
@ -726,22 +725,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories);
|
d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories);
|
||||||
d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags);
|
d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags);
|
||||||
|
|
||||||
d.MassSetBox(out ShellMass, m_density, m_size.X , m_size.Y, m_size.Z);
|
m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass
|
||||||
|
|
||||||
m_mass = ShellMass.mass; // update mass
|
d.MassSetBoxTotal(out ShellMass, m_mass, m_size.X, m_size.Y, m_size.Z);
|
||||||
|
|
||||||
// rescale PID parameters
|
PID_D = basePID_D * m_mass / _parent_scene.ODE_STEPSIZE;
|
||||||
PID_D = _parent_scene.avPIDD;
|
PID_P = basePID_P * m_mass / _parent_scene.ODE_STEPSIZE;
|
||||||
PID_P = _parent_scene.avPIDP;
|
|
||||||
|
|
||||||
// rescale PID parameters so that this aren't affected by mass
|
|
||||||
// and so don't get unstable for some masses
|
|
||||||
// also scale by ode time step so you don't need to refix them
|
|
||||||
|
|
||||||
PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
|
|
||||||
PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
|
|
||||||
PID_P /= 50 * 80;
|
|
||||||
PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
|
|
||||||
|
|
||||||
Body = d.BodyCreate(_parent_scene.world);
|
Body = d.BodyCreate(_parent_scene.world);
|
||||||
|
|
||||||
|
@ -857,8 +846,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact)
|
public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision)
|
||||||
{
|
{
|
||||||
|
feetcollision = false;
|
||||||
|
|
||||||
if (me == bonebox) // inner bone
|
if (me == bonebox) // inner bone
|
||||||
{
|
{
|
||||||
|
@ -870,44 +860,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (me == topbox) // keep a box head
|
if (me == topbox) // keep a box head
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// rotate elipsoide assuming only rotation around Z
|
float t;
|
||||||
float ca = m_orientation.W * m_orientation.W - m_orientation.Z * m_orientation.Z;
|
|
||||||
float sa = 2 * m_orientation.W * m_orientation.Z;
|
|
||||||
|
|
||||||
float isx;
|
|
||||||
float isy;
|
|
||||||
|
|
||||||
if (me == feetbox) // feet have narrow bounds
|
|
||||||
{
|
|
||||||
|
|
||||||
isx = m_invElipSizeX * invFeetScale;
|
|
||||||
isy = m_invElipSizeY * invFeetScale;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isx = m_invElipSizeX;
|
|
||||||
isy = m_invElipSizeY;
|
|
||||||
}
|
|
||||||
|
|
||||||
float a = isx * ca - isy * sa;
|
|
||||||
float b = isx * sa + isy * ca;
|
|
||||||
|
|
||||||
float offx = contact.pos.X - _position.X;
|
float offx = contact.pos.X - _position.X;
|
||||||
float er = offx * a;
|
|
||||||
er *= er;
|
|
||||||
|
|
||||||
float offy = contact.pos.Y - _position.Y;
|
float offy = contact.pos.Y - _position.Y;
|
||||||
float ty = offy * b;
|
|
||||||
er += ty * ty;
|
|
||||||
|
|
||||||
if (me == midbox)
|
if (me == midbox)
|
||||||
{
|
{
|
||||||
if (er > 4.0f) // no collision
|
t = offx * offx + offy * offy;
|
||||||
return false;
|
|
||||||
if (er < 0.2f)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
float t = offx * offx + offy * offy;
|
|
||||||
t = (float)Math.Sqrt(t);
|
t = (float)Math.Sqrt(t);
|
||||||
t = 1 / t;
|
t = 1 / t;
|
||||||
offx *= t;
|
offx *= t;
|
||||||
|
@ -930,24 +889,36 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
else if (me == feetbox)
|
else if (me == feetbox)
|
||||||
{
|
{
|
||||||
float c = feetSZ * 2;
|
|
||||||
float h = contact.pos.Z - _position.Z;
|
float h = contact.pos.Z - _position.Z;
|
||||||
|
|
||||||
|
if (Math.Abs(contact.normal.Z) > 0.95f)
|
||||||
|
{
|
||||||
|
feetcollision = true;
|
||||||
|
if (h < boneOff)
|
||||||
|
IsColliding = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
float offz = h - feetOff; // distance from top of feetbox
|
float offz = h - feetOff; // distance from top of feetbox
|
||||||
|
|
||||||
float tz = offz / c;
|
if (offz > 0)
|
||||||
er += tz * tz;
|
|
||||||
|
|
||||||
if (er > 4.0f) // no collision
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (er > 0.2f)
|
if (offz > -0.01)
|
||||||
{
|
{
|
||||||
float t = offx * offx + offy * offy + offz * offz;
|
offx = 0;
|
||||||
|
offy = 0;
|
||||||
|
offz = -1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = offx * offx + offy * offy + offz * offz;
|
||||||
t = (float)Math.Sqrt(t);
|
t = (float)Math.Sqrt(t);
|
||||||
t = 1 / t;
|
t = 1 / t;
|
||||||
offx *= t;
|
offx *= t;
|
||||||
offy *= t;
|
offy *= t;
|
||||||
offz *= t;
|
offz *= t;
|
||||||
|
}
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
{
|
{
|
||||||
|
@ -961,8 +932,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
contact.normal.Y = -offy;
|
contact.normal.Y = -offy;
|
||||||
contact.normal.Z = -offz;
|
contact.normal.Z = -offz;
|
||||||
}
|
}
|
||||||
}
|
feetcollision = true;
|
||||||
|
|
||||||
if (h < boneOff)
|
if (h < boneOff)
|
||||||
IsColliding = true;
|
IsColliding = true;
|
||||||
}
|
}
|
||||||
|
@ -1105,6 +1075,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
contact.SurfaceNormal.Y = 0f;
|
contact.SurfaceNormal.Y = 0f;
|
||||||
contact.SurfaceNormal.Z = -1f;
|
contact.SurfaceNormal.Z = -1f;
|
||||||
contact.RelativeSpeed = -vel.Z;
|
contact.RelativeSpeed = -vel.Z;
|
||||||
|
contact.CharacterFeet = true;
|
||||||
AddCollisionEvent(0, contact);
|
AddCollisionEvent(0, contact);
|
||||||
|
|
||||||
vec.Z *= 0.5f;
|
vec.Z *= 0.5f;
|
||||||
|
|
|
@ -224,9 +224,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// private IntPtr WaterHeightmapData = IntPtr.Zero;
|
// private IntPtr WaterHeightmapData = IntPtr.Zero;
|
||||||
// private GCHandle WaterMapHandler = new GCHandle();
|
// private GCHandle WaterMapHandler = new GCHandle();
|
||||||
|
|
||||||
public float avPIDD = 2200f; // make it visible
|
|
||||||
public float avPIDP = 900f; // make it visible
|
|
||||||
private float avCapRadius = 0.37f;
|
|
||||||
private float avDensity = 3f;
|
private float avDensity = 3f;
|
||||||
private float avMovementDivisorWalk = 1.3f;
|
private float avMovementDivisorWalk = 1.3f;
|
||||||
private float avMovementDivisorRun = 0.8f;
|
private float avMovementDivisorRun = 0.8f;
|
||||||
|
@ -486,7 +483,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
avDensity = physicsconfig.GetFloat("av_density", avDensity);
|
avDensity = physicsconfig.GetFloat("av_density", avDensity);
|
||||||
avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
|
avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
|
||||||
avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
|
avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
|
||||||
avCapRadius = physicsconfig.GetFloat("av_capsule_radius", avCapRadius);
|
|
||||||
|
|
||||||
contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
|
contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
|
||||||
|
|
||||||
|
@ -1040,6 +1036,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
IntPtr Joint;
|
IntPtr Joint;
|
||||||
|
|
||||||
|
bool FeetCollision = false;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int ncontacts = 0;
|
int ncontacts = 0;
|
||||||
while(true)
|
while(true)
|
||||||
|
@ -1058,7 +1056,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
if(dop1foot)
|
if(dop1foot)
|
||||||
{
|
{
|
||||||
if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact)))
|
if (!(((OdeCharacter)p1).Collide(g1, false, ref curContact, ref FeetCollision)))
|
||||||
{
|
{
|
||||||
if (++i >= count)
|
if (++i >= count)
|
||||||
break;
|
break;
|
||||||
|
@ -1068,7 +1066,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
else if(dop2foot)
|
else if(dop2foot)
|
||||||
{
|
{
|
||||||
if(!(((OdeCharacter) p2).Collide(g2,true,ref curContact)))
|
if (!(((OdeCharacter)p2).Collide(g2, true, ref curContact, ref FeetCollision)))
|
||||||
{
|
{
|
||||||
if (++i >= count)
|
if (++i >= count)
|
||||||
break;
|
break;
|
||||||
|
@ -1178,8 +1176,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ncontacts > 0)
|
if (ncontacts > 0)
|
||||||
|
{
|
||||||
|
maxDepthContact.CharacterFeet = FeetCollision;
|
||||||
collision_accounting_events(p1, p2, maxDepthContact);
|
collision_accounting_events(p1, p2, maxDepthContact);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
if (notskipedcount > geomContactPointsStartthrottle)
|
if (notskipedcount > geomContactPointsStartthrottle)
|
||||||
{
|
{
|
||||||
|
@ -1393,7 +1393,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
pos.X = position.X;
|
pos.X = position.X;
|
||||||
pos.Y = position.Y;
|
pos.Y = position.Y;
|
||||||
pos.Z = position.Z;
|
pos.Z = position.Z;
|
||||||
OdeCharacter newAv = new OdeCharacter(avName, this, pos, size, avPIDD, avPIDP, avDensity, avMovementDivisorWalk, avMovementDivisorRun);
|
OdeCharacter newAv = new OdeCharacter(avName, this, pos, size, avDensity, avMovementDivisorWalk, avMovementDivisorRun);
|
||||||
newAv.Flying = isFlying;
|
newAv.Flying = isFlying;
|
||||||
newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
|
newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue