Physics Engine Interface
From OpenSimulator
Contents |
Base Classes
Note: I (User:Rknop) am trying to figure this out by looking at some of the code; my main interest is the NewtonPlugin. AS such, there are whole swaths of the physics engine, such as joints, that I have no clue about at the moment
The base classes for a physics module can be found in OpenSim.Region.Physics.Manager. The physics module itself should be a subclass of Physics, e.g. OpenSim.Region.Physics.OdePlugin.
- PhysicsActor is the base class for both prims and avatars.
- PhysicsScene is the main base class that interfaces with the region's Scene.
- (others)
The Physics Scene doesn't access the Region Scene. The region scene will tell the physics engine about prims and avatars, and will send updates to the physics engine. It will then pull positions and velocities of objects and avatars out of the physics engine.
For the most part, the things that will be interfacing with the physics engine are the classes OpenSim.Region.Framework.Scenes.Scene, OpenSim.Region.Framework.Scenes.SceneObjectGroup, and OpenSim.Region.Framework.Scenes.SceneObjectPart
The Plugin Class
If you're writing a Physics engine named Foo, you need to write a class OpenSim.Region.Physics.FooPlugin with the following methods:
- FooPlugin() — constructor
- bool Init() — (not sure exactly when this is called. return true)
- PhysicsScene GetScene(String sceneIdentifier) — return a FooScene, which is derived from PhysicsScene
- string GetName() — return the name that folks can use in OpenSim.ini to select this physics engine
- Dispose() — destructor
PhysicsScene
Your class OpenSim.Region.Physics.FooScene must derive from OpenSim.Region.Physics.PhysicsScene. Members include:
- public override void Initialize(IMesher meshmerizer, IConfigSource config)
- Passes in the Meshing plugin to the Physics Plugin.
- public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size, bool isFlying)
- Scene calls this method when adding an avatar to the physics scene or changing appearance
- public override void SetWaterLevel(float baseheight)
- If water is simulated in your physics engine, this passes in the visual base height
- public override void RemovePrim(PhysicsActor prim)
- This gets called when a prim is made into something the physics engine no longer needs to know about. The physics engine should remove it from any internal lists of prims it is keeping track of.
- public override void RemoveAvatar(PhysicsActor character)
- Like RemovePrim, but for avatars.
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, PhysicsVector size, Quarternion rotation)
- Tells the physics engine to add a new prim it needs to keep track of. This prim is not a physical prim, but as long as it's not phantom, physical objects may collide with it, and thus the physics engine (may) need to know about it. (Unless the physics engine punts on collisions, as, for instance, NewtonPlugin does.) Comments in the code indicate that this method is slated to be removed....
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, PhysicsVector size, Quarternion rotation, bool isPhysical)
- Like the previous one, but you've got the flag that tells you if it's physical or not.
- public override void AddPhysicsActorTaint(PhysicsActor prim)
- When the scene makes a change to the Physics Scene, it informs the Physics Plugin that it tainted the object to give the physics scene a chance to update it's internal data during or before next step
- public override void GetResults()
- When the physics engine is multi-threaded (such as PhysX), GetResults would be called to Select the threads and wait until they're finished.
- public override bol IsThreaded
- A member that needs a get method. Returns if the Physics Plugin/Engine is Multi-Threaded
- public override void SetTerrain(float[] heightMap)
- Sets terrain using a flattened(strided) y-flipped float array of Constants.RegionSize by Constants.RegionSize. float val= heightmap[y * Constants.RegionSize + x]
- public override void DeleteTerrain()
- Remove terrain. (does this ever get called?)
- public override Dictionary<unit, float> GetTopColliders()
- Provides the Scene with information about the Physics Scene (requested through the Estate Module). uint is the unique ID of the object in the Simulator. float is a rating value.
- public override float Simulate(float timestep)
- This is the core function. This gets called by the main loop when it wants the Physics engine to do its magic and propagate forward the positions and velocities of all the stuff it knows about. The physics engine should update the Position and Velocity members of the PhysicsActor class it knows about (those things that have been added to it by the methods above). Important: when the physics engine thinks that things have changed enough for any given prims that the surrounding scene should updates it's own idea about the positions and velocities of those prims, it should call the RequestPhysicsterseUpdate() method of the changed PhysicsActors(). (The safest, but slowest, way to do this is for Simulate() to call this for every physical prim it knows about every time it is called.)
PhysicsActor
PhysicsActor represents both prims and characters. You may want to make separate classes for the two. You can get away with this because PhysicsActors are actually created by PhysicsScene. Your subclass of PhysicsScene has different methods called when an avatar or a prim is added to the scene, returning a PhysicsActor. You can return the appropriate subclass in each case.
Members:
- int PhysicsActorType
- Needs get and set methods. Return ActorTypes.Prim or ActorTypes.Agent if it's a prim or an avatar.
- bool IsPhysical
- Needs get and set
- PhysicsVector Position
- Needs get and set. If an object is physical, the physics engine keeps the "real" position for that object. However, it's the surrounding scene's impression of the position that gets rendered and sent to the client. It will pull the position out of the physics engine by looking at this member, and tell the physics engine about any external changes in its position through this member. Note that the scene doesn't automatically pull out the position, but only when it thinks it needs to. You can call the RequestPhysicsterseUpdate() method of PhysicsActor to ask the Scene to update its position for any given PhysicsActor. (See PhysicsScene.Simulate() above.)
- PhysicsVector Velocity
- Need get and set. Similar considerations to Position
- PhysicsVector RotationalVelocity
- Needs get and set
- PhysicsVector Acceleration
- Needs get; there's no set method.
- void SetAcceleration(PhysicsVector accel)
- Do what you'd think Acceleration.set would do
- PhysicsVector Size
- Needs get and set
- float Mass
- Needs get; there is no set method at the moment
- void SetMass(float mass)
- Instead of Mass.set
- void SetMomentum(PhysicsVector momentum)
- I am disturbed that this exists in addition to Velocity.set and SetMass....
- Quarternion Orientation
- Needs get and set
- bool ThrottleUpdates
- Needs get and set. I'm not sure what this means, exactly.
- bool IsColliding
- Needs get and set.
- bool CollidingGround
- Needs get and set
- bool CollidingObj
- Needs get and set
- bool Stopped
- Just needs get
- PhysicsVector CenterOfMass
- Just needs get
- PhysicsVector GeometricCenter
- Just needs get
- PrimitiveBaseShape Shape
- Just needs set
- PhysicsVector Force
- Needs get and set. I think this is a steady force (in N) always acting on the object.
- PhysicsVector Torque
- Needs get and set. Like Force, I think this is a steady torque operating on the object.
- void AddForce(PhysicsVector force, bool pushforce)
- This should apply a one-time impulse to the object of magnitude "force" Newton-seconds. I am not sure what "pushforce" means....
- void AddAngularForce(PhsyicsVector force, bool pushforce)
- A one-time angular impulse. I'm not sure the units, nor what pushforce means.
- int VehicleType
- (I don't know anything about the vehicle code requirements)
- void VehicleFloatParam(int param, float value)
- void VehicleVectorParam(int param, PhysicsVector value)
- void VehicleRotationParam(int param, Quarternion rotation)
- void SetVoulumeDetect(int param)
- void VehicleVectorParam(int param, PhysicsVector value)
- This is some weird mode that can be set via a LSL function
- float Buoyancy
- Needs get and set
- bool FloatOnWater
- Just needs set
- float CollisionScore
- Needs get and set. I don't know what this is.
- bool Flying
- Needs get and set
- bool SetAlwaysRun
- Needs get and set
- unit LocalID
- Needs set. I don't know what this is
- bool Grabbed
- Needs set. I'm not sure what this is, but I'm guessing it's when you control-click on an object?
- void link(PhysicsActor obj)
- I haven't delved into how linking works in the physics engine. I'm guessing that this says "link yourself to obj with obj as the root", but I could be wrong.
- void delink()
- void LockAngularMomentum(PhysicsVector axis)
- bool Selected
- void LockAngularMomentum(PhysicsVector axis)
- Just needs set
- void CrossingFailure()
- PhysicsVector PIDTarget
- Just needs set. I don't know what this is, but I'm guessing it's a place to which an object is supposed to move.
- bool PIDActive
- Just needs set.
- float PIDTau
- Just needs set. I'm guessing that this is the timescale (in seconds) in which the object should move to PIDTarget when it is set to be PID Active.
- float PIDHoverHeight
- float PIDHoverActive
- PIDHoverType PIDHoverType
- float PIDHoverTau
- void SubscribeEvents(int ms)
- float PIDHoverActive
- I do not know what sorts of events the PhysicsActor sends... hopefully I'll update this if/when I figure that out! It looks like you can ask for OnPositionUpdate, OnVelocityUpdate, OnOrientationUpdate, OnRequestTerseUpdate, OnCollisionUpdate, and OnOutOfBounds... but I have yet to fully understand the OpenSim event system, so I may be speaking out of the side of my mouth here.
- bool SubscribedEvents()