Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

0.7.5-pf-bulletsim
Justin Clark-Casey (justincc) 2013-01-01 23:27:10 +00:00
commit e8a3cc7019
30 changed files with 1902 additions and 891 deletions

View File

@ -107,12 +107,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule
public void ScriptRemoved(UUID itemID)
{
System.Console.WriteLine("TEST Script Removed!");
// System.Console.WriteLine("TEST Script Removed!");
}
public void ObjectRemoved(UUID objectID)
{
System.Console.WriteLine("TEST Obj Removed!");
// System.Console.WriteLine("TEST Obj Removed!");
}
}
}

View File

@ -111,10 +111,6 @@ public sealed class BSPrim : BSPhysObject
_mass = CalculateMass();
// No body or shape yet
PhysBody = new BulletBody(LocalID);
PhysShape = new BulletShape();
Linkset.Refresh(this);
DetailLog("{0},BSPrim.constructor,call", LocalID);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenSim.Region.Physics.BulletSPlugin
{
/*
public sealed class BSAPIXNA : BSAPITemplate
{
}
*/
}

View File

@ -0,0 +1,662 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin {
// Constraint type values as defined by Bullet
public enum ConstraintType : int
{
POINT2POINT_CONSTRAINT_TYPE = 3,
HINGE_CONSTRAINT_TYPE,
CONETWIST_CONSTRAINT_TYPE,
D6_CONSTRAINT_TYPE,
SLIDER_CONSTRAINT_TYPE,
CONTACT_CONSTRAINT_TYPE,
D6_SPRING_CONSTRAINT_TYPE,
MAX_CONSTRAINT_TYPE
}
// ===============================================================================
[StructLayout(LayoutKind.Sequential)]
public struct ConvexHull
{
Vector3 Offset;
int VertexCount;
Vector3[] Vertices;
}
public enum BSPhysicsShapeType
{
SHAPE_UNKNOWN = 0,
SHAPE_CAPSULE = 1,
SHAPE_BOX = 2,
SHAPE_CONE = 3,
SHAPE_CYLINDER = 4,
SHAPE_SPHERE = 5,
SHAPE_MESH = 6,
SHAPE_HULL = 7,
// following defined by BulletSim
SHAPE_GROUNDPLANE = 20,
SHAPE_TERRAIN = 21,
SHAPE_COMPOUND = 22,
SHAPE_HEIGHTMAP = 23,
SHAPE_AVATAR = 24,
};
// The native shapes have predefined shape hash keys
public enum FixedShapeKey : ulong
{
KEY_NONE = 0,
KEY_BOX = 1,
KEY_SPHERE = 2,
KEY_CONE = 3,
KEY_CYLINDER = 4,
KEY_CAPSULE = 5,
KEY_AVATAR = 6,
}
[StructLayout(LayoutKind.Sequential)]
public struct ShapeData
{
public uint ID;
public BSPhysicsShapeType Type;
public Vector3 Position;
public Quaternion Rotation;
public Vector3 Velocity;
public Vector3 Scale;
public float Mass;
public float Buoyancy;
public System.UInt64 HullKey;
public System.UInt64 MeshKey;
public float Friction;
public float Restitution;
public float Collidable; // true of things bump into this
public float Static; // true if a static object. Otherwise gravity, etc.
public float Solid; // true if object cannot be passed through
public Vector3 Size;
// note that bools are passed as floats since bool size changes by language and architecture
public const float numericTrue = 1f;
public const float numericFalse = 0f;
}
[StructLayout(LayoutKind.Sequential)]
public struct SweepHit
{
public uint ID;
public float Fraction;
public Vector3 Normal;
public Vector3 Point;
}
[StructLayout(LayoutKind.Sequential)]
public struct RaycastHit
{
public uint ID;
public float Fraction;
public Vector3 Normal;
}
[StructLayout(LayoutKind.Sequential)]
public struct CollisionDesc
{
public uint aID;
public uint bID;
public Vector3 point;
public Vector3 normal;
}
[StructLayout(LayoutKind.Sequential)]
public struct EntityProperties
{
public uint ID;
public Vector3 Position;
public Quaternion Rotation;
public Vector3 Velocity;
public Vector3 Acceleration;
public Vector3 RotationalVelocity;
}
// Format of this structure must match the definition in the C++ code
// NOTE: adding the X causes compile breaks if used. These are unused symbols
// that can be removed from both here and the unmanaged definition of this structure.
[StructLayout(LayoutKind.Sequential)]
public struct ConfigurationParameters
{
public float defaultFriction;
public float defaultDensity;
public float defaultRestitution;
public float collisionMargin;
public float gravity;
public float XlinearDamping;
public float XangularDamping;
public float XdeactivationTime;
public float XlinearSleepingThreshold;
public float XangularSleepingThreshold;
public float XccdMotionThreshold;
public float XccdSweptSphereRadius;
public float XcontactProcessingThreshold;
public float XterrainImplementation;
public float XterrainFriction;
public float XterrainHitFraction;
public float XterrainRestitution;
public float XterrainCollisionMargin;
public float XavatarFriction;
public float XavatarStandingFriction;
public float XavatarDensity;
public float XavatarRestitution;
public float XavatarCapsuleWidth;
public float XavatarCapsuleDepth;
public float XavatarCapsuleHeight;
public float XavatarContactProcessingThreshold;
public float XvehicleAngularDamping;
public float maxPersistantManifoldPoolSize;
public float maxCollisionAlgorithmPoolSize;
public float shouldDisableContactPoolDynamicAllocation;
public float shouldForceUpdateAllAabbs;
public float shouldRandomizeSolverOrder;
public float shouldSplitSimulationIslands;
public float shouldEnableFrictionCaching;
public float numberOfSolverIterations;
public float XlinksetImplementation;
public float XlinkConstraintUseFrameOffset;
public float XlinkConstraintEnableTransMotor;
public float XlinkConstraintTransMotorMaxVel;
public float XlinkConstraintTransMotorMaxForce;
public float XlinkConstraintERP;
public float XlinkConstraintCFM;
public float XlinkConstraintSolverIterations;
public float physicsLoggingFrames;
public const float numericTrue = 1f;
public const float numericFalse = 0f;
}
// The states a bullet collision object can have
public enum ActivationState : uint
{
ACTIVE_TAG = 1,
ISLAND_SLEEPING,
WANTS_DEACTIVATION,
DISABLE_DEACTIVATION,
DISABLE_SIMULATION,
}
public enum CollisionObjectTypes : int
{
CO_COLLISION_OBJECT = 1 << 0,
CO_RIGID_BODY = 1 << 1,
CO_GHOST_OBJECT = 1 << 2,
CO_SOFT_BODY = 1 << 3,
CO_HF_FLUID = 1 << 4,
CO_USER_TYPE = 1 << 5,
}
// Values used by Bullet and BulletSim to control object properties.
// Bullet's "CollisionFlags" has more to do with operations on the
// object (if collisions happen, if gravity effects it, ...).
public enum CollisionFlags : uint
{
CF_STATIC_OBJECT = 1 << 0,
CF_KINEMATIC_OBJECT = 1 << 1,
CF_NO_CONTACT_RESPONSE = 1 << 2,
CF_CUSTOM_MATERIAL_CALLBACK = 1 << 3,
CF_CHARACTER_OBJECT = 1 << 4,
CF_DISABLE_VISUALIZE_OBJECT = 1 << 5,
CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
// Following used by BulletSim to control collisions and updates
BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10,
BS_FLOATS_ON_WATER = 1 << 11,
BS_VEHICLE_COLLISIONS = 1 << 12,
BS_NONE = 0,
BS_ALL = 0xFFFFFFFF
};
// Values f collisions groups and masks
public enum CollisionFilterGroups : uint
{
// Don't use the bit definitions!! Define the use in a
// filter/mask definition below. This way collision interactions
// are more easily found and debugged.
BNoneGroup = 0,
BDefaultGroup = 1 << 0, // 0001
BStaticGroup = 1 << 1, // 0002
BKinematicGroup = 1 << 2, // 0004
BDebrisGroup = 1 << 3, // 0008
BSensorTrigger = 1 << 4, // 0010
BCharacterGroup = 1 << 5, // 0020
BAllGroup = 0x000FFFFF,
// Filter groups defined by BulletSim
BGroundPlaneGroup = 1 << 10, // 0400
BTerrainGroup = 1 << 11, // 0800
BRaycastGroup = 1 << 12, // 1000
BSolidGroup = 1 << 13, // 2000
// BLinksetGroup = xx // a linkset proper is either static or dynamic
BLinksetChildGroup = 1 << 14, // 4000
};
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2.
public enum ConstraintParams : int
{
BT_CONSTRAINT_ERP = 1, // this one is not used in Bullet as of 20120730
BT_CONSTRAINT_STOP_ERP,
BT_CONSTRAINT_CFM,
BT_CONSTRAINT_STOP_CFM,
};
public enum ConstraintParamAxis : int
{
AXIS_LINEAR_X = 0,
AXIS_LINEAR_Y,
AXIS_LINEAR_Z,
AXIS_ANGULAR_X,
AXIS_ANGULAR_Y,
AXIS_ANGULAR_Z,
AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls
AXIS_ANGULAR_ALL,
AXIS_ALL
};
public abstract class BSAPITemplate
{
// Returns the name of the underlying Bullet engine
public abstract string BulletEngineName { get; }
public abstract string BulletEngineVersion { get; protected set;}
// Initialization and simulation
public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParameters parms,
int maxCollisions, ref CollisionDesc[] collisionArray,
int maxUpdates, ref EntityProperties[] updateArray
);
public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
out int updatedEntityCount, out int collidersCount);
public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value);
public abstract void Shutdown(BulletWorld sim);
public abstract bool PushUpdate(BulletBody obj);
// =====================================================================================
// Mesh, hull, shape and body creation helper routines
public abstract BulletShape CreateMeshShape(BulletWorld world,
int indicesCount, int[] indices,
int verticesCount, float[] vertices );
public abstract BulletShape CreateHullShape(BulletWorld world,
int hullCount, float[] hulls);
public abstract BulletShape BuildHullShapeFromMesh(BulletWorld world, BulletShape meshShape);
public abstract BulletShape BuildNativeShape(BulletWorld world, ShapeData shapeData);
public abstract bool IsNativeShape(BulletShape shape);
public abstract void SetShapeCollisionMargin(BulletShape shape, float margin);
public abstract BulletShape BuildCapsuleShape(BulletWorld world, float radius, float height, Vector3 scale);
public abstract BulletShape CreateCompoundShape(BulletWorld sim, bool enableDynamicAabbTree);
public abstract int GetNumberOfCompoundChildren(BulletShape cShape);
public abstract void AddChildShapeToCompoundShape(BulletShape cShape, BulletShape addShape, Vector3 pos, Quaternion rot);
public abstract BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx);
public abstract BulletShape RemoveChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx);
public abstract void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape);
public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id);
public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape);
public abstract int GetBodyType(BulletBody obj);
public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot);
public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot);
public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot);
public abstract void DestroyObject(BulletWorld sim, BulletBody obj);
// =====================================================================================
public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin);
public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
float scaleFactor, float collisionMargin);
// =====================================================================================
// Constraint creation and helper routines
public abstract BulletConstraint Create6DofConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 frame1loc, Quaternion frame1rot,
Vector3 frame2loc, Quaternion frame2rot,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
public abstract BulletConstraint Create6DofConstraintToPoint(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 joinPoint,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
public abstract BulletConstraint CreateHingeConstraint(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 pivotinA, Vector3 pivotinB,
Vector3 axisInA, Vector3 axisInB,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
public abstract void SetConstraintEnable(BulletConstraint constrain, float numericTrueFalse);
public abstract void SetConstraintNumSolverIterations(BulletConstraint constrain, float iterations);
public abstract bool SetFrames(BulletConstraint constrain,
Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot);
public abstract bool SetLinearLimits(BulletConstraint constrain, Vector3 low, Vector3 hi);
public abstract bool SetAngularLimits(BulletConstraint constrain, Vector3 low, Vector3 hi);
public abstract bool UseFrameOffset(BulletConstraint constrain, float enable);
public abstract bool TranslationalLimitMotor(BulletConstraint constrain, float enable, float targetVel, float maxMotorForce);
public abstract bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold);
public abstract bool CalculateTransforms(BulletConstraint constrain);
public abstract bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis);
public abstract bool DestroyConstraint(BulletWorld world, BulletConstraint constrain);
// =====================================================================================
// btCollisionWorld entries
public abstract void UpdateSingleAabb(BulletWorld world, BulletBody obj);
public abstract void UpdateAabbs(BulletWorld world);
public abstract bool GetForceUpdateAllAabbs(BulletWorld world);
public abstract void SetForceUpdateAllAabbs(BulletWorld world, bool force);
// =====================================================================================
// btDynamicsWorld entries
public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj);
public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj);
public abstract bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects);
public abstract bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain);
// =====================================================================================
// btCollisionObject entries
public abstract Vector3 GetAnisotripicFriction(BulletConstraint constrain);
public abstract Vector3 SetAnisotripicFriction(BulletConstraint constrain, Vector3 frict);
public abstract bool HasAnisotripicFriction(BulletConstraint constrain);
public abstract void SetContactProcessingThreshold(BulletBody obj, float val);
public abstract float GetContactProcessingThreshold(BulletBody obj);
public abstract bool IsStaticObject(BulletBody obj);
public abstract bool IsKinematicObject(BulletBody obj);
public abstract bool IsStaticOrKinematicObject(BulletBody obj);
public abstract bool HasContactResponse(BulletBody obj);
public abstract void SetCollisionShape(BulletWorld sim, BulletBody obj, BulletShape shape);
public abstract BulletShape GetCollisionShape(BulletBody obj);
public abstract int GetActivationState(BulletBody obj);
public abstract void SetActivationState(BulletBody obj, int state);
public abstract void SetDeactivationTime(BulletBody obj, float dtime);
public abstract float GetDeactivationTime(BulletBody obj);
public abstract void ForceActivationState(BulletBody obj, ActivationState state);
public abstract void Activate(BulletBody obj, bool forceActivation);
public abstract bool IsActive(BulletBody obj);
public abstract void SetRestitution(BulletBody obj, float val);
public abstract float GetRestitution(BulletBody obj);
public abstract void SetFriction(BulletBody obj, float val);
public abstract float GetFriction(BulletBody obj);
public abstract Vector3 GetPosition(BulletBody obj);
public abstract Quaternion GetOrientation(BulletBody obj);
public abstract void SetTranslation(BulletBody obj, Vector3 position, Quaternion rotation);
// public abstract IntPtr GetBroadphaseHandle(BulletBody obj);
// public abstract void SetBroadphaseHandle(BulletBody obj, IntPtr handle);
public abstract void SetInterpolationLinearVelocity(BulletBody obj, Vector3 vel);
public abstract void SetInterpolationAngularVelocity(BulletBody obj, Vector3 vel);
public abstract void SetInterpolationVelocity(BulletBody obj, Vector3 linearVel, Vector3 angularVel);
public abstract float GetHitFraction(BulletBody obj);
public abstract void SetHitFraction(BulletBody obj, float val);
public abstract CollisionFlags GetCollisionFlags(BulletBody obj);
public abstract CollisionFlags SetCollisionFlags(BulletBody obj, CollisionFlags flags);
public abstract CollisionFlags AddToCollisionFlags(BulletBody obj, CollisionFlags flags);
public abstract CollisionFlags RemoveFromCollisionFlags(BulletBody obj, CollisionFlags flags);
public abstract float GetCcdMotionThreshold(BulletBody obj);
public abstract void SetCcdMotionThreshold(BulletBody obj, float val);
public abstract float GetCcdSweptSphereRadius(BulletBody obj);
public abstract void SetCcdSweptSphereRadius(BulletBody obj, float val);
public abstract IntPtr GetUserPointer(BulletBody obj);
public abstract void SetUserPointer(BulletBody obj, IntPtr val);
// =====================================================================================
// btRigidBody entries
public abstract void ApplyGravity(BulletBody obj);
public abstract void SetGravity(BulletBody obj, Vector3 val);
public abstract Vector3 GetGravity(BulletBody obj);
public abstract void SetDamping(BulletBody obj, float lin_damping, float ang_damping);
public abstract void SetLinearDamping(BulletBody obj, float lin_damping);
public abstract void SetAngularDamping(BulletBody obj, float ang_damping);
public abstract float GetLinearDamping(BulletBody obj);
public abstract float GetAngularDamping(BulletBody obj);
public abstract float GetLinearSleepingThreshold(BulletBody obj);
public abstract void ApplyDamping(BulletBody obj, float timeStep);
public abstract void SetMassProps(BulletBody obj, float mass, Vector3 inertia);
public abstract Vector3 GetLinearFactor(BulletBody obj);
public abstract void SetLinearFactor(BulletBody obj, Vector3 factor);
public abstract void SetCenterOfMassByPosRot(BulletBody obj, Vector3 pos, Quaternion rot);
// Add a force to the object as if its mass is one.
public abstract void ApplyCentralForce(BulletBody obj, Vector3 force);
// Set the force being applied to the object as if its mass is one.
public abstract void SetObjectForce(BulletBody obj, Vector3 force);
public abstract Vector3 GetTotalForce(BulletBody obj);
public abstract Vector3 GetTotalTorque(BulletBody obj);
public abstract Vector3 GetInvInertiaDiagLocal(BulletBody obj);
public abstract void SetInvInertiaDiagLocal(BulletBody obj, Vector3 inert);
public abstract void SetSleepingThresholds(BulletBody obj, float lin_threshold, float ang_threshold);
public abstract void ApplyTorque(BulletBody obj, Vector3 torque);
// Apply force at the given point. Will add torque to the object.
public abstract void ApplyForce(BulletBody obj, Vector3 force, Vector3 pos);
// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass.
public abstract void ApplyCentralImpulse(BulletBody obj, Vector3 imp);
// Apply impulse to the object's torque. Force is scaled by object's mass.
public abstract void ApplyTorqueImpulse(BulletBody obj, Vector3 imp);
// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces.
public abstract void ApplyImpulse(BulletBody obj, Vector3 imp, Vector3 pos);
public abstract void ClearForces(BulletBody obj);
public abstract void ClearAllForces(BulletBody obj);
public abstract void UpdateInertiaTensor(BulletBody obj);
public abstract Vector3 GetLinearVelocity(BulletBody obj);
public abstract Vector3 GetAngularVelocity(BulletBody obj);
public abstract void SetLinearVelocity(BulletBody obj, Vector3 val);
public abstract void SetAngularVelocity(BulletBody obj, Vector3 angularVelocity);
public abstract Vector3 GetVelocityInLocalPoint(BulletBody obj, Vector3 pos);
public abstract void Translate(BulletBody obj, Vector3 trans);
public abstract void UpdateDeactivation(BulletBody obj, float timeStep);
public abstract bool WantsSleeping(BulletBody obj);
public abstract void SetAngularFactor(BulletBody obj, float factor);
public abstract void SetAngularFactorV(BulletBody obj, Vector3 factor);
public abstract Vector3 GetAngularFactor(BulletBody obj);
public abstract bool IsInWorld(BulletBody obj);
public abstract void AddConstraintRef(BulletBody obj, BulletConstraint constrain);
public abstract void RemoveConstraintRef(BulletBody obj, BulletConstraint constrain);
public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index);
public abstract int GetNumConstraintRefs(BulletBody obj);
public abstract bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask);
// =====================================================================================
// btCollisionShape entries
public abstract float GetAngularMotionDisc(BulletShape shape);
public abstract float GetContactBreakingThreshold(BulletShape shape, float defaultFactor);
public abstract bool IsPolyhedral(BulletShape shape);
public abstract bool IsConvex2d(BulletShape shape);
public abstract bool IsConvex(BulletShape shape);
public abstract bool IsNonMoving(BulletShape shape);
public abstract bool IsConcave(BulletShape shape);
public abstract bool IsCompound(BulletShape shape);
public abstract bool IsSoftBody(BulletShape shape);
public abstract bool IsInfinite(BulletShape shape);
public abstract void SetLocalScaling(BulletShape shape, Vector3 scale);
public abstract Vector3 GetLocalScaling(BulletShape shape);
public abstract Vector3 CalculateLocalInertia(BulletShape shape, float mass);
public abstract int GetShapeType(BulletShape shape);
public abstract void SetMargin(BulletShape shape, float val);
public abstract float GetMargin(BulletShape shape);
// =====================================================================================
// Debugging
public abstract void DumpRigidBody(BulletWorld sim, BulletBody collisionObject);
public abstract void DumpCollisionShape(BulletWorld sim, BulletShape collisionShape);
public abstract void DumpConstraint(BulletWorld sim, BulletConstraint constrain);
public abstract void DumpActivationInfo(BulletWorld sim);
public abstract void DumpAllInfo(BulletWorld sim);
public abstract void DumpPhysicsStatistics(BulletWorld sim);
};
}

View File

@ -137,7 +137,7 @@ public sealed class BSCharacter : BSPhysObject
private void SetPhysicalProperties()
{
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody);
ZeroMotion(true);
ForcePosition = _position;
@ -152,32 +152,32 @@ public sealed class BSCharacter : BSPhysObject
// Needs to be reset especially when an avatar is recreated after crossing a region boundry.
Flying = _flying;
BulletSimAPI.SetRestitution2(PhysBody.ptr, BSParam.AvatarRestitution);
BulletSimAPI.SetMargin2(PhysShape.ptr, PhysicsScene.Params.collisionMargin);
BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale);
BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold);
PhysicsScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution);
PhysicsScene.PE.SetMargin(PhysShape, PhysicsScene.Params.collisionMargin);
PhysicsScene.PE.SetLocalScaling(PhysShape, Scale);
PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
if (BSParam.CcdMotionThreshold > 0f)
{
BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold);
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
}
UpdatePhysicalMassProperties(RawMass, false);
// Make so capsule does not fall over
BulletSimAPI.SetAngularFactorV2(PhysBody.ptr, OMV.Vector3.Zero);
PhysicsScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero);
BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT);
PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT);
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody);
// BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG);
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_DEACTIVATION);
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
// PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION);
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
// Do this after the object has been added to the world
PhysBody.collisionType = CollisionType.Avatar;
PhysBody.ApplyCollisionMask();
PhysBody.ApplyCollisionMask(PhysicsScene);
}
// The avatar's movement is controlled by this motor that speeds up and slows down
@ -210,8 +210,7 @@ public sealed class BSCharacter : BSPhysObject
if (!Flying && !IsColliding)
{
stepVelocity.Z = _velocity.Z;
DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}",
LocalID, stepVelocity);
// DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
}
// 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
@ -231,8 +230,7 @@ public sealed class BSCharacter : BSPhysObject
AddForce(moveForce, false, true);
}
*/
DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}",
LocalID, stepVelocity, _velocity, Mass, moveForce);
// DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
AddForce(moveForce, false, true);
});
}
@ -267,10 +265,10 @@ public sealed class BSCharacter : BSPhysObject
{
if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape)
{
BulletSimAPI.SetLocalScaling2(PhysShape.ptr, Scale);
PhysicsScene.PE.SetLocalScaling(PhysShape, Scale);
UpdatePhysicalMassProperties(RawMass, true);
// Make sure this change appears as a property update event
BulletSimAPI.PushUpdate2(PhysBody.ptr);
PhysicsScene.PE.PushUpdate(PhysBody);
}
});
@ -311,7 +309,7 @@ public sealed class BSCharacter : BSPhysObject
PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
{
if (PhysBody.HasPhysicalBody)
BulletSimAPI.ClearAllForces2(PhysBody.ptr);
PhysicsScene.PE.ClearAllForces(PhysBody);
});
}
public override void ZeroAngularMotion(bool inTaintTime)
@ -322,10 +320,10 @@ public sealed class BSCharacter : BSPhysObject
{
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero);
PhysicsScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero);
// The next also get rid of applied linear force but the linear velocity is untouched.
BulletSimAPI.ClearForces2(PhysBody.ptr);
PhysicsScene.PE.ClearForces(PhysBody);
}
});
}
@ -341,7 +339,7 @@ public sealed class BSCharacter : BSPhysObject
public override OMV.Vector3 Position {
get {
// Don't refetch the position because this function is called a zillion times
// _position = BulletSimAPI.GetObjectPosition2(Scene.World.ptr, LocalID);
// _position = PhysicsScene.PE.GetObjectPosition(Scene.World, LocalID);
return _position;
}
set {
@ -352,19 +350,19 @@ public sealed class BSCharacter : BSPhysObject
{
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
});
}
}
public override OMV.Vector3 ForcePosition {
get {
_position = BulletSimAPI.GetPosition2(PhysBody.ptr);
_position = PhysicsScene.PE.GetPosition(PhysBody);
return _position;
}
set {
_position = value;
PositionSanityCheck();
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
}
}
@ -420,7 +418,7 @@ public sealed class BSCharacter : BSPhysObject
{
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
});
ret = true;
}
@ -435,8 +433,8 @@ public sealed class BSCharacter : BSPhysObject
}
public override void UpdatePhysicalMassProperties(float physMass, bool inWorld)
{
OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass);
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia);
OMV.Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
PhysicsScene.PE.SetMassProps(PhysBody, physMass, localInertia);
}
public override OMV.Vector3 Force {
@ -448,7 +446,7 @@ public sealed class BSCharacter : BSPhysObject
{
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetObjectForce2(PhysBody.ptr, _force);
PhysicsScene.PE.SetObjectForce(PhysBody, _force);
});
}
}
@ -522,7 +520,7 @@ public sealed class BSCharacter : BSPhysObject
{
_currentFriction = BSParam.AvatarStandingFriction;
if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
}
}
else
@ -531,12 +529,12 @@ public sealed class BSCharacter : BSPhysObject
{
_currentFriction = BSParam.AvatarFriction;
if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetFriction2(PhysBody.ptr, _currentFriction);
PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
}
}
BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
BulletSimAPI.Activate2(PhysBody.ptr, true);
PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
PhysicsScene.PE.Activate(PhysBody, true);
}
}
public override OMV.Vector3 Torque {
@ -578,7 +576,7 @@ public sealed class BSCharacter : BSPhysObject
{
get
{
_orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr);
_orientation = PhysicsScene.PE.GetOrientation(PhysBody);
return _orientation;
}
set
@ -586,8 +584,8 @@ public sealed class BSCharacter : BSPhysObject
_orientation = value;
if (PhysBody.HasPhysicalBody)
{
// _position = BulletSimAPI.GetPosition2(BSBody.ptr);
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
// _position = PhysicsScene.PE.GetPosition(BSBody);
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
}
}
}
@ -638,9 +636,9 @@ public sealed class BSCharacter : BSPhysObject
if (PhysBody.HasPhysicalBody)
{
if (_floatOnWater)
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER);
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
else
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER);
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
}
});
}
@ -678,7 +676,7 @@ public sealed class BSCharacter : BSPhysObject
// Buoyancy is faked by changing the gravity applied to the object
float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
if (PhysBody.HasPhysicalBody)
BulletSimAPI.SetGravity2(PhysBody.ptr, new OMV.Vector3(0f, 0f, grav));
PhysicsScene.PE.SetGravity(PhysBody, new OMV.Vector3(0f, 0f, grav));
}
}
@ -736,10 +734,10 @@ public sealed class BSCharacter : BSPhysObject
PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
{
// Bullet adds this central force to the total force for this tick
DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
// DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce);
PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
}
});
}

View File

@ -37,6 +37,7 @@ public abstract class BSConstraint : IDisposable
private static string LogHeader = "[BULLETSIM CONSTRAINT]";
protected BulletWorld m_world;
protected BSScene PhysicsScene;
protected BulletBody m_body1;
protected BulletBody m_body2;
protected BulletConstraint m_constraint;
@ -48,8 +49,10 @@ public abstract class BSConstraint : IDisposable
public abstract ConstraintType Type { get; }
public bool IsEnabled { get { return m_enabled; } }
public BSConstraint()
public BSConstraint(BulletWorld world)
{
m_world = world;
PhysicsScene = m_world.physicsScene;
}
public virtual void Dispose()
@ -59,11 +62,11 @@ public abstract class BSConstraint : IDisposable
m_enabled = false;
if (m_constraint.HasPhysicalConstraint)
{
bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.ptr);
bool success = PhysicsScene.PE.DestroyConstraint(m_world, m_constraint);
m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}",
BSScene.DetailLogZero,
m_body1.ID, m_body1.ptr.ToString("X"),
m_body2.ID, m_body2.ptr.ToString("X"),
m_body1.ID, m_body1.AddrString,
m_body2.ID, m_body2.AddrString,
success);
m_constraint.Clear();
}
@ -74,7 +77,7 @@ public abstract class BSConstraint : IDisposable
{
bool ret = false;
if (m_enabled)
ret = BulletSimAPI.SetLinearLimits2(m_constraint.ptr, low, high);
ret = PhysicsScene.PE.SetLinearLimits(m_constraint, low, high);
return ret;
}
@ -82,7 +85,7 @@ public abstract class BSConstraint : IDisposable
{
bool ret = false;
if (m_enabled)
ret = BulletSimAPI.SetAngularLimits2(m_constraint.ptr, low, high);
ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high);
return ret;
}
@ -91,7 +94,7 @@ public abstract class BSConstraint : IDisposable
bool ret = false;
if (m_enabled)
{
BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.ptr, cnt);
PhysicsScene.PE.SetConstraintNumSolverIterations(m_constraint, cnt);
ret = true;
}
return ret;
@ -103,7 +106,7 @@ public abstract class BSConstraint : IDisposable
if (m_enabled)
{
// Recompute the internal transforms
BulletSimAPI.CalculateTransforms2(m_constraint.ptr);
PhysicsScene.PE.CalculateTransforms(m_constraint);
ret = true;
}
return ret;
@ -122,7 +125,7 @@ public abstract class BSConstraint : IDisposable
// Setting an object's mass to zero (making it static like when it's selected)
// automatically disables the constraints.
// If the link is enabled, be sure to set the constraint itself to enabled.
BulletSimAPI.SetConstraintEnable2(m_constraint.ptr, BSParam.NumericBool(true));
PhysicsScene.PE.SetConstraintEnable(m_constraint, BSParam.NumericBool(true));
}
else
{

View File

@ -43,46 +43,44 @@ public sealed class BSConstraint6Dof : BSConstraint
Vector3 frame1, Quaternion frame1rot,
Vector3 frame2, Quaternion frame2rot,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
: base(world)
{
m_world = world;
m_body1 = obj1;
m_body2 = obj2;
m_constraint = new BulletConstraint(
BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
m_constraint = PhysicsScene.PE.Create6DofConstraint(m_world, m_body1, m_body2,
frame1, frame1rot,
frame2, frame2rot,
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
m_enabled = true;
world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
BSScene.DetailLogZero, world.worldID,
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
}
public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 joinPoint,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
: base(world)
{
m_world = world;
m_body1 = obj1;
m_body2 = obj2;
if (!obj1.HasPhysicalBody || !obj2.HasPhysicalBody)
{
world.physicsScene.DetailLog("{0},BS6DOFConstraint,badBodyPtr,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
BSScene.DetailLogZero, world.worldID,
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
world.physicsScene.Logger.ErrorFormat("{0} Attempt to build 6DOF constraint with missing bodies: wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
LogHeader, world.worldID, obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
LogHeader, world.worldID, obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
m_enabled = false;
}
else
{
m_constraint = new BulletConstraint(
BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
m_constraint = PhysicsScene.PE.Create6DofConstraintToPoint(m_world, m_body1, m_body2,
joinPoint,
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
world.physicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
BSScene.DetailLogZero, world.worldID, m_constraint.ptr.ToString("X"),
obj1.ID, obj1.ptr.ToString("X"), obj2.ID, obj2.ptr.ToString("X"));
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
PhysicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
BSScene.DetailLogZero, world.worldID, m_constraint.AddrString,
obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
if (!m_constraint.HasPhysicalConstraint)
{
world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
@ -101,7 +99,7 @@ public sealed class BSConstraint6Dof : BSConstraint
bool ret = false;
if (m_enabled)
{
BulletSimAPI.SetFrames2(m_constraint.ptr, frameA, frameArot, frameB, frameBrot);
PhysicsScene.PE.SetFrames(m_constraint, frameA, frameArot, frameB, frameBrot);
ret = true;
}
return ret;
@ -112,9 +110,9 @@ public sealed class BSConstraint6Dof : BSConstraint
bool ret = false;
if (m_enabled)
{
BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
BulletSimAPI.SetConstraintParam2(m_constraint.ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
PhysicsScene.PE.SetConstraintParam(m_constraint, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
PhysicsScene.PE.SetConstraintParam(m_constraint, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
PhysicsScene.PE.SetConstraintParam(m_constraint, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
ret = true;
}
return ret;
@ -125,7 +123,7 @@ public sealed class BSConstraint6Dof : BSConstraint
bool ret = false;
float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
if (m_enabled)
ret = BulletSimAPI.UseFrameOffset2(m_constraint.ptr, onOff);
ret = PhysicsScene.PE.UseFrameOffset(m_constraint, onOff);
return ret;
}
@ -135,7 +133,7 @@ public sealed class BSConstraint6Dof : BSConstraint
float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
if (m_enabled)
{
ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.ptr, onOff, targetVelocity, maxMotorForce);
ret = PhysicsScene.PE.TranslationalLimitMotor(m_constraint, onOff, targetVelocity, maxMotorForce);
m_world.physicsScene.DetailLog("{0},BS6DOFConstraint,TransLimitMotor,enable={1},vel={2},maxForce={3}",
BSScene.DetailLogZero, enable, targetVelocity, maxMotorForce);
}
@ -146,7 +144,7 @@ public sealed class BSConstraint6Dof : BSConstraint
{
bool ret = false;
if (m_enabled)
ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.ptr, threshold);
ret = PhysicsScene.PE.SetBreakingImpulseThreshold(m_constraint, threshold);
return ret;
}
}

View File

@ -40,15 +40,13 @@ public sealed class BSConstraintHinge : BSConstraint
Vector3 pivotInA, Vector3 pivotInB,
Vector3 axisInA, Vector3 axisInB,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
: base(world)
{
m_world = world;
m_body1 = obj1;
m_body2 = obj2;
m_constraint = new BulletConstraint(
BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr,
pivotInA, pivotInB,
axisInA, axisInB,
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
m_constraint = PhysicsScene.PE.CreateHingeConstraint(world, obj1, obj2,
pivotInA, pivotInB, axisInA, axisInB,
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
m_enabled = true;
}

View File

@ -558,30 +558,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Friction affects are handled by this vehicle code
float friction = 0f;
BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction);
PhysicsScene.PE.SetFriction(Prim.PhysBody, friction);
// Moderate angular movement introduced by Bullet.
// TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
// Maybe compute linear and angular factor and damping from params.
float angularDamping = BSParam.VehicleAngularDamping;
BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping);
PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, angularDamping);
// Vehicles report collision events so we know when it's on the ground
BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS);
PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass);
BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia);
BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr);
Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(Prim.PhysShape, m_vehicleMass);
PhysicsScene.PE.SetMassProps(Prim.PhysBody, m_vehicleMass, localInertia);
PhysicsScene.PE.UpdateInertiaTensor(Prim.PhysBody);
Vector3 grav = PhysicsScene.DefaultGravity * (1f - Prim.Buoyancy);
BulletSimAPI.SetGravity2(Prim.PhysBody.ptr, grav);
PhysicsScene.PE.SetGravity(Prim.PhysBody, grav);
VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4}",
Prim.LocalID, m_vehicleMass, friction, localInertia, angularDamping);
}
else
{
BulletSimAPI.RemoveFromCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS);
PhysicsScene.PE.RemoveFromCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
}
}
@ -651,7 +651,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if ((m_knownChanged & m_knownChangedVelocity) != 0)
{
Prim.ForceVelocity = m_knownVelocity;
BulletSimAPI.SetInterpolationLinearVelocity2(Prim.PhysBody.ptr, VehicleVelocity);
PhysicsScene.PE.SetInterpolationLinearVelocity(Prim.PhysBody, VehicleVelocity);
}
if ((m_knownChanged & m_knownChangedForce) != 0)
@ -661,7 +661,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
Prim.ForceRotationalVelocity = m_knownRotationalVelocity;
// Fake out Bullet by making it think the velocity is the same as last time.
BulletSimAPI.SetInterpolationAngularVelocity2(Prim.PhysBody.ptr, m_knownRotationalVelocity);
PhysicsScene.PE.SetInterpolationAngularVelocity(Prim.PhysBody, m_knownRotationalVelocity);
}
if ((m_knownChanged & m_knownChangedRotationalForce) != 0)
@ -669,7 +669,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// If we set one of the values (ie, the physics engine didn't do it) we must force
// an UpdateProperties event to send the changes up to the simulator.
BulletSimAPI.PushUpdate2(Prim.PhysBody.ptr);
PhysicsScene.PE.PushUpdate(Prim.PhysBody);
}
m_knownChanged = 0;
}
@ -823,7 +823,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (!IsActive) return;
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr);
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
ForgetKnownVehicleProperties();
@ -840,7 +840,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
PushKnownChanged();
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
BulletSimAPI.DumpRigidBody2(PhysicsScene.World.ptr, Prim.PhysBody.ptr);
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
Prim.LocalID, VehiclePosition, Prim.Force, VehicleVelocity, VehicleRotationalVelocity);

View File

@ -131,10 +131,10 @@ public sealed class BSLinksetCompound : BSLinkset
{
// The origional prims are removed from the world as the shape of the root compound
// shape takes over.
BulletSimAPI.AddToCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
PhysicsScene.PE.AddToCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
PhysicsScene.PE.ForceActivationState(child.PhysBody, ActivationState.DISABLE_SIMULATION);
// We don't want collisions from the old linkset children.
BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
PhysicsScene.PE.RemoveFromCollisionFlags(child.PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
child.PhysBody.collisionType = CollisionType.LinksetChild;
@ -159,12 +159,12 @@ public sealed class BSLinksetCompound : BSLinkset
else
{
// The non-physical children can come back to life.
BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
PhysicsScene.PE.RemoveFromCollisionFlags(child.PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
child.PhysBody.collisionType = CollisionType.LinksetChild;
// Don't force activation so setting of DISABLE_SIMULATION can stay if used.
BulletSimAPI.Activate2(child.PhysBody.ptr, false);
PhysicsScene.PE.Activate(child.PhysBody, false);
ret = true;
}
return ret;
@ -196,7 +196,7 @@ public sealed class BSLinksetCompound : BSLinkset
bool ret = false;
DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), IsRoot(child));
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, IsRoot(child));
if (!IsRoot(child))
{
@ -280,8 +280,8 @@ public sealed class BSLinksetCompound : BSLinkset
{
DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
child.LocalID,
LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"),
child.LocalID, child.PhysBody.ptr.ToString("X"));
LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString,
child.LocalID, child.PhysBody.AddrString);
// Cause the child's body to be rebuilt and thus restored to normal operation
RecomputeChildWorldPosition(child, false);
@ -359,7 +359,7 @@ public sealed class BSLinksetCompound : BSLinkset
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
BulletShape newShape = cPrim.PhysShape;
cPrim.PhysShape = saveShape;
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot);
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetPos, lci.OffsetRot);
}
else
{
@ -371,7 +371,7 @@ public sealed class BSLinksetCompound : BSLinkset
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
}
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot);
PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
}
}
return false; // 'false' says to move onto the next child in the list
@ -386,12 +386,7 @@ public sealed class BSLinksetCompound : BSLinkset
Rebuilding = false;
}
BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr);
// DEBUG: see of inter-linkset collisions are causing problems for constraint linksets.
// BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
}
}
}

View File

@ -48,12 +48,15 @@ public sealed class BSLinksetConstraints : BSLinkset
{
base.Refresh(requestor);
// Queue to happen after all the other taint processing
PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
{
if (HasAnyChildren && IsRoot(requestor))
RecomputeLinksetConstraints();
});
if (HasAnyChildren && IsRoot(requestor))
{
// Queue to happen after all the other taint processing
PhysicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
{
if (HasAnyChildren && IsRoot(requestor))
RecomputeLinksetConstraints();
});
}
}
// The object is going dynamic (physical). Do any setup necessary
@ -95,7 +98,7 @@ public sealed class BSLinksetConstraints : BSLinkset
bool ret = false;
DetailLog("{0},BSLinksetConstraint.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"));
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString);
lock (m_linksetActivityLock)
{
@ -144,8 +147,8 @@ public sealed class BSLinksetConstraints : BSLinkset
DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
childx.LocalID,
rootx.LocalID, rootx.PhysBody.ptr.ToString("X"),
childx.LocalID, childx.PhysBody.ptr.ToString("X"));
rootx.LocalID, rootx.PhysBody.AddrString,
childx.LocalID, childx.PhysBody.AddrString);
PhysicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate()
{
@ -184,8 +187,8 @@ public sealed class BSLinksetConstraints : BSLinkset
DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
rootPrim.LocalID,
rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"),
childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X"),
rootPrim.LocalID, rootPrim.PhysBody.AddrString,
childPrim.LocalID, childPrim.PhysBody.AddrString,
rootPrim.Position, childPrim.Position, midPoint);
// create a constraint that allows no freedom of movement between the two objects
@ -249,14 +252,14 @@ public sealed class BSLinksetConstraints : BSLinkset
bool ret = false;
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
rootPrim.LocalID,
rootPrim.LocalID, rootPrim.PhysBody.ptr.ToString("X"),
childPrim.LocalID, childPrim.PhysBody.ptr.ToString("X"));
rootPrim.LocalID, rootPrim.PhysBody.AddrString,
childPrim.LocalID, childPrim.PhysBody.AddrString);
// Find the constraint for this link and get rid of it from the overall collection and from my list
if (PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
{
// Make the child refresh its location
BulletSimAPI.PushUpdate2(childPrim.PhysBody.ptr);
PhysicsScene.PE.PushUpdate(childPrim.PhysBody);
ret = true;
}
@ -283,11 +286,8 @@ public sealed class BSLinksetConstraints : BSLinkset
float linksetMass = LinksetMass;
LinksetRoot.UpdatePhysicalMassProperties(linksetMass, true);
// DEBUG: see of inter-linkset collisions are causing problems
// BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass);
LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass);
foreach (BSPhysObject child in m_children)
{
@ -304,11 +304,7 @@ public sealed class BSLinksetConstraints : BSLinkset
}
constrain.RecomputeConstraintVariables(linksetMass);
// DEBUG: see of inter-linkset collisions are causing problems
// BulletSimAPI.SetCollisionFilterMask2(child.BSBody.ptr,
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
// BulletSimAPI.DumpConstraint2(PhysicsScene.World.ptr, constrain.Constraint.ptr); // DEBUG DEBUG
// PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
}
}

View File

@ -280,7 +280,7 @@ public static class BSParam
(s,cf,p,v) => { s.UnmanagedParams[0].gravity = cf.GetFloat(p, v); },
(s) => { return s.UnmanagedParams[0].gravity; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{s.UnmanagedParams[0].gravity=x;}, p, PhysParameterEntry.APPLY_TO_NONE, v); },
(s,o,v) => { BulletSimAPI.SetGravity2(s.World.ptr, new Vector3(0f,0f,v)); } ),
(s,o,v) => { s.PE.SetGravity(o.PhysBody, new Vector3(0f,0f,v)); } ),
new ParameterDefn("LinearDamping", "Factor to damp linear movement per second (0.0 - 1.0)",
@ -288,49 +288,49 @@ public static class BSParam
(s,cf,p,v) => { LinearDamping = cf.GetFloat(p, v); },
(s) => { return LinearDamping; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearDamping=x;}, p, l, v); },
(s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, AngularDamping); } ),
(s,o,v) => { s.PE.SetDamping(o.PhysBody, v, AngularDamping); } ),
new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
0f,
(s,cf,p,v) => { AngularDamping = cf.GetFloat(p, v); },
(s) => { return AngularDamping; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularDamping=x;}, p, l, v); },
(s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, LinearDamping, v); } ),
(s,o,v) => { s.PE.SetDamping(o.PhysBody, LinearDamping, v); } ),
new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
0.2f,
(s,cf,p,v) => { DeactivationTime = cf.GetFloat(p, v); },
(s) => { return DeactivationTime; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{DeactivationTime=x;}, p, l, v); },
(s,o,v) => { BulletSimAPI.SetDeactivationTime2(o.PhysBody.ptr, v); } ),
(s,o,v) => { s.PE.SetDeactivationTime(o.PhysBody, v); } ),
new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
0.8f,
(s,cf,p,v) => { LinearSleepingThreshold = cf.GetFloat(p, v); },
(s) => { return LinearSleepingThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{LinearSleepingThreshold=x;}, p, l, v); },
(s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
(s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ),
new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
1.0f,
(s,cf,p,v) => { AngularSleepingThreshold = cf.GetFloat(p, v); },
(s) => { return AngularSleepingThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{AngularSleepingThreshold=x;}, p, l, v); },
(s,o,v) => { BulletSimAPI.SetSleepingThresholds2(o.PhysBody.ptr, v, v); } ),
(s,o,v) => { s.PE.SetSleepingThresholds(o.PhysBody, v, v); } ),
new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
0f, // set to zero to disable
(s,cf,p,v) => { CcdMotionThreshold = cf.GetFloat(p, v); },
(s) => { return CcdMotionThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdMotionThreshold=x;}, p, l, v); },
(s,o,v) => { BulletSimAPI.SetCcdMotionThreshold2(o.PhysBody.ptr, v); } ),
(s,o,v) => { s.PE.SetCcdMotionThreshold(o.PhysBody, v); } ),
new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
0f,
(s,cf,p,v) => { CcdSweptSphereRadius = cf.GetFloat(p, v); },
(s) => { return CcdSweptSphereRadius; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{CcdSweptSphereRadius=x;}, p, l, v); },
(s,o,v) => { BulletSimAPI.SetCcdSweptSphereRadius2(o.PhysBody.ptr, v); } ),
(s,o,v) => { s.PE.SetCcdSweptSphereRadius(o.PhysBody, v); } ),
new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
0.1f,
(s,cf,p,v) => { ContactProcessingThreshold = cf.GetFloat(p, v); },
(s) => { return ContactProcessingThreshold; },
(s,p,l,v) => { s.UpdateParameterObject((x)=>{ContactProcessingThreshold=x;}, p, l, v); },
(s,o,v) => { BulletSimAPI.SetContactProcessingThreshold2(o.PhysBody.ptr, v); } ),
(s,o,v) => { s.PE.SetContactProcessingThreshold(o.PhysBody, v); } ),
new ParameterDefn("TerrainImplementation", "Type of shape to use for terrain (0=heightmap, 1=mesh)",
(float)BSTerrainPhys.TerrainImplementation.Mesh,

View File

@ -67,6 +67,11 @@ public abstract class BSPhysObject : PhysicsActor
PhysObjectName = name;
TypeName = typeName;
// We don't have any physical representation yet.
PhysBody = new BulletBody(localID);
PhysShape = new BulletShape();
// A linkset of just me
Linkset = BSLinkset.Factory(PhysicsScene, this);
LastAssetBuildFailed = false;
@ -303,7 +308,7 @@ public abstract class BSPhysObject : PhysicsActor
PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
{
if (PhysBody.HasPhysicalBody)
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
});
}
else
@ -319,7 +324,7 @@ public abstract class BSPhysObject : PhysicsActor
{
// Make sure there is a body there because sometimes destruction happens in an un-ideal order.
if (PhysBody.HasPhysicalBody)
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
});
}
// Return 'true' if the simulator wants collision events

View File

@ -111,10 +111,7 @@ public sealed class BSPrim : BSPhysObject
_mass = CalculateMass();
// No body or shape yet
PhysBody = new BulletBody(LocalID);
PhysShape = new BulletShape();
// Cause linkset variables to be initialized (like mass)
Linkset.Refresh(this);
DetailLog("{0},BSPrim.constructor,call", LocalID);
@ -123,7 +120,7 @@ public sealed class BSPrim : BSPhysObject
{
CreateGeomAndObject(true);
CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr);
CurrentCollisionFlags = PhysicsScene.PE.GetCollisionFlags(PhysBody);
});
}
@ -256,7 +253,7 @@ public sealed class BSPrim : BSPhysObject
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
{
if (PhysBody.HasPhysicalBody)
BulletSimAPI.ClearAllForces2(PhysBody.ptr);
PhysicsScene.PE.ClearAllForces(PhysBody);
});
}
public override void ZeroAngularMotion(bool inTaintTime)
@ -268,8 +265,8 @@ public sealed class BSPrim : BSPhysObject
// DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
}
});
}
@ -295,7 +292,7 @@ public sealed class BSPrim : BSPhysObject
*/
// don't do the GetObjectPosition for root elements because this function is called a zillion times.
// _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
// _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody);
return _position;
}
set {
@ -321,14 +318,14 @@ public sealed class BSPrim : BSPhysObject
}
public override OMV.Vector3 ForcePosition {
get {
_position = BulletSimAPI.GetPosition2(PhysBody.ptr);
_position = PhysicsScene.PE.GetPosition(PhysBody);
return _position;
}
set {
_position = value;
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
ActivateIfPhysical(false);
}
}
@ -408,10 +405,10 @@ public sealed class BSPrim : BSPhysObject
{
if (IsStatic)
{
BulletSimAPI.SetGravity2(PhysBody.ptr, PhysicsScene.DefaultGravity);
PhysicsScene.PE.SetGravity(PhysBody, PhysicsScene.DefaultGravity);
Inertia = OMV.Vector3.Zero;
BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
PhysicsScene.PE.SetMassProps(PhysBody, 0f, Inertia);
PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
}
else
{
@ -422,18 +419,18 @@ public sealed class BSPrim : BSPhysObject
// 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);
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody);
}
// The computation of mass props requires gravity to be set on the object.
BulletSimAPI.SetGravity2(PhysBody.ptr, grav);
PhysicsScene.PE.SetGravity(PhysBody, grav);
Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass);
BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia);
BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
Inertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass);
PhysicsScene.PE.SetMassProps(PhysBody, physMass, Inertia);
PhysicsScene.PE.UpdateInertiaTensor(PhysBody);
// center of mass is at the zero of the object
// DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation);
// DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(PhysBody, ForcePosition, ForceOrientation);
DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2},grav={3},inWorld={4}", LocalID, physMass, Inertia, grav, inWorld);
if (inWorld)
@ -443,7 +440,7 @@ public sealed class BSPrim : BSPhysObject
// Must set gravity after it has been added to the world because, for unknown reasons,
// adding the object resets the object's gravity to world gravity
BulletSimAPI.SetGravity2(PhysBody.ptr, grav);
PhysicsScene.PE.SetGravity(PhysBody, grav);
}
}
@ -486,7 +483,7 @@ public sealed class BSPrim : BSPhysObject
DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force);
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, _force);
PhysicsScene.PE.ApplyCentralForce(PhysBody, _force);
ActivateIfPhysical(false);
}
}
@ -586,7 +583,7 @@ public sealed class BSPrim : BSPhysObject
_velocity = value;
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity);
PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
ActivateIfPhysical(false);
}
}
@ -652,9 +649,9 @@ public sealed class BSPrim : BSPhysObject
{
if (PhysBody.HasPhysicalBody)
{
// _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
// _position = PhysicsScene.PE.GetObjectPosition(PhysicsScene.World, BSBody);
// DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
}
});
}
@ -664,13 +661,13 @@ public sealed class BSPrim : BSPhysObject
{
get
{
_orientation = BulletSimAPI.GetOrientation2(PhysBody.ptr);
_orientation = PhysicsScene.PE.GetOrientation(PhysBody);
return _orientation;
}
set
{
_orientation = value;
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
}
}
public override int PhysicsActorType {
@ -726,7 +723,7 @@ public sealed class BSPrim : BSPhysObject
// Mangling all the physical properties requires the object not be in the physical world.
// This is a NOOP if the object is not in the world (BulletSim and Bullet ignore objects not found).
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody);
// Set up the object physicalness (does gravity and collisions move this object)
MakeDynamic(IsStatic);
@ -743,7 +740,7 @@ public sealed class BSPrim : BSPhysObject
AddObjectToPhysicalWorld();
// Rebuild its shape
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
// Recompute any linkset parameters.
// When going from non-physical to physical, this re-enables the constraints that
@ -765,28 +762,28 @@ public sealed class BSPrim : BSPhysObject
if (makeStatic)
{
// Become a Bullet 'static' object type
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
// Stop all movement
ZeroMotion(true);
// Set various physical properties so other object interact properly
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction);
PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution);
// Mass is zero which disables a bunch of physics stuff in Bullet
UpdatePhysicalMassProperties(0f, false);
// Set collision detection parameters
if (BSParam.CcdMotionThreshold > 0f)
{
BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold);
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
}
// The activation state is 'disabled' so Bullet will not try to act on it.
// BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
// PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_SIMULATION);
// Start it out sleeping and physical actions could wake it up.
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING);
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ISLAND_SLEEPING);
// This collides like a static object
PhysBody.collisionType = CollisionType.Static;
@ -797,22 +794,22 @@ public sealed class BSPrim : BSPhysObject
else
{
// Not a Bullet static object
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_STATIC_OBJECT);
// Set various physical properties so other object interact properly
MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, true);
BulletSimAPI.SetFriction2(PhysBody.ptr, matAttrib.friction);
BulletSimAPI.SetRestitution2(PhysBody.ptr, matAttrib.restitution);
PhysicsScene.PE.SetFriction(PhysBody, matAttrib.friction);
PhysicsScene.PE.SetRestitution(PhysBody, matAttrib.restitution);
// per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
// Since this can be called multiple times, only zero forces when becoming physical
// BulletSimAPI.ClearAllForces2(BSBody.ptr);
// PhysicsScene.PE.ClearAllForces(BSBody);
// For good measure, make sure the transform is set through to the motion state
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
// Center of mass is at the center of the object
// DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation);
// DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation);
// A dynamic object has mass
UpdatePhysicalMassProperties(RawMass, false);
@ -820,22 +817,22 @@ public sealed class BSPrim : BSPhysObject
// Set collision detection parameters
if (BSParam.CcdMotionThreshold > 0f)
{
BulletSimAPI.SetCcdMotionThreshold2(PhysBody.ptr, BSParam.CcdMotionThreshold);
BulletSimAPI.SetCcdSweptSphereRadius2(PhysBody.ptr, BSParam.CcdSweptSphereRadius);
PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
}
// Various values for simulation limits
BulletSimAPI.SetDamping2(PhysBody.ptr, BSParam.LinearDamping, BSParam.AngularDamping);
BulletSimAPI.SetDeactivationTime2(PhysBody.ptr, BSParam.DeactivationTime);
BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold);
BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, BSParam.ContactProcessingThreshold);
PhysicsScene.PE.SetDamping(PhysBody, BSParam.LinearDamping, BSParam.AngularDamping);
PhysicsScene.PE.SetDeactivationTime(PhysBody, BSParam.DeactivationTime);
PhysicsScene.PE.SetSleepingThresholds(PhysBody, BSParam.LinearSleepingThreshold, BSParam.AngularSleepingThreshold);
PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
// This collides like an object.
PhysBody.collisionType = CollisionType.Dynamic;
// Force activation of the object so Bullet will act on it.
// Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG);
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
// There might be special things needed for implementing linksets.
Linkset.MakeDynamic(this);
@ -848,7 +845,7 @@ public sealed class BSPrim : BSPhysObject
// the functions after this one set up the state of a possibly newly created collision body.
private void MakeSolid(bool makeSolid)
{
CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(PhysBody.ptr);
CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(PhysBody);
if (makeSolid)
{
// Verify the previous code created the correct shape for this type of thing.
@ -856,7 +853,7 @@ public sealed class BSPrim : BSPhysObject
{
m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType);
}
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
}
else
{
@ -864,7 +861,7 @@ public sealed class BSPrim : BSPhysObject
{
m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType);
}
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_NO_CONTACT_RESPONSE);
// Change collision info from a static object to a ghosty collision object
PhysBody.collisionType = CollisionType.VolumeDetect;
@ -877,7 +874,7 @@ public sealed class BSPrim : BSPhysObject
private void ActivateIfPhysical(bool forceIt)
{
if (IsPhysical && PhysBody.HasPhysicalBody)
BulletSimAPI.Activate2(PhysBody.ptr, forceIt);
PhysicsScene.PE.Activate(PhysBody, forceIt);
}
// Turn on or off the flag controlling whether collision events are returned to the simulator.
@ -885,11 +882,11 @@ public sealed class BSPrim : BSPhysObject
{
if (wantsCollisionEvents)
{
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
}
else
{
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
}
}
@ -900,14 +897,14 @@ public sealed class BSPrim : BSPhysObject
{
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody);
// TODO: Fix this. Total kludge because adding object to world resets its gravity to default.
// Replace this when the new AddObjectToWorld function is complete.
BulletSimAPI.SetGravity2(PhysBody.ptr, ComputeGravity());
PhysicsScene.PE.SetGravity(PhysBody, ComputeGravity());
// Collision filter can be set only when the object is in the world
if (!PhysBody.ApplyCollisionMask())
if (!PhysBody.ApplyCollisionMask(PhysicsScene))
{
m_log.ErrorFormat("{0} Failed setting object collision mask: id={1}", LogHeader, LocalID);
DetailLog("{0},BSPrim.UpdatePhysicalParameters,failedSetMaskGroup,cType={1}", LocalID, PhysBody.collisionType);
@ -944,9 +941,9 @@ public sealed class BSPrim : BSPhysObject
PhysicsScene.TaintedObject("BSPrim.setFloatOnWater", delegate()
{
if (_floatOnWater)
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER);
CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
else
CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_FLOATS_ON_WATER);
CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
});
}
}
@ -972,7 +969,7 @@ public sealed class BSPrim : BSPhysObject
_rotationalVelocity = value;
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
PhysicsScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
ActivateIfPhysical(false);
}
}
@ -1064,7 +1061,7 @@ public sealed class BSPrim : BSPhysObject
DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce);
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.ApplyCentralForce2(PhysBody.ptr, addForce);
PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce);
ActivateIfPhysical(false);
}
});
@ -1088,7 +1085,7 @@ public sealed class BSPrim : BSPhysObject
{
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.ApplyTorque2(PhysBody.ptr, angForce);
PhysicsScene.PE.ApplyTorque(PhysBody, angForce);
ActivateIfPhysical(false);
}
});
@ -1111,7 +1108,7 @@ public sealed class BSPrim : BSPhysObject
{
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse);
PhysicsScene.PE.ApplyTorqueImpulse(PhysBody, applyImpulse);
ActivateIfPhysical(false);
}
});

View File

@ -26,6 +26,7 @@
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
@ -42,14 +43,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
public sealed class BSScene : PhysicsScene, IPhysicsParameters
{
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS SCENE]";
internal static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
internal static readonly string LogHeader = "[BULLETS SCENE]";
// The name of the region we're working for.
public string RegionName { get; private set; }
public string BulletSimVersion = "?";
// The handle to the underlying managed or unmanaged version of Bullet being used.
public string BulletEngineName { get; private set; }
public BSAPITemplate PE;
public Dictionary<uint, BSPhysObject> PhysObjects;
public BSShapeCollection Shapes;
@ -99,11 +104,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Pinned memory used to pass step information between managed and unmanaged
internal int m_maxCollisionsPerFrame;
internal CollisionDesc[] m_collisionArray;
internal GCHandle m_collisionArrayPinnedHandle;
internal int m_maxUpdatesPerFrame;
internal EntityProperties[] m_updateArray;
internal GCHandle m_updateArrayPinnedHandle;
public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
public const uint GROUNDPLANE_ID = 1;
@ -149,12 +152,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// A pointer to an instance if this structure is passed to the C++ code
// Used to pass basic configuration values to the unmanaged code.
internal ConfigurationParameters[] UnmanagedParams;
GCHandle m_paramsHandle;
// Handle to the callback used by the unmanaged code to call into the managed code.
// Used for debug logging.
// Need to store the handle in a persistant variable so it won't be freed.
private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
// Sometimes you just have to log everything.
public Logging.LogWriter PhysicsLogging;
@ -187,16 +184,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Allocate pinned memory to pass parameters.
UnmanagedParams = new ConfigurationParameters[1];
m_paramsHandle = GCHandle.Alloc(UnmanagedParams, GCHandleType.Pinned);
// Set default values for physics parameters plus any overrides from the ini file
GetInitialParameterValues(config);
// allocate more pinned memory close to the above in an attempt to get the memory all together
m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame];
m_collisionArrayPinnedHandle = GCHandle.Alloc(m_collisionArray, GCHandleType.Pinned);
m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
// Get the connection to the physics engine (could be native or one of many DLLs)
PE = SelectUnderlyingBulletEngine(BulletEngineName);
// Enable very detailed logging.
// By creating an empty logger when not logging, the log message invocation code
@ -211,22 +204,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
PhysicsLogging = new Logging.LogWriter();
}
// If Debug logging level, enable logging from the unmanaged code
m_DebugLogCallbackHandle = null;
if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
{
m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
if (PhysicsLogging.Enabled)
// The handle is saved in a variable to make sure it doesn't get freed after this call
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
else
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
}
// Get the version of the DLL
// TODO: this doesn't work yet. Something wrong with marshaling the returned string.
// BulletSimVersion = BulletSimAPI.GetVersion();
// m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
// Allocate memory for returning of the updates and collisions from the physics engine
m_collisionArray = new CollisionDesc[m_maxCollisionsPerFrame];
m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
// The bounding box for the simulated world. The origin is 0,0,0 unless we're
// a child in a mega-region.
@ -234,11 +214,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// area. It tracks active objects no matter where they are.
Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
// m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
World = new BulletWorld(0, this, BulletSimAPI.Initialize2(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(),
m_DebugLogCallbackHandle));
World = PE.Initialize(worldExtent, Params, m_maxCollisionsPerFrame, ref m_collisionArray, m_maxUpdatesPerFrame, ref m_updateArray);
Constraints = new BSConstraintCollection(World);
@ -268,6 +244,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
{
BSParam.SetParameterConfigurationValues(this, pConfig);
// There are two Bullet implementations to choose from
BulletEngineName = pConfig.GetString("BulletEngine", "BulletUnmanaged");
// Very detailed logging for physics debugging
// TODO: the boolean values can be moved to the normal parameter processing.
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
@ -309,16 +288,41 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
return ret;
}
// Called directly from unmanaged code so don't do much
private void BulletLogger(string msg)
// Select the connection to the actual Bullet implementation.
// The main engine selection is the engineName up to the first hypen.
// So "Bullet-2.80-OpenCL-Intel" specifies the 'bullet' class here and the whole name
// is passed to the engine to do its special selection, etc.
private BSAPITemplate SelectUnderlyingBulletEngine(string engineName)
{
m_log.Debug("[BULLETS UNMANAGED]:" + msg);
}
// For the moment, do a simple switch statement.
// Someday do fancyness with looking up the interfaces in the assembly.
BSAPITemplate ret = null;
// Called directly from unmanaged code so don't do much
private void BulletLoggerPhysLog(string msg)
{
DetailLog("[BULLETS UNMANAGED]:" + msg);
string selectionName = engineName.ToLower();
int hyphenIndex = engineName.IndexOf("-");
if (hyphenIndex > 0)
selectionName = engineName.ToLower().Substring(0, hyphenIndex - 1);
switch (selectionName)
{
case "bulletunmanaged":
ret = new BSAPIUnman(engineName, this);
break;
case "bulletxna":
// ret = new BSAPIXNA(engineName, this);
break;
}
if (ret == null)
{
m_log.ErrorFormat("{0) COULD NOT SELECT BULLET ENGINE: '[BulletSim]PhysicsEngine' must be either 'BulletUnmanaged-*' or 'BulletXNA-*'", LogHeader);
}
else
{
m_log.WarnFormat("{0} Selected bullet engine {1} -> {2}/{3}", LogHeader, engineName, ret.BulletEngineName, ret.BulletEngineVersion);
}
return ret;
}
public override void Dispose()
@ -355,7 +359,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
}
// Anything left in the unmanaged code should be cleaned out
BulletSimAPI.Shutdown2(World.ptr);
PE.Shutdown(World);
// Not logging any more
PhysicsLogging.Close();
@ -468,9 +472,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
LastTimeStep = timeStep;
int updatedEntityCount = 0;
IntPtr updatedEntitiesPtr;
int collidersCount = 0;
IntPtr collidersPtr;
int beforeTime = 0;
int simTime = 0;
@ -486,6 +488,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
TriggerPreStepEvent(timeStep);
// the prestep actions might have added taints
numTaints += _taintOperations.Count;
ProcessTaints();
InTaintTime = false; // Only used for debugging so locking is not necessary.
@ -493,23 +496,25 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
// Only enable this in a limited test world with few objects.
if (m_physicsPhysicalDumpEnabled)
BulletSimAPI.DumpAllInfo2(World.ptr);
PE.DumpAllInfo(World);
// step the physical world one interval
m_simulationStep++;
int numSubSteps = 0;
try
{
if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
if (PhysicsLogging.Enabled)
beforeTime = Util.EnvironmentTickCount();
numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount);
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps,
updatedEntityCount, collidersCount, ObjectsWithCollisions.Count);
if (PhysicsLogging.Enabled)
{
simTime = Util.EnvironmentTickCountSubtract(beforeTime);
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps,
updatedEntityCount, collidersCount, ObjectsWithCollisions.Count);
}
}
catch (Exception e)
{
@ -521,8 +526,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
collidersCount = 0;
}
// Don't have to use the pointers passed back since we know it is the same pinned memory we passed in.
// Get a value for 'now' so all the collision and update routines don't have to get their own.
SimulationNowTime = Util.EnvironmentTickCount();
@ -564,7 +567,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Objects that are done colliding are removed from the ObjectsWithCollisions list.
// Not done above because it is inside an iteration of ObjectWithCollisions.
// This complex collision processing is required to create an empty collision
// event call after all collisions have happened on an object. This enables
// event call after all real collisions have happened on an object. This enables
// the simulator to generate the 'collision end' event.
if (ObjectsWithNoMoreCollisions.Count > 0)
{
@ -593,11 +596,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
// Only enable this in a limited test world with few objects.
if (m_physicsPhysicalDumpEnabled)
BulletSimAPI.DumpAllInfo2(World.ptr);
PE.DumpAllInfo(World);
// The physics engine returns the number of milliseconds it simulated this call.
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
// Multiply by 55 to give a nominal frame rate of 55.
// Multiply by a fixed nominal frame rate to give a rate similar to the simulator (usually 55).
return (float)numSubSteps * m_fixedTimeStep * 1000f * NominalFrameRate;
}

View File

@ -141,9 +141,9 @@ public sealed class BSShapeCollection : IDisposable
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,body={1}", body.ID, body);
PhysicsScene.TaintedObject(inTaintTime, "BSShapeCollection.ReferenceBody", delegate()
{
if (!BulletSimAPI.IsInWorld2(body.ptr))
if (!PhysicsScene.PE.IsInWorld(body))
{
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, body.ptr);
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, body);
if (DDetail) DetailLog("{0},BSShapeCollection.ReferenceBody,addedToWorld,ref={1}", body.ID, body);
}
});
@ -166,15 +166,15 @@ public sealed class BSShapeCollection : IDisposable
// If the caller needs to know the old body is going away, pass the event up.
if (bodyCallback != null) bodyCallback(body);
if (BulletSimAPI.IsInWorld2(body.ptr))
if (PhysicsScene.PE.IsInWorld(body))
{
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, body.ptr);
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, body);
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,removingFromWorld. Body={1}", body.ID, body);
}
// Zero any reference to the shape so it is not freed when the body is deleted.
BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, body.ptr, IntPtr.Zero);
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, body.ptr);
PhysicsScene.PE.SetCollisionShape(PhysicsScene.World, body, new BulletShape());
PhysicsScene.PE.DestroyObject(PhysicsScene.World, body);
});
}
}
@ -259,9 +259,9 @@ public sealed class BSShapeCollection : IDisposable
{
// Native shapes are not tracked and are released immediately
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,ptr={1},taintTime={2}",
BSScene.DetailLogZero, shape.ptr.ToString("X"), inTaintTime);
BSScene.DetailLogZero, shape.AddrString, inTaintTime);
if (shapeCallback != null) shapeCallback(shape);
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape);
}
else
{
@ -332,36 +332,36 @@ public sealed class BSShapeCollection : IDisposable
// Called at taint-time.
private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback)
{
if (!BulletSimAPI.IsCompound2(shape.ptr))
if (!PhysicsScene.PE.IsCompound(shape))
{
// Failed the sanity check!!
PhysicsScene.Logger.ErrorFormat("{0} Attempt to free a compound shape that is not compound!! type={1}, ptr={2}",
LogHeader, shape.type, shape.ptr.ToString("X"));
LogHeader, shape.type, shape.AddrString);
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,notACompoundShape,type={1},ptr={2}",
BSScene.DetailLogZero, shape.type, shape.ptr.ToString("X"));
BSScene.DetailLogZero, shape.type, shape.AddrString);
return;
}
int numChildren = BulletSimAPI.GetNumberOfCompoundChildren2(shape.ptr);
int numChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(shape);
if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceCompound,shape={1},children={2}", BSScene.DetailLogZero, shape, numChildren);
for (int ii = numChildren - 1; ii >= 0; ii--)
{
IntPtr childShape = BulletSimAPI.RemoveChildShapeFromCompoundShapeIndex2(shape.ptr, ii);
BulletShape childShape = PhysicsScene.PE.RemoveChildShapeFromCompoundShapeIndex(shape, ii);
DereferenceAnonCollisionShape(childShape);
}
BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr);
PhysicsScene.PE.DeleteCollisionShape(PhysicsScene.World, shape);
}
// Sometimes we have a pointer to a collision shape but don't know what type it is.
// Figure out type and call the correct dereference routine.
// Called at taint-time.
private void DereferenceAnonCollisionShape(IntPtr cShape)
private void DereferenceAnonCollisionShape(BulletShape shapeInfo)
{
MeshDesc meshDesc;
HullDesc hullDesc;
BulletShape shapeInfo = new BulletShape(cShape);
IntPtr cShape = shapeInfo.ptr;
if (TryGetMeshByPtr(cShape, out meshDesc))
{
shapeInfo.type = BSPhysicsShapeType.SHAPE_MESH;
@ -376,13 +376,13 @@ public sealed class BSShapeCollection : IDisposable
}
else
{
if (BulletSimAPI.IsCompound2(cShape))
if (PhysicsScene.PE.IsCompound(shapeInfo))
{
shapeInfo.type = BSPhysicsShapeType.SHAPE_COMPOUND;
}
else
{
if (BulletSimAPI.IsNativeShape2(cShape))
if (PhysicsScene.PE.IsNativeShape(shapeInfo))
{
shapeInfo.isNativeShape = true;
shapeInfo.type = BSPhysicsShapeType.SHAPE_BOX; // (technically, type doesn't matter)
@ -400,7 +400,7 @@ public sealed class BSShapeCollection : IDisposable
else
{
PhysicsScene.Logger.ErrorFormat("{0} Could not decypher shape type. Region={1}, addr={2}",
LogHeader, PhysicsScene.RegionName, cShape.ToString("X"));
LogHeader, PhysicsScene.RegionName, shapeInfo.AddrString);
}
}
@ -467,7 +467,7 @@ public sealed class BSShapeCollection : IDisposable
// Get the scale of any existing shape so we can see if the new shape is same native type and same size.
OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero;
if (prim.PhysShape.HasPhysicalShape)
scaleOfExistingShape = BulletSimAPI.GetLocalScaling2(prim.PhysShape.ptr);
scaleOfExistingShape = PhysicsScene.PE.GetLocalScaling(prim.PhysShape);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}",
prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.type);
@ -570,19 +570,15 @@ public sealed class BSShapeCollection : IDisposable
if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
{
// The proper scale has been calculated in the prim.
newShape = new BulletShape(
// Bullet's capsule total height is the passed "height + (radius * 2)" so, the base
// capsule is radius of 0.5f (1 diameter) and height of two (1.0f + 0.5f * 2)".
// This must be taken into account when computing the scaling of the capsule.
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
, shapeType);
newShape = PhysicsScene.PE.BuildCapsuleShape(PhysicsScene.World, 1f, 1f, prim.Scale);
if (DDetail) DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
}
else
{
// Native shapes are scaled in Bullet so set the scaling to the size
newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
newShape = PhysicsScene.PE.BuildNativeShape(PhysicsScene.World, nativeShapeData);
}
if (!newShape.HasPhysicalShape)
{
@ -629,13 +625,14 @@ public sealed class BSShapeCollection : IDisposable
private BulletShape CreatePhysicalMesh(string objName, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{
BulletShape newShape = new BulletShape();
IMesh meshData = null;
IntPtr meshPtr = IntPtr.Zero;
MeshDesc meshDesc;
if (Meshes.TryGetValue(newMeshKey, out meshDesc))
{
// If the mesh has already been built just use it.
meshPtr = meshDesc.ptr;
newShape = new BulletShape(meshDesc.ptr, BSPhysicsShapeType.SHAPE_MESH);
}
else
{
@ -658,11 +655,10 @@ public sealed class BSShapeCollection : IDisposable
// m_log.DebugFormat("{0}: BSShapeCollection.CreatePhysicalMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}",
// LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count);
meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World,
indices.GetLength(0), indices, vertices.Count, verticesAsFloats);
}
}
BulletShape newShape = new BulletShape(meshPtr, BSPhysicsShapeType.SHAPE_MESH);
newShape.shapeKey = newMeshKey;
return newShape;
@ -700,12 +696,14 @@ public sealed class BSShapeCollection : IDisposable
private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
{
BulletShape newShape = new BulletShape();
IntPtr hullPtr = IntPtr.Zero;
HullDesc hullDesc;
if (Hulls.TryGetValue(newHullKey, out hullDesc))
{
// If the hull shape already is created, just use it.
hullPtr = hullDesc.ptr;
newShape = new BulletShape(hullDesc.ptr, BSPhysicsShapeType.SHAPE_HULL);
}
else
{
@ -793,11 +791,10 @@ public sealed class BSShapeCollection : IDisposable
}
}
// create the hull data structure in Bullet
hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls);
newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
}
}
BulletShape newShape = new BulletShape(hullPtr, BSPhysicsShapeType.SHAPE_HULL);
newShape.shapeKey = newHullKey;
return newShape;
@ -819,12 +816,12 @@ public sealed class BSShapeCollection : IDisposable
// Don't need to do this as the shape is freed when the new root shape is created below.
// DereferenceShape(prim.PhysShape, true, shapeCallback);
BulletShape cShape = new BulletShape(
BulletSimAPI.CreateCompoundShape2(PhysicsScene.World.ptr, false), BSPhysicsShapeType.SHAPE_COMPOUND);
BulletShape cShape = PhysicsScene.PE.CreateCompoundShape(PhysicsScene.World, false);
// Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
CreateGeomMeshOrHull(prim, shapeCallback);
BulletSimAPI.AddChildShapeToCompoundShape2(cShape.ptr, prim.PhysShape.ptr, OMV.Vector3.Zero, OMV.Quaternion.Identity);
PhysicsScene.PE.AddChildShapeToCompoundShape(cShape, prim.PhysShape, OMV.Vector3.Zero, OMV.Quaternion.Identity);
if (DDetail) DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
prim.LocalID, cShape, prim.PhysShape);
@ -932,7 +929,7 @@ public sealed class BSShapeCollection : IDisposable
// If not a solid object, body is a GhostObject. Otherwise a RigidBody.
if (!mustRebuild)
{
CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.PhysBody.ptr);
CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(prim.PhysBody);
if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY
|| !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT)
{
@ -947,20 +944,16 @@ public sealed class BSShapeCollection : IDisposable
DereferenceBody(prim.PhysBody, true, bodyCallback);
BulletBody aBody;
IntPtr bodyPtr = IntPtr.Zero;
if (prim.IsSolid)
{
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
prim.LocalID, prim.RawPosition, prim.RawOrientation);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
aBody = PhysicsScene.PE.CreateBodyFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody);
}
else
{
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
prim.LocalID, prim.RawPosition, prim.RawOrientation);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
aBody = PhysicsScene.PE.CreateGhostFromShape(sim, shape, prim.LocalID, prim.RawPosition, prim.RawOrientation);
if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody);
}
aBody = new BulletBody(prim.LocalID, bodyPtr);
ReferenceBody(aBody, true);

View File

@ -91,11 +91,17 @@ public abstract class BSShape
// All shapes have a static call to get a reference to the physical shape
// protected abstract static BSShape GetReference();
// Returns a string for debugging that uniquily identifies the memory used by this instance
public string AddrString
{
get { return ptr.ToString("X"); }
}
public override string ToString()
{
StringBuilder buff = new StringBuilder();
buff.Append("<p=");
buff.Append(ptr.ToString("X"));
buff.Append(AddrString);
buff.Append(",s=");
buff.Append(type.ToString());
buff.Append(",k=");
@ -126,7 +132,8 @@ public class BSShapeNative : BSShape
BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
{
// Native shapes are not shared and are always built anew.
return new BSShapeNative(physicsScene, prim, shapeType, shapeKey);
//return new BSShapeNative(physicsScene, prim, shapeType, shapeKey);
return null;
}
private BSShapeNative(BSScene physicsScene, BSPhysObject prim,
@ -141,14 +148,15 @@ public class BSShapeNative : BSShape
nativeShapeData.HullKey = (ulong)shapeKey;
/*
if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
{
ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale);
ptr = PhysicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale);
physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
}
else
{
ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData);
ptr = PhysicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData);
}
if (ptr == IntPtr.Zero)
{
@ -157,15 +165,18 @@ public class BSShapeNative : BSShape
}
type = shapeType;
key = (UInt64)shapeKey;
*/
}
// Make this reference to the physical shape go away since native shapes are not shared.
public override void Dereference(BSScene physicsScene)
{
/*
// Native shapes are not tracked and are released immediately
physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr);
PhysicsScene.PE.DeleteCollisionShape(physicsScene.World, this);
ptr = IntPtr.Zero;
// Garbage collection will free up this instance.
*/
}
}

View File

@ -44,7 +44,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
{
static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]";
BulletHeightMapInfo m_mapInfo = null;
BulletHMapInfo m_mapInfo = null;
// Constructor to build a default, flat heightmap terrain.
public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
@ -58,7 +58,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
{
initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION;
}
m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero);
m_mapInfo = new BulletHMapInfo(id, initialMap);
m_mapInfo.minCoords = minTerrainCoords;
m_mapInfo.maxCoords = maxTerrainCoords;
m_mapInfo.terrainRegionBase = TerrainBase;
@ -72,7 +72,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
Vector3 minCoords, Vector3 maxCoords)
: base(physicsScene, regionBase, id)
{
m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero);
m_mapInfo = new BulletHMapInfo(id, initialMap);
m_mapInfo.minCoords = minCoords;
m_mapInfo.maxCoords = maxCoords;
m_mapInfo.minZ = minCoords.Z;
@ -91,13 +91,11 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
// Using the information in m_mapInfo, create the physical representation of the heightmap.
private void BuildHeightmapTerrain()
{
m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
m_mapInfo.minCoords, m_mapInfo.maxCoords,
m_mapInfo.heightMap, BSParam.TerrainCollisionMargin);
// Create the terrain shape from the mapInfo
m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
BSPhysicsShapeType.SHAPE_TERRAIN);
m_mapInfo.terrainShape = PhysicsScene.PE.CreateTerrainShape( m_mapInfo.ID,
new Vector3(m_mapInfo.sizeX, m_mapInfo.sizeY, 0), m_mapInfo.minZ, m_mapInfo.maxZ,
m_mapInfo.heightMap, 1f, BSParam.TerrainCollisionMargin);
// The terrain object initial position is at the center of the object
Vector3 centerPos;
@ -105,27 +103,26 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f);
centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f);
m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr,
m_mapInfo.ID, centerPos, Quaternion.Identity));
m_mapInfo.terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_mapInfo.terrainShape,
m_mapInfo.ID, centerPos, Quaternion.Identity);
// Set current terrain attributes
BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainFriction);
BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, BSParam.TerrainHitFraction);
BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, BSParam.TerrainRestitution);
BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
PhysicsScene.PE.SetFriction(m_mapInfo.terrainBody, BSParam.TerrainFriction);
PhysicsScene.PE.SetHitFraction(m_mapInfo.terrainBody, BSParam.TerrainHitFraction);
PhysicsScene.PE.SetRestitution(m_mapInfo.terrainBody, BSParam.TerrainRestitution);
PhysicsScene.PE.SetCollisionFlags(m_mapInfo.terrainBody, CollisionFlags.CF_STATIC_OBJECT);
// Return the new terrain to the world of physical objects
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_mapInfo.terrainBody);
// redo its bounding box now that it is in the world
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_mapInfo.terrainBody);
m_mapInfo.terrainBody.collisionType = CollisionType.Terrain;
m_mapInfo.terrainBody.ApplyCollisionMask();
m_mapInfo.terrainBody.ApplyCollisionMask(PhysicsScene);
// Make it so the terrain will not move or be considered for movement.
BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
PhysicsScene.PE.ForceActivationState(m_mapInfo.terrainBody, ActivationState.DISABLE_SIMULATION);
return;
}
@ -137,10 +134,9 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
{
if (m_mapInfo.terrainBody.HasPhysicalBody)
{
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_mapInfo.terrainBody);
// Frees both the body and the shape.
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr);
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_mapInfo.terrainBody);
}
}
m_mapInfo = null;

View File

@ -133,20 +133,17 @@ public sealed class BSTerrainManager : IDisposable
public void CreateInitialGroundPlaneAndTerrain()
{
// The ground plane is here to catch things that are trying to drop to negative infinity
BulletShape groundPlaneShape = new BulletShape(
BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f,
BSParam.TerrainCollisionMargin),
BSPhysicsShapeType.SHAPE_GROUNDPLANE);
m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID,
Vector3.Zero, Quaternion.Identity));
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr);
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_groundPlane.ptr);
BulletShape groundPlaneShape = PhysicsScene.PE.CreateGroundPlaneShape(BSScene.GROUNDPLANE_ID, 1f, BSParam.TerrainCollisionMargin);
m_groundPlane = PhysicsScene.PE.CreateBodyWithDefaultMotionState(groundPlaneShape,
BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity);
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_groundPlane);
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_groundPlane);
// Ground plane does not move
BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION);
PhysicsScene.PE.ForceActivationState(m_groundPlane, ActivationState.DISABLE_SIMULATION);
// Everything collides with the ground plane.
m_groundPlane.collisionType = CollisionType.Groundplane;
m_groundPlane.ApplyCollisionMask();
m_groundPlane.ApplyCollisionMask(PhysicsScene);
// Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain.
BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize);
@ -158,9 +155,9 @@ public sealed class BSTerrainManager : IDisposable
{
if (m_groundPlane.HasPhysicalBody)
{
if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr))
if (PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_groundPlane))
{
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr);
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_groundPlane);
}
m_groundPlane.Clear();
}

View File

@ -91,9 +91,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}",
ID, indicesCount, indices.Length, verticesCount, vertices.Length);
m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
indicesCount, indices, verticesCount, vertices),
BSPhysicsShapeType.SHAPE_MESH);
m_terrainShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World, indicesCount, indices, verticesCount, vertices);
if (!m_terrainShape.HasPhysicalShape)
{
// DISASTER!!
@ -106,7 +104,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
Vector3 pos = regionBase;
Quaternion rot = Quaternion.Identity;
m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainShape.ptr, ID, pos, rot));
m_terrainBody = PhysicsScene.PE.CreateBodyWithDefaultMotionState(m_terrainShape, ID, pos, rot);
if (!m_terrainBody.HasPhysicalBody)
{
// DISASTER!!
@ -116,34 +114,34 @@ public sealed class BSTerrainMesh : BSTerrainPhys
}
// Set current terrain attributes
BulletSimAPI.SetFriction2(m_terrainBody.ptr, BSParam.TerrainFriction);
BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, BSParam.TerrainHitFraction);
BulletSimAPI.SetRestitution2(m_terrainBody.ptr, BSParam.TerrainRestitution);
BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
PhysicsScene.PE.SetFriction(m_terrainBody, BSParam.TerrainFriction);
PhysicsScene.PE.SetHitFraction(m_terrainBody, BSParam.TerrainHitFraction);
PhysicsScene.PE.SetRestitution(m_terrainBody, BSParam.TerrainRestitution);
PhysicsScene.PE.SetCollisionFlags(m_terrainBody, CollisionFlags.CF_STATIC_OBJECT);
// Static objects are not very massive.
BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero);
PhysicsScene.PE.SetMassProps(m_terrainBody, 0f, Vector3.Zero);
// Put the new terrain to the world of physical objects
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, m_terrainBody);
// Redo its bounding box now that it is in the world
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr);
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, m_terrainBody);
m_terrainBody.collisionType = CollisionType.Terrain;
m_terrainBody.ApplyCollisionMask();
m_terrainBody.ApplyCollisionMask(PhysicsScene);
// Make it so the terrain will not move or be considered for movement.
BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
PhysicsScene.PE.ForceActivationState(m_terrainBody, ActivationState.DISABLE_SIMULATION);
}
public override void Dispose()
{
if (m_terrainBody.HasPhysicalBody)
{
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, m_terrainBody);
// Frees both the body and the shape.
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr);
PhysicsScene.PE.DestroyObject(PhysicsScene.World, m_terrainBody);
}
}

View File

@ -35,7 +35,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// These hold pointers to allocated objects in the unmanaged space.
// The physics engine controller class created at initialization
public struct BulletWorld
public class BulletWorld
{
public BulletWorld(uint worldId, BSScene bss, IntPtr xx)
{
@ -50,7 +50,7 @@ public struct BulletWorld
}
// An allocated Bullet btRigidBody
public struct BulletBody
public class BulletBody
{
public BulletBody(uint id) : this(id, IntPtr.Zero)
{
@ -72,23 +72,32 @@ public struct BulletBody
public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
// Apply the specificed collision mask into the physical world
public bool ApplyCollisionMask()
public bool ApplyCollisionMask(BSScene physicsScene)
{
// Should assert the body has been added to the physical world.
// (The collision masks are stored in the collision proxy cache which only exists for
// a collision body that is in the world.)
return BulletSimAPI.SetCollisionGroupMask2(ptr,
return physicsScene.PE.SetCollisionGroupMask(this,
BulletSimData.CollisionTypeMasks[collisionType].group,
BulletSimData.CollisionTypeMasks[collisionType].mask);
}
// Used for log messages for a unique display of the memory/object allocated to this instance
public string AddrString
{
get
{
return ptr.ToString("X");
}
}
public override string ToString()
{
StringBuilder buff = new StringBuilder();
buff.Append("<id=");
buff.Append(ID.ToString());
buff.Append(",p=");
buff.Append(ptr.ToString("X"));
buff.Append(AddrString);
buff.Append(",c=");
buff.Append(collisionType);
buff.Append(">");
@ -96,9 +105,14 @@ public struct BulletBody
}
}
public struct BulletShape
public class BulletShape
{
public BulletShape(IntPtr xx) : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN)
public BulletShape()
: this(IntPtr.Zero, BSPhysicsShapeType.SHAPE_UNKNOWN)
{
}
public BulletShape(IntPtr xx)
: this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN)
{
}
public BulletShape(IntPtr xx, BSPhysicsShapeType typ)
@ -119,11 +133,20 @@ public struct BulletShape
}
public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } }
// Used for log messages for a unique display of the memory/object allocated to this instance
public string AddrString
{
get
{
return ptr.ToString("X");
}
}
public override string ToString()
{
StringBuilder buff = new StringBuilder();
buff.Append("<p=");
buff.Append(ptr.ToString("X"));
buff.Append(AddrString);
buff.Append(",s=");
buff.Append(type.ToString());
buff.Append(",k=");
@ -136,7 +159,7 @@ public struct BulletShape
}
// An allocated Bullet btConstraint
public struct BulletConstraint
public class BulletConstraint
{
public BulletConstraint(IntPtr xx)
{
@ -149,17 +172,25 @@ public struct BulletConstraint
ptr = IntPtr.Zero;
}
public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } }
// Used for log messages for a unique display of the memory/object allocated to this instance
public string AddrString
{
get
{
return ptr.ToString("X");
}
}
}
// An allocated HeightMapThing which holds various heightmap info.
// Made a class rather than a struct so there would be only one
// instance of this and C# will pass around pointers rather
// than making copies.
public class BulletHeightMapInfo
public class BulletHMapInfo
{
public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) {
public BulletHMapInfo(uint id, float[] hm) {
ID = id;
Ptr = xx;
heightMap = hm;
terrainRegionBase = OMV.Vector3.Zero;
minCoords = new OMV.Vector3(100f, 100f, 25f);
@ -168,7 +199,6 @@ public class BulletHeightMapInfo
sizeX = sizeY = 256f;
}
public uint ID;
public IntPtr Ptr;
public float[] heightMap;
public OMV.Vector3 terrainRegionBase;
public OMV.Vector3 minCoords;

View File

@ -31,6 +31,7 @@ CRASHES
VEHICLES TODO LIST:
=================================================
Angular motor direction is global coordinates rather than local coordinates
Border crossing with linked vehicle causes crash
Vehicles (Move smoothly)
Add vehicle collisions so IsColliding is properly reported.
@ -60,7 +61,8 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
BULLETSIM TODO LIST:
=================================================
Avatar density is WAY off. Compare and calibrate with what's in SL.
Implement an avatar mesh shape. The Bullet capsule is way too limited.
Consider just hand creating a vertex/index array in a new BSShapeAvatar.
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.
@ -78,7 +80,7 @@ Small physical objects do not interact correctly
Create chain of .5x.5x.1 torui and make all but top physical so to hang.
The chain will fall apart and pairs will dance around on ground
Chains of 1x1x.2 will stay connected but will dance.
Chains above 2x2x.4 are move stable and get stablier as torui get larger.
Chains above 2x2x.4 are more stable and get stablier as torui get larger.
Add PID motor for avatar movement (slow to stop, ...)
setForce should set a constant force. Different than AddImpulse.
Implement raycast.
@ -97,9 +99,16 @@ Selecting and deselecting physical objects causes CPU processing time to jump
Re-implement buoyancy as a separate force on the object rather than diddling gravity.
Register a pre-step event to add the force.
More efficient memory usage when passing hull information from BSPrim to BulletSim
Avatar movement motor check for zero or small movement. Somehow suppress small movements
when avatar has stopped and is just standing. Simple test for near zero has
the problem of preventing starting up (increase from zero) especially when falling.
Physical and phantom will drop through the terrain
LINKSETS
======================================================
Offset the center of the linkset to be the geometric center of all the prims
Not quite the same as the center-of-gravity
Linksets should allow collisions to individual children
Add LocalID to children shapes in LinksetCompound and create events for individuals
LinksetCompound: when one of the children changes orientation (like tires
@ -162,6 +171,9 @@ Avatar attachments have no mass? http://forums-archive.secondlife.com/54/f0/3179
INTERNAL IMPROVEMENT/CLEANUP
=================================================
Create the physical wrapper classes (BulletBody, BulletShape) by methods on
BSAPITemplate and make their actual implementation Bullet engine specific.
For the short term, just call the existing functions in ShapeCollection.
Consider moving prim/character body and shape destruction in destroy()
to postTimeTime rather than protecting all the potential sets that
might have been queued up.
@ -195,6 +207,9 @@ Should taints check for existance or activeness of target?
keeps the object from being freed, but that is just an accident.
Possibly have and 'active' flag that is checked by the taint processor?
Parameters for physics logging should be moved from BSScene to BSParam (at least boolean ones)
Can some of the physical wrapper classes (BulletBody, BulletWorld, BulletShape) be 'sealed'?
There are TOO MANY interfaces from BulletSim core to Bullet itself
Think of something to eliminate one or more of the layers
THREADING
=================================================
@ -253,3 +268,5 @@ llApplyImpulse()
(Resolution: tested on SL and OS. AddForce scales the force for timestep)
llSetBuoyancy() (DONE)
(Resolution: Bullet resets object gravity when added to world. Moved set gravity)
Avatar density is WAY off. Compare and calibrate with what's in SL. (DONE)
(Resolution: set default density to 3.5 (from 60) which is closer to SL)

View File

@ -96,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected float m_ScriptDelayFactor = 1.0f;
protected float m_ScriptDistanceFactor = 1.0f;
protected float m_MinTimerInterval = 0.5f;
protected float m_recoilScaleFactor = 0.0f;
protected DateTime m_timer = DateTime.Now;
protected bool m_waitingForScriptAnswer = false;
@ -146,6 +147,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// there's an smtp config, so load in the snooze time.
EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME);
}
// Rezzing an object with a velocity can create recoil. This feature seems to have been
// removed from recent versions of SL. The code computes recoil (vel*mass) and scales
// it by this factor. May be zero to turn off recoil all together.
m_recoilScaleFactor = m_ScriptEngine.Config.GetFloat("RecoilScaleFactor", m_recoilScaleFactor);
}
public override Object InitializeLifetimeService()
@ -2829,10 +2834,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
PhysicsActor pa = new_group.RootPart.PhysActor;
//Recoil.
if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
{
//Recoil.
llApplyImpulse(vel * groupmass, 0);
Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
if (recoil != Vector3.Zero)
{
llApplyImpulse(recoil, 0);
}
}
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
});

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1747,6 +1747,7 @@
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
<Reference name="BulletXNA.dll" path="../../../../bin/"/>
<Reference name="log4net.dll" path="../../../../bin/"/>
<Files>