* Fix an over compensation for bounciness on flat Primitive
* Implement the linear impulse portion of llPushObject. We should have a lsl compatible implementation of that portion of the push. Angular.. well. still have yet to implement a torque accumulator. * llPushObject respects the region and parcel settings for Restrict Push, it also respects GodMode as is defined in the LSL spec.0.6.0-stable
parent
739f1591da
commit
0916b38b83
|
@ -634,8 +634,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (pushforce)
|
if (pushforce)
|
||||||
{
|
{
|
||||||
m_pidControllerActive = false;
|
m_pidControllerActive = false;
|
||||||
|
force *= 100f;
|
||||||
doForce(force);
|
doForce(force);
|
||||||
|
//System.Console.WriteLine("Push!");
|
||||||
//_target_velocity.X += force.X;
|
//_target_velocity.X += force.X;
|
||||||
// _target_velocity.Y += force.Y;
|
// _target_velocity.Y += force.Y;
|
||||||
//_target_velocity.Z += force.Z;
|
//_target_velocity.Z += force.Z;
|
||||||
|
|
|
@ -575,10 +575,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (checkDupe(contacts[i],p2.PhysicsActorType))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_collision_depth = (contacts[i].depth > max_collision_depth) ? contacts[i].depth : max_collision_depth;
|
max_collision_depth = (contacts[i].depth > max_collision_depth) ? contacts[i].depth : max_collision_depth;
|
||||||
//m_log.Warn("[CCOUNT]: " + count);
|
//m_log.Warn("[CCOUNT]: " + count);
|
||||||
|
@ -759,7 +756,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
if (contacts[i].depth >= 0f)
|
if (contacts[i].depth >= 0f && !checkDupe(contacts[i], p2.PhysicsActorType))
|
||||||
{
|
{
|
||||||
// If we're colliding against terrain
|
// If we're colliding against terrain
|
||||||
if (name1 == "Terrain" || name2 == "Terrain")
|
if (name1 == "Terrain" || name2 == "Terrain")
|
||||||
|
@ -863,11 +860,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom)
|
if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f)
|
if (Math.Abs(contact.depth - contactGeom.depth) < 0.072f)
|
||||||
{
|
{
|
||||||
//contactGeom.depth *= .00005f;
|
//contactGeom.depth *= .00005f;
|
||||||
//m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth));
|
//m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth));
|
||||||
// m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
|
//m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3456,10 +3456,176 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local)
|
public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
SceneObjectPart targ = World.GetSceneObjectPart((UUID)target);
|
bool pushrestricted = World.RegionInfo.RegionSettings.RestrictPushing;
|
||||||
if (targ == null)
|
bool pushAllowed = false;
|
||||||
|
|
||||||
|
bool pusheeIsAvatar = false;
|
||||||
|
UUID targetID = UUID.Zero;
|
||||||
|
|
||||||
|
if (!UUID.TryParse(target,out targetID))
|
||||||
return;
|
return;
|
||||||
targ.ApplyImpulse(new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z), local != 0);
|
|
||||||
|
ScenePresence pusheeav = null;
|
||||||
|
//SceneObjectPart pusheeob = null;
|
||||||
|
EntityBase obj = null;
|
||||||
|
Vector3 PusheePos = Vector3.Zero;
|
||||||
|
SceneObjectPart pusheeob = null;
|
||||||
|
|
||||||
|
List<ScenePresence> avatars = World.GetAvatars();
|
||||||
|
|
||||||
|
foreach (ScenePresence avatar in avatars)
|
||||||
|
{
|
||||||
|
if (avatar.UUID == targetID)
|
||||||
|
{
|
||||||
|
pusheeIsAvatar = true;
|
||||||
|
|
||||||
|
// Pushee doesn't have a physics actor
|
||||||
|
if (avatar.PhysicsActor == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Pushee is in GodMode this pushing object isn't owned by them
|
||||||
|
if (avatar.GodLevel > 0 && m_host.OwnerID != targetID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pusheeav = avatar;
|
||||||
|
|
||||||
|
// Find pushee position
|
||||||
|
// Pushee Linked?
|
||||||
|
if (pusheeav.ParentID != 0)
|
||||||
|
{
|
||||||
|
SceneObjectPart parentobj = World.GetSceneObjectPart(pusheeav.ParentID);
|
||||||
|
if (parentobj != null)
|
||||||
|
{
|
||||||
|
PusheePos = parentobj.AbsolutePosition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PusheePos = pusheeav.AbsolutePosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PusheePos = pusheeav.AbsolutePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = (EntityBase)pusheeav;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pusheeIsAvatar)
|
||||||
|
{
|
||||||
|
pusheeob = World.GetSceneObjectPart((UUID)target);
|
||||||
|
|
||||||
|
// We can't find object
|
||||||
|
if (pusheeob == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Object not pushable. Not an attachment and has no physics component
|
||||||
|
if (!pusheeob.IsAttachment && pusheeob.PhysActor == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PusheePos = pusheeob.AbsolutePosition;
|
||||||
|
//obj = (EntityBase)pusheeob;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (pushrestricted)
|
||||||
|
{
|
||||||
|
ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X,PusheePos.Y);
|
||||||
|
|
||||||
|
// We didn't find the parcel but region is push restricted so assume it is NOT ok
|
||||||
|
if (targetlandObj == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Need provisions for Group Owned here
|
||||||
|
if (m_host.OwnerID == targetlandObj.landData.OwnerID || targetlandObj.landData.IsGroupOwned || m_host.OwnerID == targetID)
|
||||||
|
{
|
||||||
|
pushAllowed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y);
|
||||||
|
if (targetlandObj == null)
|
||||||
|
{
|
||||||
|
// We didn't find the parcel but region isn't push restricted so assume it's ok
|
||||||
|
pushAllowed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Parcel push restriction
|
||||||
|
if ((targetlandObj.landData.Flags & (uint)Parcel.ParcelFlags.RestrictPushObject) == (uint)Parcel.ParcelFlags.RestrictPushObject)
|
||||||
|
{
|
||||||
|
// Need provisions for Group Owned here
|
||||||
|
if (m_host.OwnerID == targetlandObj.landData.OwnerID || targetlandObj.landData.IsGroupOwned || m_host.OwnerID == targetID)
|
||||||
|
{
|
||||||
|
pushAllowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parcel.ParcelFlags.RestrictPushObject
|
||||||
|
//pushAllowed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Parcel isn't push restricted
|
||||||
|
pushAllowed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pushAllowed)
|
||||||
|
{
|
||||||
|
float distance = (PusheePos - m_host.AbsolutePosition).Length();
|
||||||
|
float distance_term = distance * distance * distance; // Script Energy
|
||||||
|
float pusher_mass = m_host.GetMass();
|
||||||
|
|
||||||
|
float PUSH_ATTENUATION_DISTANCE = 17f;
|
||||||
|
float PUSH_ATTENUATION_SCALE = 5f;
|
||||||
|
float distance_attenuation = 1f;
|
||||||
|
if (distance > PUSH_ATTENUATION_DISTANCE)
|
||||||
|
{
|
||||||
|
float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE;
|
||||||
|
distance_attenuation = 1f / normalized_units;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z);
|
||||||
|
{
|
||||||
|
float impulse_length = applied_linear_impulse.Length();
|
||||||
|
|
||||||
|
float desired_energy = impulse_length * pusher_mass;
|
||||||
|
if (desired_energy > 0f)
|
||||||
|
desired_energy += distance_term;
|
||||||
|
|
||||||
|
float scaling_factor = 1f;
|
||||||
|
scaling_factor *= distance_attenuation;
|
||||||
|
applied_linear_impulse *= scaling_factor;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (pusheeIsAvatar)
|
||||||
|
{
|
||||||
|
if (pusheeav != null)
|
||||||
|
{
|
||||||
|
if (pusheeav.PhysicsActor != null)
|
||||||
|
{
|
||||||
|
if (local != 0)
|
||||||
|
{
|
||||||
|
applied_linear_impulse *= m_host.GetWorldRotation();
|
||||||
|
}
|
||||||
|
pusheeav.PhysicsActor.AddForce(new PhysicsVector(applied_linear_impulse.X, applied_linear_impulse.Y, applied_linear_impulse.Z), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pusheeob != null)
|
||||||
|
{
|
||||||
|
if (pusheeob.PhysActor != null)
|
||||||
|
{
|
||||||
|
pusheeob.ApplyImpulse(applied_linear_impulse, local != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void llPassCollisions(int pass)
|
public void llPassCollisions(int pass)
|
||||||
|
|
Loading…
Reference in New Issue