diff options
author | Teravus Ovares | 2008-10-17 23:19:00 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-10-17 23:19:00 +0000 |
commit | 0916b38b8300c41f66c2f22e79c77f3c5f6f4cb7 (patch) | |
tree | 5cf1a9a56529525797ce8577ed1c49208a65ffd7 /OpenSim/Region/ScriptEngine/Shared/Api | |
parent | * Remove mono warnings (diff) | |
download | opensim-SC_OLD-0916b38b8300c41f66c2f22e79c77f3c5f6f4cb7.zip opensim-SC_OLD-0916b38b8300c41f66c2f22e79c77f3c5f6f4cb7.tar.gz opensim-SC_OLD-0916b38b8300c41f66c2f22e79c77f3c5f6f4cb7.tar.bz2 opensim-SC_OLD-0916b38b8300c41f66c2f22e79c77f3c5f6f4cb7.tar.xz |
* 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.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 172 |
1 files changed, 169 insertions, 3 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6a6109b..956a500 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -3456,10 +3456,176 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3456 | public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local) | 3456 | public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local) |
3457 | { | 3457 | { |
3458 | m_host.AddScriptLPS(1); | 3458 | m_host.AddScriptLPS(1); |
3459 | SceneObjectPart targ = World.GetSceneObjectPart((UUID)target); | 3459 | bool pushrestricted = World.RegionInfo.RegionSettings.RestrictPushing; |
3460 | if (targ == null) | 3460 | bool pushAllowed = false; |
3461 | |||
3462 | bool pusheeIsAvatar = false; | ||
3463 | UUID targetID = UUID.Zero; | ||
3464 | |||
3465 | if (!UUID.TryParse(target,out targetID)) | ||
3461 | return; | 3466 | return; |
3462 | targ.ApplyImpulse(new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z), local != 0); | 3467 | |
3468 | ScenePresence pusheeav = null; | ||
3469 | //SceneObjectPart pusheeob = null; | ||
3470 | EntityBase obj = null; | ||
3471 | Vector3 PusheePos = Vector3.Zero; | ||
3472 | SceneObjectPart pusheeob = null; | ||
3473 | |||
3474 | List<ScenePresence> avatars = World.GetAvatars(); | ||
3475 | |||
3476 | foreach (ScenePresence avatar in avatars) | ||
3477 | { | ||
3478 | if (avatar.UUID == targetID) | ||
3479 | { | ||
3480 | pusheeIsAvatar = true; | ||
3481 | |||
3482 | // Pushee doesn't have a physics actor | ||
3483 | if (avatar.PhysicsActor == null) | ||
3484 | return; | ||
3485 | |||
3486 | // Pushee is in GodMode this pushing object isn't owned by them | ||
3487 | if (avatar.GodLevel > 0 && m_host.OwnerID != targetID) | ||
3488 | return; | ||
3489 | |||
3490 | pusheeav = avatar; | ||
3491 | |||
3492 | // Find pushee position | ||
3493 | // Pushee Linked? | ||
3494 | if (pusheeav.ParentID != 0) | ||
3495 | { | ||
3496 | SceneObjectPart parentobj = World.GetSceneObjectPart(pusheeav.ParentID); | ||
3497 | if (parentobj != null) | ||
3498 | { | ||
3499 | PusheePos = parentobj.AbsolutePosition; | ||
3500 | } | ||
3501 | else | ||
3502 | { | ||
3503 | PusheePos = pusheeav.AbsolutePosition; | ||
3504 | } | ||
3505 | } | ||
3506 | else | ||
3507 | { | ||
3508 | PusheePos = pusheeav.AbsolutePosition; | ||
3509 | } | ||
3510 | |||
3511 | obj = (EntityBase)pusheeav; | ||
3512 | break; | ||
3513 | } | ||
3514 | } | ||
3515 | |||
3516 | if (!pusheeIsAvatar) | ||
3517 | { | ||
3518 | pusheeob = World.GetSceneObjectPart((UUID)target); | ||
3519 | |||
3520 | // We can't find object | ||
3521 | if (pusheeob == null) | ||
3522 | return; | ||
3523 | |||
3524 | // Object not pushable. Not an attachment and has no physics component | ||
3525 | if (!pusheeob.IsAttachment && pusheeob.PhysActor == null) | ||
3526 | return; | ||
3527 | |||
3528 | PusheePos = pusheeob.AbsolutePosition; | ||
3529 | //obj = (EntityBase)pusheeob; | ||
3530 | } | ||
3531 | |||
3532 | |||
3533 | if (pushrestricted) | ||
3534 | { | ||
3535 | ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X,PusheePos.Y); | ||
3536 | |||
3537 | // We didn't find the parcel but region is push restricted so assume it is NOT ok | ||
3538 | if (targetlandObj == null) | ||
3539 | return; | ||
3540 | |||
3541 | // Need provisions for Group Owned here | ||
3542 | if (m_host.OwnerID == targetlandObj.landData.OwnerID || targetlandObj.landData.IsGroupOwned || m_host.OwnerID == targetID) | ||
3543 | { | ||
3544 | pushAllowed = true; | ||
3545 | } | ||
3546 | } | ||
3547 | else | ||
3548 | { | ||
3549 | ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); | ||
3550 | if (targetlandObj == null) | ||
3551 | { | ||
3552 | // We didn't find the parcel but region isn't push restricted so assume it's ok | ||
3553 | pushAllowed = true; | ||
3554 | } | ||
3555 | else | ||
3556 | { | ||
3557 | // Parcel push restriction | ||
3558 | if ((targetlandObj.landData.Flags & (uint)Parcel.ParcelFlags.RestrictPushObject) == (uint)Parcel.ParcelFlags.RestrictPushObject) | ||
3559 | { | ||
3560 | // Need provisions for Group Owned here | ||
3561 | if (m_host.OwnerID == targetlandObj.landData.OwnerID || targetlandObj.landData.IsGroupOwned || m_host.OwnerID == targetID) | ||
3562 | { | ||
3563 | pushAllowed = true; | ||
3564 | } | ||
3565 | |||
3566 | //Parcel.ParcelFlags.RestrictPushObject | ||
3567 | //pushAllowed = true; | ||
3568 | } | ||
3569 | else | ||
3570 | { | ||
3571 | // Parcel isn't push restricted | ||
3572 | pushAllowed = true; | ||
3573 | } | ||
3574 | } | ||
3575 | } | ||
3576 | if (pushAllowed) | ||
3577 | { | ||
3578 | float distance = (PusheePos - m_host.AbsolutePosition).Length(); | ||
3579 | float distance_term = distance * distance * distance; // Script Energy | ||
3580 | float pusher_mass = m_host.GetMass(); | ||
3581 | |||
3582 | float PUSH_ATTENUATION_DISTANCE = 17f; | ||
3583 | float PUSH_ATTENUATION_SCALE = 5f; | ||
3584 | float distance_attenuation = 1f; | ||
3585 | if (distance > PUSH_ATTENUATION_DISTANCE) | ||
3586 | { | ||
3587 | float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE; | ||
3588 | distance_attenuation = 1f / normalized_units; | ||
3589 | } | ||
3590 | |||
3591 | Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z); | ||
3592 | { | ||
3593 | float impulse_length = applied_linear_impulse.Length(); | ||
3594 | |||
3595 | float desired_energy = impulse_length * pusher_mass; | ||
3596 | if (desired_energy > 0f) | ||
3597 | desired_energy += distance_term; | ||
3598 | |||
3599 | float scaling_factor = 1f; | ||
3600 | scaling_factor *= distance_attenuation; | ||
3601 | applied_linear_impulse *= scaling_factor; | ||
3602 | |||
3603 | } | ||
3604 | if (pusheeIsAvatar) | ||
3605 | { | ||
3606 | if (pusheeav != null) | ||
3607 | { | ||
3608 | if (pusheeav.PhysicsActor != null) | ||
3609 | { | ||
3610 | if (local != 0) | ||
3611 | { | ||
3612 | applied_linear_impulse *= m_host.GetWorldRotation(); | ||
3613 | } | ||
3614 | pusheeav.PhysicsActor.AddForce(new PhysicsVector(applied_linear_impulse.X, applied_linear_impulse.Y, applied_linear_impulse.Z), true); | ||
3615 | } | ||
3616 | } | ||
3617 | } | ||
3618 | else | ||
3619 | { | ||
3620 | if (pusheeob != null) | ||
3621 | { | ||
3622 | if (pusheeob.PhysActor != null) | ||
3623 | { | ||
3624 | pusheeob.ApplyImpulse(applied_linear_impulse, local != 0); | ||
3625 | } | ||
3626 | } | ||
3627 | } | ||
3628 | } | ||
3463 | } | 3629 | } |
3464 | 3630 | ||
3465 | public void llPassCollisions(int pass) | 3631 | public void llPassCollisions(int pass) |