From 80cee1b85a646045c02e2bb675056d532ce2fe27 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 24 Dec 2012 08:56:02 -0800 Subject: BulletSim: Fix single physical prim reporting its mass as zero. Properly return root mass as mass of just the root prim rather than the mass of the linkset. SOG has the logic to add the masses together to get the linkset mass. Update TODO list. --- .../Region/Physics/BulletSPlugin/BSCharacter.cs | 9 +-- OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 20 +++--- .../Physics/BulletSPlugin/BSLinksetCompound.cs | 13 ++-- .../Physics/BulletSPlugin/BSLinksetConstraints.cs | 6 +- .../Region/Physics/BulletSPlugin/BSPhysObject.cs | 3 +- OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 71 ++++++++++++++-------- .../Region/Physics/BulletSPlugin/BulletSimTODO.txt | 15 ++++- 7 files changed, 83 insertions(+), 54 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 8e059ee..bf0545a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -174,7 +174,7 @@ public sealed class BSCharacter : BSPhysObject BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius); } - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, false); // Make so capsule does not fall over BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero); @@ -224,7 +224,7 @@ public sealed class BSCharacter : BSPhysObject if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) { BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale); - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, true); // Make sure this change appears as a property update event BulletSimAPI.PushUpdate2(PhysBody.ptr); } @@ -390,7 +390,7 @@ public sealed class BSCharacter : BSPhysObject public override float RawMass { get {return _mass; } } - public override void UpdatePhysicalMassProperties(float physMass) + public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) { OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); @@ -772,8 +772,9 @@ public sealed class BSCharacter : BSPhysObject // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) { - stepVelocity = OMV.Vector3.Zero; _velocityMotor.Enabled = false; + stepVelocity = OMV.Vector3.Zero; + ZeroMotion(true); DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 8580928..756faed 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs @@ -97,14 +97,7 @@ public abstract class BSLinkset } // We keep the prim's mass in the linkset structure since it could be dependent on other prims - protected float m_mass; - public float LinksetMass - { - get - { - return m_mass; - } - } + public float LinksetMass { get; protected set; } public virtual bool LinksetIsColliding { get { return false; } } @@ -128,7 +121,7 @@ public abstract class BSLinkset PhysicsScene = scene; LinksetRoot = parent; m_children = new HashSet(); - m_mass = parent.RawMass; + LinksetMass = parent.RawMass; Rebuilding = false; } @@ -143,7 +136,7 @@ public abstract class BSLinkset // Don't add the root to its own linkset if (!IsRoot(child)) AddChildToLinkset(child); - m_mass = ComputeLinksetMass(); + LinksetMass = ComputeLinksetMass(); } return this; } @@ -162,7 +155,7 @@ public abstract class BSLinkset return this; } RemoveChildFromLinkset(child); - m_mass = ComputeLinksetMass(); + LinksetMass = ComputeLinksetMass(); } // The child is down to a linkset of just itself @@ -230,7 +223,10 @@ public abstract class BSLinkset // When physical properties are changed the linkset needs to recalculate // its internal properties. // May be called at runtime or taint-time. - public abstract void Refresh(BSPhysObject requestor); + public virtual void Refresh(BSPhysObject requestor) + { + LinksetMass = ComputeLinksetMass(); + } // Flag denoting the linkset is in the process of being rebuilt. // Used to know not the schedule a rebuild in the middle of a rebuild. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 2a7b72c..d5cbf5f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -5,7 +5,7 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclat simer. * * Redistributions in binary form must reproduce the above copyrightD * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -89,6 +89,8 @@ public sealed class BSLinksetCompound : BSLinkset // its internal properties. public override void Refresh(BSPhysObject requestor) { + base.Refresh(requestor); + // Something changed so do the rebuilding thing // ScheduleRebuild(); } @@ -96,13 +98,13 @@ public sealed class BSLinksetCompound : BSLinkset // Schedule a refresh to happen after all the other taint processing. private void ScheduleRebuild(BSPhysObject requestor) { - DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}", + DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1}", requestor.LocalID, Rebuilding); // When rebuilding, it is possible to set properties that would normally require a rebuild. // If already rebuilding, don't request another rebuild. if (!Rebuilding) { - PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate() + PhysicsScene.PostTaintObject("BSLinksetCompound.ScheduleRebuild", LinksetRoot.LocalID, delegate() { if (HasAnyChildren) RecomputeLinksetCompound(); @@ -123,7 +125,6 @@ public sealed class BSLinksetCompound : BSLinkset if (IsRoot(child)) { // The root is going dynamic. Make sure mass is properly set. - m_mass = ComputeLinksetMass(); ScheduleRebuild(LinksetRoot); } else @@ -377,8 +378,8 @@ public sealed class BSLinksetCompound : BSLinkset }); // With all of the linkset packed into the root prim, it has the mass of everyone. - float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + LinksetMass = LinksetMass; + LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true); } finally { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index d95f223..6b592e7 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs @@ -46,6 +46,8 @@ public sealed class BSLinksetConstraints : BSLinkset // refresh will happen once after all the other taints are applied. public override void Refresh(BSPhysObject requestor) { + base.Refresh(requestor); + // Queue to happen after all the other taint processing PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate() { @@ -279,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset private void RecomputeLinksetConstraints() { float linksetMass = LinksetMass; - LinksetRoot.UpdatePhysicalMassProperties(linksetMass); + LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true); // DEBUG: see of inter-linkset collisions are causing problems // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, @@ -292,7 +294,7 @@ public sealed class BSLinksetConstraints : BSLinkset // A child in the linkset physically shows the mass of the whole linkset. // This allows Bullet to apply enough force on the child to move the whole linkset. // (Also do the mass stuff before recomputing the constraint so mass is not zero.) - child.UpdatePhysicalMassProperties(linksetMass); + child.UpdatePhysicalMassProperties(linksetMass, true); BSConstraint constrain; if (!PhysicsScene.Constraints.TryGetConstraint(LinksetRoot.PhysBody, child.PhysBody, out constrain)) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index c76f869..4bed535 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -96,7 +96,8 @@ public abstract class BSPhysObject : PhysicsActor // Return the object mass without calculating it or having side effects public abstract float RawMass { get; } // Set the raw mass but also update physical mass properties (inertia, ...) - public abstract void UpdatePhysicalMassProperties(float mass); + // 'inWorld' true if the object has already been added to the dynamic world. + public abstract void UpdatePhysicalMassProperties(float mass, bool inWorld); // The last value calculated for the prim's inertia public OMV.Vector3 Inertia { get; set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 26b8df5..159f79f 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -115,6 +115,8 @@ public sealed class BSPrim : BSPhysObject PhysBody = new BulletBody(LocalID); PhysShape = new BulletShape(); + Linkset.Refresh(this); + DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time PhysicsScene.TaintedObject("BSPrim.create", delegate() @@ -384,13 +386,13 @@ public sealed class BSPrim : BSPhysObject } // Return the effective mass of the object. - // If there are multiple items in the linkset, add them together for the root + // The definition of this call is to return the mass of the prim. + // If the simulator cares about the mass of the linkset, it will sum it itself. public override float Mass { get { - return Linkset.LinksetMass; - // return _mass; + return _mass; } } @@ -400,22 +402,41 @@ public sealed class BSPrim : BSPhysObject } // Set the physical mass to the passed mass. // Note that this does not change _mass! - public override void UpdatePhysicalMassProperties(float physMass) + public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) { - if (IsStatic) + if (PhysBody.HasPhysicalBody) { - Inertia = OMV.Vector3.Zero; - BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); - } - else - { - Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); - BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); - BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); - // center of mass is at the zero of the object - // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); - DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); + if (IsStatic) + { + Inertia = OMV.Vector3.Zero; + BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + } + else + { + if (inWorld) + { + // Changing interesting properties doesn't change proxy and collision cache + // information. The Bullet solution is to re-add the object to the world + // after parameters are changed. + BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + } + + float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); + BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); + + Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); + BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia); + BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); + // center of mass is at the zero of the object + // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); + DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia); + + if (inWorld) + { + BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr); + } + } } } @@ -714,7 +735,7 @@ public sealed class BSPrim : BSPhysObject Linkset.Refresh(this); DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", - LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); + LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody, PhysShape); } // "Making dynamic" means changing to and from static. @@ -737,7 +758,7 @@ public sealed class BSPrim : BSPhysObject BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution); // Mass is zero which disables a bunch of physics stuff in Bullet - UpdatePhysicalMassProperties(0f); + UpdatePhysicalMassProperties(0f, false); // Set collision detection parameters if (BSParam.CcdMotionThreshold > 0f) { @@ -777,7 +798,7 @@ public sealed class BSPrim : BSPhysObject // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); // A dynamic object has mass - UpdatePhysicalMassProperties(RawMass); + UpdatePhysicalMassProperties(RawMass, false); // Set collision detection parameters if (BSParam.CcdMotionThreshold > 0f) @@ -950,13 +971,9 @@ public sealed class BSPrim : BSPhysObject set { _buoyancy = value; // DetailLog("{0},BSPrim.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); - // Buoyancy is faked by changing the gravity applied to the object - if (PhysBody.HasPhysicalBody) - { - float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); - BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav)); - ActivateIfPhysical(false); - } + // Force the recalculation of the various inertia,etc variables in the object + UpdatePhysicalMassProperties(_mass, true); + ActivateIfPhysical(false); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 9a7e965..0f27d67 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -1,11 +1,17 @@ CURRENT PRIORITIES ================================================= -Smooth avatar movement with motor - Should motor update be all at taint-time? +Smooth avatar movement with motor (DONE) + Should motor update be all at taint-time? (Yes, DONE) + Fix avatar slowly sliding when standing (zero motion when stopped) +llApplyImpulse() + Compare mass/movement in OS and SL. Calibrate actions. +llSetBuoyancy() +Boats float low in the water Enable vehicle border crossings (at least as poorly as ODE) Terrain skirts Avatar created in previous region and not new region when crossing border Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) +Add material densities to the material types. Vehicle movement on terrain smoothness Vehicle script tuning/debugging Avanti speed script @@ -52,6 +58,8 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl BULLETSIM TODO LIST: ================================================= +In SL, perfect spheres don't seem to have rolling friction. Add special case. +Avatar density is WAY off. Compare and calibrate with what's in SL. Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. @@ -82,6 +90,9 @@ Linkset.Position and Linkset.Orientation requre rewrite to properly return Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F) Should the different PID factors have non-equal contributions for different values of Efficiency? +Selecting and deselecting physical objects causes CPU processing time to jump + http://www.youtube.com/watch?v=Hjg57fWg8yI&hd=1 + put thousand physical objects, select and deselect same. CPU time will be large. LINKSETS ====================================================== -- cgit v1.1